Jiminner的背景颜色与Nimbus

时间:2016-02-01 09:10:43

标签: java swing jspinner nimbus

是否有人已成功更改使用Nimbus设置的JSpinner编辑器的背景颜色?

我尝试了在StackOverflow上找到的不同选项。他们都没有工作。 我在下面总结了它们。

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的复制/粘贴,我改变了一些颜色:

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);
    }

}

有没有人知道如何设置这种颜色?

感谢您阅读!!

1 个答案:

答案 0 :(得分:2)

更改微调器的编辑器的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);
            };
        });
    }
}