[英]JavaFX - Concurrency and updating label
我對這些代碼有疑問。 我想制作一個應用程序,只要按下“切換按鈕”,它就會同時在標簽中顯示隨機值。 那就是我創建的,可以正常工作,但是幾秒鍾后的窗口太可怕了。 我究竟做錯了什么?
以下是產生隨機值的類代碼:
public class ValueMaker{
private StringPropterty x, y, z;
private Random generator;
private boolean isStarted = false;
private int randomizedX(){ return generator.nextInt(10); }
private int randomizedY(){ return generator.nextInt(10); }
private int randomizedZ(){ return generator.nextInt(10); }
public StringProperty xProperty(){ return x; }
public StringProperty yProperty(){ return y; }
public StringProperty zProperty() { return z; }
public ValueMaker(){
x = new SimpleStringProperty("0");
y = new SimpleStringProperty("0");
z = new SimpleStringProperty("0");
generator = new Random();
}
private void setValues(){
Platform.runLater(new Runnable() {
@Override
public void run() {
x.set(String.valueOf(randomizedX()));
y.set(String.valueOf(randomizedY()));
z.set(String.valueOf(randomizedZ()));
}
});
}
public startRandomize(){
isStarted = true;
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (isStarted){
setValues();
}
}
});
t.start();
}
public stopRandomize(){
isStarted = false;
}
}
這是一段控制器代碼,它調用了這些方法:
@FXML
private void initialize(){
labelX.textProperty().bind(ValueMaker.xProperty());
labelY.textProperty().bind(ValueMaker.yProperty());
labelZ.textProperty().bind(ValueMaker.zProperty());
startRandomizeButton.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue==true){
ValueMaker.startRandomize();
}
else{
ValueMaker.stopRandomize();
}
}
});
}
您正在通過連續調用Platform.runLater
來阻塞JavaFX應用程序線程。 實現此目的的最佳方法是使用AnimationTimer
,該AnimationTimer
在活動的每個幀中都會被調用。
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
x.set(String.valueOf(randomizedX()));
y.set(String.valueOf(randomizedY()));
z.set(String.valueOf(randomizedZ()));
}
};
然后在您的示例中調用計時器:
startRandomizeButton.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
// newValue==true is not required
if (newValue){
timer.start();
}
else{
timer.stop();
}
});
}
我認為當您啟動線程時-它會使用所有可用資源。 它在無限循環中工作,並生成隨機數而不會發生“中斷”。
嘗試將sleep
添加到線程的循環中,以便將其暫停數毫秒並釋放一點CPU。
無論如何,您可能都需要添加睡眠,否則隨機標簽的變化會太快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.