2016-06-14 91 views
-1

我是Java和JavaFX的新手我的代码有一个很大的问题。我使用JavaFX和Scene Builder工作。观察者和线程的问题

我的目标是计算一个房间的热方程,现在我试图在标签上显示我的结果。

我在一个循环中计算方程,标签应该每次更新以显示最后的结果。我在YouTube上找到了一个视频,我试图这样做,但它不起作用。 =(也许你能帮助我: -/

这不是完整的代码,我删除了不必要的东西

我没有得到任何错误,但它不工作

youtube video

这是我第一次班,我计算出的热量:

import java.lang.reflect.Array; 
import java.util.ArrayList; 
import java.util.concurrent.*; 

public class Raum { 
    int zeit; 
    int startTemperatur; 

    // length, width, height 
    int x; 
    int y; 
    int z; 

    double sensorwert; 
    String sensorwertString; 
    private final List<TemperaturSensorListener> listeners = new ArrayList(); 
    //and so on 

    public Raum() {  
     ExecutorService service = Executors.newCachedThreadPool(); 
     service.submit(() -> { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 

      } 
      temperaturverlauf(); // is this correct? 
      for (TemperaturSensorListener listener : listeners) { 
       listener.onReadingChanged(); 
      } 
     });  
    } 

    // Calculate Heat equation 
    public void temperaturverlauf() { 
     double[][][] raumTemp = new double[x][y][z]; 
     double[][][] raumTempneu = new double[x][y][z]; 
     zeit = 0; 

     //Start temperature for every position 
     for (int posX = 0; posX < x; posX++) { 
      for (int posY = 0; posY < y; posY++) { 
       for (int posZ = 0; posZ < z; posZ++) { 
        raumTemp[posX][posY][posZ] = startTemperatur;  
       } 
      } 
     } 

     /*Heater*/ 
     raumTemp[0][0][0] = startHeizung; 

     while (zeit < 100) { 
      for (int posX = 0; posX < x; posX++) { 
       for (int posY = 0; posY < y; posY++) { 
        for (int posZ = 0; posZ < z; posZ++) { 
         // Compute the heat of every quadrant in the room 
         // upper left corner 
         if (posX == 0 && posY == Array.getLength(raumTemp[0]) - 1 && posZ == 0) { 
          raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ] - temperaturleitfähigkeit * (4 * raumTemp[posX][posY][posZ] - raumTemp[posX + 1][posY][posZ] - raumTemp[posX][posY - 1][posZ] - raumTemp[posX][posY][posZ + 1] - mauertemp); 
         }  
         // Upper right corner , walls and so on 
        }  
       } 
      } 

      raumTemp = raumTempneu; 

      // print out the heat of the sensor position and convert it to a string. this String has to be displayed in a label 
      System.out.println("raum1:" + raumTemp[Array.getLength(raumTemp) - 1][Array.getLength(raumTemp[0]) - 1][1]); 
      sensorwert = raumTemp[Array.getLength(raumTemp) - 1][Array.getLength(raumTemp[0]) - 1][1]; 
      sensorwertString = Double.toString(sensorwert); 
     } 
    } 

    public void addListener(TemperaturSensorListener listener) { 
     listeners.add(listener); 
    } 

    public String getSensorwertString() { 
     return sensorwertString; 
    } 
} 

这是我第二类,在它的标签:

import javafx.application.Platform; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.*; 

import java.net.URL; 
import java.util.ResourceBundle; 

public class FXMLDocumentController implements Initializable { 
    private Raum r = new Raum(); 

    // Slider for heater temperature 
    @FXML 
    private Slider slider1; 

    // Label with the String from the other class 
    @FXML 
    private final Label anzeigetempaktuell1 = new Label(r.getSensorwertString()); 

    // Textfields so user can type in the size of the room 
    @FXML 
    private TextField laenge; 

    @FXML 
    private TextField breite; 

    @FXML 
    private TextField hoehe; 

    // starttemperature 
    @FXML 
    private TextField tempAktuell; 

    // target temperature 
    @FXML 
    private TextField tempGewuenscht; 

    //this button should start the application after the user typed in the required values 
    @FXML 
    private Button button; 

    @FXML 
    private void handleButtonAction(ActionEvent event) { 
     r.temperaturverlauf();// i think this is wrong 
    } 

    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     slider1.setMin(17); 
     slider1.setMax(85); 
     slider1.setValue(45); 

     slider1.valueProperty().addListener((ov, old_val, new_val) -> { 
      r.maxHeizung = (double) new_val; 
      System.out.println(r.maxHeizung); 
     }); 

     // this is a relevant part i think but i think its the same like in the video 
     r.addListener(new TemperaturSensorListener() { 
      @Override 
      public void onReadingChanged() { 
       updateTemperatureLabel(); 
      } 

      private void updateTemperatureLabel() { 
       Platform.runLater(() -> anzeigetempaktuell1.setText(r.getSensorwertString())); 
      } 
     }); 
    } 
} 

这是最后一堂课:

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.*; 
import javafx.stage.Stage; 

public class SmartHome extends Application { 
    @Override 
    public void start(Stage stage) throws Exception { 
     Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); 

     Scene scene = new Scene(root); 

     stage.setScene(scene); 
     stage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

的问题是,我这个FXMLDocumentController类工作,并在视频中的人都没有。我不知道将所有内容写入initialize方法是否正确。我不知道该怎么办。

+1

您可以在代码中修复缩进吗?这是很难阅读的。 –

+0

我试过了:-o我希望现在好一点。谢谢 –

+2

出于某种原因,粘贴代码中的空白量是[令我疯狂](https://www.youtube.com/watch?v=SsoOG6ZeyUI),所以我删除了一些并修复了一些标点符号。 – jewelsea

回答

0

您的sleep呼叫位于temperaturverlauf的呼叫之外。您发送给执行程序的任务会一次休眠1000毫秒,然后运行所有计算,将输出转储至System.out。然后,最后,它会打电话给你的观察员。

听起来这不是你想要的。如果您想在计算过程中暂停一下,那么这就是您需要拨打sleep电话的地方。同样,如果您希望观察员在每次值发生变化时都通知观察员,则在值更改处您需要拨打onReadingChanged

我推荐一个体系结构修订版来使这个重新设计变得更容易:编写你的计算方法,以便它只计算一个变化。这将使您更容易区分您的担忧,以便其他代理可以按照以下顺序进行操作:

  1. 调用方法来计算一个温度变化。
  2. 用新值更新标签。
  3. 睡一秒钟。