1

First off, I apologize for the long post, I just wanted to be clear and show you my issue so it can better be resolved.

I have the following code:

    JPanel panelCard = new JPanel();

    String[] cards = {"VISA", "MASTERCARD", "DISCOVER"};

    JComboBox cardType = new JComboBox(cards);

    panelCard.add(cardType);

    GroupLayout layout2 = new GroupLayout(panelCCInfo);

    panelCCInfo.setLayout(layout2);

    layout2.setAutoCreateGaps(true);
    layout2.setAutoCreateContainerGaps(true);

    GroupLayout.SequentialGroup hGroup2 = layout2.createSequentialGroup();

    hGroup2.addGroup(layout2.createParallelGroup()
            .addComponent(cardName)
            .addComponent(cardNumber)
            .addComponent(expDate));
    hGroup2.addGroup(layout2.createParallelGroup()
            .addComponent(cardNameField)
            .addComponent(cardNumberField)
            .addComponent(expDateField));
    hGroup2.addGroup(layout2.createParallelGroup()
            .addComponent(panelCard));
    layout2.setHorizontalGroup(hGroup2);

    GroupLayout.SequentialGroup vGroup2 = layout2.createSequentialGroup();

    vGroup2.addGroup(layout2.createParallelGroup(Alignment.BASELINE)
            .addComponent(cardName)
            .addComponent(cardNameField));
    vGroup2.addGroup(layout2.createParallelGroup(Alignment.BASELINE)
            .addComponent(cardNumber)
            .addComponent(cardNumberField));
    vGroup2.addGroup(layout2.createParallelGroup(Alignment.BASELINE)
            .addComponent(expDate)
            .addComponent(expDateField)
            .addComponent(panelCard));
    layout2.setVerticalGroup(vGroup2);

    panelCheckout.add(panelCCInfo, BorderLayout.CENTER);

And when I run it, it displays this window: enter image description here

But I would like to achieve this: enter image description here

The problem occurs when I try to add a 3rd vertical group with the panelCard in the code:

    hGroup2.addGroup(layout2.createParallelGroup().addComponent(panelCard));

It would seem that the 2 text field are cut off because of this, but I dont want it cut off.

What can I do to achieve the 2nd picture?

Thanks so much!

Pangu
  • 3,721
  • 11
  • 53
  • 120
  • 1
    Is using another `LayoutManager` an option ? This is for example trivial using a `FormLayout` (from JGoodies). `GroupLayout` is as far as I am concerned only designed for UI builders. Not to hand-code anything in it – Robin Nov 30 '13 at 13:36
  • `GroupLayout` was indeed created with UI builders in mind, but my experience is that it is great for hand-coded UIs too. – barjak Nov 30 '13 at 21:00

2 Answers2

1

Here is how I'd do it:

import javax.swing.*;
import static javax.swing.GroupLayout.*;
import static javax.swing.GroupLayout.Alignment.*;

public class Mastercard {

    public static void main(String[] args) {
        JLabel lblCardHolder = new JLabel("Card holder");
        JTextField tfCardHolder = new JTextField();
        JLabel lblCardNumber = new JLabel("Card number");
        JTextField tfCardNumber = new JTextField();
        JLabel lblExpirationDate = new JLabel("Expiration date");
        JTextField tfExpirationDate = new JTextField();
        JComboBox combo = new JComboBox(new String[]{"Visa"});

        JPanel panel = new JPanel();
        GroupLayout layout = new GroupLayout(panel);
        panel.setLayout(layout);

        layout.setAutoCreateContainerGaps(true);
        layout.setAutoCreateGaps(true);

        layout.setHorizontalGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup()
                    .addComponent(lblCardHolder)
                    .addComponent(lblCardNumber)
                    .addComponent(lblExpirationDate))
                .addGroup(layout.createParallelGroup()
                    .addComponent(tfCardHolder)
                    .addComponent(tfCardNumber)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(tfExpirationDate)
                        .addComponent(combo, DEFAULT_SIZE, 100, PREFERRED_SIZE))));

        layout.setVerticalGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(BASELINE)
                    .addComponent(lblCardHolder)
                    .addComponent(tfCardHolder))
                .addGroup(layout.createParallelGroup(BASELINE)
                    .addComponent(lblCardNumber)
                    .addComponent(tfCardNumber))
                .addGroup(layout.createParallelGroup(BASELINE)
                    .addComponent(lblExpirationDate)
                    .addComponent(tfExpirationDate)
                    .addComponent(combo)));

        JFrame f = new JFrame();
        f.setContentPane(panel);
        f.pack();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

