Memra

Swing components & containers

Build a window from a JFrame, lay components into containers with a layout manager, and wire up the scrollable-text-area-plus-buttons shape the Greenhouse control panel needs.

Swing is a tree of components

A Swing GUI is a containment hierarchy: a top-level window holds a content pane, the content pane holds containers, and containers hold the leaf components the user sees. Every visible widget is a JComponent (button, label, text area, etc.); every JComponent is also a Container, so the tree can nest arbitrarily.

The three pieces you assemble every time:

- A top-level window — almost always JFrame. It supplies the OS window frame, the title bar, and the close button. You never add components directly to a JFrame; you add them to its content pane (frame.getContentPane()), though frame.add(...) is a convenience that forwards to the content pane. - Intermediate containersJPanel is the workhorse. A panel groups components and gives them their own layout manager so you can compose complex screens out of simple rectangles. - Atomic componentsJButton, JLabel, JTextField, JTextArea, JCheckBox, and so on.

Layout managers decide *where*

A Container does not position its children by pixel coordinates by default — a layout manager does. The common ones:

- BorderLayout (the default for a JFrame's content pane) — five regions: NORTH, SOUTH, EAST, WEST, CENTER. The center stretches to fill leftover space; the edges take their preferred size. - FlowLayout (the default for a JPanel) — lays components left-to-right, wrapping like words; good for a row of buttons. - GridLayout(rows, cols) — equal-sized cells; good for a button grid. - BoxLayout — a single row or column with fine spacing control.

Scrollbars wrap, they don't attach

A JTextArea does not scroll on its own. You make it scrollable by wrapping it in a JScrollPane and adding the *scroll pane* — not the text area — to the container. This is the decorator pattern: the scroll pane is a container that holds the view and supplies the bars.

Worked example — the Greenhouse control panel skeleton

Project Part 3 is a window with a scrollable status log across the top and a row of control buttons below. BorderLayout makes this trivial: the scrolling log goes CENTER (so it grows with the window), the buttons go SOUTH in their own FlowLayout panel:

import javax.swing.*;
import java.awt.BorderLayout;

public class ControlPanel {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Greenhouse Controls");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JTextArea log = new JTextArea(15, 40);
        log.setEditable(false);                 // a read-only status log
        frame.add(new JScrollPane(log), BorderLayout.CENTER);

        JPanel buttons = new JPanel();          // FlowLayout by default
        buttons.add(new JButton("Run"));
        buttons.add(new JButton("Suspend"));
        buttons.add(new JButton("Resume"));
        buttons.add(new JButton("Open"));
        buttons.add(new JButton("Exit"));
        frame.add(buttons, BorderLayout.SOUTH);

        frame.pack();                           // size to fit components
        frame.setVisible(true);                 // realize the window
    }
}

Trace the sizing: setDefaultCloseOperation(EXIT_ON_CLOSE) makes the X button end the program (the default merely *hides* the window). pack() walks the component tree, asks each component its preferred size, and sizes the frame to exactly fit — so the JTextArea(15, 40) (15 rows by 40 columns) drives the window height. setVisible(true) is what actually realizes and shows it; before that call nothing is on screen.

The JScrollPane(log) wrapper is the load-bearing detail: had we written frame.add(log, BorderLayout.CENTER) the text area would still display, but a long event log would overflow with no way to scroll.

NORMAL ~/memra/learn/comp-308/swing-components-containers utf-8 LF