Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable Layout in Swing

Tags:

java

layout

swing

How would you go about getting a decent looking gui generated when you don't know how many components you will have and how big they will be?

A user, for instance, enters how many textfields they want and which of those textfields are grouped in bordered panels and the program generates this.

I've been using GridLayout, but the problem is that it makes all cells of the same width and height, which is fine when all components have the same size, but when I, for example, have a textfield and a bordered panel with multiple fields, either the textfield gets stretched out or the panel is squeezed.

I would like all components to have their minimum size, but still, you know, usable.

Example of how it is now, using GridLayout, all fields are normal, one-line JTextFields where the panel titled date is totally squeezed (it has three fields in it) and the first level fields are way to big. Anyone have any pointers?

like image 440
thepandaatemyface Avatar asked Jul 04 '10 13:07

thepandaatemyface


People also ask

What are the various layouts in Swing?

Most UIs are built using some combination of them, typically by nesting layout managers. The most commonly used layouts are FlowLayout, BorderLayout and BoxLayout. LayoutManagers are a concept from AWT that is also used in Swing.

Which is the default layout in Swing?

Java BorderLayout It is the default layout of a frame or window. The BorderLayout provides five constants for each region: public static final int NORTH. public static final int SOUTH.

What are the 3 types of Java Swing containers?

As we mentioned before, Swing provides three generally useful top-level container classes: JFrame , JDialog , and JApplet .

What is the use of setLayout () method?

The setLayout(...) method allows you to set the layout of the container, often a JPanel, to say FlowLayout, BorderLayout, GridLayout, null layout, or whatever layout desired. The layout manager helps lay out the components held by this container.


3 Answers

MiGLayout has a lot of appeal, but BoxLayout is an alternative.

image

import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;

public class BoxTest extends JPanel {

    private List<JTextField> fields = new ArrayList<JTextField>();

    public BoxTest() {
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.add(createPane(3, "One ", Color.red));
        this.add(createPane(3, "Two ", Color.green));
        this.add(createPane(10, "Three ", Color.blue));
    }

    private JPanel createPane(int n, String s, Color c) {
        JPanel outer = new JPanel();
        outer.setLayout(new BoxLayout(outer, BoxLayout.Y_AXIS));
        outer.setBorder(BorderFactory.createLineBorder(c, 2));
        for (int i = 0; i < n; i++) {
            JPanel inner = new JPanel();
            inner.setLayout(new BoxLayout(inner, BoxLayout.X_AXIS));
            JLabel label = new JLabel(s + i + ":", JLabel.RIGHT);
            label.setPreferredSize(new Dimension(80, 32));
            inner.add(label);
            JTextField tf = new JTextField("Stackoverflow!", 32);
            inner.add(tf);
            fields.add(tf);
            outer.add(inner);
        }
        return outer;
    }

    private void display() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JScrollPane jsp = new JScrollPane(this,
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        this.validate();
        Dimension d = this.getPreferredSize();
        d.height /= 2;
        jsp.getViewport().setPreferredSize(d);
        jsp.getVerticalScrollBar().setUnitIncrement(
            this.getPreferredSize().height / fields.size());
        f.add(jsp);
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new BoxTest().display();
            }
        });
    }
}
like image 150
trashgod Avatar answered Sep 28 '22 07:09

trashgod


I would look at miglayout. It's a lot more useful than any of the inbuilt layout managers.

like image 39
Gordon Avatar answered Sep 28 '22 06:09

Gordon


Your general goal - "usable component sizes" clashes with "unknown number". Make the number large enough and they won't fit any screen.

Overthink if you wouldn't be better off with using JTables (cells can be made editable) in conjuction with a JScrollPanel. If you want/must keep your approach of generating components, put the whole JPanel that contains your components into a JScrollPane, that way the components wont be squeezed to badly.

like image 31
Durandal Avatar answered Sep 28 '22 07:09

Durandal