当前位置: 首页 > 知识库问答 >
问题:

从不同类中的不同线程修改JavaFX gui

颛孙和悌
2023-03-14

我试图创建一个环境,在这个环境中设置一个图形用户界面,当用户通过监听器修改它的组件时,另一个线程每隔X秒就向它添加新元素。(这是一个游戏,是的)

我希望游戏在一个类中,而“元素加法器”线程在另一个类中——但Java当然抱怨我无法从另一个线程修改JavaFX GUI。

我见过使用Platform.run稍后()的解决方案,但就我所知,所有这些解决方案都使用匿名内部类。我真的希望我的加法器在另一个(命名的)班级。

如果您有任何提示,我们将不胜感激。下面是代码的最低版本,它再现了问题:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class DifferentThreadJavaFXMinimal extends Application {

    private Thread t;
    private GridPane gp;

    public static void main(String[] args){
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        gp = new GridPane();
        Scene gameScene = new Scene(gp, 600,500);
        primaryStage.setScene(gameScene);

        t = new Thread(new Thread2(instance()));




        primaryStage.show();
        t.start(); 
    }
    void addElement(int i) {
        Button actualButton = new Button("TEST");
        gp.add(actualButton,i,i);
    }
    public DifferentThreadJavaFXMinimal instance(){
        return this;
    }

}

class Thread2 implements Runnable {
    private DifferentThreadJavaFXMinimal d;

    Thread2(DifferentThreadJavaFXMinimal dt){
        d=dt;
    }

    @Override
    public void run() {
        for (int i=0;i<4;i++) {
        d.addElement(i);
        }
    }

}

共有1个答案

郭阳曜
2023-03-14

您仍然可以使用独立类。

规则是UI的更改必须发生在FX应用程序线程上。您可以通过包装来自其他线程的调用来实现这一点,这些线程将更改传递给Platform.run稍后(...)中的Runnable中的UI。

在示例代码中,d.addElement(i)更改了UI,因此您将执行以下操作:

class Thread2 implements Runnable {
    private DifferentThreadJavaFXMinimal d;

    Thread2(DifferentThreadJavaFXMinimal dt){
        d=dt;
    }

    @Override
    public void run() {
        for (int i=0;i<4;i++) {
            final int value = i ;
            Platform.runLater(() -> d.addElement(value));
            // presumably in real life some kind of blocking code here....
        }
        System.out.println("Hahó");
    }

}
 类似资料:
  • 我的问题与这个老问题很相似,但没有令人满意的答案贴在那里。 在DB2中有一个DB表,我试图通过两个或多个单独的Java线程对其进行并行记录读取,前提是这些线程应该读取不同的数据集,即如果线程1读取了前1000条记录,线程2不应该选择这些记录,而是选择不同的1000条记录(如果可用的话)。 由于线程将读取不同的行,因此在读取时不会发生冲突。Connection对象也不会在线程之间共享--它们将使用自

  • 问题内容: 我通过一个会话连接到数据库。在整个程序中,我总是有相同的会话。我的线程“ 1”从数据库中捕获主要数据。必须允许用户取消该线程。因此,如果用户频繁或快速按下“取消”按钮(这是我的解释),则会发生以下错误: 如果我取消线程“ 1”完成并尝试从数据库加载另一个主数据集后在后台运行的线程“ 2”,则会发生相同的错误。 我在两个线程中使用同一会话的失败是吗? 解决此类问题的正确方法是什么? 问题

  • 问题内容: 据我所知,操作系统创建线程时,每个线程都会获得一个不同的堆栈。我想知道每个线程是否也有与自己不同的堆吗? 问题答案: 否。所有线程共享一个公共堆。 每个线程都有一个专用堆栈,它可以快速添加和删除其中的项目。这样可以使基于堆栈的内存速度更快,但是,如果您使用过多的堆栈内存(如无限递归中所发生的那样),则会导致堆栈溢出。 由于所有线程共享同一个堆,因此必须同步对分配器/释放器的访问。有许多

  • 问题内容: 使用JMeter,我要检查仅允许1次更新的锁定部分 我正在运行具有10个线程的线程组,并且期望只有1个(并非总是第一个)线程返回0,而其他9个线程返回1如何断言呢? 线程组(10)-HTTP采样器– 断言 编辑 10实际上是一个动态属性。因此,我需要任何线程计数来期望只有1个断言才能返回成功。 该测试是为了检查记录锁定是否正常工作,即使在压力/负载测试中也只能更新一次记录。 编辑2 使

  • 我们在一个基于Swing/Spring的大型应用程序中看到以下异常。该错误发生在用户交互过程中,触发Spring通过commons logging报告警告,后者反过来调用log4j。不幸的是,我无法将这个问题分解为一个独立的示例。 Windows XP SP3、log4j-1.2.17、commons-logging-1.1.1、spring-4.1.2上的Java 8u40 未使用OSGI、we

  • 我试图设置两个线程,它们在另一个类中增加或减少一个整数。我对这个属性的同步有一些问题。 这是我的主要类,我在其中设置了线程和计数器类: 这是我的柜台课: 这是我的Thread1类:(runnable类是一样的,只是用“实现Runnable”而不是“扩展线程”) 但是,我的输出始终是10000000。尽管我同步了两种方法。有人能解释这是怎么回事吗?