我正在尝试使用nimbus L& F来自定义JComboBox的外观。
以下是一些代码:
NamedPainter.java
package gui.combo;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.Painter;
public class NamedPainter implements Painter<JComponent>
{
String name;
public NamedPainter(String name)
{
this.name = name;
}
@Override
public void paint(Graphics2D g, JComponent object, int width, int height)
{
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, width, height);
g.setFont(new Font("Arial", Font.PLAIN, 12));
g.setColor(Color.YELLOW);
g.drawString(name, 0, 10);
}
}
ColorRectanglePainter.java
package gui.combo;
import java.awt.Color;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.Painter;
public class ColorRectanglePainter implements Painter<JComponent>
{
private final Color color;
public ColorRectanglePainter(final Color color)
{
this.color = color;
}
@Override
public void paint(Graphics2D g, JComponent object, int width, int height)
{
g.setColor(color);
g.fillRect(0, 0, width, height);
}
}
CustomizeComboNimbus.java
package gui.combo;
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.util.Map.Entry;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
public class CustomizeComboNimbus
{
/**
* @param args
*/
public static void main(String[] args)
{
// Set nimbus L&F
try
{
for(LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
{
if("Nimbus".equals(info.getName()))
{
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch(Exception e)
{
// No nimbus...
e.printStackTrace();
return;
}
ColorRectanglePainter redPainter = new ColorRectanglePainter(Color.RED);
// Get default UI and modify it
final UIDefaults boxDefaults = new UIDefaults();
for(Entry<Object, Object> entry : UIManager.getLookAndFeelDefaults().entrySet())
{
try
{
String key = (String)entry.getKey();
if(key.startsWith("ComboBox"))
{
if(key.contains("Painter"))
{
if(key.contains("arrowButton"))
{
// Set a painter which paint a red rectangle for arrowButton
boxDefaults.put(key, redPainter);
System.err.println("Replacing the painter for " + key + " with redPainter");
}
else
{
// Set a painter that display the name of the nimbusKey when it is triggered
NamedPainter painter = new NamedPainter(key);
boxDefaults.put(key, painter);
System.err.println("Replacing the painter for " + key + " with NamedPainter");
}
}
}
}
catch(Exception e)
{
}
}
final String[] toDisplay = { "Hello", "World", "Pimp", "My", "Combo" };
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
JFrame frame = new JFrame("Pimp my combo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComboBox<String> classicCombo = new JComboBox<>(toDisplay);
JComboBox<String> pimpedCombo = new JComboBox<>(toDisplay);
// set the modif to pimpedCombo
pimpedCombo.putClientProperty("Nimbus.Overrides", boxDefaults);
pimpedCombo.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
Container pane = frame.getContentPane();
pane.setLayout(new GridLayout(2, 1));
pane.add(classicCombo);
pane.add(pimpedCombo);
frame.pack();
frame.setVisible(true);
}
});
}
}
这是控制台输出:
Replacing the painter for ComboBox:"ComboBox.arrowButton" Editable+Selected].backgroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.textField"[Enabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Pressed].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Editable+Focused].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Disabled].foregroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Editable+MouseOver].backgroundPainter with redPainter
Replacing the painter for ComboBox[Enabled+Selected].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[MouseOver].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Selected].foregroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Disabled+Editable].backgroundPainter with redPainter
Replacing the painter for ComboBox[Editable+Pressed].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Focused+Pressed].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Disabled+Pressed].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Editable+Enabled].backgroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Enabled].foregroundPainter with redPainter
Replacing the painter for ComboBox[Disabled+Editable].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[MouseOver].foregroundPainter with redPainter
Replacing the painter for ComboBox[Disabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.textField"[Disabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Enabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Editable+MouseOver].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.textField"[Selected].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Focused].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Editable+Pressed].backgroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Pressed].foregroundPainter with redPainter
Replacing the painter for ComboBox[Editable+Enabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Focused+MouseOver].backgroundPainter with NamedPainter
当然,它看起来像什么:
但是,这并不是我的预期!我以为已经用自定义redPainter
替换了所有的ComboBox: arrowButton Painter,我不会看到小三角形的黑色(或白色)箭头,只是一个红色的矩形。
另外,我没有经理改变前景文字的颜色。如何在组合和选择弹出菜单中执行此操作?
[编辑]
进一步调查:我尝试使用UIManager.getLookAndFeelDefaults().put
而不是boxDefaults.put
来放置属性,我得到了arrowButton的预期结果,它显示为红色方块(适用于经典和pimped组合,明显)。所以,我猜我错误的是覆盖了拉皮条组合的属性,即我从Jasper Pott's blog得到的两行
pimpedCombo.putClientProperty("Nimbus.Overrides", boxDefaults);
pimpedCombo.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
有人可以提供帮助吗?
[编辑2]
如果我使用UIManager.put
代替UIManager.getLookAndFeelDefaults().put
,我也会注意到不一致的行为,其中arrowButton将显示为红色,例如仅在mouseOver上显示为红色,或者cliked等.Javadoc说UIManger.put
仅影响“开发者默认值”,而不是L&amp; F默认值。有什么不同?任何帮助,链接到关于一切如何工作的良好文档将是有帮助的。
答案 0 :(得分:0)
Nimbus.Overrides例如内部组件(例如JComboBox内的JTextField)不起作用。我已经为UIManager.getLookAndFeelDefaults()添加了必要的画家,并通过实例实现了父控件分离的自定义逻辑。