Nimbus часто выглядит великолепно, но для некоторых цветовых комбинаций результат -не оптимален. В моем случае фон из JPopupMenu
не подходит, поэтому я хочу установить его вручную.
Я на Java 7 и, что интересно, Nimbus полностью игнорирует настройку некоторых свойств вUIManager
(нравитсяPopupMenu.background
). Поэтому моим единственным вариантом было создать подкласс JPopupMenu
, который переопределяет paintComponent(...)
. Я знаю, это противно, но, по крайней мере, это сработало.
Однако, если вы добавите JMenu
в другое меню, оно встроит свой собственный экземпляр JPopupMenu
, и я не мог понять, как заменить его своим собственным подклассом.
Даже присвоение встроенному экземпляру собственного PopupMenuUI
не дало никаких результатов. Если он унаследован непосредственно от JPopupMenu
, вызывался переопределенный метод paint(...)
, но, что бы я ни делал, ничего не рисовалось. Если унаследовано отjavax.swing.plaf.synth.SynthPopupMenuUI
paint
даже не вызывается, и в результате я вообще не установил собственный PopupMenuUI
.
Итак, простой вопрос: :Как мне настроить цвет фона одного JPopupMenu
или (, если это проще )всех их на Java 7, используя Nimbus в качестве L&F?
Изменить :Пример кода
Взгляните на следующий код и результат:
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);
}
Я знаю, некоторые говорят, что вы должны использовать UIManager.put(key, value)
илиUIManager.getLookAndFeelDefautls().put(key,value)
перед настройкой L&F, но для меня это не дает никаких результатов (означает :вообще никаких изменений в цветах по умолчанию ). Код выше, по крайней мере, приносит:
То же самое (означает, что ничего )не произойдет, если вы используете 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);
. дает, как и ожидалось:
Вы можете получить этот JPopupMenu
с помощью JMenu.getPopupMenu()
, но вы не можете установить его. Даже переопределение этого метода в собственном подклассе JMenu
не дает никаких результатов, поскольку JMenu
, похоже, обращается к своему обернутому экземпляру JPopupMenu
без использования геттера.