MigLayout: reference component width by id

59 Views Asked by At

I would like to layout my components as shown in this picture.

enter image description here

In short:

  • aTextField must have a fixed size of 250px;
  • bButton has a fixed size that dependes on the text label;
  • bTextField should grow so that it's width plus bButton width reach 250px.

This is my code:

import java.awt.Container;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;

public class MigLayoutIdReference extends JFrame {

    private final MigLayout migLayout = new MigLayout("debug", "", "");
    private final JLabel aLabel = new JLabel("Label A");
    private final JTextField aTextField = new JTextField();
    private final JLabel bLabel = new JLabel("Label B");
    private final JTextField bTextField = new JTextField();
    private final JButton bButton = new JButton("B Button");

    public MigLayoutIdReference() {
        Container container = getContentPane();
        container.setLayout(migLayout);
        add(aLabel, "");
        add(aTextField, "id aTextField, w 250!, wrap");
        add(bLabel, "");
        add(bTextField, "width aTextField.w-bButton.w");
        add(bButton, "id bButton, wrap");
        setResizable(true);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        new MigLayoutIdReference();
    }
}

Unfortunately it seems that MigLayout does not allow to calculate width based on other components that you recall by id. When running my code I get:

Caused by: java.lang.IllegalArgumentException: Size may not contain links

Am I missing something? Apart from referencing components by id, how could I achieve the desired result?

1

There are 1 best solutions below

1
Abra On
  • I changed the MigLayout constructor invocation and added row constraints and column constraints.
  • I made aTextField span two columns.
  • I gave bTextField the growx constraint.

Now the width of bTextField will adjust so that together with the width of bButton it will match the width of aTextField.

import java.awt.Container;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;

public class MigLayoutIdReference extends JFrame {
    private final MigLayout migLayout = new MigLayout("debug", "[][grow][]", "[][]");
    private final JLabel aLabel = new JLabel("Label A");
    private final JTextField aTextField = new JTextField();
    private final JLabel bLabel = new JLabel("Label B");
    private final JTextField bTextField = new JTextField();
    private final JButton bButton = new JButton("B Button");

    public MigLayoutIdReference() {
        Container container = getContentPane();
        container.setLayout(migLayout);
        add(aLabel, "");
        add(aTextField, "id aTextField, w 250!, wrap, span 2");
        add(bLabel, "");
        add(bTextField, "growx");
        add(bButton, "id bButton,wrap");
        setResizable(true);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        new MigLayoutIdReference();
    }
}

Here is a screen capture:

screen capture