2

我问了一个关于在 GUI 中使用线程的问题并得到以下回复:

你必须重新设计你的程序。

  1. GUI 元素应仅从 GUI 线程 (EDT) 中更新,而不是从独立线程中更新。
  2. 客户端连接应该分为 2 个弱连接部分:发送消息和接收消息。接收应该是一个单独的线程,发送可以是一个线程或一个类。
  3. 当接收线程读取消息时,它使用 SwingUtilities.invokeLater(Runnable) 将消息发送到 EDT。示例可以在其他地方找到。
  4. 当用户输入文本时,文本直接发送到套接字,或者排入队列,稍后由发送线程(如果有)处理。

我想知道的是 JavaFx 对 EDT 的响应是什么,有人可以举例说明如何使用它吗?

我的第一篇文章可以在这个链接找到服务器/客户端程序在线程启动后停止工作

  • 请注意,我是否已经在 javaFx Scene builder 中构建了我的 GUI。
4

2 回答 2

2

您是否在 JavaFX 中寻找相应的 SwingUtil.invokeLater。如果是,则为 Platform.runLater(java.lang.Runnable runnable)

引用 API http://docs.oracle.com/javafx/2/api/javafx/application/Platform.html

在未来某个未指定的时间在 JavaFX 应用程序线程上运行指定的 Runnable。

于 2012-10-14T15:04:27.677 回答
1

就个人而言,我只是重写了Task的 run 方法来保持核心忙碌并完成工作。非可视任务是通过扩展 Service 类来完成的。JavaFX 应用程序线程专门用于调用Service上的所有方法和状态。

服务是一种非可视组件,它封装了在一个或多个后台线程上执行某些工作所需的信息。

Task 是 FutureTask 的完全可观察的实现。Tasks 公开了额外的状态和可观察属性,这些属性对于在 JavaFX 中编写异步任务很有用,这些属性在 Worker 接口中定义。

发送消息等非 UI 计算应该通过运行任务在单独的线程中进行。当使用Platform.runLater(java.lang.Runnable runnable)从 JavaFX 应用程序线程(与 EDT 相同)接收消息时,您可以更改 UI(显示消息),但它会使 UI 滞后,因此最好从单独的线程中执行密集的工作。

因此,您可以定义一个任务并通过调用来触发新线程new Thread(task).start();。在您的 Task 匿名类中,您可以添加一个侦听器,用于在收到消息时更新 UI。一个任务可以有以下WorkerStateEvent,你可以监听它们。

使用来自http://fxexperience.com/2011/07/worker-threading-in-javafx-2-0/的 Task并使用 stateProperty 监听器的示例代码。

Task task = new Task<Void>() {
    @Override public Void run() {
        static final int max = 1000000;
        for (int i=1; i<=max; i++) {
            updateProgress(i, max);
        }
        return null;
    }
};
ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

task.stateProperty().addListener(new ChangeListener<Worker.State>() {

        @Override
        public void changed(ObservableValue<? extends State> observable,
                State oldValue, Worker.State newState) {
            if(newState==Worker.State.SUCCEEDED){
                //doSomething()
            }
        }
    });
于 2012-10-14T06:44:10.423 回答