我正在尝试使用彩色项目制作彩色下拉列表(请参阅下面的代码)。组合框失去焦点后,颜色会被应用。
这是正确的行为吗?
当组合框具有焦点时,如何更改前景和/或背景颜色?
感谢
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
public class DropDown {
enum Colors {
red(Color.red), orange(Color.orange), green(Color.green), yellow(Color.yellow), blue(Color.blue);
Colors(Color color) {
this.color = color;
}
static String[] listModel() {
java.util.List<Colors> values = Arrays.asList(values());
String s = values.toString().replaceAll(" ", "");
return s.substring(1, s.length() - 1).split(",");
}
final Color color;
}
static class ColoredCellRenderer implements ListCellRenderer {
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
private final static Dimension preferredSize = new Dimension(0, 20);
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
if (index != -1) if (value instanceof String) renderer.setForeground(Colors.valueOf((String) value).color);
else
System.out.println("not a string");
else
System.out.println("in getListCellRendererComponent, index=-1");
renderer.setPreferredSize(preferredSize);
return renderer;
}
}
private static JComboBox addLabeledComboBox(Container c, String label, String[] model) {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
Border border = BorderFactory.createLineBorder(Color.green, 1);
panel.setBorder(border);
JLabel l = new JLabel(label);
panel.add(l);
final JComboBox comboBox = new JComboBox(model);
comboBox.setName(label);
l.setLabelFor(comboBox);
comboBox.setRenderer(new ColoredCellRenderer());
panel.add(comboBox);
c.add(panel);
return comboBox;
}
private static void addContent(Container c) {
c.setLayout(new BoxLayout(c, BoxLayout.Y_AXIS));
ActionListener actionListener = new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JComboBox) {
final JComboBox comboBox = (JComboBox) e.getSource();
Object selected = comboBox.getSelectedItem();
String string = (String) selected;
Color color = Colors.valueOf(string).color;
int i = comboBox.getSelectedIndex();
if (i != -1) {
System.out.println("comboBox " + comboBox.getName() + " " + color);
comboBox.setForeground(color);
System.out.println(comboBox.hasFocus());
// comboBox.repaint();
} else
System.out.println("in actionListener selected=" + selected);
} else
System.out.println("in actionListener selected is not a comboBox");
}
};
c.add(new JButton("button"));
for (int i = 0; i < 2; i++) {
JPanel panel = new JPanel();
Border border = BorderFactory.createLineBorder(Color.red, 1);
panel.setBorder(border);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(new JLabel("label " +(i+1)));
JComboBox comboBox = addLabeledComboBox(panel, "" + (i + 1), Colors.listModel());
comboBox.addActionListener(actionListener);
comboBox.setSelectedIndex(0); // select something
c.add(panel);
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Colored JComboBox");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addContent(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@SuppressWarnings("synthetic-access") public void run() {
createAndShowGUI();
}
});
}
}
答案 0 :(得分:4)
请拆分Editor和Renderer,并将这两个方法添加到DefaultListCellRenderer
cellHasFocus
isSelected
示例
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.event.EventListenerList;
class ColorComboBoxEditor1 implements ComboBoxEditor {
final protected JLabel editor;
//final protected JButton editor;
private EventListenerList listenerList = new EventListenerList();
ColorComboBoxEditor1(Color initialColor) {
editor = new JLabel("");
/*editor = new JButton("");
editor.setBackground(initialColor);
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Color currentBackground = editor.getBackground();
Color color = JColorChooser.showDialog(editor, "Color Chooser", currentBackground);
if ((color != null) && (currentBackground != color)) {
//editor.setBackground(color);
editor.setForeground(color);
fireActionEvent(color);
}
}
};
editor.addActionListener(actionListener);*/
}
@Override
public void addActionListener(ActionListener l) {
listenerList.add(ActionListener.class, l);
}
@Override
public Component getEditorComponent() {
return editor;
}
@Override
public Object getItem() {
return editor.getBackground();
}
@Override
public void removeActionListener(ActionListener l) {
listenerList.remove(ActionListener.class, l);
}
@Override
public void selectAll() {
}
@Override
public void setItem(Object newValue) {
if (newValue instanceof Color) {
Color color = (Color) newValue;
//editor.setBackground(color);
editor.setForeground(color);
editor.setText(String.valueOf(newValue));
} else {
try {
Color color = Color.decode(newValue.toString());
//editor.setBackground(color);
editor.setForeground(color);
editor.setText(String.valueOf(newValue));
} catch (NumberFormatException e) {
}
}
}
protected void fireActionEvent(Color color) {
Object listeners[] = listenerList.getListenerList();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ActionListener.class) {
ActionEvent actionEvent = new ActionEvent(editor, ActionEvent.ACTION_PERFORMED, color.toString());
((ActionListener) listeners[i + 1]).actionPerformed(actionEvent);
}
}
}
}
class ColorCellRenderer1 implements ListCellRenderer {
private DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
// Width doesn't matter as the combo box will size
private final static Dimension preferredSize = new Dimension(0, 20);
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Color) {
//renderer.setBackground((Color) value);
renderer.setBackground(Color.white);
renderer.setForeground((Color) value);
}
if (cellHasFocus || isSelected) {
renderer.setBorder(new LineBorder(Color.DARK_GRAY));
} else {
renderer.setBorder(null);
}
renderer.setPreferredSize(preferredSize);
return renderer;
}
}
class ColorComboBoxEditorRendererDemo1 {
public ColorComboBoxEditorRendererDemo1() {
Color colors[] = {Color.BLACK, Color.BLUE, Color.GREEN, Color.RED, Color.WHITE, Color.YELLOW};
JFrame frame = new JFrame("Color JComboBox");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JComboBox comboBox = new JComboBox(colors);
comboBox.setEditable(true);
comboBox.setRenderer(new ColorCellRenderer1());
Color color = (Color) comboBox.getSelectedItem();
ComboBoxEditor editor = new ColorComboBoxEditor1(color);
comboBox.setEditor(editor);
frame.add(comboBox, BorderLayout.NORTH);
final JLabel label = new JLabel();
label.setOpaque(true);
label.setBackground((Color) comboBox.getSelectedItem());
frame.add(label, BorderLayout.CENTER);
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
Color selectedColor = (Color) comboBox.getSelectedItem();
label.setBackground(selectedColor);
}
};
comboBox.addActionListener(actionListener);
frame.setSize(300, 200);
frame.setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ColorComboBoxEditorRendererDemo1 cCBERD1 = new ColorComboBoxEditorRendererDemo1();
}
});
}
}
答案 1 :(得分:4)
这是另一种方法:
//JList#setSelectionForeground(...) version
static class ColoredCellRenderer implements ListCellRenderer {
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
private final Color selectionBackground = new Color(240,200,200);
public Component getListCellRendererComponent(
JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Color fgc = Colors.valueOf((String)value).color;
if(index<0) {
//comboBox.setForeground(fgc); //Windows, CDE/Motif Look & Feel
list.setSelectionForeground(fgc);
list.setSelectionBackground(selectionBackground);
}
JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
if (index != -1) {
renderer.setForeground(fgc);
}
return renderer;
}
}
//html version
static class ComboHtmlRenderer extends DefaultListCellRenderer {
private final Color selectionBackground = new Color(240,200,200);
@Override public Component getListCellRendererComponent(
JList list, Object value, int index, boolean isSelected, boolean hasFocus) {
Color fgc = Colors.valueOf((String)value).color;
if(index<0) {
list.setSelectionBackground(selectionBackground);
}
JLabel l = (JLabel)super.getListCellRendererComponent(
list, value, index, isSelected, hasFocus);
l.setText("<html><font color="+hex(fgc)+">"+value);
l.setBackground(isSelected?selectionBackground:list.getBackground());
return l;
}
private static String hex(Color c) {
return String.format("#%06x", c.getRGB()&0xffffff);
}
}
答案 2 :(得分:2)
示例中的前景文本颜色似乎正常工作。某些其他颜色由组件的UI委托管理给定的Look&amp;感觉,如下图所示。请注意,代理人可以选择以保持各种状态对比度的方式应用颜色,例如选择,启用等。您可以在文章UIManager Defaults中了解更多信息。
public static void main(String[] args) {
UIManager.put("ComboBox.background", new ColorUIResource(Color.lightGray));
UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta));
UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.yellow));
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@SuppressWarnings("synthetic-access")
public void run() {
createAndShowGUI();
}
});
}