【问题标题】:GridBagLayout is not displaying as expectedGridBagLayout 未按预期显示
【发布时间】:2013-05-08 14:56:22
【问题描述】:

这是我第一次涉足 GridBagLayout,已经在线查看了 Java 文档(以及许多 SO Q&A),并且我创建了一个面板,我希望这样显示:

+--------------------------+
|      choose a timer      |
+--------+--------+--------+
|  5min  |  25min | 30min  |
+--------+--------+--------+
|         00:00:00         |
+--------+--------+--------+
|  Start |  Pause |  Quit  |
+--------+--------+--------+

这是我正在使用的 GridBagLayout。

public class ButtonSel extends JFrame implements ActionListener {
    JLabel buttonSelLabel = new JLabel("Choose Which Timer To Run");
    JButton pomoButton    = new JButton("00:25:00");
    JButton shrtButton    = new JButton("00:05:00");
    JButton longButton    = new JButton("00:30:00");
    JButton startButton   = new JButton("Go");
    JButton pauseButton   = new JButton("Pause");
    JButton quitButton    = new JButton("Quit");
    JLabel textDisplay    = new JLabel("00:00:00");
     //
    JPanel timerPanel     = new JPanel();
     //

public ButtonSel() {
    super("ButtonTest");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

            add(buttonSelLabel, c);    // line 1
             c.fill = GridBagConstraints.HORIZONTAL;
             c.gridx = 1;
             c.gridy = 1;
             c.gridwidth = 3;

            add(pomoButton, c);        // line 2
             c.gridx = 1;
             c.gridy = 2;
             c.gridwidth = 1;

            add(shrtButton, c);
             c.gridx = 2;
             c.gridy = 2;
             c.gridwidth = 1;

            add(longButton, c);
             c.gridx = 3;
             c.gridy = 2;
             c.gridwidth = 1;

            add(textDisplay, c);       // line 3
             c.fill = GridBagConstraints.HORIZONTAL;
             c.gridx=1;
             c.gridy=3;
             c.gridwidth=3;

            add(startButton, c);       // line 4
             c.gridx = 1;
             c.gridy = 4;
             c.gridwidth = 1;

            add(pauseButton, c);
             c.gridx = 2;
             c.gridy = 4;
             c.gridwidth = 1;

            add(quitButton, c);
             c.gridx = 2;
             c.gridy = 4;
             c.gridwidth = 1;

    pomoButton.addActionListener(this);
    shrtButton.addActionListener(this);
    longButton.addActionListener(this);
    startButton.addActionListener(this);
    pauseButton.addActionListener(this);
    quitButton.addActionListener(this);
}
public void actionPerformed(ActionEvent radioSelect) {
    Object source = radioSelect.getSource();
    if (source == pomoButton)
        textDisplay.setText("00:25:00");
    else
    if (source == shrtButton)
        textDisplay.setText("00:05:00");
    else
    if (source == longButton)
        textDisplay.setText("00:30:00");
    else
    if (source == startButton)
        textDisplay.setText("Started");
    else
    if (source == pauseButton)
        textDisplay.setText("Paused");
    else
    if (source == quitButton)
        textDisplay.setText("Quit");
    else
        textDisplay.setText("00:00:00");
}
}

我得到了这个输出,

并从this question 中获取有关水平对齐的提示,我将HORIZONTAL 约束添加到字段中。现在我得到了:

我使用(0,0)(1,1) 作为我的起始(x,y) 坐标,有趣的是,结果相同。

谁能看到我遗漏的东西?

【问题讨论】:

  • 您的代码不可运行,因此我无法对此进行测试,但您对所有组件都使用了相同的 GridBagConstraints 实例。我看到您为您的第一个组件设置 c.fill = GridBagConstraints.HORIZONTAL。这就是您想要的所有组件吗?在将 GridBagConstraints 添加到组件后,您还需要设置它们。在添加之前设置它们。
  • 啊哈……做到了。我以为你在添加组件参数之前添加组件,但它应该是相反的:定义参数,然后添加组件。还;代码已更新,因此可以运行。
  • 在这一点上,是的,我想要HORIZONAL 用于我的所有组件。一旦我让它工作并看到它的外观,我将决定是否保留它......

标签: java swing layout gridbaglayout


【解决方案1】:

我不得不添加几行代码以使您的代码真正可运行。

您在将 GridBagConstraints 添加到组件后设置它们。您必须在添加之前设置它们。

诀窍是将要居中的 JLabels 的 setHorizo​​ntalAlignment 方法设置为居中对齐。

我格式化了您的代码并添加了一些插图,以使您的 GUI 更具视觉吸引力。

这是 GUI 的图片。

