2016-01-14 82 views
0

我的程序在某些情况下不会关闭指定的框架。出于某种原因,当使用run命令运行IntelliJ时,它会很好地关闭,但是在编译成jar并使用Launch4J封装后,它会在我尝试以编程方式关闭它时卡住。这里是适用的代码:JFrame.dispose不关闭框架

Classic.java

import javax.swing.*; 
import java.io.FileNotFoundException; 
import java.io.PrintStream; 
import java.util.*; 
import java.text.SimpleDateFormat; 
import static javax.swing.SwingUtilities.invokeLater; 
public class Classic extends Game{ 
    private static JFrame gui; 
... 
    //Starts game and opens gui 
    public void play() { 
     invokeLater(Classic::startGUI); 
     //startGUI() intiates gui correctly, let me know if you need it 
     new Thread(Classic::startGame).start(); 
    } 
... 
    public static void startGame() { 
     //Program works fine until closing window; 
     //Game methods and code omitted 
     print("Thank you for playing!" + System.lineSeparator() + "Press enter to exit."); 
     boolean end = false; 
     while (!end) { 
      //isInputReady() checks if user pressed enter 
      end = newContentPane.isInputReady(); 
     } 
     gui.dispose(); 
    } 
} 

我不知道这是否是一个代码错误或Launch4J一个错误,因为这只是在Launch4J编译版本时(不通过的IntelliJ或通过java.exe -jar)。

编辑:我也尝试杀死与thread.interrupt()的GUI线程,但没有改变结果。

+0

...我想它会关闭代码到达方法结束后。我没有明确的接近线程。 – greatmastermario

回答

0

您可以尝试gui.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);(实例化GUI对象后设置这个选项)

通常情况下,一个JVM关闭每个非守护进程线程到达其结束之后。 Swing创建自己的线程来处理事件(EDT)。我认为在某些情况下,在你的应用程序中,非deamon线程仍在运行,这会阻止JVM关闭。

您可以在此线程找到其他信息:JFrame.dispose() vs System.exit()

+0

我使用JFrame.dispose()的原因是只关闭窗口。上面的游戏代码是通过一个单独的菜单启动的,但我不希望菜单在游戏结束时关闭。同样如上所述,通过IntelliJ或Jar运行时可以正常工作,但使用Launch4J进行编译会导致此问题。 – greatmastermario

+0

事实上,在你希望关闭应用程序之后,一个线程仍然在运行,所以你只需要选择:对于VM退出时使用System.exit()这并不好,或者检查哪些线程仍在运行。使用Thread-API访问所有线程并将其打印到控制台。然后你会看到从IDE到Launch4j的区别。 – morpheus05

+0

当我在寻找线程时,我看看JVM线程还是其他地方?它不应该与JVM有任何关系,因为它在IntelliJ和Jar中具有正确的行为。 Launch4J不是程序的一部分,它只是将它作为Windows可执行文件运行的一个包装。在这种情况下它有独立的JVM处理吗? 此外,我并不想关闭整个程序,只是窗口。游戏(如上所示)在与选项不同的窗口中打开,该选项保持打开状态,以便在完成后开始新游戏。 – greatmastermario