Hemmels
Hemmels

Reputation: 892

java SystemTray.add(TrayIcon) hangs Swing GUI on exit

Here's an interesting bug (read: i've probably missed something) in Java Swing I spent the last 2 days trying to trace.

First things first, create a SSCCE. Here you go.

class GUI extends JFrame{
    public static void main(String[] args){
        // All GUI work should be handled in the EDT.
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                new GUI().setVisible(true);
            }
        });
    }

    GUI(){
         // Make a nice icon
        ImageIcon img = new ImageIcon(this.getClass().getClassLoader().getResource("img/1.png"));

        // Make a TrayIcon with the image
        SystemTray sysTray = SystemTray.getSystemTray();
        TrayIcon trayIcon = new TrayIcon(img.getImage());
        try {
            sysTray.add(trayIcon);
        }
        catch(AWTException e) {
            e.printStackTrace();
           System.out.println("System Tray unsupported!");
        }

        this.setTitle("Example GUI");
        this.setIconImage(img.getImage());
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }
}

If I run this and close the Window, I would expect it to dispose, and the various Threads to terminate. This is the case if I comment out the "Make a TrayIcon" try/catch block.

The sysTray.add() line seems to not create an Exception, but having it in the code stops the Threads from terminating, as the code hangs on a wait() in the AWT-EventQueue Thread.

Is this a bug, or something I'm missing?

Cheers all.

Upvotes: 3

Views: 1094

Answers (1)

Jon Egeland
Jon Egeland

Reputation: 12613

To get the program to terminate properly when you close it, you need to set the DefaultCloseOperation to EXIT_ON_CLOSE, like this:

GUI.setDefaultCloseOperation(EXIT_ON_CLOSE);

EXIT_ON_CLOSE is defined in JFrame so you don't need to define it or import it from anywhere.

Check the API for more exit operations:

Upvotes: 2

Related Questions