Wie wendet man ein BoxLayout an?

Ein BoxLayout lässt sich funktional mit einem FlowLayout vergleichen. Es kann Komponenten jedoch nacheinander vertikal oder horizontal anordnen.

Ein BoxLayout kann in allen Containern und nicht nur wie gelegentlich vermutet in Containern der Klasse Box, verwendet werden. Um dies zu demonstrieren verwenden die folgenden Beispiele als Container ein JPanel. Das BoxLayout ordnet die enthaltenen Komponenten fest horizontal oder vertikal an, ohne die Anordnung bei Verkleinern des Containers umzubrechen.

Wird eine Instanz des BoxLayout einem Container hinzugefügt, so wird bei der Objektbildung durch ein Argument angegeben, in welcher Richtung einzufügende Komponenten angeordnet werden sollen. Hierzu stehen vier statische int-Variablen zur Verfügung:

LINE_AXIS
Ordnet Komponenten so an, wie eine Textzeile durch die Eigenschaft ComponentOrientation im Container angeordnet wird.
PAGE_AXIS
Ordnet Komponenten so an, wie eine Folge von Zeilen durch die Eigenschaft ComponentOrientation im Container angeordnet wird.
X_AXIS
Ordnet Komponenten im Container von links nach rechts an.
Y_AXIS
Ordnet Komponenten im Container von oben nach unten an.

LINE_AXIS und PAGE_AXIS wurden erst mit Java 1.4 eingeführt, um Internationalisierung zu ermöglichen, entsprechen im westlichen Umfeld jedoch einer Anordnung von links nach rechts bzw. von oben nach unten.

public class BoxLayoutBsp1 {

    public BoxLayoutBsp1() {
        init();
    }

    private void createLayout(JPanel panel) {
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        JTextField field = new JTextField("Textfeld");
        panel.add(new JButton("click"));
        panel.add(field);
        panel.add(new JLabel("Label"));
    }

    private void init() {
        JPanel panel = new JPanel();
        createLayout(panel);
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setTitle("BoxLayout");
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new BoxLayoutBsp1());
    }
}

Im Beispiel wird ein kleines Fenster erzeugt, auf dem ohne Abstand nacheinander ein Button, ein Textfeld und ein Label in einer Reihe angeordnet sind. Das hierzu benötigte BoxLayout wird in der rot markierten Zeile des Quelltextes erzeugt und dem Container, einem JPanel, hinzugefügt. Hierzu werden dem Konstruktor des BoxLayout als erstem Parameter der Container selbst und als zweitem die Layoutrichtung in Form einer der o.a. Konstanten, hier X_AXIS, übergeben.
In den letzten drei Zeilen der Methode createLayout() werden die Komponenten dem Container hinzugefügt.

Größenanpassung der Komponenten

Einfaches horizontales BoxLayout
Horizontales BoxLayout
Fenster horizontal nach rechts
                        aufgezogen
Fenster horizontal nach rechts aufgezogen

BoxLayout versucht, die Dimensionen der Komponenten nach deren jeweiliger bevorzugten Größe (PreferredSize) zu bemessen. Ist der Container größer als der Platzbedarf der Komponenten, werden diese nach Möglichkeit angepasst, um den Container vollständig zu füllen.

Das betrifft beide Dimensionen! Mag die Längenanpassung in unserem Beispiel hinnehmbar sein, so ist dies bei dessen vertikaler Größe nicht der Faall.

Ein BoxLayout berücksichtigt auch die Minimal- und Maximalgrößen von Komponenten, sofern diese gesetzt wurden. Somit kann eine Größenänderung durch die Angabe der Textfeld-Größe verhindert werden.

private void createLayout(Box panel) {
    JTextField field = new JTextField("Textfeld");
    field.setMinimumSize(field.getPreferredSize());
    field.setMaximumSize(field.getPreferredSize());
    panel.add(new JButton("click"));
    panel.add(field);
    panel.add(new JLabel("Label"));
}
Einfaches horizontales BoxLayout vertikal aufgezogen
Fenster vertikal aufgezogen
Einfaches horizontales BoxLayout vertikal aufgezogen mit Größenbegrenzung
Fenster vertikal aufgezogen mit Größenbegrenzung

Wird die Minimalgröße einer Komponente definiert und die Containergröße unterschreitet den gesamten Platzbedarf, so werden die der fraglichen Komponente nachfolgenden Komponenten beschnitten oder fallen fort.

private void createLayout(JPanel panel) {
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    Dimension dim = new Dimension(100, 15);
    JTextField field = new JTextField("Textfeld");
    field.setMaximumSize(dim);
    field.setMinimumSize(dim);
    field.setPreferredSize(dim);
    panel.add(new JButton("click"));
    panel.add(field);
    panel.add(new JLabel("Label"));
}
Fenster mit BoxLayout von rechts verkleinert
Fenster von rechts verkleinert
Fenster mit BoxLayout horizontal nach rechts
                        aufgezogen
Fenster horizontal nach rechts aufgezogen

Freiräume, Abstände und Zwischenräume

Die Klasse Box bietet einige Möglichkeiten, Freiraum, Abstände und Zwischenräume zwischen Komponenten zu definieren.

Freiraum bei Größenänderung

