为什么GridBagLayout锚不能用于多个按钮?

时间:2012-07-13 22:51:51

标签: java swing anchor gridbaglayout

我正在尝试将两个按钮叠放在一起,并将它们固定在面板的顶部,但第二个按钮仍然位于面板的中央。

在此代码中,我创建了一个拆分窗格,然后向其添加两个面板。一个面板包含按钮(我感兴趣的面板),另一个面板包含文本字段。按钮使一些文本出现在文本字段中。

我想弄清楚GridBagLayout参数的哪个正确组合将允许我将两个按钮放在彼此之上(两者之间没有间隙)并将它们锚定到面板的顶部。我用加权和网格参数尝试了一些不同的东西,但无济于事。

提前感谢您的时间和回复。

package gridbagtest;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class GridBagTest
{
    public static void main(String[] args)
    {
        JFrame gridTest = new JFrame("Grid Bag Layout Test");

        JSplitPane splitPaneHorizontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);

        final JTextField blah = new JTextField(30);
        JPanel textPane = new JPanel();
        textPane.add(blah);

        JPanel buttonPane = new JPanel();
        buttonPane.setBackground(Color.WHITE);
        buttonPane.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.FIRST_LINE_START;
        c.gridx = 0;
//      c.gridy = GridBagConstraints.RELATIVE;
        c.gridy = 0;
        c.weightx = 1;
        c.weighty = 1;

        JButton flightPlanButton = new JButton("First Button");

        flightPlanButton.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {   blah.setText("First Button pushed");    }
         });

        buttonPane.add(flightPlanButton, c);

        JButton powerButton = new JButton("Second Button");
        powerButton.addActionListener(new ActionListener()                            
        {
            public void actionPerformed(ActionEvent e) 
            {   blah.setText("Second Button pushed");   }
        });

        c.gridy = 1;
        buttonPane.add(powerButton, c);

        splitPaneHorizontal.setTopComponent(new JScrollPane(buttonPane));
        splitPaneHorizontal.setBottomComponent(textPane);   

        gridTest.add(splitPaneHorizontal);
        gridTest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gridTest.pack();
        gridTest.setSize(600,800);
        gridTest.setVisible(true);

    }
}

2 个答案:

答案 0 :(得分:2)

我认为一个问题是你没有在按钮下面添加任何东西来填补空白区域。有很多方法可以解决这个问题。一个是完全避免GridBagLayout,将JButton放在使用BoxLayout的JPanel中,并将该JPanel放入另一个在BorderLayout.PAGE_START(或NORTH)位置使用BorderLayout的JPanel。另一个,我将展示你将按钮的重量设置为0,然后添加另一个组件,如空的JLabel或在这里我使用盒子类的胶水,给它一个体面的重量,一个体面的高度,说剩余,看看会发生什么:

  JPanel buttonPane = new JPanel();
  buttonPane.setBackground(Color.WHITE);
  buttonPane.setLayout(new GridBagLayout());
  GridBagConstraints c = new GridBagConstraints();
  c.fill = GridBagConstraints.HORIZONTAL;
  c.anchor = GridBagConstraints.FIRST_LINE_START;
  c.gridx = 0;
  c.gridy = 0;
  c.weightx = 1;
  c.weighty = 0;

  JButton flightPlanButton = new JButton("First Button");

  flightPlanButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
        blah.setText("First Button pushed");
     }
  });

  buttonPane.add(flightPlanButton, c);

  JButton powerButton = new JButton("Second Button");

  c.gridy = 1;
  buttonPane.add(powerButton, c);

  c.gridy = 2;
  c.fill = GridBagConstraints.BOTH;
  c.anchor = GridBagConstraints.LINE_END;
  c.weighty = 100.0;
  c.gridheight = GridBagConstraints.REMAINDER;
  buttonPane.add(Box.createGlue(), c);

另外,我相信Devon_C_Miller所说的,如果你要更改字段,你需要创建一个新的GridBagConstraint,这是不对的,事实上Oracle在它自己的GridBagLayout API中无视这一点。

Devon_C_Miller还有一点:确定,我检查了GridBagLayout源代码,发现该类将此信息存储在名为 comptable HashTable<Component, GridBagConstraints>变量中,并且{* 1}}方法将信息放在此表中,GridBagConstraints对象在添加到表之前先进行克隆,完全证明不需要创建新的GridBagConstraints对象(尽管通常这样做是很好的编程习惯,但出于其他原因)。

答案 1 :(得分:0)

如果添加新的GridBagConstraints对象并将其用于第二个按钮添加,则可以修复代码。

        GridBagConstraints d = new GridBagConstraints();
        d.fill = GridBagConstraints.HORIZONTAL;
        d.gridx = 0;
        d.gridy = 0;
        d.weightx = 0;
        d.weighty = 0;

然后在你的添加中使用它。

        buttonPane.add(flightPlanButton, d);

我运行了这段代码,它按照你想要的方式堆叠按钮。