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 containers — JPanel 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 components — JButton, 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.