0

I am creating an application in Java and I would like that when you minimize to an icon, the application will have to "hide" in the system tray. The code I use is this: (the significant part of the code)

myFrame = new JFrame();
myFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowIconified(WindowEvent e) {                
                PutTray();
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
                System.out.println("Deiconified");

            }

        });

This is a "PutTray" function:

private void PutTray()
    {
            try 
            {
                tray.add(trayIcon); // Initialized elsewhere
                myFrame.setVisible(false);

            } catch (AWTException e) {
                System.err.println(e);
            }
    }

To restore (via option in the pop-up menu when you press the icon minimized):

MenuItem show = new MenuItem("Show");
            show.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {


                    myFrame.setVisible(true); 
                    myFrame.setState(JFrame.NORMAL);
                    tray.remove(trayIcon);

                }
            });

The code works perfectly on Windows 8, but it does not work on Linux (Kali Linux and even Ubuntu). Why Windows yes and Linux no?

EDIT:

On Linux, after you press the command to show the application, it appears for a very small moment, and then minimizes again. Basically is triggered the event "windowDeiconified" and immediately after the event "windowIconified" without taking the time to do something else and then the application is shown in the system tray.

user2263764
  • 341
  • 5
  • 21

2 Answers2

1

As Dan Getz suggests, I also thought the order of setVisible and setState should be inverted since the javadoc for setState says:

If the frame is not visible on the * screen, the events may or may not be * generated.

but this didn't help.

The one thing that did help though was replacing setVisible(false) with dispose(). They are similar in that you can use setVisible(true) to reopen a disposed window. You can read more about it here: JDialog setVisible(false) vs dispose() I'll try to find an explanation and come back with it :)

SSCCE to simulate OP problem:

public class Test {
    private JFrame myFrame;
    public Test() {
        myFrame = new JFrame();
        myFrame.setVisible(true);
        myFrame.setSize(300, 300);
        myFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowIconified(WindowEvent e) {
                PutTray();
            }
        });
    }
    private void PutTray() {
        myFrame.setVisible(false); //replace with dispose(); and it's ok
        Timer t = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                myFrame.setVisible(true);
            }
        });
        t.setRepeats(false);
        t.start();
    }
    public static void main(String[] args) {
        new Test();
    }
}
Community
  • 1
  • 1
Vlad Topala
  • 896
  • 1
  • 8
  • 34
0

I think you are getting it wrong!

Maybe you are confused about deiconified and visibility

windowIconified() will be called when we click minimize button

and

windowDeiconified()

is called when we restore it from taskbar and not system tray!

In order to restore from system tray you need to use this

trayIcon.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            window.setVisible(true);
        }
    });

Basically i don't think the difference between dispose() & setVisible() will bother you in this specific problem

Still, my recommendation is to use setVisible() here

gprem062
  • 11
  • 3