【问题标题】:JavaFX access gui button action from another threadJavaFX 从另一个线程访问 gui 按钮操作
【发布时间】:2013-02-22 17:13:12
【问题描述】:

我正在从另一个类(即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 内部,我已经尝试过,但没有得到任何结果,我的程序正在获取卡住了。)

任何建议,帮助,欢迎就如何解决这个问题提出建议。谢谢!

【问题讨论】:

    标签: java multithreading button javafx-2 javafx


    【解决方案1】:

    恕我直言,最好的方法是将您的数据(即:转弯)放在单独的类中。

    记住 JavaFX 是一个 MVC 模型。您可以使用 Model 类来保留此信息并引用此信息。如果要将模型类的引用传递给另一个线程,则必须同步这个。

    这样你就可以把事情分开了。你的控制器只会控制场景在做什么。您的模型将存储信息。

    This answer 为如何实现这一点提供了一个很好的起点。

    例如,我有一个任务(文件监视程序),我将其称为如下所示。这是我的控制器的快速快照:

    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 {
            //...
        }
    }
    

    希望这会有所帮助!

    【讨论】:

    • 非常感谢您的回复。我会试一试。 @blo0p3r
    • 我是否也可以实现 MVC 模型,即使我没有 FXML。我只是通过扩展 Application 创建 JavaFX gui。
    • ResultFileWatcher 是控制器吗?我有点困惑。还是仅仅是监听变化的任务。
    • 是的,即使您不使用 FXML,您仍然可以实现 MVC 模型。在这种情况下,线条可能会变得有点模糊,因为分离代码有点困难,但可以做到。 ResultFileWatcher 只是我对 Task 的实现。我将更新答案以更好地显示这一点。
    • 非常感谢您的帮助。我现在已经实现了 Controller 类,它就像一个魅力。
    猜你喜欢
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 2011-10-15
    • 2013-05-30
    • 1970-01-01
    • 2014-10-13
    • 1970-01-01
    相关资源
    最近更新 更多