我有一些信號處理數據大致以50Hz的頻率輸入。我需要根據信號值實時更新矩形的不透明度。我正在嘗試在JavaFX 8中開發UI。Java FX8用戶界面更新延遲
暫時我正在模擬使用JavaFX服務中隨機數生成器的信號值。
我正在使用Platform.runLater來更新UI,但是這不會實時更新值,我通讀了類似的問題,他人遇到類似的問題,並且正常的建議是不要經常調用Platform.runLater,而是批量更新。
在我的情況下,如果我批量更新,不透明度變化的頻率將不等於信號頻率。
有關如何實現此目的的任何想法?
public class FlickerController
{
@FXML
private Rectangle leftBox;
@FXML
private Rectangle rightBox;
@FXML
private ColorPicker leftPrimary;
@FXML
private ColorPicker leftSecondary;
@FXML
private ColorPicker rightPrimary;
@FXML
private ColorPicker rightSecondary;
@FXML
private Slider leftFrequency;
@FXML
private Slider rightFrequency;
@FXML
private Button startButton;
@FXML
private Label leftfreqlabel;
@FXML
private Label rightfreqlabel;
@FXML
private Label rightBrightness;
@FXML
private Label leftBrightness;
private boolean running = false;
DoubleProperty leftopacity = new SimpleDoubleProperty(1);
DoubleProperty rightopacity = new SimpleDoubleProperty(1);
private FlickerThread ftLeft;
private FlickerThread ftRight;
public void initialize()
{
leftopacity.addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
{
Platform.runLater(new Runnable()
{
@Override
public void run()
{
double brightness = leftopacity.doubleValue();
leftBrightness.setText(""+brightness);
leftBox.opacityProperty().set(brightness);
}
});
}
});
rightopacity.addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
{
Platform.runLater(new Runnable()
{
@Override
public void run()
{
double brightness = rightopacity.doubleValue();
rightBrightness.setText(""+brightness);
rightBox.opacityProperty().set(brightness);
}
});
}
});
startButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event)
{
if(running)
{
synchronized(this)
{
running=false;
}
startButton.setText("Start");
}
else
{
running=true;
ftLeft = new FlickerThread((int)leftFrequency.getValue(),leftopacity);
ftRight = new FlickerThread((int)rightFrequency.getValue(), rightopacity);
try
{
ftLeft.start();
ftRight.start();
}
catch(Throwable t)
{
t.printStackTrace();
}
startButton.setText("Stop");
}
}
});
leftFrequency.valueProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
{
leftfreqlabel.setText(newValue.intValue()+"");
}
});
rightFrequency.valueProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue)
{
rightfreqlabel.setText(newValue.intValue()+"");
}
});
}
class FlickerThread extends Service<Void>
{
private long sleeptime;
DoubleProperty localval = new SimpleDoubleProperty(1) ;
public FlickerThread(int freq, DoubleProperty valtoBind)
{
this.sleeptime = (1/freq)*1000;
valtoBind.bind(localval);
}
@Override
protected Task <Void>createTask()
{
return new Task<Void>() {
@Override
protected Void call() throws Exception
{
while(running)
{
double val = Math.random();
System.out.println(val);
localval.setValue(val);
Thread.sleep(sleeptime);
}
return null;
}
};
}
}
}
不綁定與被修改的屬性在場景圖中的東西(例如,節點不透明度)在另一個線程(它可能會導致不可預知的行爲)。另外,我認爲你不應該在不透明度改變偵聽器中運行調用,也不應該在JavaFX應用程序線程上同步語句。這只是一個快速審查,你可能有其他問題。此外,leftFrequency滑塊的值範圍是多少? – jewelsea
兩個滑塊的頻率範圍在1-100之間 – abacusreader
我發現這個[http://stackoverflow.com/questions/23488280/throttling-javafx-gui-updates],我正在修改我的代碼來使用AtomicReference來實現我想要更新 – abacusreader