Nimbus 通常看起来很棒,但对于某些颜色组合,结果并不理想。就我而言, a 的背景JPopupMenu
不适合,这就是我要手动设置它的原因。
我在 Java 7 上,有趣的是,Nimbus 完全忽略了UIManager
(like PopupMenu.background
) 中某些属性的设置。所以我唯一的选择是创建一个JPopupMenu
overrides的子类paintComponent(...)
。我知道,这很糟糕,但至少它奏效了。
但是,如果您将 a 添加JMenu
到另一个菜单,它会嵌入它自己的实例,JPopupMenu
我无法弄清楚如何用我自己的子类替换它。
即使为嵌入式实例分配一个自己PopupMenuUI
也没有带来任何结果。JPopupMenu
如果调用了直接从被覆盖的方法继承的paint(...)
方法,但是无论我做什么,都没有绘制任何内容。如果从 继承javax.swing.plaf.synth.SynthPopupMenuUI
paint
甚至没有被调用,结果是如果我根本没有设置自己PopupMenuUI
的。
所以一个简单的问题是:如何JPopupMenu
使用 Nimbus 作为 L&F 在 Java 7 上调整一个或(如果更容易的话)所有这些的背景颜色?
编辑:代码示例
看看下面的代码和结果:
public static void main(final String[] args) {
try {
UIManager.setLookAndFeel(NimbusLookAndFeel.class.getCanonicalName());
UIManager.getLookAndFeelDefaults().put("PopupMenu.background", Color.GREEN);
UIManager.getLookAndFeelDefaults().put("Panel.background", Color.RED);
UIManager.getLookAndFeelDefaults().put("List.background", Color.BLUE);
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200,200);
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
JList list = new JList();
panel.add(list);
frame.getContentPane().add(panel);
JPopupMenu menu = new JPopupMenu();
menu.add(new JMenuItem("A"));
menu.add(new JMenuItem("B"));
menu.add(new JMenuItem("C"));
frame.setVisible(true);
menu.show(frame, 50, 50);
}
我知道,有人说你应该在设置 L&F之前UIManager.put(key, value)
使用or ,但对我来说这不会带来任何结果(意思是:根本没有改变默认颜色)。上面的代码至少带来了:UIManager.getLookAndFeelDefautls().put(key,value)
如果您使用JPopupMenu.setBackground(...)
. 这是因为 Nimbus 使用了一个内部绘制程序,它根据 Nimbus 的原色计算颜色并忽略组件的属性。在此示例中,您可以使用以下解决方法:
JPopupMenu menu = new JPopupMenu() {
@Override
public void paintComponent(final Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0,0,getWidth(), getHeight());
}
};
这带来了
JMenu
但是,如果您插入一个本身包装JPopupMenu
您无法覆盖的a,则此解决方法不起作用:
JMenu jmenu = new JMenu("D");
jmenu.add(new JMenuItem("E"));
menu.add(jmenu);
正如预期的那样:
JPopupMenu
您可以使用它来检索它,JMenu.getPopupMenu()
但不能设置它。即使在自己的子类中重写此方法JMenu
也不会带来任何结果,因为JMenu
似乎在JPopupMenu
不使用 getter 的情况下访问它的封装实例。