我一直在學習關於JavaFX的任務和使用這些用Platform.runLater
或任務的updateValue
方法等,但應用程序線程進行通信,我Task
需要知道當用戶按下一個按鈕GUI,因爲這可能會改變任務的updateValue
方法返回的值。我如何去做這件事?我知道如何響應單線程應用程序上的按鈕事件,但我不確定如何以線程安全的方式處理它。的JavaFX應用程序線程任務間通信
更新:
這是我到目前爲止,這是實現按鈕事件的一個明智的辦法?
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.PixelFormat;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.control.Button;
import java.nio.IntBuffer;
public class TaskExample extends Application {
private Canvas canvas;
private PixelWriter pixel_writer;
@Override
public void start(Stage primaryStage) throws Exception {
canvas = new Canvas(256, 256);
pixel_writer = canvas.getGraphicsContext2D().getPixelWriter();
MyTask task = new MyTask();
task.valueProperty().addListener((c) -> {
if(task.getValue() != null) {
update(task.getValue());
}
});
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
Button button = new Button("Button 1");
// On the button click event it calls the eventFired() method
button.setOnAction((event) -> {
task.eventFired();
});
Pane pane = new VBox();
pane.getChildren().addAll(canvas, button);
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}
public void update(IntBuffer data) {
pixel_writer.setPixels(
0,
0,
256,
256,
PixelFormat.getIntArgbInstance(),
data,
256
);
}
public static void main(String[] args) {
launch(args);
}
class MyTask extends Task<IntBuffer> {
public void eventFired() {
System.out.println("Event fired");
}
public void update(IntBuffer data) {
updateValue(data);
}
@Override
protected IntBuffer call() throws InterruptedException {
while(true) {
for (int i=0; i<3; i++) {
Thread.sleep(1000);
IntBuffer data = IntBuffer.allocate(256*256);
for(int j=0; j<256*256; j++) {
switch(i) {
case 0: data.put(0xFF0000FF); break;
case 1: data.put(0xFF00FF00); break;
case 2: data.put(0xFFFF0000); break;
}
}
data.rewind();
update(data);
}
}
}
}
}
您發佈的代碼沒有任何問題,但實際上並沒有描述您所描述的內容:即兩個線程不會互動。當您按下按鈕時,任務將在FX應用程序線程上向控制檯顯示一條消息。但沒有任何更改會影響後臺線程上發生的情況。所以,如果你想問「這項工作」,你需要實際展示一些你所描述的代碼。 –
啊,我沒有意識到他們沒有互動。如何在後臺線程上運行'eventFired'方法? – soarjay
你不能在後臺線程上運行它。但大概只是給控制檯發送消息並不是你真正想要做的。你想做些什麼(除了你知道這個階段的人以外沒有人會改變'call'方法中發生的事情,不是嗎? –