经过一番研究后,我想出了一条出路,只改变了可编辑JComboBox文本区域的背景颜色,但还有更好的方法吗?
我想要的是什么:
我的结果应如下所示:
我现在在做什么:
为了澄清,我已经得到了上面的结果,但我认为实现它的代码实在太过分了,因为在第一步中我用所需颜色绘制所有内容(文本字段,按钮和列表)。然后我从按钮中删除颜色,然后通过BasicComboBoxRenderer从列表中删除颜色。
我的代码:
public static void changeOnlyEditorBackgroundColorOfEditableJComboBox(final JComboBox cb, final Color color) {
//paint the whole ComboBox
cb.getEditor().getEditorComponent().setBackground(color);
//remove the color from the button
final Component[] comps = cb.getComponents();
for (int i = 0; i < comps.length; i++) { // hack valid only for Metal L&F
if (comps[i] instanceof MetalComboBoxButton) {
final MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton)comps[i];
coloredArrowsButton.setBackground(null);
break;
}
}
//remove the color from the list
cb.setRenderer(new RemoveColorFromComboBoxListRenderer());
}
private static class RemoveColorFromComboBoxListRenderer extends BasicComboBoxRenderer {
// only slightly changed from the original implementation.
@Override
public Component getListCellRendererComponent(final JList list,
final Object value,
final int index,
final boolean isSelected,
final boolean cellHasFocus) {
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
// these lines were changed to always set the background white and the forground black
setBackground(Color.white);
setForeground(Color.black);
}
setFont(list.getFont());
if (value instanceof Icon) {
setIcon((Icon)value);
} else {
setText((value == null) ? "" : value.toString());
}
return this;
}
}
所以我希望我能够监督一些事情并且有更好的方法来做到这一点。
最后,这是指向SSCCE的链接。
答案 0 :(得分:1)
我认为应该使用XxxRanderer
使用JComboBox.getEditor()。getEditorComponent()。setBackground(Color.YELLOW);
e.g。 (UIManager的键只适用于不可编辑的JComboBox,奇怪但是......)
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.Vector;
import javax.swing.*;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalComboBoxButton;
public class MyComboBox {
private Vector<String> listSomeString = new Vector<String>();
private JComboBox someComboBox = new JComboBox(listSomeString);
private JComboBox editableComboBox = new JComboBox(listSomeString);
private JComboBox non_EditableComboBox = new JComboBox(listSomeString);
private JFrame frame;
public MyComboBox() {
listSomeString.add("-");
listSomeString.add("Snowboarding");
listSomeString.add("Rowing");
listSomeString.add("Knitting");
listSomeString.add("Speed reading");
//
someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
someComboBox.setFont(new Font("Serif", Font.BOLD, 16));
someComboBox.setEditable(true);
someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW);
((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW);
someComboBox.getEditor().getEditorComponent().addFocusListener(fcsListener);
//
editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
editableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
editableComboBox.setEditable(true);
JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent());
text.setBackground(Color.YELLOW);
JComboBox coloredArrowsCombo = editableComboBox;
Component[] comp = coloredArrowsCombo.getComponents();
for (int i = 0; i < comp.length; i++) {
if (comp[i] instanceof MetalComboBoxButton) {
MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i];
coloredArrowsButton.setBackground(null);
break;
}
}
editableComboBox.getEditor().getEditorComponent().addFocusListener(fcsListener);
//
non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
non_EditableComboBox.addFocusListener(fcsListener);
//
frame = new JFrame();
frame.setLayout(new GridLayout(0, 1, 10, 10));
frame.add(someComboBox);
frame.add(editableComboBox);
frame.add(non_EditableComboBox);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
}
//
private FocusListener fcsListener = new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
dumpInfo(e);
}
@Override
public void focusLost(FocusEvent e) {
dumpInfo(e);
}
private void dumpInfo(FocusEvent e) {
final Component c = e.getComponent();
System.out.println("Source : " + name(e.getComponent()));
System.out.println("Opposite : " + name(e.getOppositeComponent()));
System.out.println("Temporary: " + e.isTemporary());
if (c instanceof JFormattedTextField) {//works for editable JComboBox too
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
((JFormattedTextField) c).selectAll();
}
});
} else if (c instanceof JTextField) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
((JTextField) c).selectAll();
}
});
} else if (c instanceof JTextField) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
((JComboBox) c).getEditor().selectAll();
}
});
}
}
private String name(Component c) {
return (c == null) ? null : c.getName();
}
};
public static void main(String[] args) {
UIManager.put("ComboBox.background", new ColorUIResource(Color.yellow));
UIManager.put("JTextField.background", new ColorUIResource(Color.yellow));
UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta));
UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.blue));
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MyComboBox aCTF = new MyComboBox();
}
});
}
}
答案 1 :(得分:0)
我发现了这种奇怪的行为。 myComboBox位于JBAlet中的JPanel中:
private javax.swing.JComboBox myComboBox = new javax.swing.JComboBox();
// This works:
myComboBox.setBackground(Color.yellow);
// This works too:
myComboBox.setBackground(new Color(255, 255, 0));
// This works NOT! Background is now white (= default color of JComboBox)
// but should be light yellow.
myComboBox.setBackground(new Color(255, 255, 150));
答案 2 :(得分:0)
我对前景色有同样的问题,但问题似乎只发生在默认的L&amp; F,当使用例如系统L&amp; F组件的行为与预期一致。 我曾经按照以下解决方案更改列表项的颜色。
combobox.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (index != -1) comp.setForeground(UIManager.getColor("List.foreground"));
return comp;
}
});
combobox.getEditor().getEditorComponent().setForeground(Color.RED);