Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent JPopUpMenu disappearing when checking checkboxes in it?

I want to use JCheckBoxMenuItems in a JPopupMenu. It works, but the problem is that the popup menu disappears when a checkbox item has been checked or unchecked. So if one wants to check/uncheck several items, the popup needs to be launched repeatedly, which is irritating.

Curiously, if I use just plain JCheckBox items in the menu (instead of JCheckBoxMenuItems), the behavior is just as it should be: the popup stays there and the checkboxes can be checked/unchecked. Once done, the popup can be closed just by clicking outside it.

How do I make the popup to behave like that when the items there are JCheckBoxMenuItems? I would prefer using JCheckBoxMenuItems because of their looks.

like image 937
Joonas Pulakka Avatar asked Sep 21 '10 10:09

Joonas Pulakka


3 Answers

I found a much easier solution for this problem

JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem("sample");
menuItem.putClientProperty("CheckBoxMenuItem.doNotCloseOnMouseClick", Boolean.TRUE);

I found this solution while reading the code from

BasicMenuItemUI.doNotCloseOnMouseClick()
like image 186
Till Woitendorf Avatar answered Oct 20 '22 15:10

Till Woitendorf


Well, found working answer from http://forums.sun.com/thread.jspa?threadID=5432911. Basically, create a custom UI:

public class StayOpenCheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI {

   @Override
   protected void doClick(MenuSelectionManager msm) {
      menuItem.doClick(0);
   }

   public static ComponentUI createUI(JComponent c) {
      return new StayOpenCheckBoxMenuItemUI();
   }
}

And set it in the JCheckBoxMenuItem:

myJCheckBoxMenuItem.setUI(new StayOpenCheckBoxMenuItemUI());

Don't know if this is the most elegant possible solution, but works perfectly.

like image 12
Joonas Pulakka Avatar answered Nov 13 '22 16:11

Joonas Pulakka


I ran into an issue with the nice Joonas Pulakka's answer because the "UIManager lookandFeel" was ignored.

I found the nice trick below on http://tips4java.wordpress.com/2010/09/12/keeping-menus-open/

The point is to reopen immediatly the menu after it has been closed, it's invisible and keep the application look and feel and behavior.

public class StayOpenCBItem extends JCheckBoxMenuItem {

    private static MenuElement[] path;

    {
        getModel().addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                if (getModel().isArmed() && isShowing()) {
                    path = MenuSelectionManager.defaultManager().getSelectedPath();
                }
            }
        });
    }

    public StayOpenCBItem(String text) {
        super(text);
    }

    @Override
    public void doClick(int pressTime) {
        super.doClick(pressTime);
        MenuSelectionManager.defaultManager().setSelectedPath(path);
    }
}
like image 3
FabiF Avatar answered Nov 13 '22 17:11

FabiF