5

I am trying to increase/decrease the font size of JButton text automatically (if JButton increases/stretches its text will also increase, if JButton decreases its text will also decrease). The default font of the JButtons will be Sans-Serif size 20 and it can never decrease below 20 (it can be 21, 30, 40 or anything above or equal to 20 but never anything below 20). I have a JPanel, called MenuJPanel, it uses the GridLayout to add 5 JButtons which will increase/decrease in size as the JPanel increases/deceases. I chose the GridLayout as it seems to be the best layout for this purpose, am I wrong? I also added a componentResized to the MenuJPanel. Below you can see my code which partially works.

enter image description here

public class MenuJPanel extends JPanel {

    private JButton resizeBtn1;
    private JButton resizeBtn2;
    private JButton resizeBtn3;
    private JButton resizeBtn4;
    private JButton resizeBtn5;

    public MenuJPanel() {
        initComponents();
      this.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {

                Font btnFont = resizeBtn1.getFont();
                String btnText = resizeBtn1.getText();

                int stringWidth = resizeBtn1.getFontMetrics(btnFont).stringWidth(btnText);
                int componentWidth = resizeBtn1.getWidth();

                // Find out how much the font can grow in width.
                double widthRatio = (double) componentWidth / (double) stringWidth;

                int newFontSize = (int) (btnFont.getSize() * widthRatio);
                int componentHeight = resizeBtn1.getHeight();

                // Pick a new font size so it will not be larger than the height of label.
                int fontSizeToUse = Math.min(newFontSize, componentHeight);

                // Set the label's font size to the newly determined size.
                resizeBtn1.setFont(new Font(btnFont.getName(), Font.BOLD, fontSizeToUse));
            }
        });
    }

    private void initComponents() {

        resizeBtn1 = new javax.swing.JButton();
        resizeBtn2 = new javax.swing.JButton();
        resizeBtn3 = new javax.swing.JButton();
        resizeBtn4 = new javax.swing.JButton();
        resizeBtn5 = new javax.swing.JButton();

        setLayout(new java.awt.GridLayout(5, 0));

        resizeBtn1.setText("Text to resize 1");
        add(resizeBtn1);

        resizeBtn2.setText("Text to resize 2");
        add(resizeBtn2);

        resizeBtn3.setText("Text to resize 3");
        add(resizeBtn3);

        resizeBtn4.setText("Text to resize 4");
        add(resizeBtn4);

        resizeBtn5.setText("Text to resize 5");
        add(resizeBtn5);
    }
}
jadrijan
  • 1,438
  • 4
  • 31
  • 48
  • 3
    your issue is that you didn't posted an SSCCE, whats btnOperatorLogout, where in main class, sorry lazyness beat me too, btw this simple issue were solved many times on this forum, I can to see a few code for DeriveFont & JLabel – mKorbel Dec 05 '12 at 15:23
  • thanks, I just fixed the example code – jadrijan Dec 05 '12 at 15:32
  • 1
    do you able to compute inner area (see line about JButton if is selected) meaning get Insets from JButton and minus 1pixel for Borders (see line about JButton if is selected), then result is available dimension for SwingUtilities#computeStringWidht :-) – mKorbel Dec 05 '12 at 15:36

1 Answers1

5

Ordinarily, the ButtonUI delegate for a JButton calculates the button's preferred size based on the designer's chosen font and the platform's aesthetics. As your approach defeats this, it's up to you to decide how the text will scale with the button and accommodate button decorations.

Absent creating your own ButtonUI, you can simply scale the text. In this example, TextLayout is used to render the text in a BufferedImage at an arbitrarily large size that can be scaled down as needed. In this example, a single digit's glyph is rendered in a BufferedImage and scaled to fit the button's current size. If you need to deal with the relative positioning of an Icon, see SwingUtilities.layoutCompoundLabel(), examined here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thank you very much for this answer. I have one more question, what if the Text of my JButton uses HTML for example: "Line1
    Line2", will the above examples still work?
    – jadrijan Dec 05 '12 at 19:44
  • Thank you I will try it and let you know – jadrijan Dec 05 '12 at 20:00
  • I'm not sure; `layoutCompoundLabel()` may handle that. It might be easier to render the `JLabel`, as shown [here](http://stackoverflow.com/a/7028497/230513) for `JPanel` [edited]. – trashgod Dec 05 '12 at 20:06