为什么我的所有组件都聚集在JFrame的中心

时间:2013-03-20 12:24:00

标签: java swing awt layout-manager gridbaglayout

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

但我拥有的是: enter image description here

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

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 );

3 个答案:

答案 0 :(得分:4)

问题是框架的大小小于内容窗格的总首选大小。从那里,你得到一个闪亮的布局。

还有一些事情:

  • 在您的JFrame上使用pack()代替setSize()以获得合适的帧大小。
  • 避免使用gridx/gridy,它们往往会使约束变得复杂且难以维护
  • anchor/fill几乎应始终与大于0的weightx和/或weighty合并
  • 而不是使用FlowLayout的默认JPanel,使用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);
            }
        });
    }

}

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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);