How to fix gap in GridBagLayout
Asked Answered
L

4

5

I am using a GridBagLayout to create a JPanel, called 'Preset', that gets replicated several times in a JFrame. Each Preset will have multiple rows (JPanels). My goal is that only one line (the first) will show up, but when the edit button is clicked, they will all show. Right now, the edit button works, but there is a massive space between the lines. I want it to be such that when the extra lines are collapsed, each Preset will be directly above each other (no space). You can see in the following picture what I am talking about.

This is how it looks: enter image description here

This is how I want it to Look: enter image description here

I am fairly certain I need to do something with the GridBag, but I don't know what. I have read several tutorials and have written it as I thought it should be, but no luck.


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;
    }
}
}
Laminous answered 31/7, 2013 at 14:16 Comment(6)
Can you mock up an image demonstrating what you would like to see? I don't understand from your description what you are attempting to do.Catlee
Just updated the post, hope it helps.Laminous
I updated the code for SSCCELaminous
Put your GridBagLayout panel inside of another JPanel with a FlowLayout.Rondelet
If one of the responses is a complete answer, please mark it as the 'answer' to your question. it's part of how SO works.Homy
I'm aware of how it works. There's a reason I haven't marked one as 'answer'.Laminous
M
5

Remove every statement that assigns padding in the Y AXIS for the GridBagConstraints of the Preset JPanel, i.e.

cons.ipady = 100;
Moonshot answered 31/7, 2013 at 16:18 Comment(4)
That defiantly did help. but didn't solve it 100%. When I expand the edit button, a space is generated between each Preset. Here is a picture of what happens. i.imgur.com/f2KUhId.pngLaminous
This doesnt happen in your SSCCE code. There's obviously some difference in the way the real app is laid out. Try to remodel the real app's layout based on the SSCCEMoonshot
Correct there are a lot of differences. In the actual app, the edit button makes line 2 display, otherwise it's hidden.Laminous
Update your SSCCE so that it reflects more closely (or even exactly) the real app otherwise people just resort to guessing :)Moonshot
H
1

I don't consider this a "real" answer to your question, but something for you to consider: get rid of gridbag. I don't see anything in your desired layout that requires it. Create each panel with two subpanels; the second subpanel contains the stuff that you want to make invisible by default and display later, and use setVisible() to do that.

I've never gotten comfortable with all of the GridBagConstraints, which seem to interact in ways for which I have no clear model. I avoid GridBagLayout for that reason, so I can't help do this with GridBagLayout. But I don't see why you can't do this with simpler (and less wordy) existing Swing containers and layout managers.

Homy answered 31/7, 2013 at 14:49 Comment(1)
I tried that. I do use setVisible() to change the visibility of line2. The problem with Swing, is that it works, but it has empty space where line 2 (is/should be). I don't want there to be any blank empty spaces...anywhere.Laminous
H
1

This is a real answer to the background question (how to get the effect you want):

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

Of course, I don't know what's different about the internals of your panels, or how they differ otherwise, but the "show" and "hide" buttons cause the secondary panel within the top panel of the frame to appear and disappear, leaving no gaps.

I still don't like GridBagLayout.

Homy answered 31/7, 2013 at 16:49 Comment(0)
R
0

I got the same problem and found a 70% Solution . If you use rowWeights and set it to 0 for all but your last component (with rowWeights 1.0), nearly all spaces vanish. If your containing Component is larger than all the other components, there remains only the gap before the last component.

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

Maybe this helps a little

Redvers answered 2/10, 2013 at 13:38 Comment(1)
Fixed the other 30% If you set the last rows Component anchor to North, the only remaining gap is between your last row and the bottom of the container ;) Found it here, #13286119 thx Guillaume PoletRedvers

© 2022 - 2024 — McMap. All rights reserved.