我将其更改为Nimbus的外观,如here所述。

除了JCheckBoxMenuItems(检查正方形消失了)之外,它都工作正常。选择颜色也不正确。

这是带有JCheckBoxMenuItems的popupmenu的代码:

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。

问题的原因是我为JCheckBoxMenuItems设置了新的UI,因为当用户选中/取消选中某个项目时,我不想关闭弹出菜单。

这是代码:

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

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


有没有办法让这种关闭功能保持在灵气的外观和感觉之外?

最佳答案

不是答案code by aterai from 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);
    }
}

09-15 16:14