【问题标题】:Why are all my components clustered at the center of the JFrame为什么我的所有组件都聚集在 JFrame 的中心
【发布时间】:2023-03-13 21:35:01
【问题描述】:

我正在使用网格包布局来创建如下所示的布局:

但我所拥有的是:

为什么会这样?我已经指定了左对齐并占据了所有水平空间,但我仍然得到了这个。这是我的代码:

public DepotView()
{
    setSize(FRAME_WIDTH,FRAME_HEIGHT);
    setLocationRelativeTo ( null );

    getContentPane ().setLayout ( new GridBagLayout());

    JPanel workerPanel = createTextAreaPanel("Processing: ",workerArea);
    GridBagConstraints c = new GridBagConstraints();
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 2;
    c.gridheight = 1;
    c.weightx = 1;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.anchor = GridBagConstraints.FIRST_LINE_START;
    getContentPane().add ( workerPanel );


    JPanel customerPanel = createTextAreaPanel("Customers: ",textArea);
    c = new GridBagConstraints();
    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.5;
    c.insets = new Insets(5,5,5,5);
    getContentPane().add ( customerPanel );

    JPanel depotPanel = createTextAreaPanel("Depot: ",depotArea);
    c = new GridBagConstraints();
    c.gridx = 1;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.5;
    c.insets = new Insets(5,5,5,5);
    getContentPane().add ( depotPanel );


    //pack();
    setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );

【问题讨论】:

    标签: java swing awt layout-manager gridbaglayout


    【解决方案1】:

    问题在于框架的大小小于内容窗格的总首选大小。从那里,你会得到一个旋转的布局。

    还有一些事情:

    • 在您的 JFrame 上使用 pack() 而不是 setSize() 以获得适当的帧大小。
    • 避免使用gridx/gridy,它们会使约束变得复杂且难以维护
    • anchor/fill 应该几乎总是与大于 0 的 weightx 和/或 weighty 结合使用
    • 不要使用默认的 FlowLayoutJPanel,而是使用 LayoutManager,这将利用额外的可用空间(例如 BorderLayout
    • 不要使用static 变量,它只是邪恶的
    • 您的 textarea 变量始终为空。

    这是一段看起来运行良好的代码:

    import java.awt.BorderLayout;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.SwingUtilities;
    
    public class DepotView extends JFrame {
    
        private JTextArea textArea;
        private JTextArea depotArea;
        private JTextArea workerArea;
    
        public DepotView() {
    
            getContentPane().setLayout(new GridBagLayout());
    
            JPanel workerPanel = createTextAreaPanel("Processing: ", workerArea = new JTextArea());
            GridBagConstraints c = new GridBagConstraints();
            c.gridwidth = GridBagConstraints.REMAINDER;
            c.weightx = 1.0;
            c.weighty = 1.0;
            c.fill = GridBagConstraints.BOTH;
            c.anchor = GridBagConstraints.FIRST_LINE_START;
            getContentPane().add(workerPanel, c);
    
            JPanel customerPanel = createTextAreaPanel("Customers: ", textArea = new JTextArea());
            c = new GridBagConstraints();
            c.insets = new Insets(5, 5, 5, 5);
            c.fill = GridBagConstraints.BOTH;
            c.weightx = 1.0;
            c.weighty = 1.0;
            c.anchor = GridBagConstraints.FIRST_LINE_START;
            getContentPane().add(customerPanel, c);
    
            JPanel depotPanel = createTextAreaPanel("Depot: ", depotArea = new JTextArea());
            c = new GridBagConstraints();
            c.weightx = 1.0;
            c.weighty = 1.0;
            c.gridwidth = GridBagConstraints.REMAINDER;
            c.insets = new Insets(5, 5, 5, 5);
            c.fill = GridBagConstraints.BOTH;
            getContentPane().add(depotPanel, c);
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            pack();
            setLocationRelativeTo(null);
        }
    
        private JPanel createTextAreaPanel(String label, JTextArea textArea) {
            JPanel customerQueuePanel = new JPanel(new BorderLayout());
    
            customerQueuePanel.add(new JLabel(label), BorderLayout.NORTH);
            textArea.setRows(15);
            textArea.setColumns(20);
            textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 14));
            textArea.setEditable(false);
    
            JScrollPane scrollPane = new JScrollPane(textArea);
            customerQueuePanel.add(scrollPane);
            return customerQueuePanel;
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new DepotView().setVisible(true);
                }
            });
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      您似乎只是在将面板添加到框架时忘记包含GridBadConstriants。只需将 getContentPane().add(panel); 更改为 getContentPane().add(panel, c); 即可。

      【讨论】:

      • 抱歉,我在发布此问题时正在更改代码 - 我确实将 GridBagConstraints 传递给了 add 方法。
      【解决方案3】:

      JPanel 的布局未正确定义。您当前正在使用JPanel 的默认布局FlowLayout,在您的情况下这是一个糟糕的选择。

      • 它不会调整组件的大小以匹配容器的大小(JPanel)。
      • 根据JPanel 的大小,它会将文本放在标签旁边。

      最好的选择可能是使用BorderLayout

      同时设置JPanel 的最小尺寸:

      JPanel customerQueuePanel = new JPanel(new BorderLayout());
      customerQueuePanel.setMinimumSize(new Dimension(250, 150));
      ...
      customerQueuePanel.add ( new JLabel(label), BorderLayout.NORTH);
      customerQueuePanel.add( scrollPane, BorderLayout.CENTER); 
      

      编辑:上面的代码是对您从问题中删除的 createTextArea 方法的编辑。

      也像之前一样添加约束作为参数。

      getContentPane().add(panel, c);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-29
        • 1970-01-01
        • 2018-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多