java - Swing Call 是什么意思?

标签 java swing

我有一个需要时间来加载所有内容的项目,因此我创建了一个启动画面,通过进度条告诉用户完全加载和显示 UI 需要多长时间,但我遇到了一个问题。

当我创建启动画面时,它显示正确,但随后我创建并初始化了主框架,所有内容都卡住,直到它完全加载。

所以,我尝试使用 SwingWorker 在线程中加载我的 Principal 框架(并且它有效)但是在未知的 NullPointerException 之后我发现这是一个糟糕的想法,因为我没有在 EDT 中创建我的 UI,所以我被困在这里。

我知道我必须在事件分派(dispatch)线程 (EDT) 中执行 Swing 调用并在 SwingWorkers 中执行非 swing 繁重的工作,但初始化主框架的 Swing 组件也是一项繁重的工作,所以我该怎么办?

我在这里阅读了一些问题,特别是 this ,我想我明白了,但我有疑问。举个例子:

SwingUtilities.invokeAndWait(new Runnable() {
    public void run() {
        new SplashScreen();
    }
});
// Code to start system (nothing that touches the GUI)
SwingUtilities.invokeAndWait(new Runnable() {
    public void run() {
        new MainFrame();
    }
});
//.. etc

和读this site上面写着:

The Swing framework manages component drawing, updates, and event handlers on the EDT.

创建新组件是 Swing Call 吗?如果是,new MainFrame() 需要一些时间,因为项目有很多组件需要初始化,我该怎么办?

我如何告诉 Splash 类似“程序已加载 50%”之类的信息?

Swing Call 是什么意思?如何正确使用 invokeLaterSwingWorker?也许解决方案太明显或已经有答案,但我看不到,如果是这种情况,我深表歉意。

谢谢!

最佳答案

您走在正确的轨道上。但是不要使用 invokeAndWait(如果你不得不这样做) - 使用 invokeLater:

调用并等待

Causes doRun.run() to be executed synchronously on the AWT event dispatching thread.

invokeLater

Causes doRun.run() to be executed asynchronously on the AWT event dispatching thread.

考虑 block 包装 doLater 是在 EDT 线程上运行的,而包装在 doOutside 中的代码是在另一个线程中调用的(这就是为什么不阻塞 UI):

编辑:

正如评论中所指出的,我添加了对我将使用的概念的解释。


doLater {
    // here goes the code
}

是一个概念:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        // here goes the code
    }
});

doOutside {
    // here goes the code
}

是一个概念:

new Thread(new Runnable() {
    @Override
    public void run() {
        // here goes the code
    }
}).start();

doLater {
    final MainFrame m = new MainFrame();
    doOutside {
        // handle heavy operation
        final int result = 1;
        doLater {
            m.setResult(result);
        }
    }
}

结论:任何以某种方式接触 Swing 的东西都必须在 EDT 上运行。 如果你想更新百分比:

doLater {
    final MainFrame m = new MainFrame();
    doOutside {
        // handle progress
        for(int i = 0; i < someSize; ++i) {
            final int progress = i;
            doLater {
                m.getProgressBar().setProgress(progress);
            }

        }
    }
}

希望您现在理解这个概念。 SwingWorker 只是做一些事情,如 doOutside === doInBackground & doLater === done/进度

顺便说一句。上面的代码是一个真实的代码:lookup Griffon Groovy 中的框架。

关于java - Swing Call 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31466009/

相关文章:

Java和布局

java - 从一个tomcat服务器获取数据到另一个tomcat服务器

java - SLF4J API 的 NoSuchMethodError

java - 在 java 中导入 .xlsx 文件时出现 OutOfMemoryException

javascript - 想要在wicket中调用js方法而不使用ajax的onclick或onsubmit按钮

java - 将 JPanel 与 WindowBuilder 重叠用于 eclipse

Java - PaintComponent 导致我的程序变慢

java - 如何向 JOptionPane 中的多个文本字段添加验证?

java - 如何将整数与 JLabel 进行比较?

Java:返回 String 或 int 的方法