无法在Swing中正确调整JPanel大小

4

我正在学习Swing,并为自己练习构建了一个示例GUI。非常基础,它在JFrame的西、中、东三个面板上有三个面板。在最后一个面板中,有另一个面板和一个按钮。该面板是我的扩展JPanel,名为DrawPanel。每次单击其下方的Repaint按钮时,它会绘制一个随机的Rectangle。这是我的代码:

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

public class Tester
{
    public static DrawPanel panelEastDrawPanelCenter;

    public static void main()
    {
        Tester gui = new Tester();
        gui.go();
    }
    public void go()
    {
        JFrame frame = new JFrame("This is the title");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create all the Western Panel components
        JPanel panelWest = new JPanel();
        //    panelWest.setLayout(new BorderLayout());
        JButton panelWestButtonWest = new JButton("Western-most West Button");
        JButton panelWestButtonCenter = new JButton("Western-most Center Button");
        JButton panelWestButtonEast = new JButton("Western-most East Button");

        // Create all Center Panel components
        JPanel panelCenter = new JPanel();
            panelCenter.setBackground(Color.darkGray);
        JButton panelCenterButtonCenter = new JButton("Center Button");

        // Create all East Panel components
        JPanel panelEast = new JPanel();
        panelEastDrawPanelCenter = new DrawPanel();
            panelEastDrawPanelCenter.setSize(50,50);
        JButton panelEastButtonSouth = new JButton("Repaint");
            panelEastButtonSouth.addActionListener(new panelEastButtonSouthListener());

        // Add everything to the GUI
        // West Panel
        frame.getContentPane().add(BorderLayout.WEST, panelWest);
        panelWest.add(BorderLayout.WEST, panelWestButtonWest);
        panelWest.add(BorderLayout.CENTER, panelWestButtonCenter);     
        panelWest.add(BorderLayout.EAST, panelWestButtonEast);

        // Center Panel
        frame.getContentPane().add(BorderLayout.CENTER, panelCenter);
        panelCenter.add(BorderLayout.CENTER, panelCenterButtonCenter);

        // East Panel
        frame.getContentPane().add(BorderLayout.EAST, panelEast);
        panelEast.add(panelEastDrawPanelCenter);
        panelEast.add(panelEastButtonSouth);

        frame.pack();
        //frame.setSize(frame.getWidth(), 500);
        frame.setVisible(true);
    }
    class panelEastButtonSouthListener implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            panelEastDrawPanelCenter.repaint();
        }
    }
    class DrawPanel extends JPanel // JPanel that displays a rectangle upon clicking the button "Repaint"
    {
        public void paintComponent(Graphics g)
        {
            g.setColor(Color.WHITE); // Removes previous rectangle
            g.fillRect(0,0, this.getWidth(),this.getHeight());

            g.setColor(randColor()); // Puts a new rectangle on screen, rand size and color
            int height = (int)(Math.random() * this.getHeight());
            int width = (int)(Math.random() * this.getHeight());
            int x = (int)(Math.random() * 20);
            int y = (int)(Math.random() * 20);
            g.fillRect(x,y, height,width);
        }
        public Color randColor()
        {
            int r = (int)(Math.random() * 255);
            int g = (int)(Math.random() * 255);
            int b = (int)(Math.random() * 255);
            return new Color(r, g, b);
        }
    }
}

我遇到的问题是虽然我明确地为DrawPanel对象(panelEastDrawPanelCenter)设置了50×50的大小,但当我运行程序时,它(DrawPanel)仍然是一个小面板,紧挨着按钮,而panelEast(包含DrawPanel和按钮的容器)仍然是相同的宽度(永远不会变宽)。我意识到我可以这样说
frame.pack();
frame.setSize(frame.getWidth(), 500);

如果我将东侧面板设置为使用 BorderLayoutBoxLayout 布局,这将使 DrawPanel 显示更大。

  1. 但我不明白为什么设置 DrawPanel 对象的大小实际上并没有改变其大小,而且无论我执行 setSize(50,50);,它都保持很小。
  2. 我该如何让中间面板停止调整大小,以便东侧面板可以调整为更宽?或者如何调整东侧面板的大小?
3个回答

8

边界布局(BorderLayout)会尊重其西部和东部组件的首选宽度。并且它会尊重其中心组件的首选宽度和高度。因此,您的DrawPanel应该覆盖getPreferredSize()方法,并返回适当的首选大小。

由于DrawPanel位于具有南部组件的BorderLayout的中心位置,因此东侧面板的首选宽度将是绘图面板和按钮首选宽度中的最大值。


1
我觉得这个方法可以工作,但不是最合适的方法。为什么不直接调用 setPreferredSize(Dimension d) 而不是重写 getPreferredSize() 呢?:-. - Zéychin
@Zéychin 我在 API 中找不到那个方法(我在 Component 下查找了),当我尝试在我的代码中使用它时,它显示“no suitable method found for setPreferredSize(int,int)”。 - Alex G
3
因为一个组件应该知道它的首选大小(根据它所包含的其他组件、它的布局、字体、外观等),而不是被外部强制设置一个首选大小。每次使用JButton或JLabel时,您都不会设置它们的首选大小,对吧?这是因为JButton或JLabel会返回适当的值。 - JB Nizet
1
@Zéychin 也许你会接受...,也许不会。 - mKorbel
刚才我找到了setPreferredSize(Dimension d),忽略我之前的评论... - Alex G

2

你尝试过使用panel.setPerferredSize(Dimension size);吗?


2

建议使用setPreferredSize(Dimension)方法代替setSize(int, int)方法,并在此之后调用pack()方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接