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.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Moon Cheesez
  • 2,489
  • 3
  • 24
  • 38
  • Works fine for me. Post a proper [SSCCE](http://sscce.org/) 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. – camickr Nov 21 '15 at 03:57
  • 1
    `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 uses – MadProgrammer Nov 21 '15 at 04:01
  • `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. – Andrew Thompson Nov 21 '15 at 04:19
  • @Moon Cheesez [for example](http://stackoverflow.com/a/5755124/714968) – mKorbel Nov 21 '15 at 13:41

2 Answers2

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);
            }
        });
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 4
    (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 :) – camickr Nov 21 '15 at 05:28
  • @camickr Always the sage analysis. :) I also saw value to side-stepping the entire 'problem' of the PLAF, as suggested in your answer. – Andrew Thompson Nov 21 '15 at 07:41
  • Back from the future, this also solves the same problem with Jython JButtons. – Moon Cheesez Jun 02 '16 at 14:31
3

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.

camickr
  • 321,443
  • 19
  • 166
  • 288