【问题标题】:Why does my Swing main thread die?为什么我的 Swing 主线程死掉了?
【发布时间】:2017-08-10 14:15:39
【问题描述】:

早上,

我在使用 Java - Swing 时遇到了一个奇怪的问题。 这是我的主要方法

public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {

                    PrincipalWindow windowImportLoadCurve = new PrincipalWindow();
                    JFrame.setDefaultLookAndFeelDecorated(true);
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    setModelViewTable(windowImportLoadCurve);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

从 Eclipse IDE (Neon 2.0) 内部运行它。它创建了 4 个线程

Daemon Thread [AWT-Windows] (Running)   
Thread [DestroyJavaVM] (Running)    -> Main
Thread [AWT-Shutdown] (Running) 
Thread [AWT-EventQueue-0] (Running) 

它运行正常并且工作正常,当 GUI 应用程序完成时,JVM 只是关闭。所以我使用带有外部依赖项的 Maven Install 生成了一个 jar

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>weblogic-client-unpack</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>                              
                                    <outputDirectory>${project.build.directory}/</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                    <execution>
                        <id>jboss-client-unpack</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <outputDirectory>${project.build.directory}/</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>                   
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <id>ingrid-load-generator-package-assembly</id>
                        <phase>install</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <manifest>
                                <mainClass>main.MainGenerator</mainClass>
                            </manifest>
                            <descriptors>
                                <descriptor>src/main/assembly/assembly-bin.xml</descriptor>
                            </descriptors>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>    

并开始使用蝙蝠跑步。同一个应用程序创建相同的 4 个线程,因此它打开 GUI(使用 SwingUtility.invokeLater() 线程)并继续运行主程序。但是当 GUI 实际打开时,它会立即关闭,无需任何用户操作。

【问题讨论】:

  • 您为什么使用SwingUtilities.invokeLater() 来完成所有设置代码?如果您直接从main() 执行此操作会发生什么?
  • @Thomas 因为应该这样做。阅读文档。
  • @Thomas 这就是应该做的事情:docs.oracle.com/javase/tutorial/uiswing/concurrency/…
  • 嗯,谢谢,TIL。我实际上确实查找了一个 Swing 教程,但它并没有这样做。我是正确的(该教程也是如此)。距离自己接触 Swing 已经有 15 年了……

标签: java eclipse multithreading swing maven


【解决方案1】:

我的第一个猜测是错误的。

尝试创建/发布一个仅使用显示您所看到行为的摆动组件的最小代码示例。

这是一个适合我的例子:

public class Test {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            JFrame jf=new JFrame("Hi");
            jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            JF.setSize(500,200);
            jf.setVisible(true);
}});}}

如果这对您不起作用,则与您的环境有关。如果它对您有用,请将其作为起点并开始将其转换为更像您的代码,并在每次更改后运行测试。当您找到破坏它的更改时,您就有了答案。

【讨论】:

  • 我已经插入了 Thread.sleep(10000L);在 main 结束时,GUI opne 等待 10 秒并关闭。我已经将 invokeLater 更改为 invokeAndWait 并且没有任何更改。如何将 join() 放入 SwingUtilities 线程?还是等待??
  • GUI 已打开,因此可见已启用,不需要 sysout。我已经从 SwingUitilities 更改为一个公共线程,以尝试它仍然有效
  • 你没有得到打印的堆栈跟踪?您的代码是否有可能在某处有一个空的 catch 语句?是那个还是system.exit?如果显示窗口,您的应用不应退出。
  • 是的 :( 没有例外,我在调试模式下每行运行它,什么都没有...... mais 线程刚刚完成并关闭 JVM。
  • 是的,在远程调试中运行,我可以看到窗口打开并使用她,而主线程在断点处停止,但是当我释放 de BP 时,窗口关闭并且 JVM 完成跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
  • 2013-04-01
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 2020-01-02
相关资源
最近更新 更多