带有 Nimbus 的 JSpinner 的背景颜色
Background color of JSpinner with Nimbus
有没有人已经成功地更改了带有 Nimbus 样式的 JSpinner 编辑器的背景颜色?
我尝试了在 Whosebug 上找到的不同选项。 None 他们成功了。
我在下面总结了它们。
1) 基本上使用setBackground.
此解决方案适用于我尝试过的每个组件,但适用于 JSpinner:
if (sometest)
component.setBackground(Color.red);
else
component.setBackground(null);
背景颜色不变。
2) 设置编辑器的背景颜色:
if (component instanceof JSpinner) {
// component.setBackground(new Color(0,0,0,0)); // doesn't change anything
// component.setOpaque(false); // doesn't change anything
final JComponent editor = ((JSpinner) component).getEditor();
int c=editor.getComponentCount();
for (int i = 0; i < c; i++) {
final Component comp = editor.getComponent(i);
if (comp instanceof JTextComponent) {
comp.setBackground(Color.red);
}
}
3) 使用 Nimbus 覆盖
我定义了一个新的 Painter,它是 SpinnerPanelSpinnerFormattedTextFieldPainter
的 copy/paste,我在其中更改了一些颜色:
public class MySpinnerEditorPainter extends AbstractRegionPainter {
//package private integers representing the available states that
//this painter will paint. These are used when creating a new instance
//of SpinnerPanelSpinnerFormattedTextFieldPainter to determine which region/state is being painted
//by that instance.
static final int BACKGROUND_DISABLED = 1;
static final int BACKGROUND_ENABLED = 2;
static final int BACKGROUND_FOCUSED = 3;
static final int BACKGROUND_SELECTED = 4;
static final int BACKGROUND_SELECTED_FOCUSED = 5;
private int state; //refers to one of the static final ints above
private PaintContext ctx;
//the following 4 variables are reused during the painting code of the layers
private Path2D path = new Path2D.Float();
private Rectangle2D rect = new Rectangle2D.Float(0, 0, 0, 0);
private RoundRectangle2D roundRect = new RoundRectangle2D.Float(0, 0, 0, 0, 0, 0);
private Ellipse2D ellipse = new Ellipse2D.Float(0, 0, 0, 0);
//All Colors used for painting are stored here. Ideally, only those colors being used
//by a particular instance of SpinnerPanelSpinnerFormattedTextFieldPainter would be created. For the moment at least,
//however, all are created for each instance.
private Color color1 = decodeColor("nimbusBlueGrey", -0.6111111f, -0.110526316f, -0.74509805f, -237);
private Color color2 = decodeColor("nimbusBlueGrey", -0.006944418f, -0.07187897f, 0.06666666f, 0);
private Color color3 = decodeColor("nimbusBlueGrey", 0.007936537f, -0.07703349f, 0.0745098f, 0);
private Color color4 = decodeColor("nimbusBlueGrey", 0.007936537f, -0.07968931f, 0.14509803f, 0);
private Color color5 = decodeColor("nimbusBlueGrey", 0.007936537f, -0.07856284f, 0.11372548f, 0);
private Color color6 = decodeColor("nimbusBase", 0.040395975f, -0.60315615f, 0.29411763f, 0);
private Color color7 = decodeColor("nimbusBase", 0.016586483f, -0.6051466f, 0.3490196f, 0);
private Color color8 = decodeColor("nimbusBlueGrey", -0.027777791f, -0.0965403f, -0.18431371f, 0);
private Color color9 = decodeColor("nimbusBlueGrey", 0.055555582f, -0.1048766f, -0.08f, 0);
private Color color10 = decodeColor("nimbusBlueGrey", 0.055555582f, -0.105624355f, 0.054901958f, 0);
private Color color11 = decodeColor("nimbusBlueGrey", 0.0f, -0.110526316f, 0.25490195f, 0);
private Color color12 = decodeColor("nimbusBlueGrey", 0.055555582f, -0.105344966f, 0.011764705f, 0);
private Color color13 = Color.orange; //decodeColor("nimbusLightBackground", 0.0f, 0.0f, 0.0f, 0);
private Color color14 = decodeColor("nimbusFocus", 0.0f, 0.0f, 0.0f, 0);
private Color color15 = decodeColor("nimbusBlueGrey", 0.055555582f, -0.1048766f, -0.05098039f, 0);
//Array of current component colors, updated in each paint call
private Object[] componentColors;
public MySpinnerEditorPainter(int state) {
// this(new AbstractRegionPainter.PaintContext(null, null, false), state);
this(null, state);
}
public MySpinnerEditorPainter(Object ctx, int state) {
super();
this.state = state;
if ((ctx == null) || !(ctx instanceof PaintContext)) {
this.ctx = new PaintContext(new Insets(7, 7, 7, 7), new Dimension(10, 20), false);
}
else {
this.ctx = (PaintContext) ctx;
}
}
@Override
protected void doPaint(Graphics2D g, JComponent c, int width, int height, Object[] extendedCacheKeys) {
//populate componentColors array with colors calculated in getExtendedCacheKeys call
componentColors = extendedCacheKeys;
//generate this entire method. Each state/bg/fg/border combo that has
//been painted gets its own KEY and paint method.
switch (state) {
case BACKGROUND_DISABLED:
paintBackgroundDisabled(g);
break;
case BACKGROUND_ENABLED:
paintBackgroundEnabled(g);
break;
case BACKGROUND_FOCUSED:
paintBackgroundFocused(g);
break;
case BACKGROUND_SELECTED:
paintBackgroundSelected(g);
break;
case BACKGROUND_SELECTED_FOCUSED:
paintBackgroundSelectedAndFocused(g);
break;
}
}
然后我定义一个新的 UIDefaults:
// 1) (trickiest part) Getting a PaintContext
Object context = null;
AbstractRegionPainter abstractPainter = (AbstractRegionPainter) UIManager.get("ProgressBar[Enabled].foregroundPainter");
// could only be achieved by reflection ?
try {
Class<?> clazz = abstractPainter.getClass();
// get the protected Method of AbstractRegionPainter
Method protectedMethod = clazz.getDeclaredMethod("getPaintContext");
protectedMethod.setAccessible(true);
AbstractRegionPainter.PaintContext
context = (Object) protectedMethod.invoke(abstractPainter); // 3 is constant for "FOREGROUND_ENABLED"
} catch (Exception e) {
e.printStackTrace();
}
// 2) Create and define the UIDefaults
spinner_editthrough = new UIDefaults();
// 2.1) the "Spinner.nextButton"
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Disabled].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_DISABLED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Enabled].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_ENABLED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Focused+MouseOver].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_MOUSEOVER_FOCUSED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Focused+Pressed].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_PRESSED_FOCUSED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Focused].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_FOCUSED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[MouseOver].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_MOUSEOVER));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Pressed].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_PRESSED));
// 2.2) the "Spinner.formattedTextField"
spinner_editthrough.put("Spinner:Panel:\"Spinner.formattedTextField\"[Enabled].backgroundPainter", new MySpinnerEditorPainter(context, MySpinnerEditorPainter.BACKGROUND_ENABLED));
spinner_editthrough.put("Spinner:Panel:\"Spinner.formattedTextField\"[Focused].backgroundPainter", new MySpinnerEditorPainter(context, MySpinnerEditorPainter.BACKGROUND_FOCUSED));
spinner_editthrough.put("Spinner:Panel:\"Spinner.formattedTextField\"[Selected].backgroundPainter", new MySpinnerEditorPainter(context, MySpinnerEditorPainter.BACKGROUND_SELECTED));
spinner_editthrough.put("Spinner:Panel:\"Spinner.formattedTextField\"[Focused+Selected].backgroundPainter", new MySpinnerEditorPainter(context, MySpinnerEditorPainter.BACKGROUND_SELECTED_FOCUSED));
我分配给我的 JSpinner:
if (component instanceof JSpinner) {
if (sometest) {
component.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
component.putClientProperty("Nimbus.Overrides", spinner_editthrough);
}
else {
component.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
component.putClientProperty("Nimbus.Overrides", spinner_normal);
}
}
最后但同样重要的是:我检查了 JSpinner 的创建。
似乎我没有错:
public static class ExtraParameterComponentIntInc extends JSpinner implements ExtraParameterComponent {
private JLabel label;
private ExtraParameterDefinitionInt extra;
// private EventListenerList listenerList = null;
private ExtraParameterComponentIntInc(ExtraParameterDefinitionInt extra) {
super(new SpinnerNumberModel((int) extra.getDefaultValue(), (int) extra.getMinimumValue(), (int) extra.getMaximumValue(),
(int) ((extra.getIncrement() != null) ? extra.getIncrement() : 1)));
this.extra = extra;
final JFormattedTextField editor = ((JSpinner.DefaultEditor) this.getEditor()).getTextField();
editor.setColumns(6);
this.label = new JLabel(extra.label);
editor.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(java.awt.event.KeyEvent evt) {
if (KeyEvent.VK_ENTER != evt.getKeyCode()) {
return;
}
fireActionPerformed();
}
});
}
protected void fireActionPerformed() {
if (listenerList == null)
return;
ActionEvent event = new ActionEvent(ExtraParameterComponentIntInc.this, ActionEvent.ACTION_PERFORMED, "keypressed");
for (ActionListener listener : listenerList.getListeners(ActionListener.class)) {
listener.actionPerformed(event);
}
}
@Override
public Object getValue() {
// extra est null uniquement à l'initialisation
return (extra!=null)?ExtraParameterDefinition.castExtraParameterValue(extra,super.getValue()):super.getValue();
}
@Override
public void setValue(Object value) {
// Le JSpinner n'accepte pas de valeur null => on force 0
if (value==null) value=0;
super.setValue(value);
}
@Override
public JLabel getLabel() {
return label;
}
@Override
public void addActionListener(ActionListener e) {
if (listenerList == null)
listenerList = new EventListenerList();
listenerList.add(ActionListener.class, e);
}
@Override
public void removeActionListener(ActionListener e) {
if (listenerList == null)
return;
listenerList.remove(ActionListener.class, e);
}
}
有人知道如何设置这种颜色吗?
感谢阅读!!
更改 ui 微调器编辑器并覆盖 ui
的绘制方法
final JComponent editor = spinner.getEditor();
int c=editor.getComponentCount();
for (int i = 0; i < c; i++) {
final Component comp = editor.getComponent(i);
if (comp instanceof JTextComponent) {
((JTextComponent) comp).setUI(new SynthFormattedTextFieldUI(){
protected void paint(javax.swing.plaf.synth.SynthContext context, java.awt.Graphics g) {
g.setColor(Color.pink);
g.fillRect(3, 3, getComponent().getWidth()-3, getComponent().getHeight()-6);
super.paint(context, g);
};
});
}
}
有没有人已经成功地更改了带有 Nimbus 样式的 JSpinner 编辑器的背景颜色?
我尝试了在 Whosebug 上找到的不同选项。 None 他们成功了。 我在下面总结了它们。
1) 基本上使用setBackground.
此解决方案适用于我尝试过的每个组件,但适用于 JSpinner:
if (sometest)
component.setBackground(Color.red);
else
component.setBackground(null);
背景颜色不变。
2) 设置编辑器的背景颜色:
if (component instanceof JSpinner) {
// component.setBackground(new Color(0,0,0,0)); // doesn't change anything
// component.setOpaque(false); // doesn't change anything
final JComponent editor = ((JSpinner) component).getEditor();
int c=editor.getComponentCount();
for (int i = 0; i < c; i++) {
final Component comp = editor.getComponent(i);
if (comp instanceof JTextComponent) {
comp.setBackground(Color.red);
}
}
3) 使用 Nimbus 覆盖
我定义了一个新的 Painter,它是 SpinnerPanelSpinnerFormattedTextFieldPainter
的 copy/paste,我在其中更改了一些颜色:
public class MySpinnerEditorPainter extends AbstractRegionPainter {
//package private integers representing the available states that
//this painter will paint. These are used when creating a new instance
//of SpinnerPanelSpinnerFormattedTextFieldPainter to determine which region/state is being painted
//by that instance.
static final int BACKGROUND_DISABLED = 1;
static final int BACKGROUND_ENABLED = 2;
static final int BACKGROUND_FOCUSED = 3;
static final int BACKGROUND_SELECTED = 4;
static final int BACKGROUND_SELECTED_FOCUSED = 5;
private int state; //refers to one of the static final ints above
private PaintContext ctx;
//the following 4 variables are reused during the painting code of the layers
private Path2D path = new Path2D.Float();
private Rectangle2D rect = new Rectangle2D.Float(0, 0, 0, 0);
private RoundRectangle2D roundRect = new RoundRectangle2D.Float(0, 0, 0, 0, 0, 0);
private Ellipse2D ellipse = new Ellipse2D.Float(0, 0, 0, 0);
//All Colors used for painting are stored here. Ideally, only those colors being used
//by a particular instance of SpinnerPanelSpinnerFormattedTextFieldPainter would be created. For the moment at least,
//however, all are created for each instance.
private Color color1 = decodeColor("nimbusBlueGrey", -0.6111111f, -0.110526316f, -0.74509805f, -237);
private Color color2 = decodeColor("nimbusBlueGrey", -0.006944418f, -0.07187897f, 0.06666666f, 0);
private Color color3 = decodeColor("nimbusBlueGrey", 0.007936537f, -0.07703349f, 0.0745098f, 0);
private Color color4 = decodeColor("nimbusBlueGrey", 0.007936537f, -0.07968931f, 0.14509803f, 0);
private Color color5 = decodeColor("nimbusBlueGrey", 0.007936537f, -0.07856284f, 0.11372548f, 0);
private Color color6 = decodeColor("nimbusBase", 0.040395975f, -0.60315615f, 0.29411763f, 0);
private Color color7 = decodeColor("nimbusBase", 0.016586483f, -0.6051466f, 0.3490196f, 0);
private Color color8 = decodeColor("nimbusBlueGrey", -0.027777791f, -0.0965403f, -0.18431371f, 0);
private Color color9 = decodeColor("nimbusBlueGrey", 0.055555582f, -0.1048766f, -0.08f, 0);
private Color color10 = decodeColor("nimbusBlueGrey", 0.055555582f, -0.105624355f, 0.054901958f, 0);
private Color color11 = decodeColor("nimbusBlueGrey", 0.0f, -0.110526316f, 0.25490195f, 0);
private Color color12 = decodeColor("nimbusBlueGrey", 0.055555582f, -0.105344966f, 0.011764705f, 0);
private Color color13 = Color.orange; //decodeColor("nimbusLightBackground", 0.0f, 0.0f, 0.0f, 0);
private Color color14 = decodeColor("nimbusFocus", 0.0f, 0.0f, 0.0f, 0);
private Color color15 = decodeColor("nimbusBlueGrey", 0.055555582f, -0.1048766f, -0.05098039f, 0);
//Array of current component colors, updated in each paint call
private Object[] componentColors;
public MySpinnerEditorPainter(int state) {
// this(new AbstractRegionPainter.PaintContext(null, null, false), state);
this(null, state);
}
public MySpinnerEditorPainter(Object ctx, int state) {
super();
this.state = state;
if ((ctx == null) || !(ctx instanceof PaintContext)) {
this.ctx = new PaintContext(new Insets(7, 7, 7, 7), new Dimension(10, 20), false);
}
else {
this.ctx = (PaintContext) ctx;
}
}
@Override
protected void doPaint(Graphics2D g, JComponent c, int width, int height, Object[] extendedCacheKeys) {
//populate componentColors array with colors calculated in getExtendedCacheKeys call
componentColors = extendedCacheKeys;
//generate this entire method. Each state/bg/fg/border combo that has
//been painted gets its own KEY and paint method.
switch (state) {
case BACKGROUND_DISABLED:
paintBackgroundDisabled(g);
break;
case BACKGROUND_ENABLED:
paintBackgroundEnabled(g);
break;
case BACKGROUND_FOCUSED:
paintBackgroundFocused(g);
break;
case BACKGROUND_SELECTED:
paintBackgroundSelected(g);
break;
case BACKGROUND_SELECTED_FOCUSED:
paintBackgroundSelectedAndFocused(g);
break;
}
}
然后我定义一个新的 UIDefaults:
// 1) (trickiest part) Getting a PaintContext
Object context = null;
AbstractRegionPainter abstractPainter = (AbstractRegionPainter) UIManager.get("ProgressBar[Enabled].foregroundPainter");
// could only be achieved by reflection ?
try {
Class<?> clazz = abstractPainter.getClass();
// get the protected Method of AbstractRegionPainter
Method protectedMethod = clazz.getDeclaredMethod("getPaintContext");
protectedMethod.setAccessible(true);
AbstractRegionPainter.PaintContext
context = (Object) protectedMethod.invoke(abstractPainter); // 3 is constant for "FOREGROUND_ENABLED"
} catch (Exception e) {
e.printStackTrace();
}
// 2) Create and define the UIDefaults
spinner_editthrough = new UIDefaults();
// 2.1) the "Spinner.nextButton"
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Disabled].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_DISABLED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Enabled].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_ENABLED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Focused+MouseOver].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_MOUSEOVER_FOCUSED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Focused+Pressed].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_PRESSED_FOCUSED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Focused].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_FOCUSED));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[MouseOver].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_MOUSEOVER));
spinner_editthrough.put("Spinner:\"Spinner.nextButton\"[Pressed].backgroundPainter", new SpinnerNextPainter(context, SpinnerNextPainter.BACKGROUND_PRESSED));
// 2.2) the "Spinner.formattedTextField"
spinner_editthrough.put("Spinner:Panel:\"Spinner.formattedTextField\"[Enabled].backgroundPainter", new MySpinnerEditorPainter(context, MySpinnerEditorPainter.BACKGROUND_ENABLED));
spinner_editthrough.put("Spinner:Panel:\"Spinner.formattedTextField\"[Focused].backgroundPainter", new MySpinnerEditorPainter(context, MySpinnerEditorPainter.BACKGROUND_FOCUSED));
spinner_editthrough.put("Spinner:Panel:\"Spinner.formattedTextField\"[Selected].backgroundPainter", new MySpinnerEditorPainter(context, MySpinnerEditorPainter.BACKGROUND_SELECTED));
spinner_editthrough.put("Spinner:Panel:\"Spinner.formattedTextField\"[Focused+Selected].backgroundPainter", new MySpinnerEditorPainter(context, MySpinnerEditorPainter.BACKGROUND_SELECTED_FOCUSED));
我分配给我的 JSpinner:
if (component instanceof JSpinner) {
if (sometest) {
component.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
component.putClientProperty("Nimbus.Overrides", spinner_editthrough);
}
else {
component.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
component.putClientProperty("Nimbus.Overrides", spinner_normal);
}
}
最后但同样重要的是:我检查了 JSpinner 的创建。
似乎我没有错:
public static class ExtraParameterComponentIntInc extends JSpinner implements ExtraParameterComponent {
private JLabel label;
private ExtraParameterDefinitionInt extra;
// private EventListenerList listenerList = null;
private ExtraParameterComponentIntInc(ExtraParameterDefinitionInt extra) {
super(new SpinnerNumberModel((int) extra.getDefaultValue(), (int) extra.getMinimumValue(), (int) extra.getMaximumValue(),
(int) ((extra.getIncrement() != null) ? extra.getIncrement() : 1)));
this.extra = extra;
final JFormattedTextField editor = ((JSpinner.DefaultEditor) this.getEditor()).getTextField();
editor.setColumns(6);
this.label = new JLabel(extra.label);
editor.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(java.awt.event.KeyEvent evt) {
if (KeyEvent.VK_ENTER != evt.getKeyCode()) {
return;
}
fireActionPerformed();
}
});
}
protected void fireActionPerformed() {
if (listenerList == null)
return;
ActionEvent event = new ActionEvent(ExtraParameterComponentIntInc.this, ActionEvent.ACTION_PERFORMED, "keypressed");
for (ActionListener listener : listenerList.getListeners(ActionListener.class)) {
listener.actionPerformed(event);
}
}
@Override
public Object getValue() {
// extra est null uniquement à l'initialisation
return (extra!=null)?ExtraParameterDefinition.castExtraParameterValue(extra,super.getValue()):super.getValue();
}
@Override
public void setValue(Object value) {
// Le JSpinner n'accepte pas de valeur null => on force 0
if (value==null) value=0;
super.setValue(value);
}
@Override
public JLabel getLabel() {
return label;
}
@Override
public void addActionListener(ActionListener e) {
if (listenerList == null)
listenerList = new EventListenerList();
listenerList.add(ActionListener.class, e);
}
@Override
public void removeActionListener(ActionListener e) {
if (listenerList == null)
return;
listenerList.remove(ActionListener.class, e);
}
}
有人知道如何设置这种颜色吗?
感谢阅读!!
更改 ui 微调器编辑器并覆盖 ui
的绘制方法final JComponent editor = spinner.getEditor();
int c=editor.getComponentCount();
for (int i = 0; i < c; i++) {
final Component comp = editor.getComponent(i);
if (comp instanceof JTextComponent) {
((JTextComponent) comp).setUI(new SynthFormattedTextFieldUI(){
protected void paint(javax.swing.plaf.synth.SynthContext context, java.awt.Graphics g) {
g.setColor(Color.pink);
g.fillRect(3, 3, getComponent().getWidth()-3, getComponent().getHeight()-6);
super.paint(context, g);
};
});
}
}