Presentation model
Move the state of the screen out of the screen.
A presentation model is a class holding everything the screen needs to show, including state that belongs to the interface rather than to the domain: which button is enabled, what the validation message says, whether the panel is busy.
The view then does almost nothing. It reads properties and displays them; it forwards input and nothing else.
The problem it solves
Left alone, view state accumulates inside widgets:
if (nameField.getText().isEmpty() || ageField.getText().isEmpty()) {
saveButton.setEnabled(false);
}
The rule “you may save when both fields are filled” now lives inside a UI class. You cannot test it without constructing a window, and if a second screen needs the same rule it gets copied.
With a presentation model:
public class CustomerForm {
private String name = "";
private String age = "";
public boolean isSaveEnabled() {
return !name.isBlank() && !age.isBlank();
}
}
That is a plain object. It can be tested in a unit test with no display at all, which for form logic is where most of the bugs are.
Versus a domain model
The domain model is Customer — the data and rules that would exist whatever the interface. The presentation model is CustomerForm — what this particular screen is doing right now, including a half-typed age that is not yet a valid number.
Keeping them apart lets the domain model stay strict. The form can hold "4x" as a string while validation decides what to say about it; Customer never has to accept an invalid age.
Keeping them in step
Something must copy values between the presentation model and the widgets, in both directions. Frameworks with data binding do it declaratively. In plain Swing you write it: listeners push edits into the model, and a refresh method reads the model back into the components.
That synchronisation code is dull and it is the price of the pattern. What you get for it is that the interesting logic sits in a class you can test in milliseconds.
When it is overkill
For a dialog with two fields and a button, this is more structure than the problem deserves. It earns its keep when a screen has real conditional behaviour — fields that enable each other, validation that changes as you type, state worth preserving across a rebuild of the view.