How to prevent JPopUpMenu disappearing when checking checkboxes in it?
Asked Answered
C

3

10

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.

Connacht answered 21/9, 2010 at 10:26 Comment(1)
I think this is a bug and should be fixed by the Swing library authors, rather than avoided using workarounds. The only problem is, that Java developpers rather find excuses than fix their bugs.Zionism
C
12

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.

Connacht answered 21/9, 2010 at 11:6 Comment(2)
"working answer" refers to link to forums sun com which is brokenOlimpia
Additional information on this solution can be found here: coderanch.com/t/497325/GUI/java/…Lucid
G
3

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);
    }
}
Gesture answered 8/4, 2014 at 14:4 Comment(1)
For me, this does not work when used in a JPopupMenu. Quoting author from the article’s comments “The enhancements provided here were not intended to work with any kind of popup menu.”Pianism
T
2

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()
Twin answered 22/9, 2021 at 7:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.