Search code examples
javamultithreadingswingcountdownlatcheventqueue

On closing the main Swing window, the other thread on the EventQueue gets not created


I write Java SE 8 desktop application. It's got a Swing UI.

Platform:

  • Eclipse IDE
  • Windows 10 OS

Now when I close the main window, by pressing on the "X" on the top-right-corner, I have a listener to listen for such event.

The listener right here:

 private void listenerForClosingResources(){
         this.addWindowListener(new WindowAdapter() {
             @Override
             public void windowClosing(WindowEvent e) {
                 if(e.getID() == WindowEvent.WINDOW_CLOSING){
                     CountDownLatch continueOn = new CountDownLatch(1);
                     saveUnsavedTmpProject(continueOn);

                     try {
                         continueOn.await();
                     }
                     catch(InterruptedException ee) {
                         ee.printStackTrace();
                     }                      
                 }
             }
         });    
     }

So, I use the listener to identify the window closing event, and when that happens I ask the user whether or not to save the project (it's data on DB).

This method (saveUnsavedTmpProject(continueOn);) leads to the other window which supposed to take the name under which to save the project.

Now the CountDownLatch forces the main window to stay up, up till when the user confirms/rejects saving the project on the other panel.

The other class method which creates the window, leading to saving the project, is right here:

public static void getInstance(CountDownLatch continueOn, String openProjectName) {
        if(frame == null) {
            synchronized(SaveAsPane.class) {
                if(frame == null) {
                    carryOn = continueOn;

                    if(!openProjectName.isEmpty()){
                        openProject = openProjectName;
                    }

                    EventQueue.invokeLater(new Runnable() {
                        public void run() {
                            try {
                                frame = new SaveAsPane();
                                frame.setVisible(true);
                                frame.setLocationRelativeTo(MainGUI.getMainGUI());

                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });                     
                }
            }
        }
    }

Now, when I run the app, I don't get inside the run() method (and no window pops-up). But that only happens when I access this method only from the mentioned above listener. Which has the CountDownLatch, and it appears that it stops the execution of the new thread.

The latch gets counted-down when the user confirms/denies saving the project, so that the execution flow continues on. Yet, I create the additional thread on the EventQueue.

How come that the thread gets stopped?


Solution

  • The Java group on facebook.com pointed me to the right direction. The solution is this:

    • redefine what the close button (X) does on the main GUI.

    And here it comes:

    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);   
    

    And now when I click the main GUI window's close button, the close does not lead to closing the window. Meaning that I don't need any longer the CountDownLatch class, which was stopping the main window from closing up (and waiting till the user counts-down on the other class).

    In the end, I made the app to work in the way I like.