Question

How can I change the background and foreground color of a JSpinner in swing?
is there any simple solution except override the paint() method?
setting the background or foreground color doesn't work, at least for me.
I also tested with all default look and feels, no success.
JDK: 1.7.0.51 Win764

Thanks in advance

Was it helpful?

Solution

The JSpinner is a compound component. Simply said: By default, it conains a JFormattedTextField that shows the value, and two buttons for increasing and decreasing the value.

One way to set these colors may thus be to obtain the text field from the spinner, and set its foreground and background color:

Component c = spinner.getEditor().getComponent(0);
c.setForeground(Color.BLUE);
c.setBackground(Color.RED);

but you might have to make this more robust to make sure that it works for all LookAndFeels, and all editors, regardless of how the spinner (and the editor) are constructed internally.


EDIT in response to the comment: Does it work in this case?

import java.awt.Color;
import java.awt.Component;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class SpinnerColors
{
    public static void main(String[] args)
    {
        // Optionally:
        setLookAndFeel();

        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void setLookAndFeel()
    {
        try
        {
            UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JSpinner spinner = new JSpinner();
        setColors(spinner, Color.BLUE, Color.RED);

        f.getContentPane().add(spinner);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static void setColors(
        JSpinner spinner, Color foreground, Color background)
    {
        JComponent editor = spinner.getEditor();
        System.out.println("Editor "+editor);
        int n = editor.getComponentCount();
        for (int i=0; i<n; i++)
        {
            Component c = editor.getComponent(i);
            System.out.println("Component "+i+": "+c);
            if (c instanceof JTextField)
            {
                c.setForeground(foreground);
                c.setBackground(background);
            }
        }
    }
}

Note that if you are using the "Nimbus" look and feel, things might be more difficult. Nimbus is known for notoriously ignoring background colors....


EDIT2 in response to the second comment: It is basically possible to access the buttons, but for the default L&Fs, these are specialized buttons (BasicArrowButton) where the paint method is overridden to paint the tiny "up" and "down" arrows. So setting the foreground on these will not have any effect. Instead, you'd have to modify the L&F defaults, which may always be a hassle. So this might or might not have the effect that you want to achieve:

private static void setButtonColors(
    JSpinner spinner, Color foreground, Color background)
{
    int n = spinner.getComponentCount();
    for (int i=0; i<n; i++)
    {
        Component c = spinner.getComponent(i);
        if (c instanceof JButton)
        {
            c.setForeground(foreground); // Has no effect
            c.setBackground(background);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top