BoxLayout 为自定义组件提供了意外的宽度

BoxLayout giving unexpected width for custom component

我有一个非常简单的自定义组件。它的首选尺寸和最大尺寸为 100x100,只是一个红色矩形。我将其添加到使用框布局的 JPanel 中。我希望自定义组件的大小为 100x100,但实际上是 50x100(始终是最大宽度的一半)。

代码如下:

public class Testing extends JFrame {

    class TestComponent extends JComponent {

        @Override
        public Dimension getMaximumSize() {
            return new Dimension(100, 100);
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setPaint(Color.RED);
            g2d.fillRect(getX(), getY(), getWidth(), getHeight());
            System.out.println(getWidth());
        }

    }

    private JPanel panel;
    private TestComponent testComponent;

    public Testing() {
        super("Testing");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setSize(1280, 720);
        setLocationRelativeTo(null);

        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        panel.setBackground(Color.CYAN);
        testComponent = new TestComponent();
        panel.add(testComponent);
        add(panel);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(()->{
            new Testing().setVisible(true);
        });
    }

}

如果我添加一个设置了首选和最大尺寸的 JPanel 而不是我的自定义组件,则不会发生这种情况。

        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        panel.setBackground(Color.CYAN);
        // testComponent = new TestComponent();
        // panel.add(testComponent);
        JPanel test = new JPanel();
        test.setPreferredSize(new Dimension(100,100));
        test.setMaximumSize(new Dimension(100,100));
        test.setBackground(Color.RED);
        panel.add(test);
        add(panel);

我不确定我错过了什么。谢谢!

重写方法 getAnyKindOfSize() 通常不是一个好的做法。尝试将组件添加到使用 FlowLayout 的嵌套 JPanel 中,然后将此 JPanel 添加到 BoxLayout-ed 面板。像这样:

testComponent = new TestComponent();
testComponent.setPreferredSize(new Dimension(100, 100));

JPanel flowPanel = new JPanel(new FlowLayout());
flowPanel.add(testComponent);
panel.add(flowPanel);

和:

class TestComponent extends JComponent {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setPaint(Color.RED);
        g2d.fillRect(0, 0, getWidth(), getHeight()); //Notice x, y
    }

}

I have a custom component that is extremely simple.

自定义组件负责确定其:

  1. 最小尺寸
  2. 首选尺码
  3. 最大尺寸

您只实施首选尺寸和最大尺寸。

But it still doesn't make sense why the component isn't centered and is half the maximum width.

BoxLayout 尝试遵守组件的最小和最大尺寸。

默认的最小尺寸是 (0, 0),这似乎导致了 BoxLayout 的混乱。我不确定为什么。我会说它是 BoxLayout 的 bug/feature。

您需要实现 getMinimumSize() 方法。这似乎有效:

@Override
public Dimension getMinimumSize() {
    return new Dimension(2, 2);
}

请注意,我尝试了 (1, 1),但没有用。再次,不知道为什么。

我建议您可以使用:

@Override
public Dimension getMinimumSize() {
    return getPreferredSize();
}

对于最小值和最大值方法,您似乎希望大小保持不变。