我会采取务实的方式,只需将组合框传递给渲染器,例如
class ColorIcon implements Icon {
final Color color;
public ColorIcon(Color color) { this.color = color; }
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(color);
g.fillRect(x, y, getIconWidth(), getIconHeight());
}
@Override public int getIconWidth() { return 40; }
@Override public int getIconHeight() { return 12; }
}
Color[] colors = { Color.YELLOW, Color.RED, Color.LIGHT_GRAY, Color.BLUE, Color.GREEN };
JComboBox<Color> cmb = new JComboBox<>(colors);
cmb.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(
JList<?> list, Object value, int index, boolean sel, boolean focus) {
Color color = (Color)value;
Component c = super.getListCellRendererComponent(list, value, index, sel, focus);
setIcon(new ColorIcon(cmb.isEnabled()? color: color.darker()));
setText(String.format("#%06x", color.getRGB() & 0xFFFFFF));
return c;
}
});
JCheckBox chk = new JCheckBox("Disabled?");
chk.addChangeListener(ev -> cmb.setEnabled(!chk.isSelected()));
JFrame f = new JFrame("Test");
f.add(cmb, BorderLayout.PAGE_START);
f.add(chk, BorderLayout.PAGE_END);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
这意味着您不能在不同的组合框之间共享此渲染器的单个实例,但这很少会成为问题。事实上,由于共享这样的渲染器意味着在渲染过程中可能会发生使组件适应不同父级的情况,因此共享可能会比实例化几个渲染器产生更高的成本。
您仍然可以使逻辑可共享,例如
private static JComboBox<Color> setupColorRender(JComboBox<Color> cmb) {
ListCellRenderer<? super Color> def = cmb.getRenderer();
ListCellRenderer<? super Color> r
= def instanceof JLabel? def: new DefaultListCellRenderer();
JLabel label = (JLabel)def;
cmb.setRenderer((list, color, index, sel, focus) -> {
Component c = r.getListCellRendererComponent(list, color, index, sel, focus);
label.setIcon(new ColorIcon(cmb.isEnabled()? color: color.darker()));
label.setText(String.format("#%06x", color.getRGB() & 0xFFFFFF));
return c;
});
return cmb;
}
Color[] colors = { Color.YELLOW, Color.RED, Color.LIGHT_GRAY, Color.BLUE, Color.GREEN };
JComboBox<Color> cmb = setupColorRender(new JComboBox<>(colors));
JCheckBox chk = new JCheckBox("Disabled?");
chk.addChangeListener(ev -> cmb.setEnabled(!chk.isSelected()));
JFrame f = new JFrame("Test");
f.add(cmb, BorderLayout.PAGE_START);
f.add(chk, BorderLayout.PAGE_END);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
可以为任意数量的组合框调用此 setupColorRender 方法。它进一步使用委托而不是典型的子类,只要它仍然是JLabel 的子类,它就允许使用提供的原始外观渲染器。这种方法在某些外观和感觉上具有更好的视觉效果。