Home > Web > Advanced Swing popup windows

Advanced Swing popup windows


If you want a popup menu from which you can select an option than obviously JPopupMenu is the answer. In this tip we’ll discuss how to do more complicated popups.

But what happens if you want to include in your popup some other components than JMenuItem’s? The approach will be to use JWindow/JFrame/JDialog and implement the popup functionality for it.

To be more clear I’ll describe the expected behavior of a popup window:

  • The popup window is shown when an invoking component(e.g. toggle button) is selected;
  • The user can enter input in the window;
  • The popup window is hidden when it loses focus;
  • The popup window is hidden when the invoking component is deselected.

The required steps for implementing it will be:

  1. Add an action listener to the invoking component (a JToggleButton will be the most suited one regarding the selected/deselected state) to show or hide the component;
  2. Add a window focus listener to the window to hide the window when the focus is lost (see expected behavior (c)).

    invokePopupButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            // set popup window visibility
            if (!popupWindow.isVisible()) {
                // show the popup if not visible
                invokePopupButton.setText("Hide popup");
                popupWindow.setVisible(true);
                popupWindow.requestFocus();
            } else {
                // hide it otherwise
                invokePopupButton.setText("Show popup");
                popupWindow.setVisible(false);
            }
        }
    });
    
    ...
    
    popupWindow.addWindowFocusListener(new WindowFocusListener() {
        public void windowGainedFocus(WindowEvent e) {
    
        }
    
        public void windowLostFocus(WindowEvent e) {
            // this will invoke the action on the popup invoking button
            // and hide the visible window
            invokePopupButton.doClick();
        }
    });

Basically that’s the idea and the above code will do the trick. Tough it will not entirely work. Click on the button and the window will be shown. Click anywhere outside the window and the window will be hidden. But if you click on the button the popup will be hidden and immediately shown.
Why?
When you click the button the order of events is: the window loses focus and then the button is actioned. And if you look at the code this will be like clicking twice the button.

SwingUtilities.invokeLater() will do the trick.

popupWindow.addWindowFocusListener(new WindowFocusListener() {
    public void windowGainedFocus(WindowEvent e) {

    }

    public void windowLostFocus(WindowEvent e) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if (popupWindow.isVisible())
                    invokePopupButton.doClick();
            }
        });
    }
});

This will push the focus lost event on the popup window to the end of event queue. And now everything will work smoothly.

Of course this code can be optimized and adapted to your own needs but you basically got the idea.

Categories: Web
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: