Show how a Mediator coordinates Swing components, and explain what each colleague is responsible for.
answer
- Dialog = mediator, widgets = colleagues
- Listeners stay thin: just notify the mediator
- Mediator holds the enable/show/clear rules
- Widgets expose setters, know nothing of peers
- Big forms -> god dialog -> split into sub-panels
basics
~20 sA dialog acts as the mediator and holds its buttons, text fields, and checkboxes. Each component, on change, just tells the dialog. The dialog contains the rules (like enabling a button) and updates the other components. Components never reference each other.
solid answer
~50 sIn Swing, a Mediator is usually the dialog/form class (or a dedicated controller) that owns the child components. Each component registers a listener whose action just calls back into the mediator, e.g. mediator.componentChanged(this). The mediator holds references to all components and contains the coordination rules: enable the Submit button only when the name field is non-empty, reveal a panel when a checkbox is ticked, clear a field when another changes, and so on. The colleagues stay dumb: a JTextField only knows how to be a text field and to report changes; it has no knowledge of the JButton it affects. This keeps the components reusable and puts all the cross-component logic in one readable place. The cost is that the dialog/mediator can accumulate a lot of conditional logic and drift toward a god object as the form grows, so large forms are often split into sub-mediators or sub-panels.
code
java · 38 lines// Mediator: the dialog owns the widgets and holds all coordination rules.
class LoginDialog {
private final JTextField username = new JTextField();
private final JPasswordField password = new JPasswordField();
private final JButton loginButton = new JButton("Log in");
private final JCheckBox remember = new JCheckBox("Remember me");
private final JTextField deviceName = new JTextField();
LoginDialog() {
// Thin listeners: they only notify the mediator, never touch peers.
username.getDocument().addDocumentListener(onChange(this::recalculate));
password.getDocument().addDocumentListener(onChange(this::recalculate));
remember.addActionListener(e -> rememberToggled());
recalculate();
rememberToggled();
}
// Rule: button enabled only when both fields are non-empty.
private void recalculate() {
boolean ready = !username.getText().isBlank()
&& password.getPassword().length > 0;
loginButton.setEnabled(ready); // mediator drives the colleague
}
// Rule: extra field appears only when 'remember me' is checked.
private void rememberToggled() {
deviceName.setVisible(remember.isSelected());
}
private DocumentListener onChange(Runnable r) {
return new DocumentListener() {
public void insertUpdate(DocumentEvent e) { r.run(); }
public void removeUpdate(DocumentEvent e) { r.run(); }
public void changedUpdate(DocumentEvent e) { r.run(); }
};
}
}
// username never references loginButton; the dialog (mediator) connects them.go deeper
Knows the dialog can hold the widgets and that components notify the dialog rather than each other.
Can sketch the wiring: thin listeners forwarding to the mediator, mediator holding rules and driving widgets via setters; names colleague vs mediator responsibilities.
Distinguishes the Observer listener mechanism from the Mediator coordination role, and explains how to keep the mediator from becoming a god object (sub-panels, presenters).
Relates this to UI architecture choices (MVC/MVP/MVVM), sets conventions for where coordination logic lives, and weighs maintainability/testability across a large UI codebase.
## Why Swing is the textbook example **Swing** is Java's older desktop GUI toolkit. A window is built from components like `JButton`, `JTextField`, `JCheckBox`, `JList`. These widgets constantly need to influence each other: a Save button should be greyed out until a form is valid; ticking a checkbox should reveal extra fields. If each widget reached into the others, you'd get the tangled web the Mediator pattern targets — so a coordinating object (the dialog/form, or a separate controller) plays the **mediator**, and the widgets are the **colleagues**. ## The moving parts (defining the terms) - **Component / widget**: a UI element such as `JButton`. - **Listener**: an object you register with a component that gets called when an event happens (a click, a keystroke). In Swing this is the **Observer** pattern under the hood. For Mediator, the key idea is that the listener body should be *thin*: it should just forward the event to the mediator rather than implementing cross-component logic itself. - **Mediator**: here, the dialog/form class. It holds references to all the widgets and contains the coordination rules. - **Colleague**: each widget. It reports events to the mediator and exposes simple setters (`setEnabled`, `setVisible`, `setText`) the mediator calls. ## The flow, step by step 1. The mediator (dialog) creates the widgets and keeps fields referencing them. 2. For each widget, it attaches a listener whose body simply calls a mediator method such as `notify(source)` or a specific `nameChanged()`. 3. When the user types or clicks, the listener fires and forwards to the mediator. 4. The mediator runs its rules and pushes results to the affected widgets via their setters. The widgets never reference each other — only the mediator does. That is the whole point. ## What each role is responsible for - **Colleague (widget) responsibilities**: render itself, capture raw user events, and *report* them. It should know nothing about which other widgets exist or what should happen as a consequence. It exposes small operations (enable, show, set value) for the mediator to drive. - **Mediator (dialog) responsibilities**: own the widgets, hold *all* inter-widget rules, and translate one widget's event into updates on the others. It is the single source of truth for "when X happens, Y and Z react." ## Why this is good - **Reuse**: the same `JTextField` subclass works in any form; the form-specific behavior lives in the mediator, not the field. - **Locality**: to understand or change the form's behavior, you read one class. - **Testability**: you can test the coordination rules by driving mediator methods, without simulating clicks across many widgets. ## Trade-off and the god-object slide The danger is concrete here: a real dialog with 20 fields and many rules turns the mediator into a sprawling class full of `if`/`else` updating widgets — a **god object**. Symptoms: the dialog class is hundreds of lines, every new field touches it, and the coordination logic is hard to follow. Mitigations: split the screen into sub-panels each with its own small mediator; extract rule clusters into helper objects; or move to an MVC/MVVM/presenter structure where a presenter plays a leaner mediator role. ## Note: Mediator vs the listeners themselves Swing's listener mechanism *is* Observer, not Mediator. The Mediator pattern appears when you deliberately route those listener callbacks into one coordinating object instead of letting listeners manipulate other components directly. So the same code can use Observer (for event delivery) and Mediator (for coordination) together.
- Isn't Swing's listener system already the Mediator pattern?No — the listener/event mechanism is Observer (a subject notifies registered listeners). Mediator appears when you choose to route those callbacks into one coordinating object that holds the cross-component logic, instead of letting each listener manipulate other components directly. They are commonly used together.
- Where should the coordination logic live so the dialog doesn't become a god object?Keep listeners thin and the mediator focused on one cohesive cluster. As a form grows, split it into sub-panels each with its own small mediator, extract rule clusters into helper objects, or adopt an MVC/MVP/MVVM presenter that plays a leaner mediator role.
saying these in an interview costs you the question
- Putting cross-component logic inside each widget's listener (defeats the pattern).
- Letting one widget hold a reference to another widget and call it directly.
- Claiming Swing listeners ARE Mediator (they are Observer; Mediator is how you route them).
- Treating an ever-growing dialog class as acceptable rather than a god-object smell.