如何修复GridBagLayout中的差距

时间:2013-07-31 14:16:50

标签: java swing user-interface jpanel gridbaglayout

我使用GridBagLayout创建一个名为'Preset'的JPanel,它在JFrame中被多次复制。每个Preset都有多行(JPanels)。我的目标是只显示一行(第一行),但是当点击编辑按钮时,它们都将显示。现在,编辑按钮工作,但线之间有一个巨大的空间。我想要的是,当额外的线被折叠时,每个预设将直接在彼此之上(没有空间)。您可以在下图中看到我在说什么。

它的外观如下: enter image description here

这就是我想要的样子: enter image description here

我很确定我需要对GridBag做些什么,但我不知道是什么。我已经阅读了几个教程并按照我的想法编写了它,但没有运气。谢谢你提前。


package SSCCE;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class UI extends JFrame{
    private final static int HEIGHT = 600;
    private final static int WIDTH = 730;
    private JPanel pane; //Pane that stores accounts
    private JScrollPane scroller;
    private Preset[] branches;    

    public static void main(String[] args) {
        JFrame frame = new UI();
    }    

    public UI(){
        //Make the UI close when the exit button is clicked
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    

        //Sets the size of the UI
        this.setSize(WIDTH, HEIGHT);

        //Set the layout and add components to it
        this.setLayout(new BorderLayout());

        //Reads in the settings and sets up the branches
        populateBranches();

        pane = new JPanel();
        pane.setLayout(new GridLayout(branches.length,1));
        for (int i = 0; i < branches.length; i++){
            pane.add(branches[i]);
        }

        //Create the center pane of the BorderLayout
        scroller = new JScrollPane(pane);
        scroller.createVerticalScrollBar();
        this.add(scroller,BorderLayout.CENTER);

        //Makes the UI visible
        this.setVisible(true);
    }

    private void populateBranches(){
        //Populates the branches array based on what is read in, or not read in from the file
        branches = new Preset[15];

    for (int i = 0; i < branches.length; i++){
        branches[i] = new Preset();
        branches[i].setEnabled(false);
    }
}

public class Preset extends JPanel{
    private JTextField eName;
    private JButton edit;
    private JButton activate;
    private JComboBox printer;
    private JPanel line1;
    private JPanel line2;
    private String branchName;
    private String ipAddress;
    private boolean enableAll;

    public Preset(){
        eName = new JTextField(20);
        edit = new JButton("Edit");
        activate = new JButton("Activate");

        JPanel nameContainer = new JPanel();
        nameContainer.setLayout(new FlowLayout());
        nameContainer.add(eName);

        printer = new JComboBox();

        //
        line1 = new JPanel();
        line1.setLayout(new FlowLayout());
        line1.add(nameContainer);
        line1.add(edit);
        line1.add(activate);

        //
        line2 = new JPanel();
        line2.setLayout(new BorderLayout());
        line2.add(printer, BorderLayout.WEST);

        GridBagLayout grid = new GridBagLayout();
        GridBagConstraints cons = new GridBagConstraints();
        cons.fill = GridBagConstraints.BOTH;
        this.setLayout(grid);

        cons.ipady = 100;
        cons.ipadx = 100;
        cons.weighty = 0D;
        cons.gridx = 0;
        cons.gridy = 0;
        cons.gridwidth = 2;
        cons.gridheight = 1;
        grid.setConstraints(line1, cons);
        this.add(line1);

        cons.ipady = 100;
        cons.ipadx = 100;
        cons.weighty = 0D;
        cons.gridx = 0;
        cons.gridy = 1;
        cons.gridwidth = 2;
        cons.gridheight = 1;
        grid.setConstraints(line2, cons);
        this.add(line2);

        //Enable all components
        enableAll = true;
    }
}
}

4 个答案:

答案 0 :(得分:3)

删除在Y轴中为GridBagConstraints Preset的{​​{1}}指定填充的每个语句,即

JPanel

答案 1 :(得分:0)

我不认为这是对你的问题的“真实”答案,而是你需要考虑的事情:摆脱格栅。我没有看到您需要它的所需布局中的任何内容。使用两个子面板创建每个面板;第二个子面板包含您希望在默认情况下不可见并稍后显示的内容,并使用setVisible()来执行此操作。

我从未对所有GridBagConstraints感到满意,这些GridBagConstraints似乎以我没有明确模型的方式进行交互。我出于这个原因避免使用GridBagLayout,所以我无法用GridBagLayout做到这一点。但我不明白为什么你不能用更简单(也不那么罗嗦)的现有Swing容器和布局管理器来做到这一点。

答案 2 :(得分:0)

这是对背景问题(如何获得所需效果)的真实答案:

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class LinesOneAndTwo implements ActionListener
{
  private static final long serialVersionUID = 1L;
  JFrame mainWindow = new JFrame("LinesOneandTwo");

  JButton showButton = null;
  JButton hideButton = null;
  JPanel firstb = new JPanel();

  public static void main(String[] args)
  {
    LinesOneAndTwo main = new LinesOneAndTwo();
    main.go();
  }

  private void go()
  {
    mainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    Container contentPane = mainWindow.getContentPane();
    contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
    JPanel first = new JPanel();
    JPanel firsta = new JPanel();

    JPanel second = new JPanel();
    JPanel seconda = new JPanel();
    JPanel secondb = new JPanel();

    first.setLayout(new BoxLayout(first, BoxLayout.Y_AXIS));
    firsta.setLayout(new BoxLayout(firsta, BoxLayout.X_AXIS));
    showButton = new JButton("show");
    hideButton = new JButton("hide");
    firsta.add(showButton);
    firsta.add(hideButton);
    firstb.setLayout(new BoxLayout(firstb, BoxLayout.X_AXIS));
    firstb.add(new JButton("one"));
    firstb.add(new JButton("two"));
    first.add(firsta);
    first.add(firstb);

    second.setLayout(new BoxLayout(second, BoxLayout.Y_AXIS));
    seconda.setLayout(new BoxLayout(seconda, BoxLayout.X_AXIS));
    secondb.setLayout(new BoxLayout(secondb, BoxLayout.X_AXIS));
    seconda.add(new JButton("hiya"));
    seconda.add(new JButton("there"));
    secondb.add(new JButton("not here"));
    second.add(seconda);
    second.add(secondb);
    secondb.setVisible(false);

    firstb.setVisible(false);
    showButton.addActionListener(this);
    hideButton.addActionListener(this);
    mainWindow.add(first);
    mainWindow.add(second);
    mainWindow.pack();
    mainWindow.setVisible(true);

  }

  public void actionPerformed(ActionEvent event)
  {
    if (event.getSource() == showButton)
    {
      firstb.setVisible(true);
      mainWindow.pack();
    }
    else if (event.getSource() == hideButton)
    {
      firstb.setVisible(false);
      mainWindow.pack();
    }
  }
}

当然,我不知道面板的内部有什么不同,或者它们之间的区别如何,但“显示”和“隐藏”按钮会导致框架顶部面板内的辅助面板出现,消失,不留间隙。

我仍然不喜欢GridBagLayout。

答案 3 :(得分:0)

我遇到了同样的问题并找到了70%的解决方案。 如果您使用rowWeights并将其设置为0,除了您的最后一个组件(使用rowWeights 1.0),几乎所有空格都会消失。如果包含的Component大于所有其他组件,则在最后一个组件之前只剩下间隙。

GridBagLayout gbl_panelFoo = new GridBagLayout();
gbl_panelFoo.rowWeights = new double[] {0.0, 0.0, 0.0, ... 0.0, 1.0};

也许这会有所帮助