[英]JavaFx8 Properties Binding causing “No Fx8 Application thread”
我的程序不能正常工作。 我寫了一個名為“ Uhr
”的類,這是一個簡單的計時器。 為了顯示計時器,我還寫了一個名為“ UhrMain
”的類,它應該創建一個GUI。 一切都很完美,但每當我的StringProperty
在類“ Uhr
”中被更改時,我就會得到一個“ No Fx8 Application thread
” No Fx8 Application thread
。 所以標簽沒有得到更新。
為了將時間綁定到標簽,我使用了以下代碼:
timeLabel.textProperty().bind(eineUhr.zeitProperty());
我完全不知道為什么這不起作用。
Uhr.java:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uhr;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
*
* @author
*/
public class Uhr extends Thread{
private final StringProperty zeit;
private int mSec;
private int sec;
private boolean running;
public Uhr(){
zeit = new SimpleStringProperty();
running = false;
}
public final StringProperty zeitProperty(){
return zeit;
}
public final String getZeit(){
return zeit.get();
}
public synchronized void startTimer(){
this.running = true;
}
public synchronized void stopTimer(){
this.running = false;
}
@Override
public void run(){
while(true){
try {
Thread.sleep(100);
mSec++;
if(mSec >= 10){
mSec = 0;
sec++;
zeit.set("Zeit: " + sec);
System.out.println(zeit.get());
}
} catch (InterruptedException ex) {
Logger.getLogger(Uhr.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
MainTest.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uhr;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* @author
*/
public class UhrMain extends Application {
private VBox box;
private Button startButton;
private Button stopButton;
private Label timeLabel;
private Uhr eineUhr;
@Override
public void start(Stage primaryStage) {
eineUhr = new Uhr();
eineUhr.start();
box = new VBox();
timeLabel = new Label("Zeit: ");
startButton = new Button("Start");
//startButton.setStyle("-fx-background-color: green");
startButton.setOnAction((event) -> eineUhr.startTimer());
stopButton = new Button("Stopp");
//stopButton.setStyle("-fx-background-color: red");
stopButton.setOnAction((event) -> eineUhr.stopTimer());
box.getChildren().addAll(timeLabel,startButton,stopButton);
timeLabel.textProperty().bind(eineUhr.zeitProperty());
Scene scene = new Scene(box);
primaryStage.setScene(scene);
primaryStage.setTitle("Stoppuhr");
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
我感謝任何幫助。
您應該將StringProperty
實例上的set
方法調用包裝到Platform.runLater(Runnable runnable)
以通過確保通過JavaFX Application Thread
對其進行修改來防止此問題,實際上調用set
會對您產生直接影響綁定的UI,只允許JavaFX Application Thread
修改您的UI,因為Java FX Components
不是線程安全的。
Platform.runLater(() -> zeit.set("Zeit: " + sec));
應該更改此方法:
@Override
public void run(){
while(true){
try {
Thread.sleep(100);
mSec++;
if(mSec >= 10){
mSec = 0;
sec++;
Platform.runLater(()->zeit.set("Zeit: " + sec));
System.out.println(zeit.get());
}
} catch (InterruptedException ex) {
Logger.getLogger(Uhr.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
它為我修復了崩潰。
我有一段時間沒有使用過JavaFX,但我認為你只需要在正確的UI線程中運行任何與UI相關的東西(就像大多數UI框架一樣,只有一個Thread可以訪問UI元素)。
Platform.runLater(new Runnable() {
@Override public void run() {
timeLabel.textProperty().bind(eineUhr.zeitProperty());
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.