Pregunta

I want to create a vertical list of items with a bottom status line such that when it gets resized, the space between the items and the bottom line grows. UsingMigLayout this must be pretty trivial, but somehow it isn't.

The following code does exactly what I want, but I had to use a component to do the spacing:

final JFrame frame = new JFrame();
final JPanel panel = new JPanel(new MigLayout("wrap, debug", "[grow, fill]", ""));
for (int i=0; i<5; ++i) {
    final JEditorPane line = new JEditorPane();
    line.setText("a" + i);
    panel.add(line);
}
panel.add(new JLabel(), "push"); // This should be a gap!
final JLabel status = new JLabel("status line");
panel.add(status, "");
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

I guess I could specify the growing gap in the third constructor argument, but the list length is variable. This could be all solved, too, but I doubt it's the best practice. What I was hoping for, was something like gaptop push, but it seems to do nothing at all.

What am I doing wrong? Is there an argument doing what I want?

¿Fue útil?

Solución

MigLayout is a very powerful manager indeed. This could be accomplished in multiple ways. I provide three solutions.

Solution 1

We put a greedy gap between row 5 and 6.

package com.zetcode;

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


public class MigLayoutGapGrow extends JFrame {

    public MigLayoutGapGrow() {

        initUI();

        setTitle("Gaps");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }


    private void initUI() {


        setLayout(new MigLayout("wrap", "[grow, fill]", "[][][][][]20:push[]"));

        add(new JTextField("a"+1));
        add(new JTextField("a"+2));
        add(new JTextField("a"+3));
        add(new JTextField("a"+4));
        add(new JTextField("a"+5));

        final JLabel status = new JLabel("status line");
        add(status);


        pack();
    }


    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MigLayoutGapGrow ex = new MigLayoutGapGrow();
                ex.setVisible(true);
            }
        });
    }
}

Solution 2

We enlarge the last cell in which the label is placed. The label is then aligned to the bottom.

package com.zetcode;

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


public class MigLayoutGapGrow2 extends JFrame {

    public MigLayoutGapGrow2() {

        initUI();

        setTitle("Gaps");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }


    private void initUI() {

        setLayout(new MigLayout("wrap, debug", "[grow, fill]"));

        add(new JTextField("a"+1));
        add(new JTextField("a"+2));
        add(new JTextField("a"+3));
        add(new JTextField("a"+4));
        add(new JTextField("a"+5));

        final JLabel status = new JLabel("status line");
        add(status, "pushy, bottom");

        pack();
    }


    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MigLayoutGapGrow2 ex = new MigLayoutGapGrow2();
                ex.setVisible(true);
            }
        });
    }
}

Solution 3

The label is attached to the bottom using relative positioning. Relative positioning does not seem to work with the pack() method and this might be a problem.

package com.zetcode;

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


public class MigLayoutGapGrow3 extends JFrame {

    public MigLayoutGapGrow3() {

        initUI();

        setTitle("Gaps");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }


    private void initUI() {

        setLayout(new MigLayout("wrap", "[grow, fill]"));

        add(new JTextField("a"+1), "id a1");
        add(new JTextField("a"+2));
        add(new JTextField("a"+3));
        add(new JTextField("a"+4));
        add(new JTextField("a"+5));

        final JLabel status = new JLabel("status line");
        add(status, "pos a1.x visual.y2-p");

        pack();
    }


    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MigLayoutGapGrow3 ex = new MigLayoutGapGrow3();
                ex.setVisible(true);
            }
        });
    }
}

Gaps

Otros consejos

If you add push on the component it has a different semnatic. From the docs:

Makes the row and/or column that the component is residing in grow with "weight". This can be used instead of having a "grow" keyword in the column/row constraints.

So you have to add the push keyword as the row constraint.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top