1

I want to get a JButton with white background in Windows 10 for a Java Swing application.

I have tried the following. I include a functional basic sample with two frames, both have a panel and a button, the first one does not include any customization. Buttons and Panels have a light blue/grey color (actual perceived color depends on the screen). For the second frame I try to explicitly draw white panels and buttons.

package com.example.test2;

import java.awt.Color;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test2 {

    public Test2() {

        // Frame 1, standard background
        JFrame frame1 = new JFrame();
        JPanel panel1 = new JPanel();
        JButton button1 = new JButton("Button 1");

        // Frame 2, white background
        JFrame frame2 = new JFrame();
        JPanel panel2 = new JPanel();
        JButton button2 = new JButton("Button 2");
        panel2.setBackground(Color.WHITE);
        button2.setBackground(Color.WHITE);

        // Add Components for Frame1 and show it
        frame1.add(panel1);
        panel1.add(button1);
        frame1.setSize(300, 200);
        frame1.setVisible(true);

        // Add Components for Frame2 and show it
        frame2.add(panel2);
        panel2.add(button2);
        frame2.setSize(300, 200);
        frame2.setLocation(250,150);
        frame2.setVisible(true);

    }

    public static void main(String[] args) {

        try {
            UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
        }
        Test2 t = new Test2();
    }
}

This is the result for both frames:

Frames 1 and 2 - White background

How can I make the button2 to have white background?

Note I have tried this solution (Changing the background color of JButton always shows as grey) and it does not work using Windows 10 and setting the L&F UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );.

M.E.
  • 4,955
  • 4
  • 49
  • 128
  • Hi, I do not think it is a duplicate, my question is specific to Windows 10 in Java Swing using `UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );` while the OP of the referred question does not state his specific L&F. The proposed workaround in that question does not produce any result with this code and in windows 10 (Oracle Java JDK 8). – M.E. May 17 '19 at 20:19
  • From what I understand, you're trying to get a result similar as the one in the linked question? But in white? – Frakcool May 17 '19 at 20:34
  • From what I have read and tested about the linked question, there are two options: a) the loop function and b) removing the L&F set in his code. I have tried the loop function and it does not work in my case -Windows 10 and setting L&F-. And removing the L&F is not an option. I want the Windows L&F hence I am calling UIManager.getSystemLookAndFeelClassName. My question is specific to Windows 10 and its SystemLookAndFeel. If you can make the linked example work in this case -I can not-, a working and runnable example would be welcomed. – M.E. May 17 '19 at 20:38
  • Have you tried this [answer](https://stackoverflow.com/a/7647969/2180785) It may not be related to Windows, but who knows. I can't test on Windows as I don't have any Windows PC so all I can do is provide support this way. – Frakcool May 17 '19 at 20:59
  • Thanks for the suggestion. It does not work either. As you mention it seems Windows L&F does not support changing that. Closest solution is the one provided by Sambit although solution does not address preserving size and outer border color. – M.E. May 17 '19 at 22:50
  • Maybe try [this answer](https://stackoverflow.com/a/56158001/2180785) for the button size – Frakcool May 17 '19 at 23:01
  • That answer works (I am the OP of that question). As mentioned in a comment below, my only remaining doubt would be how to retrieve the outer border color of the button, in the examples are hardcoded. – M.E. May 17 '19 at 23:02
  • You mean how to get the border size as I did with the insets in the other question? – Frakcool May 17 '19 at 23:04
  • No, I mean how to get the border color. Instead of hardcoding `LineBorder(Color.BLACK,1)` how to retrieve the color of the standard non-customized by `.setBorder` method JButton. So the button would be an exact replica. I know I can easily hardcode the color but the idea would be not to do that -for obvious reasons- – M.E. May 17 '19 at 23:06

2 Answers2

2

setContentAreaFilled(false) does the magic here.

As seen on Windows 10.

enter image description here

This code uses an 'in between' panel of cyan (easier to distinguish between the default light gray of the PLAF) to allow setting the button to a different color than the container. If you actually want the button to be the same color as the parent container displaying it, that intermediary panel can be left out.

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

public class Test2 {

    public Test2() {
        // Frame, orange background
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        JPanel panel = new JPanel();
        JButton button = new JButton("Button 2");
        button.setContentAreaFilled(false);
        panel.setBackground(Color.ORANGE);

        // Add Components
        frame.add(panel);
        panel.setBorder(new EmptyBorder(10,100,10,100));
        JPanel buttonColorPanel = new JPanel(new GridLayout());
        // adjust color as needed
        buttonColorPanel.setBackground(Color.CYAN);
        panel.add(buttonColorPanel);
        buttonColorPanel.add(button);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException |
                IllegalAccessException | UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        }
        Test2 t = new Test2();
    }
}

I made some other code changes that are just good practice, but otherwise irrelevant to the end effect. Swing GUIs should also be started on the EDT. BNI.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Thanks for the contribution. The solution creates indeed a flat coloured icon which preserves the original size but it lacks: 1) the original outer border which delimites the button and is highlighted when the mouse is over the button. 2) the visual feedback provided when the user clicks the button. The need and question was to change just the color of the button from grey to white without further modifying button behaviour and properties. I start to think that it might not be possible or too complex and that Java Swing only fits scenarios where a gray button fits. – M.E. May 18 '19 at 08:58
1

Can you try below.

JButton button2 = new JButton("Button 2");
panel2.setBackground(Color.WHITE);
button2.setBackground(Color.WHITE);
button2.setContentAreaFilled(false);
button2.setOpaque(true);
button2.setBorder(new LineBorder(Color.BLACK,1));
button2.setFocusPainted(false);
Sambit
  • 7,625
  • 7
  • 34
  • 65
  • That makes the button to have white background, but removes the border decoration. – M.E. May 17 '19 at 19:57
  • Try to remove this line. button2.setContentAreaFilled(false); – Sambit May 17 '19 at 19:58
  • Try to add, button2.setBorder(new LineBorder(Color.BLACK,1)); – Sambit May 17 '19 at 20:05
  • It creates a white background but does not preserve button size and color of the outer frame. Preserving size can be done through `getBorderInsets` method but I do not know how to preserve the color of the outer button frame. – M.E. May 17 '19 at 20:27
  • Yes, it will not have default size, you have to increase the size. I also seen after running.If you like upvote it. – Sambit May 17 '19 at 20:28
  • Size can be preserved by getting the original size with getBorderInsets and a Compound Border, but I do not know how to preserve the color of the border, in your example code it is being forced to black. I would need to get the actual color from the original button. – M.E. May 17 '19 at 20:29
  • It is better to use css. Check this link for future reference.https://stackoverflow.com/questions/5956934/can-i-use-css-for-java-swing – Sambit May 17 '19 at 20:32
  • Thanks for the suggestion Sambit, question is related to standard Java Swing, using flying-saucer to do this is overkill. – M.E. May 17 '19 at 20:41