Muhammad Umer
Muhammad Umer

Reputation: 69

Adding border to button makes it smaller

When I add border to my button, the button shrinks in size. I am using the following line to add the border:

jButton.setBorder(BorderFactory.createLineBorder(Color.RED));

This is my button without border:

Button without border

This is my button with border:

enter image description here

Upvotes: 0

Views: 726

Answers (3)

MadProgrammer
MadProgrammer

Reputation: 347194

A quick a dirty example of why setPreferredSize is a terrible idea and why you should avoid it as much as possible.

You can also have a look at Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for more of discussion on the subject

NormalExaggerated

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JButton goodButton = new JButton("Location 1");
            Insets insets = goodButton.getInsets();
            goodButton.setBorder(new CompoundBorder(
                            new LineBorder(Color.RED),
                            new EmptyBorder(insets)));
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(8, 8, 8, 8);
            add(goodButton, gbc);

            JButton badButton = new JButton("Location 2");
            badButton.setPreferredSize(new Dimension(110, 29));
            badButton.setBorder(new LineBorder(Color.RED));
            add(badButton, gbc);

            ActionListener listener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    goodButton.setText(random());
                    badButton.setText(random());

                    float size = rnd.nextInt(48) + 12;

                    Font f = goodButton.getFont().deriveFont(size);
                    goodButton.setFont(f);
                    badButton.setFont(f);
                }
            };

            goodButton.addActionListener(listener);
            badButton.addActionListener(listener);
        }

        private Random rnd = new Random();

        protected String random() {
            int length = rnd.nextInt(15) + 5;
            StringBuilder sb = new StringBuilder(length);
            for (int index = 0; index < length; index++) {
                sb.append((char)('A' + rnd.nextInt(26)));
            }
            return sb.toString();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 600);
        }

    }


}

This is some what of an exaggerated example, but I was, unfortunate enough, to inherit a project where the previous developer use setPreferredSize and while it worked "ok" on same PCs running the same OS, we had countless, seemingly random issues and many more and don't even get me started on what it did on MacOS.

But I'm only developing for Windows

Big deal, as I said, we had the app working "ok" on some Windows PCs, but as soon as some one had custom DPIs or font metrics or they upgraded to new version of Windows, it began to fall apart - Short answer - don't use setPreferredSize

Upvotes: 1

FredK
FredK

Reputation: 4084

If you want to add a border, and also want a margin between the label text and the edge of the border, create a compound border, with an empty border on the inside (with the proper size fot the margin) and do n ot set the preferred size. This will allow the button to size itself properly regardless of the text and font of the label. For example:

LineBorder border1 = new LineBorder(Color.red);
EmptyBorder border2 = new EmptyBorder(1,5,1,5);
Border newBorder = BorderFactory.createCompoundBorder(border1, border2);

Upvotes: 2

Partho KR
Partho KR

Reputation: 132

Define width and height as per your need and implement the following line of code:

jButton.setPreferredSize(new Dimension(width, height));

Upvotes: -1

Related Questions