Was ist ein BorderLayout?

Ein BorderLayout, der Standard-Layout-Manager aller ContentPanes1, teilt eine Container-Fläche in fünf Bereiche auf, die durch Konstanten der Klasse BorderLayout angesprochen werden können. In früheren Java-Versionen (< Java 1.4) wurden diese mit den Namen der vier Himmelsrichtungen, sowie "CENTER" für den zentralen Bereich, bezeichnet. Auch wenn dies nach wie vor möglich ist, empfiehlt Oracle [1] stattdessen die Verwendung der folgenden BorderLayout-Konstanten. Das Beispiel demonstriert deren Position und Anwendung.

Um den Bereich festzulegen, in den eine bestimmte Komponente geladen werden soll, werden der Methode add() als erstes Argument die Komponente und als zweites die gewünschte Bereichskonstante übergeben.

public class BorderLayoutBsp {
    
    public BorderLayoutBsp() {
        init();
    }
    
    private void init() {
        JFrame frame = new JFrame();
        JPanel topPanel = new JPanel(new FlowLayout());
        topPanel.add(createLabel("PAGE_START 1", new Color(250, 180, 180)));
        topPanel.add(createLabel("PAGE_START 2", new Color(180, 250, 250)));
        frame.add(topPanel, BorderLayout.PAGE_START);
        frame.add(createLabel("CENTER", new Color(189, 250, 180)), BorderLayout.CENTER);
        frame.add(createLabel("PAGE_END", new Color(180, 180, 180)), BorderLayout.PAGE_END);
        frame.add(createLabel("LINE_START", new Color(180, 180, 250)), BorderLayout.LINE_START);
        frame.add(createLabel("LINE_END", new Color(250, 250, 180)), BorderLayout.LINE_END);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("BorderLayout");
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    private JLabel createLabel(String pos, Color c) {
        JLabel label = new JLabel(pos, SwingConstants.CENTER);
        label.setOpaque(true);
        label.setBackground(c);
        label.setFont(new Font("Sans", Font.BOLD, 20));
        label.setText(pos);
        return label;
    }

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

Werden mehrere Komponenten einem Bereich hinzugefügt, so wird nur die zuletzt angegebene angezeigt. Sollen mehrere Komponenten innerhalb eines Bereiches sichtbar sein, so müssen diese vorher in einen weiteren Container mit beliebigem Layout-Manager eingebettet und dieser dann dem BorderLayout hinzugefügt werden. Der Bereich 'PAGE_START' des Beispiels demonstriert dies anhand eines JPanel mit zwei Labeln.

JFrame mit BorderLayout JFrame mit BorderLayout leicht aufgezogen

Die Abbildungen zeigen das im Quelltext definierte Programm, links in der initialen Version, rechts mit leicht aufgezogenem Fenster. Hierbei zeigen sich einige Eigenschaften des Layouts:

  1. Anhand der Hintergrundfarben ist zu erkennen, dass die direkt ins BorderLayout geladenen Komponenten initial in ihrer bevorzugten Größe angezeigt werden.
  2. Bei Größenänderungen des Containers passen sich die geladenen Komponenten entsprechend an und füllen den jeweiligen Bereich vollständig aus.
  3. Wird ein Untercontainer (hier das JPanel) in einen Bereich des BorderLayout geladen, der seinerseits mehrere Komponenten enthält, so unterliegen diese dem LayoutManager des Unter-Containers.
  4. Zusätzlicher Raum wird bevorzugt dem zentralen Bereich zugewiesen. Die anderen Bereiche passen sich an.

Um Abstände zwischen den fünf Layout-Bereichen und damit auch zwischen darin geladenen Komponenten zu erhalten, stellt BorderLayout die Methoden setHgap() und setVgap() bereit. Ihre Ausführung wirkt sich auf den gesamten Layout-Bereich gleichermaßen aus.

Im obigen Beispiel können Zwischenräume durch das Ermitteln des Layout-Managers des Frames und anschließender Ausführung der beiden Methoden auf diesem erreicht werden.

//...
((BorderLayout)frame.getContentPane().getLayout()).setHgap(50);
((BorderLayout)frame.getContentPane().getLayout()).setVgap(20);
//...

Hierbei ist wichtig zu beachten, dass der Layout-Manager dem ContentPane des Frame und nicht dem Frame selber zugeordnet ist. Das ContentPane muss deshalb vor dem Aufruf des Layouts explizit durch getContentPane() ermittelt werden.1,2

JFrame mit BorderLayout und Abständen
Quellen
  1. How to Use BorderLayout

1) Ein ContentPane ist ein von JComponent abgeleiteter Lightweight-Container, der der Komponentenaufnahme bei JFrame, JApplet und JDialog dient. Sein Standard-Layout-Manager ist das BorderLayout.
2) Ein Methodenaufrug JFrame#setHgap() bzw. JFrame#setVgap() bleibt ergebnislos, da das BorderLayout dem ContentPane des JFrame zugewiesen ist. Ein Aufruf von JFrame#add() funktioniert nur, da die überschriebenen add()- Methoden den Aufruf an JFrame#getContentPane()#add() weiterleiten.