Отсутствует контрольный квадрат (JCheckBoxMenuItem) при использовании внешнего вида Nimbus java

Я изменил внешний вид на Nimbus, как описано здесь.

Работает нормально, за исключением JCheckBoxMenuItems, где исчезли галочки. Цвет выделения тоже неверный.

Это код всплывающего меню с JCheckBoxMenuItems:

public class FilterByNodeUI 
{
    private JPopupMenu filterMenu;
    private PopupMenuButton menu;
    private JMenu eventLogFilters, commandFilters;
    private JCheckBoxMenuItem[] commandsPeriodicalItems, commandsPeriodicalAllPortsItems;
    private JCheckBoxMenuItem alarm, connection, standard;
    private String id;

public FilterByNodeUI(Node node)
{
    this.id = node.getIp();

    filterMenu = new JPopupMenu();
    eventLogFilter();

    int cpNbr = node.getCommands().getCommandsPeriodical().size();
    int cpapNbr = node.getCommands().getCommandsPeriodicalAllPorts().size();
    commandsPeriodicalItems = new JCheckBoxMenuItem[cpNbr];
    commandsPeriodicalAllPortsItems = new JCheckBoxMenuItem[cpapNbr];

    commandFilters = new JMenu("Commands");

    for(int i = 0; i < cpNbr; i++)
    {
        commandsPeriodicalItems[i] = menuItemFactory(node.getCommands().getCommandsPeriodical().get(i).getCommand());
        commandFilters.add(commandsPeriodicalItems[i]);
    }

    commandFilters.addSeparator();

    for(int i = 0; i < cpapNbr; i++)
    {
        commandsPeriodicalAllPortsItems[i] = menuItemFactory(node.getCommands().getCommandsPeriodicalAllPorts().get(i).getCommand());
        commandFilters.add(commandsPeriodicalAllPortsItems[i]);
    }

    filterMenu.add(eventLogFilters);
    filterMenu.add(commandFilters);

    menu = new PopupMenuButton(node.getDispName(), filterMenu);


    commandFilterListeners(commandsPeriodicalItems, node, true);
    commandFilterListeners(commandsPeriodicalAllPortsItems, node, false);   
}

private void eventLogFilter()
{
    alarm = menuItemFactory("Alarm messages");
    standard = menuItemFactory("Standard messages");
    connection = menuItemFactory("Connection messages");

    eventLogFilters = new JMenu("Event Log Messages");
    eventLogFilters.add(alarm);
    eventLogFilters.add(connection);
    eventLogFilters.add(standard);
}

private JCheckBoxMenuItem menuItemFactory(String name)
{
    JCheckBoxMenuItem tmp;
    tmp = new JCheckBoxMenuItem(name);
    tmp.setSelected(true);
    tmp.setUI(new StayOpenCheckBoxMenuItemUI());  // I set a new UI here
    return tmp;
}
}

Вот как это выглядит сейчас:

отсутствует флажок

Мне кажется, что новый внешний вид не применялся к элементам JCheckBoxMenuitems или JMenu.

Причина проблемы в том, что я установил новый пользовательский интерфейс для hte JCheckBoxMenuItems, потому что я не хочу закрывать всплывающее меню, когда пользователь проверяет/снимает отметку с элемента.

Вот код:

public class StayOpenCheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI 
{
   @Override
   protected void doClick(MenuSelectionManager msm) 
   {
       menuItem.doClick(0);
   }

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

Есть ли способ сохранить эту открывающуюся функцию рядом с нимбом?


person Bence Kaulics    schedule 16.10.2014    source источник
comment
довольно забавно, может быть, я слепой, есть ли... ничего из кода, показывающего что-то о JMenu и JCheckjBoxMenuItem   -  person mKorbel    schedule 16.10.2014
comment
С внешним видом по умолчанию он работает правильно, поэтому я подумал, что часть кода не нужна. Мне нужно каким-то образом переопределить свойства нимба для JCheckBoxMenuItem. Но я могу отредактировать свой вопрос и вставить этот фрагмент кода, если вам нужно.   -  person Bence Kaulics    schedule 16.10.2014
comment
Как указал mKorbel, вы не показали нам весь код. Опубликуйте минимальный, полный, поддающийся проверке пример, демонстрирующий проблему. Например, вы не показали, как и где были созданы и инициализированы MainFrame или menu.   -  person splungebob    schedule 16.10.2014
comment
Хорошо, я редактирую вопрос.   -  person Bence Kaulics    schedule 16.10.2014


Ответы (1)


не ответ код от aterai из OTN

введите здесь описание изображениявведите здесь описание изображения

import java.awt.*;
import javax.swing.*;
// JDK 1.6
//import com.sun.java.swing.*;
//import com.sun.java.swing.plaf.nimbus.*;
//__________________________________________
// JDK 1.7
import javax.swing.plaf.nimbus.*;

class NimbusCheckIconTest {