This is the result:

enter image description here

GroupLayout is a powerful constraint-based layout manager. When writing a group layout, you basically just describe whether components (or group of components) should be placed in sequence or in parallel. This description is done independently for the horizontal and vertical axis.

Horizontally, there are 2 groups in sequence : the labels, and the rest. The rest is composed of 3 parallel things : 2 textfields, and a sequence of tfExpirationDate and combo. This is, in plain english, what the layout.setHorizontalGroup(... describes.

Vertically, there are 3 groups in sequence : one composed of a label and a textfield in parallel, another composed of a label and a textfield in parallel, and yet another composed of a label, a textfield and a combobox in parallel. This is what layout.setVerticalGroup(... describes.

The nesting of these groups and components is important, this is why I indented everything correctly.

I find this approach of describing constraints quite easy to reason about, using only 2 concepts : sequential groups and parallel groups. Compared to grid-based layouts, it has the advantage that you don't break everything each time you want to add or move a component.

barjak
  • 10,842
  • 3
  • 33
  • 47
  • Swap `f.setSize(1024, 768);` for `f.pack()` for a +1. – Andrew Thompson Dec 01 '13 at 09:09
  • I'd prefer the +1 be for my hard-work on this answer... But I don't mind changing this line :) – barjak Dec 01 '13 at 14:16
  • *"hard-work on this answer"* Are you implying you wrote that code by hand? It looks like it was made with a GUI designer. ;) – Andrew Thompson Dec 01 '13 at 22:46
  • Yes I wrote the code by hand. I stopped using GUI designer years ago, because they make it hard to evolve a GUI design after it was created. And they get in the way when working with a team. They are still useful for prototyping and for learning, though. I admit that I stole the style of indentation from what Matisse (Netbeans' GUI designer) generates. – barjak Dec 02 '13 at 09:10
  • *"Yes I wrote the code by hand."* (stunned) I could not wrap my head around writing `GroupLayout` if my life depended on it. Kudos! – Andrew Thompson Dec 02 '13 at 09:28
  • Can I ask if you already tried to? Its Javadoc explains its API very well. Actually, I even *enjoy* writing layouts using this API (and it's the *only* layout I enjoy modifying afterwards). I think it's unfortunate that most people consider that `GroupLayout` is for code generators only. That's why I'm trying to answer every SO question about `GroupLayout` ! – barjak Dec 02 '13 at 10:43
  • I'm glad you asked. [This is my best attempt](http://stackoverflow.com/a/16353404/418556). It is a relatively trivial (but useful) two column X N row helper method. On trying to overload it to also provide for 'a row of buttons, centered at the bottom', I failed dismally. – Andrew Thompson Dec 02 '13 at 10:48
  • *"That's why I'm trying to answer every SO question about GroupLayout !"* I'll be sure to keep an eye out for them. :) – Andrew Thompson Dec 02 '13 at 10:49
  • Indeed, I'm not sure `GroupLayout` is appropriate for generic code like yours. I'll try to answer this one when I have the time. Thanks for the kind words! – barjak Dec 02 '13 at 10:55
0

Ok I figured it out using a complex combination of GridBagLayout and BorderLayout

what a mess.... :)

Pangu
  • 3,721
  • 11
  • 53
  • 120