【问题标题】:Java: Let other threads know if GUI is ready to useJava:让其他线程知道 GUI 是否可以使用
【发布时间】:2012-07-02 04:19:46
【问题描述】:

我正在编写一个应用程序,它解析XML 文件(连续)并在GUI 中显示数据(Swing)。 ParseThreadCoreProject 中,GUIGUIProject 中。

ParseThread 的开头通过 ItemListener 连接到 JCheckBoxMenuItemsetSelected() 的值是在添加到菜单后直接设置的。此时GUI不包含ParseThread需要显示解析数据的Component

我的解决方案是,ParseThread 应该等到 GUI 完全构建。 我想到了 EventQueue 之类的东西,但我不知道如何编写代码。

【问题讨论】:

  • GUI 准备好后为什么不直接启动线程?
  • 同意 -- 我不确定您的确切问题是什么,但听起来您可以使用 SwingWorker 进行后台处理,并添加 PropertyChangeListener 以通知 GUI 线程的进度。跨度>
  • 是的,在它需要运行的所有数据(直接)存在之前,我看不到创建线程的任何意义。也就是说,GUI 组件无论如何都不应该属于该类别 - 如果 GUI 以通常的方式通过消息传递进行通信,则不应发生此问题?

标签: java multithreading swing user-interface ready


【解决方案1】:

我的解决方案是,ParseThread 应该等到 GUI 完全构建。我想到了 EventQueue 之类的东西,但我不知道如何编写代码。

你遇到了Concurency in Swing 的问题,你的艰苦而长期运行的任务应该移到后台任务,对于 Swing 有两种可能性

  • (简单)使用Runnable#Thread,Swing GUI 的输出必须包装到invokeLater(),包括线程安全方法,如setTextappend e.i.

  • 使用SwingWorker

编辑

请检查我的可视化Runnable#Thread 这与连接服务器、解析长文件 e.i. 是一样的,

使用 invokeLater() 在调用之前我无法确定组件是否存在

  1. 创建图形用户界面,

  2. 显示图形用户界面,

  3. 一些(Swing / Util) Timeruser action 调用被重定向出Swing EventDispatchThread 的代码,因此有Runnable#ThreadSwingWorker

  4. 我建议两种最简单的方法

【讨论】:

  • with invokeLater() 在调用之前我无法确定组件是否存在
【解决方案2】:

好吧,我有问题了... GUI 是这样创建的:

EventQueue.invokeAndWait(new Runnable() {

            @Override
            public void run() {
                try {
                    Mainframe frame = new Mainframe();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

在构建对象大型机时,将执行此代码:

final JCheckBoxMenuItem chckbxmntmParsing = new JCheckBoxMenuItem("Parsing");
    chckbxmntmParsing.setName("mainframe.menu.data.parsing");
    localeChangedListener.add(chckbxmntmParsing);

    chckbxmntmParsing.addItemListener(new ItemListener() {

        @Override
        public void itemStateChanged(ItemEvent e) {
            if (chckbxmntmParsing.isSelected()) {
                parseManager.startParsing();
            } else {
                parseManager.stopParsing();
            }
        }
    });

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            boolean enabled = false;
            String prop = PropertyManager.get().getProperty("parser.continuousparsing.enabled");
            if (prop != null) {
                if (prop.trim().equals("true") || prop.trim().equals("1")) {
                    enabled = true;
                }
            }
            chckbxmntmParsing.setSelected(enabled);
        }
    });

所以 ParseThread 将在 GUI 构建后启动。

抱歉耽误了你的时间

【讨论】:

  • “对不起,偷了你的时间” 只为我说话(没有其他人要求我为他们说话)但不接受道歉,因为你不欠我一个。相反,感谢您为您自己的问题提供答案!非常适合问答网站。 :)
猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 2013-12-05
  • 2011-12-28
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
相关资源
最近更新 更多