Set JButton background color on windows
Asked Answered
R

2

5

I have a JButton which I want to set the background to a color.

JButton button = new JButton();
button.setVisible(true);
button.setPreferredSize(new Dimension(student_scroll.getWidth(), 50));
button.setBorder(BorderFactory.createLineBorder(Color.WHITE, 1));
button.setBackground(Color.BLACK);
button.setForeground(Color.WHITE);
button.setOpaque(true);

I used this for mac and it showed up as I wanted it to be. However, upon trying it on windows, the foreground is white(as it should) but the background is empty.

Setting background color to JButton

says to add button.setContentAreaFilled(false); which I did but had no effect. Most others say to add button.setOpaque(true);which I also did already.

What else do I have to do so that it will show up with a black background?

EDIT

As requested, the SSCCE:

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MainSwing extends JFrame {
    private static final long serialVersionUID = -8231889836024827530L;

    public static void main(String[] args) {
        try {
            System.setProperty("apple.laf.useScreenMenuBar", "true");
            System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Test");
            UIManager.put("ScrollBarUI", "main.CustomScrollBarUI");
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch(ClassNotFoundException e) {
            System.out.println("ClassNotFoundException: " + e.getMessage());
    }
    catch(InstantiationException e) {
            System.out.println("InstantiationException: " + e.getMessage());
    }
    catch(IllegalAccessException e) {
            System.out.println("IllegalAccessException: " + e.getMessage());
    }
    catch(UnsupportedLookAndFeelException e) {
            System.out.println("UnsupportedLookAndFeelException: " + e.getMessage());
    }
        SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                JFrame frame = new JFrame() {

                    Container c = getContentPane();
                    JButton button = new JButton("Hello");
                    {
                        button.setText("Hello");
                        button.setVisible(true);
                        button.setPreferredSize(new Dimension(100, 50));
                        button.setBorder(BorderFactory.createLineBorder(Color.WHITE, 1));
                        button.setBackground(Color.BLACK);
                        button.setForeground(Color.WHITE);
                        button.setOpaque(true);
                        c.add(button);
                    }

                };
                frame.setSize(500, 500);
                frame.setBackground(Color.BLACK);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

It seems that the problem has something to do with the line: UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); as when I remove it, the buttons are black.

Rothberg answered 21/11, 2015 at 3:47 Comment(4)
Works fine for me. Post a proper SSCCE that demonstrates the problem. So all you need is a frame with a button to do your test. The whole program would be 10-15 lines of code.Consultation
setContentAreaFilled(false) and or setBorderPainted(false). The "fill" effect is provided by the look and feel delegate and I don't know any way to effect the colors it usesCalcaneus
button.setVisible(true); not necessary. Just add it (to a container possibly, that is added) to a top level window (frame, window, dialog etc.) that is itself packed after components are added, then set visible. button.setPreferredSize(new Dimension(student_scroll.getWidth(), 50)); If the button has no text, the size is easily set using a (possibly transparent) image. If the button has text the size is better determined from the font size ant text content, and the margins and borders of the button that contains it. In neither case do we need to set a preferred size.Phyllys
@Moon Cheesez for exampleVetter
P
5

I'm guessing from those UIManager key/value pairs that the PLAF is the OS X based Aqua PLAF. And that seems to be part of the problem here. Here it is without the content area filled on Windows.

enter image description here

import java.awt.*;
import javax.swing.*;

public class MainSwing extends JFrame {

    public static void main(String[] args) {
        try {
            System.setProperty("apple.laf.useScreenMenuBar", "true");
            System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Test");
            UIManager.put("ScrollBarUI", "main.CustomScrollBarUI");
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace(); // more info for less LOC!
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame() {

                    Container c = getContentPane();
                    JButton button = new JButton("Hello");

                    {
                        c.setLayout(new GridLayout(0,1));
                        c.add(new JButton("Hi"));
                        button.setText(UIManager.getSystemLookAndFeelClassName());
                        button.setVisible(true);
                        button.setPreferredSize(new Dimension(400, 100));
                        button.setBorder(BorderFactory.createLineBorder(Color.WHITE, 1));
                        button.setContentAreaFilled(false);
                        button.setBackground(Color.BLACK);
                        button.setForeground(Color.WHITE);
                        button.setOpaque(true);
                        c.add(button);
                    }
                };
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}
Phyllys answered 21/11, 2015 at 5:9 Comment(3)
(1+), wow this also works for me on Windows. I found out that the setOpaque( true ) statement is important and it must be invoked after the setContentAreaFilled( false ) statement as this statement apparently invokes setOpaque(false), which I was not aware of. Learn something every day. I guess I should have read your answer in Setting Background Color to Button first :)Consultation
@Consultation Always the sage analysis. :) I also saw value to side-stepping the entire 'problem' of the PLAF, as suggested in your answer.Phyllys
Back from the future, this also solves the same problem with Jython JButtons.Rothberg
C
4

It seems that the problem has something to do with the line: UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); as when I remove it, the buttons are black.

So that is extra information we didn't have before you created the SSCCE (which is why you should always post a SSCCE with your question).

It also tells you the problem is not with your code but with the LAF. The Windows LAF ignores the setBackground(...) method and paints its own background.

One option would be to add an Icon to the button of your desired color. Then you can configure the text to be painted in the center of the button:

import java.awt.*;
import javax.swing.*;

public class ColorIcon implements Icon
{
    private Color color;
    private int width;
    private int height;

    public ColorIcon(Color color, int width, int height)
    {
        this.color = color;
        this.width = width;
        this.height = height;
    }

    public int getIconWidth()
    {
        return width;
    }

    public int getIconHeight()
    {
        return height;
    }

    public void paintIcon(Component c, Graphics g, int x, int y)
    {
        g.setColor(color);
        g.fillRect(x, y, width, height);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI()
    {
        JPanel panel = new JPanel( new GridLayout(2, 2) );

        for (int i = 0; i < 4; i++)
        {
            Icon icon = new ColorIcon(Color.RED, 50, 50);
            JButton label = new JButton( icon );
            label.setText("" + i);
            label.setHorizontalTextPosition(JButton.CENTER);
            label.setVerticalTextPosition(JButton.CENTER);
            panel.add(label);
        }

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(panel);
        f.setSize(200, 200);
        f.setLocationRelativeTo( null );
        f.setVisible(true);
    }
}

Then is should work on all LAF's.

Consultation answered 21/11, 2015 at 5:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.