Um festzulegen an welcher Stelle eines Containers überschüssiger Raum, etwa beim Aufziehen eines Fensters, platziert werden soll, kann dies durch die statischen Methoden createHorizontalGlue() und createVerticalGlue() festgelegt werden. Im folgenden Beispiel wird dieser Platz am Anfang der Zeile erzeugt, sodass alle folgenden Komponenten dann am Ende der Zeile erscheinen.

private void createLayout(JPanel panel) {
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    Dimension dim = new Dimension(100, 15);
    JTextField field = new JTextField("Textfeld");
    field.setMaximumSize(dim);
    field.setMinimumSize(dim);
    field.setPreferredSize(dim);
    panel.add(Box.createHorizontalGlue());
    panel.add(new JButton("click"));
    panel.add(field);
    panel.add(new JLabel("Label"));
}
Fenster mit 'HorizontalGlue' horizontal nach
                    rechts aufgezogen
Fenster mit 'HorizontalGlue' horizontal nach rechts aufgezogen

Wird die Abstandskomponente an mehreren Stellen platziert, so wird der Raum anteilsmäßig aufgeteilt.

private void createLayout(JPanel panel) {
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    Dimension dim = new Dimension(100, 15);
    JTextField field = new JTextField("Textfeld");
    field.setMaximumSize(dim);
    field.setMinimumSize(dim);
    field.setPreferredSize(dim);
    panel.add(Box.createHorizontalGlue());
    panel.add(new JButton("click"));
    panel.add(Box.createHorizontalGlue());
    panel.add(field);
    panel.add(Box.createHorizontalGlue());
    panel.add(new JLabel("Label"));
}
Fenster mit dreifachem 'HorizontalGlue'
                    horizontal nach rechts aufgezogen
Fenster mit dreifachem 'HorizontalGlue' horizontal nach rechts aufgezogen

Feste Abstände

Wenn es darauf ankommt, einen fest dimensionierten Raum, etwa als Abstand zwischen zwei Komponenten, zu definieren, so kann dies u.a.1 durch die statischen Methode createRigidArea() erreicht werden. Ihr wird ein Dimension-Objekt, das Breite und Höhe festlegt, als Argument übergeben. Im folgenden Beispiel wird zwischen den Komponenten ein horizontaler Abstand von 25 Pixeln erzeugt.

private void createLayout(JPanel panel) {
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    Dimension dim = new Dimension(25, 0);
    JTextField field = new JTextField("Textfeld");
    panel.add(new JButton("click"));
    panel.add(Box.createRigidArea(dim));
    panel.add(field);
    panel.add(Box.createRigidArea(dim));
    panel.add(new JLabel("Label"));
}
Fenster mit rigid areas zwischen den Komponenten, nicht aufgezogen
Fenster mit rigid areas zwischen den Komponenten, nicht aufgezogen
Fenster mit rigid areas zwischen den Komponenten, nach rechts aufgezogen
Fenster mit rigid areas zwischen den Komponenten, nach rechts aufgezogen

Ähnlich einer rigid area kann eine unsichtbare Komponente der inneren Klasse Box.Filler einen festen Abstand definieren. Sie ermöglicht jedoch darüber hinaus die Angabe einer minimalen, maximalen und bevorzugten Größe. Im folgenden Beispiel wurde das Textfeld der vorhergehenden Beispiele entfernt, um das Verhalten des Fillers besser zu verdeutlichen.

private void createLayout(JPanel panel) {
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    JTextField field = new JTextField("Textfeld");
    Dimension min = new Dimension(50, 0);
    Dimension pref = new Dimension(100, 0);
    Dimension max = new Dimension(150, 0);
    panel.add(new JButton("click"));
    panel.add(new Box.Filler(min, pref, max));
    panel.add(new JLabel("Label"));
}
Fenster mit Box.Filler
Fenster mit Box.Filler
Fenster mit Box.Filler, von rechts verkleinert
Fenster mit Box.Filler, von rechts verkleinert

Fenster mit Box.Filler, nach rechts aufgezogen
Fenster mit Box.Filler, nach rechts aufgezogen

Beim initialen Fenster besitzt der Filler eine Breite von 100 Pixeln. Sie verringert sich bis auf eine Breite von hier 50 Pixeln beim Verkleinern des Fensters. Wird das Fenster weiter von rechts verkleinert, wird der Inhalt rechts beschnitten. Beim Aufziehen des Fensters, vergrößert sich der Filler bis auf die angegebene Maximalgröße. Anschließend wird rechts vom Inhalt Freiraum eingefügt.

Dies kann man sich zunutze machen, um zwei Komponenten konstant am linken und rechten Fensterrand zu patzieren. Hierzu wird eine Abstandskomponente mit 'unendlicher' Maximalgröße zwischen beide Komponenten gesetzt.

private void createLayout(JPanel panel) {
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    Component box = Box.createHorizontalGlue();
    box.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
    panel.add(new JButton("click"));
    panel.add(box);
    panel.add(new JLabel("Label"));
}
Quellen
  1. Oracle Java Tutorial zum BoxLayout

1) Statt einer rigid area können Abstände auch durch die Methoden createHorizonalStrut() und createVerticalStrut() erzeugt werden. Oracle empfiehlt aufgrund der teilweise schlechten Kontrollierbarkeit jedoch die Verwendung von rigid areas. [1]

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.