为什么我的 JButton 大小没有使用 setSize() 或 setPreferredSize() 更改?

Why is my JButton size not changing with either setSize() or setPreferredSize()?

提问人:TimMcYeah 提问时间:11/17/2023 更新时间:11/17/2023 访问量:63

问:

我正在为一个学校项目制作一个基本的计算器,我需要满足的要求之一是在 JPanel 中更改 JButton 的大小。我试过这样做,但它没有改变。

我尝试同时使用并更改它,但这些方法都不起作用。我还尝试在不将其添加到 JPanels(在代码中解释)的情况下设置其大小,而只是将其添加到框架中,但这也不起作用。setSize()setPreferredSize()

对于在线帮助,我在 Stack Overflow 上查看了这个问题,我(在某种程度上)复制了它的代码,但它不起作用。

有人可以告诉我我做错了什么吗?

法典

进口

import java.awt.GridLayout ;
import java.awt.Dimension ;
import java.awt.event.ActionEvent ;
import java.awt.event.ActionListener ;
import javax.swing.JFrame ;
import javax.swing.JPanel ;
import javax.swing.JButton ;
import javax.swing.BoxLayout ;

public class Main {
    public JFrame frame = new JFrame("Calculator") ;
    public JButton one = new JButton("1") ;
    public JPanel mainPanel = new JPanel() ;
    public JPanel buttonsPanel = new JPanel() ;
    public static void main(String[] args) {
        Main main = new Main() ;

        main.one.setPreferredSize(new Dimension(500, 500)) ;

        main.one.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Take that fat L") ;
            }
        }) ;


        main.buttonsPanel.setLayout(new GridLayout(5, 3)) ;
        main.buttonsPanel.setMaximumSize(new Dimension(2500, 1500)) ;
        main.buttonsPanel.add(main.one) ;
        main.mainPanel.setLayout(new BoxLayout(main.mainPanel, BoxLayout.Y_AXIS)) ;
        main.mainPanel.add(main.buttonsPanel) ;

        main.frame.setContentPane(main.mainPanel) ;
        main.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;
        main.frame.setSize(500, 700) ;
        main.frame.setLocationRelativeTo(null) ;
        main.frame.setVisible(true) ;
    }
}
java swing jbutton 网格布局 boxlayout

评论

2赞 Progman 11/17/2023
布局管理器已经自动缩放您放置在 .您不需要使用 .GridLayoutbuttonsPanelsetPreferredSize()
1赞 MadProgrammer 11/17/2023
通常,应避免调用并依赖布局属性和边框setPreferred/Minimum/MaximumSize
2赞 MadProgrammer 11/17/2023
我会先摆脱它并用main.frame.setSize(500, 700) ;main.frame.pack()
0赞 MadProgrammer 11/17/2023
只是为了让我明确我的观点 - 避免这样的事情的原因是它覆盖了组件自己的内部功能,所以如果你的用户在那里启动了字体设置(就像我经常做的那样),你的布局会因此而受到影响(即 - 它将无法补偿)setPreferredSize
0赞 queeg 11/17/2023
@MadProgrammer 告诉他该做什么而不是不该做什么有意义吗?边距、填充或边框是否更合适?初学者需要多少信息才能获得第一个 UI?

答:

1赞 MadProgrammer 11/17/2023 #1

和(在窗口上)的组合对你不利。setPreferredSizesetMinimumSizesetSize

我摆脱并取而代之,这似乎已经解决了眼前的问题。buttonsPanel.setMaximumSize(new Dimension(2500, 1500));frame.setSize(500, 700)frame.pack()

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {
        public JButton one = new JButton("1");
        public JPanel buttonsPanel = new JPanel();

        public TestPane() {
            one.setPreferredSize(new Dimension(500, 500));

            one.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Take that fat L");
                }
            });

            buttonsPanel.setLayout(new GridLayout(5, 3));
            //buttonsPanel.setMaximumSize(new Dimension(2500, 1500));
            buttonsPanel.add(one);
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            add(buttonsPanel);
        }
    }
}

但是,这给您留下了另一个问题。 重写按钮使用的内部逻辑,以根据其内部属性计算其首选大小。setPreferredSize

这似乎不是一个大问题,但是当您的用户具有不寻常的字体设置时,它很快就会回来困扰您。

Swing 有一个很好的布局管理系统,您应该花一些时间尝试弄清楚如何使用它。

例如,如果我们从类似的东西开始......

public class TestPane extends JPanel {
    public TestPane() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.ipadx = 50;
        gbc.ipady = 50;
        int count = 0;
        for (int row = 0; row < 3; row++) {
            for (int col = 0; col < 3; col++) {
                JButton btn = new JButton(Integer.toString(++count));
                gbc.gridy = row;
                gbc.gridx = col;
                add(btn, gbc);
            }
        }
    }
}

现在,这是利用 ,不是最简单的布局,而是最灵活的布局之一。选择它的原因是它允许对组件应用“内部”填充,在本例中,增加宽度和高度。GridBagLayout50

这将产生类似...

enter image description here

好吧,你说大不了。但是考虑一下当字体大小发生变化时会发生什么(在此示例中,我手动修改了字体大小,但它也可能来自系统设置/首选项)

public class TestPane extends JPanel {
    public TestPane() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.ipadx = 50;
        gbc.ipady = 50;
        int count = 0;
        Font font = new JButton().getFont();
        font = font.deriveFont(font.getSize2D() * 12);
        for (int row = 0; row < 3; row++) {
            for (int col = 0; col < 3; col++) {
                JButton btn = new JButton(Integer.toString(++count));
                btn.setFont(font);
                gbc.gridy = row;
                gbc.gridx = col;

                add(btn, gbc);
            }
        }
    }
}

它输出类似...

enter image description here

而且,无需对原始代码进行任何修改(除了添加字体大小),代码就可以正常工作。

这就是为什么我们通常不鼓励使用setPreferred/Minimum/MaximumSize

现在,如果你“真的”想要方形按钮,我建议你看看在 Swing 中创建方形按钮。你也可以尝试这样的事情,但老实说,我更喜欢第一种方法。

评论

0赞 queeg 11/17/2023
感谢您分享一个很好的例子和解释。