【问题标题】:BorderLayout doesn't show correctlyBorderLayout 无法正确显示
【发布时间】:2013-01-30 02:33:52
【问题描述】:

我想要一个 JFrame,左右两边各有一个边框,颜色为黑色,宽度为 withfOfJFrame/10。

现在,我的尝试是这样的:

JFrame f = new JFrame();
f.setSize(800, 600);
f.setLayout(new BorderLayout());

JPanel leftBorder = new JPanel();
JPanel rightBorder = new JPanel();
leftBorder.setBackground(Color.black);
rightBorder.setBackground(Color.black);
leftBorder.setSize(f.getWidth()/10, f.getHeight());
rightBorder.setSize(f.getWidth()/10, f.getHeight());
JPanel center = new JPanel();
center.setBackground(Color.red);

f.add(leftBorder, BorderLayout.WEST);
f.add(center, BorderLayout.CENTER);
f.add(rightBorder, BorderLayout.EAST);    
f.setVisible(true);

这会在左侧和右侧添加一个黑色边框,但该边框具有固定大小,并且在调整窗口大小时不会重新计算。大小甚至不是 800 的 1/10(JFrame 的开始宽度)。

我做错了什么?还是有更好的方法来做到这一点?

【问题讨论】:

  • setSize() 在程序创建时只调用一次。在程序调整大小时不会在数学上重新调用它。我想知道您是否需要为此编写自己的边框或布局管理器。
  • 问题是它甚至在一开始就没有采用正确的尺寸......
  • 可能是因为您在呈现 GUI 之前调用了 getWidth()getHeight()。我自己,我通常使用getPreferredSize() 更频繁。
  • 你期待什么?调整大小(和定位)是 LayoutManager 的专有任务,因此任何 setSize 对子项的影响都为零。
  • 你可以试试ComponentListener。当调整帧大小时,调用相应的方法并说 panel.revalidate

标签: java swing jpanel border-layout


【解决方案1】:

您可以使用GridBagLayout 和适当的权重来实现所需的结果:

public class Snippet {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

                JPanel leftBorder = new JPanel();
                JPanel rightBorder = new JPanel();
                leftBorder.setBackground(Color.black);
                rightBorder.setBackground(Color.black);

                JPanel center = new JPanel();
                center.setBackground(Color.red);

                f.setLayout(new GridBagLayout());

                GridBagConstraints gbc = new GridBagConstraints();
                gbc.fill = GridBagConstraints.BOTH;
                gbc.weighty = 1.0;
                gbc.gridy = 0;
                gbc.gridwidth = 1;
                gbc.gridheight = 1;

                gbc.gridx = 0;
                gbc.weightx = 0.1;
                f.add(leftBorder, gbc);

                gbc.gridx = 1;
                gbc.weightx = 0.8;
                f.add(center, gbc);

                gbc.gridx = 2;
                gbc.weightx = 0.1;
                f.add(rightBorder, gbc);

                f.pack();
                f.setVisible(true);
            }
        });
    }
}

【讨论】:

    【解决方案2】:

    ComponentListener 非常适合此操作。

    附录:Flank 面板需要明确revalidate() 本身以响应任何大小变化。

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.event.ComponentAdapter;
    import java.awt.event.ComponentEvent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    /** @see http://stackoverflow.com/a/14588506/230513 */
    public class Test {
    
        private static final int W = 320;
        private static final Center center = new Center();
    
        private static class Center extends JPanel {
    
            public Center() {
                setBackground(Color.red);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(W, 3 * W / 4);
            }
        };
    
        private static class Flank extends JPanel {
    
            private Dimension d = new Dimension(W / 10, 0);
    
            public Flank() {
                setBackground(Color.black);
                Test.center.addComponentListener(new ComponentAdapter() {
    
                    @Override
                    public void componentResized(ComponentEvent e) {
                        d = new Dimension(e.getComponent().getWidth() / 10, 0);
                        revalidate();
                    }
                });
            }
    
            @Override
            public Dimension getPreferredSize() {
                return d;
            }
        }
    
        private void display() {
            JFrame f = new JFrame("Test");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            f.add(new Flank(), BorderLayout.WEST);
            f.add(center, BorderLayout.CENTER);
            f.add(new Flank(), BorderLayout.EAST);
    
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new Test().display();
                }
            });
        }
    }
    
    猜你喜欢
    • 1970-01-01
    • 2014-04-23
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多