2

I'm having this weird issue and it doesn't seem to be happening on Mac systems, but on Windows. I'm working on this GUI and am trying to make all of the buttons the same length (the length of the longest button) but for some reason on Windows, one of the buttons will not display the entire string and will truncate it with an ellipsis (...).

Here is the method I am using to check and set the longest button label:

    //Temp button to hold the longest button for resizing
    JButton longestButton = new JButton();

    //Find size of the largest of the 6 buttons
    for(int i = 0; i < 6; i++){
        if (buttons[i].getText().length() > longestButton.getText().length()){
            longestButton = buttons[i];
        }
    }

    //Match size of 6 hex buttons to the size of the longest one
    for(int i = 0; i < 6; i++){
        buttons[i].setPreferredSize(longestButton.getPreferredSize());
    }

Anybody have some insight into this?

Big Al
  • 980
  • 1
  • 8
  • 20
orpheus
  • 479
  • 1
  • 7
  • 20
  • 1
    `buttons[i].getText().length()` won't give the relative lengths of the rendered text unless you are using a monospaced font. You need to take into account the actual font being used – vandale Nov 19 '13 at 22:00
  • I'm not sure how to do that or implement it to change the button sizes. – orpheus Nov 19 '13 at 22:02
  • You could try using defining your own layout manager that lays out each component based on the maximum preferred width ... – MadProgrammer Nov 19 '13 at 23:19
  • @MadProgrammer: `BoxLayout` is one approach. – trashgod Nov 20 '13 at 01:15
  • @trashgod Must admit I'm not particularly familiar with `BoxLayout`, simply wrote my own to solve this issue ;) – MadProgrammer Nov 20 '13 at 01:27

2 Answers2

3

Don't use setPreferredSize() when you really mean to override getPreferredSize(). BoxLayout works well for this: "For a top-to-bottom box layout, the preferred width of the container is that of the maximum preferred width of the children." In the example below, BorderLayout.LINE_END adopts the container's preferred width. Each button overrides getMaximumSize() to effectively remove the upper limit on the button's width. The result works well across platforms.

image

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

/**
 * @see https://stackoverflow.com/a/20085489/230513
 */
public class TestViewer {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new ButtonPanel(), BorderLayout.LINE_END);
                frame.pack();
                frame.setSize(500, 300);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private static class ButtonPanel extends Box {

        public ButtonPanel() {
            super(BoxLayout.Y_AXIS);
            this.add(createButton("Button 1"));
            this.add(createButton("Button 2"));
            this.add(createButton("Long Button 3"));
            this.add(createButton("Button 4"));
            this.add(createButton("Button 5"));
        }

        private JButton createButton(String name) {
            final JButton b = new JButton(name) {

                @Override
                public Dimension getMaximumSize() {
                    return new Dimension(
                        Short.MAX_VALUE, getPreferredSize().height);
                }
            };
            b.setAlignmentX(0.5f);
            return b;
        }
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Can I use this in conjunction with GridBagLayout? I'm actually working on legacy code that's using that layout. – orpheus Nov 20 '13 at 16:13
  • Sorry, I never tried; `GridBagLayout` "uses the components' preferred sizes to determine how big the cells should be," so it's worth a try. – trashgod Nov 20 '13 at 18:23
0

Instead of finding the button with the biggest .getText().length(), you could find the button with the widest preferredSize().

for(int i = 0; i < 6; i++){
    if (buttons[i].getPreferredSize().getWidth() > longestButton.getPreferredSize().getWidth()){
        longestButton = buttons[i];
    }
} 

This fixes the issue vandale mentioned in the comments

hankd
  • 649
  • 3
  • 12