0

My program will not close the specified frame in some cases. For some reason it will close fine when ran through IntelliJ using the run command, but after compiling into a jar and wrapping with Launch4J it gets stuck when I try to close it programmatically. Here is the applicable code:

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();
    }
}

I'm not sure if this is a code error or an error with Launch4J since this only occurs in the Launch4J compiled version (not through IntelliJ or via java.exe -jar).

EDIT: I also tried killing the GUI thread with thread.interrupt(), but that didn't change the outcome.

greatmastermario
  • 87
  • 1
  • 1
  • 11

1 Answers1

0

You can try gui.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); (set this option after instantiating the gui object)

Normally, a JVM closes after every non-deamon thread reaches its end. Swing creates its own thread for handling events (EDT). I assume that in your application in certain cases a non-deamon thread is still running which prevents the JVM from closing.

You can find additional information in this thread: JFrame.dispose() vs System.exit()

Community
  • 1
  • 1
morpheus05
  • 4,772
  • 2
  • 32
  • 47
  • The reason I was using JFrame.dispose() was to only close the window. The game code above is started through a separate menu, but I don't want the menu to close at the end of the game. Also as stated above, it works fine when ran through IntelliJ or as a Jar, but compiling it with Launch4J causes the issue. – greatmastermario Jan 14 '16 at 23:11
  • The fact remains, that a after you wish to close the application, a thread is still running so you only have to option: For the VM to exit with System.exit() which is not that great or check which Threads are still running. Use the Thread-API to access all threads and print them to the console. Then you see the difference from IDE to Launch4j. – morpheus05 Jan 15 '16 at 08:57
  • When I am looking for the thread, do I look in the JVM threads or somewhere else? It shouldn't have anything to with the JVM since it has the correct behavior in IntelliJ and as a Jar. Launch4J is not a part of a program, it is just a wrapper to run it as a Windows executable. Does it have separate thread handling from the JVM in this case? Also, I am not trying to close the whole program, just the window. The game (shown above) opens in a separate window from the options, which stay open so you can start a new game after you finish. – greatmastermario Jan 25 '16 at 16:29