Search code examples
javaswingborderjbutton

Change Border Color of a JButton in Java Swing preserving the insets


I want to change the border color of a JButton component in Java Swing.

I have tried the following:

package com.example.test;

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 Test extends JFrame {

    public Test() {

        JPanel panel = new JPanel();
        JButton button1 = new JButton("Test Button 1");
        JButton button2 = new JButton("Test Button 2");
        button2.setBorder(BorderFactory.createLineBorder(Color.RED));

        panel.add(button1);
        panel.add(button2);

        this.add(panel);


        setSize(400, 400);
        setVisible(true);

    }

    public static void main(String[] args) {

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

This generates two buttons, on button2 component I try to change border color but it removes the padding. Is there anyway to preserve the original insets of a standard JButton and just change the color?

Note: I assume that the insets are being removed when assigning the new Border. But I am not 100% sure about it.

JButton Change Border Color


Solution

  • Instead of creating a LineBorder, use a CompoundBorder:

    button2.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(Color.RED, 1), 
                BorderFactory.createEmptyBorder(
                    button1.getBorder().getBorderInsets(button1).top, 
                    button1.getBorder().getBorderInsets(button1).left, 
                    button1.getBorder().getBorderInsets(button1).bottom, 
                    button1.getBorder().getBorderInsets(button1).right)));
    

    I took the BorderInsets for the button1 so that both of them have the same size.

    My answer is based on @MadProgrammer answer for this question

    enter image description here


    Btw don't extend JFrame, create an instance of it instead and if you really need to extend a component, be it a JPanel: Extends JFrame vs. creating it inside the program

    Also don't forget to call

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    

    On your JFrame instance, so that your program terminates when you close it.

    And also you missed to place your program on the EDT, see more of this on this answer