我正在从另一个类(即 StartClient
)启动 JavaFX gui 应用程序。
public class StartClient extends Application {
private Table gui;
@Override
public void start(Stage stage) throws Exception {
gui = new Table();
gui.start(stage);
我启动一个 Task
,通过它连接到服务器并接收服务器分配的轮次,这是我使用 Platform.runLater
在 gui 中设置的。
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
connectToServer(); // connect to server, set up socket, i/o streams
Object read = inputStream.readObject();
if (read instanceof String) {
turn = //parseInt from read
Platform.runLater(new Runnable() {
public void run() {
gui.setPlayerID(turn);
}
});
}
}
}; //end of task
我的问题是,我想获取玩家的移动(如果轮到他们)并将其发送回服务器,执行如下操作:
if(networkClientID == gui.getState().getTurn()){
do {
action = Table.getAction(); //static getAction returns the move from the table if there was one
} while (action == -1);
outputStream.writeObject(action + ""); // write out turn
}
我是否在后台Thread
上执行此操作(我正在从gui读取静态变量,或者我应该在javaFX线程中执行此操作,即在Platform.runLater
内,我已经尝试过,但没有得到任何结果,我的程序被卡住了。)
欢迎任何有关如何解决此问题的建议、帮助、建议。谢谢!
最佳答案
恕我直言,最好的方法是将您的数据(即:转弯)放在一个单独的类中。
请记住,JavaFX 是一种 MVC 模型。您可以使用 Model 类来保存此信息并引用此信息。如果将对模型类的引用传递给另一个线程,则必须同步该线程。
这样你就可以将事情分开。您的 Controller 只会控制场景正在做什么。您的模型将存储该信息。
This answer为如何实现这一点提供了一个非常好的起点。
例如,我有一个任务(文件观察器),我将其称为如下所示。这是我的 Controller 的快速快照:
public class myController {
private Context context;
private Executor executor;
...
myBtn.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
task = new ResultFileWatcher(context); //context is my singleton model class
executor.execute(task);
}
}
...
}
我的扩展类看起来有点像这样。这是我的 Task
(注意,它扩展了 Task
类),它将在不同的 Thread
中运行。
public class ResultFileWatcher extends Task<Object> {
private Context context;
public ResultFileWatcher(Context context) {
this.context = context;
}
...
@Override
protected Object call() throws Exception {
//...
}
}
希望这有帮助!
关于JavaFX从另一个线程访问gui按钮操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15029665/