2016-06-14 80 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. 睡一秒鐘。