我将其更改为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();
}
}
有没有办法让这种关闭功能保持在灵气的外观和感觉之外?
最佳答案
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);
}
}