    public JMenuBar createMenuBar() {
        JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem("checkIcon test");
        UIDefaults d = new UIDefaults();
        d.put("CheckBoxMenuItem[Enabled].checkIconPainter",
                new MyCheckBoxMenuItemPainter(
                MyCheckBoxMenuItemPainter.CHECKICON_ENABLED));
        d.put("CheckBoxMenuItem[MouseOver].checkIconPainter",
                new MyCheckBoxMenuItemPainter(
                MyCheckBoxMenuItemPainter.CHECKICON_MOUSEOVER));
        d.put("CheckBoxMenuItem[Enabled+Selected].checkIconPainter",
                new MyCheckBoxMenuItemPainter(
                MyCheckBoxMenuItemPainter.CHECKICON_ENABLED_SELECTED));
        d.put("CheckBoxMenuItem[MouseOver+Selected].checkIconPainter",
                new MyCheckBoxMenuItemPainter(
                MyCheckBoxMenuItemPainter.CHECKICON_SELECTED_MOUSEOVER));
        cbmi.putClientProperty("Nimbus.Overrides", d);
        cbmi.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("A Menu");
        menuBar.add(menu);
        menu.add(new JCheckBoxMenuItem("default"));
        menu.add(cbmi);
        menuBar.add(menu);
        return menuBar;
    }

    public Container createContentPane() {
        JPanel contentPane = new JPanel(new BorderLayout());
        contentPane.setOpaque(true);
        contentPane.add(new JScrollPane(new JTextArea()));
        return contentPane;
    }

    private static void createAndShowGUI() {
        try {
            for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(laf.getName())) {
                    UIManager.setLookAndFeel(laf.getClassName());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        NimbusCheckIconTest demo = new NimbusCheckIconTest();
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setJMenuBar(demo.createMenuBar());
        f.setContentPane(demo.createContentPane());
        f.setSize(320, 240);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
//copy: CheckBoxMenuItemPainter.java
class MyCheckBoxMenuItemPainter extends AbstractRegionPainter {

    static final int CHECKICON_ENABLED_SELECTED = 6;
    static final int CHECKICON_SELECTED_MOUSEOVER = 7;
    static final int CHECKICON_ENABLED = 8;
    static final int CHECKICON_MOUSEOVER = 9;
    private int state;
    private PaintContext ctx;

    public MyCheckBoxMenuItemPainter(int state) {
        super();
        this.state = state;
        this.ctx = new AbstractRegionPainter.PaintContext(
                new Insets(5, 5, 5, 5), new Dimension(9, 10), false, null, 1.0, 1.0);
    }

    @Override
    protected void doPaint(Graphics2D g, JComponent c,
            int width, int height, Object[] eckey) {
        switch (state) {
            case CHECKICON_ENABLED:
                paintcheckIconEnabled(g);
                break;
            case CHECKICON_MOUSEOVER:
                paintcheckIconMouseOver(g);
                break;
            case CHECKICON_ENABLED_SELECTED:
                paintcheckIconEnabledAndSelected(g);
                break;
            case CHECKICON_SELECTED_MOUSEOVER:
                paintcheckIconSelectedAndMouseOver(g);
                break;
        }
    }

    @Override
    protected PaintContext getPaintContext() {
        return ctx;
    }

    private void paintcheckIconEnabled(Graphics2D g) {
        g.setPaint(Color.GREEN);
        g.drawOval(0, 0, 10, 10);
    }

    private void paintcheckIconMouseOver(Graphics2D g) {
        g.setPaint(Color.PINK);
        g.drawOval(0, 0, 10, 10);
    }

    private void paintcheckIconEnabledAndSelected(Graphics2D g) {
        g.setPaint(Color.ORANGE);
        g.fillOval(0, 0, 10, 10);
    }

    private void paintcheckIconSelectedAndMouseOver(Graphics2D g) {
        g.setPaint(Color.CYAN);
        g.fillOval(0, 0, 10, 10);
    }
}
person mKorbel    schedule 16.10.2014
comment
@aterai, пожалуйста, не проще ли использовать ButtonModel, чтобы проверить это состояние в doPaint - person mKorbel; 16.10.2014
comment
Это не работает, но я нахожу причину. Я переопределяю пользовательский интерфейс флажков, я отредактирую вопрос, чтобы показать вам, как это сделать. - person Bence Kaulics; 16.10.2014
comment
@mKorbel Я совершенно согласен, java.swing.Painter#doPaint() + ButtonModel было бы намного проще :) - person aterai; 16.10.2014