这是代码。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class ButtonSel extends JFrame implements ActionListener {
    JLabel  buttonSelLabel  = new JLabel("Choose Which Timer To Run");
    JButton pomoButton      = new JButton("00:25:00");
    JButton shrtButton      = new JButton("00:05:00");
    JButton longButton      = new JButton("00:30:00");
    JButton startButton     = new JButton("Go");
    JButton pauseButton     = new JButton("Pause");
    JButton quitButton      = new JButton("Quit");
    JLabel  textDisplay     = new JLabel("00:00:00");
    JPanel  timerPanel      = new JPanel();


    public ButtonSel() {
        super("ButtonTest");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        timerPanel = new JPanel();
        timerPanel.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();

        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.CENTER;
        c.weightx = 1.0D;
        c.weighty = 1.0D;
        c.gridx = 1;
        c.gridy = 1;
        c.gridwidth = 3;
        c.gridheight = 1;
        c.insets = new Insets(10, 10, 0, 0);
        c.ipadx = 0;
        c.ipady = 0;
        buttonSelLabel.setHorizontalAlignment(SwingConstants.CENTER);
        timerPanel.add(buttonSelLabel, c); // line 1

        c.gridx = 1;
        c.gridy = 2;
        c.gridwidth = 1;
        timerPanel.add(pomoButton, c); // line 2

        c.gridx = 2;
        c.gridy = 2;
        c.gridwidth = 1;
        timerPanel.add(shrtButton, c);

        c.gridx = 3;
        c.gridy = 2;
        c.gridwidth = 1;
        c.insets = new Insets(10, 10, 0, 10);
        timerPanel.add(longButton, c);

        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 3;
        c.gridwidth = 3;
        c.insets = new Insets(10, 10, 0, 0);
        textDisplay.setHorizontalAlignment(SwingConstants.CENTER);
        timerPanel.add(textDisplay, c); // line 3

        c.gridx = 1;
        c.gridy = 4;
        c.gridwidth = 1;
        c.insets = new Insets(10, 10, 10, 0);
        timerPanel.add(startButton, c); // line 4

        c.gridx = 2;
        c.gridy = 4;
        c.gridwidth = 1;
        timerPanel.add(pauseButton, c);

        c.gridx = 3;
        c.gridy = 4;
        c.gridwidth = 1;
        c.insets = new Insets(10, 10, 10, 10);
        timerPanel.add(quitButton, c);

        pomoButton.addActionListener(this);
        shrtButton.addActionListener(this);
        longButton.addActionListener(this);
        startButton.addActionListener(this);
        pauseButton.addActionListener(this);
        quitButton.addActionListener(this);

        this.add(timerPanel);
        this.pack();
        this.setVisible(true);
    }

    public void actionPerformed(ActionEvent radioSelect) {
        Object source = radioSelect.getSource();
        if (source == pomoButton)
            textDisplay.setText("00:25:00");
        else if (source == shrtButton)
            textDisplay.setText("00:05:00");
        else if (source == longButton)
            textDisplay.setText("00:30:00");
        else if (source == startButton)
            textDisplay.setText("Started");
        else if (source == pauseButton)
            textDisplay.setText("Paused");
        else if (source == quitButton)
            textDisplay.setText("Quit");
        else
            textDisplay.setText("00:00:00");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ButtonSel();            
            }
        });
    }

}

【讨论】:

  • 太棒了。正是我想要的。两个快速跟进问题。为显示第 1 行设置的参数是否贯穿所有四行,仅在更新时更改?例如c.weightx = 1.0D; 会自动执行面板的其余部分吗?还是添加对象会将所有内容重置为默认值?可能相关; Constraints.CENTER;(SwingConstants.CENTER); 有什么区别,为什么都需要?
  • 1) 是的,为 GridBagConstraints 的唯一实例设置的 GridBagConstraints 参数执行。这是因为您只有一个实例。有人告诉我,每个组件都需要一个新的 GridBagConstraints。我不相信这在 1.6 和 1.7 中是正确的。 2) setHorizo​​ntalAlignment 的Javadoc 使用了SwingConstants,所以这就是我使用的。 :-) 3) setHorizo​​ntalAlignment 方法将 JLabel 设置在定义区域的中心。 GridBagConstraints.CENTER 将所有文本、按钮和标签设置在中心(这是 JButtons 的默认设置)。
  • (续)您可能会删除 c.anchor 分配。我尝试了不同的东西,直到 GUI 看起来像我想要的那样。
  • 这很有意义。谢谢!
【解决方案2】:

我认为一种解决方案是BoxLayout()。您可以将您的面板分成 4 个独立的面板。

1st - 选择时间 - 作为一个面板 第 2 - 5, 25,30 分钟 3日 - 00:00:00 4th - 开始暂停退出

然后准备添加 4 个面板并使用 BoxLayout() 的主面板/此面板的布局很重要: 例如

JPanel p = new JPanel();
p.add(panel1);
p.add(panel2);
p.add(panel3);
p.add(panel4);
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); 

BoxLayout.Y_AXIS - 面板将从上到下布局

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-18
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多