Home > Mobile >  GUI components not aligning vertically inside JPanel in Card layout
GUI components not aligning vertically inside JPanel in Card layout

Time:11-10

Image of my GUI.

I am trying to add components to two JPanel containers and then add those panels as cards. I want the checkboxes after labels in a vertical manner. The problem I am facing is that the components are coming in a grid of two columns:

public class MyFrame extends JFrame {

    MyFrame(int width, int height, String title){
        setTitle(title);
        setSize(width, height);
        JPanel internalJP1 = new JPanel(new GridLayout(5,1));
        JLabel hobby = new JLabel("Enter your hobbies:");
        JCheckBox cricket = new JCheckBox("Cricket");
        JCheckBox music = new JCheckBox("Music");
        JCheckBox drawing = new JCheckBox("Drawing");
        JCheckBox dancing = new JCheckBox("Dancing");
        JCheckBox other = new JCheckBox("Other");

        internalJP1.add(hobby);
        internalJP1.add(cricket);
        internalJP1.add(music);
        internalJP1.add(drawing);
        internalJP1.add(dancing);
        internalJP1.add(other);

        JPanel internalJP2 = new JPanel(new GridLayout(4,1));
        JLabel payment = new JLabel("Payment by:");
        ButtonGroup buttonGroup = new ButtonGroup();
        JRadioButton cheque = new JRadioButton("Cheque", false);
        JRadioButton cash = new JRadioButton("Cash", false);
        JRadioButton debitCard = new JRadioButton("Debit Card", false);
        JRadioButton creditCard = new JRadioButton("Credit Card", false);
        buttonGroup.add(cheque);
        buttonGroup.add(cash);
        buttonGroup.add(debitCard);
        buttonGroup.add(creditCard);

        internalJP2.add(payment);
        internalJP2.add(cheque);
        internalJP2.add(cash);
        internalJP2.add(debitCard);
        internalJP2.add(creditCard);

        Container c = getContentPane();
        CardLayout cl = new CardLayout();
        c.setLayout(cl);
        c.add(internalJP1,"crd1");
        c.add(internalJP2,"crd2");
        cl.show(c,"crd1");
    }
}

public class Jtest {
  public static void main(String[] args) {
      MyFrame frame = new MyFrame(300,200,"FirstFrame");
      frame.setVisible(true);
  }
}

CodePudding user response:

Just change this line of code (in constructor of class MyFrame)

JPanel internalJP1 = new JPanel(new GridLayout(5,1));

to this

JPanel internalJP1 = new JPanel(new GridLayout(0,1));

i.e. replace 5 with 0

I find GridLayout to not be intuitive. When the row parameter of GridLayout constructor is zero, then each row will contain exactly the number of columns indicated. Hence new GridLayout(0, 1) will ensure that each row (in the grid) will contain exactly one column and it will create as many rows as required in order to ensure this.

Note that GridLayout is not the only layout manager to use when you want to place GUI components in a single column. Swing also has BoxLayout, GridBagLayout, GroupLayout and SpringLayout.

There are also third party layout managers including JGoodies and MiG Layout.

CodePudding user response:

The fact that you are using a CardLayout to view one panel or the other does not affect the layout of those panels. Your problem is entirely related to the layout of the 2 panels.

There are 2 easy ways to fix the panels to make them 1-column:

  1. fix their number of rows so that it is >= the number of elements that you actually add. Now, you have JPanel internalJP1 = new JPanel(new GridLayout(5,1)); - but add 6 elements. If you change it to JPanel internalJP1 = new JPanel(new GridLayout(6,1));, you will solve the problem for your 1st panel. The same fix applies to your second panel. Even better, use 0 to make the layout use as many rows as it needs (see docs).
  2. use a vertical BoxLayout and do not worry about the number of elements at all - just stack them vertically. This has the additional advantage that they look better, because even if you give the layout more size than it needs, they still stack together nicely: JPanel internalJP1 = new JPanel(); internalJP1.setLayout(new BoxLayout(internalJP1, BoxLayout.Y_AXIS));
  • Related