【发布时间】:2012-07-22 06:08:32
【问题描述】:
Nimbus 通常看起来不错,但对于某些颜色组合,效果并不理想。在我的情况下,JPopupMenu 的背景不适合,这就是我想手动设置它的原因。
我使用的是 Java 7,有趣的是,Nimbus 完全忽略了 UIManager 中某些属性的设置(例如 PopupMenu.background)。所以我唯一的选择是创建一个覆盖paintComponent(...) 的JPopupMenu 的子类。我知道,这很糟糕,但至少它奏效了。
但是,如果您将 JMenu 添加到另一个菜单,它会嵌入它自己的 JPopupMenu 实例,我无法弄清楚如何用我自己的子类替换它。
即使将自己的PopupMenuUI 分配给嵌入式实例也没有带来任何结果。如果直接从JPopupMenu 继承,则调用覆盖的paint(...) 方法,但是,无论我做什么,都没有绘制任何内容。如果从javax.swing.plaf.synth.SynthPopupMenuUI 继承paint 甚至没有被调用,结果是如果我根本没有设置自己的PopupMenuUI。
所以简单的问题是:如何使用 Nimbus 作为 L&F 在 Java 7 上调整一个 JPopupMenu 或(如果更容易的话)所有这些的背景颜色?
编辑:代码示例
看看下面的代码和结果:
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) 或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,则此解决方法不起作用:
JMenu jmenu = new JMenu("D");
jmenu.add(new JMenuItem("E"));
menu.add(jmenu);
如预期的那样:
您可以使用JMenu.getPopupMenu() 检索此JPopupMenu,但您无法设置它。即使在 JMenu 自己的子类中重写此方法也不会带来任何结果,因为 JMenu 似乎在不使用 getter 的情况下访问它的封装实例 JPopupMenu。
【问题讨论】:
-
如果您概述您的实际目标,您可能会得到更好的答案。 UI 委托
PopupMenuUI并不重要。 -
@aRestless 我认为最好发布一个 SSCCE,Nimbus 不会忽略,它的开发在中间某个地方结束,当然还有(需要)添加一些代码行,另一个选项 could be or another combinations
-
@aRestless 你应该听从 mKorbel 的建议:发布SSCCE,人们可以在他们的机器上按原样运行,我相信你会得到一些答案。
标签: java swing nimbus jpopupmenu