The event driven model of a GUI breaks sequential logic code.
To keep the sequential logic, one could maintain a state, for instance an enum:
enum State {
PROMPTING,
ASKING_TWO_FIELDS,
ASKING_THREE_FIELDS,
CALCULATING,
DONE
};
private State state = State.DONE;
(This explicit abstraction is often only needed for transition from sequential logic, or multiple states on the same forms.)
Then on button press and such change the state and disable/enable input components.
Events happen asynchrone, even possibly on different threads. One must write reactive code. And on preparing things wire together what should happen on a button press. This is very fragmentary.
One solution to this chaos is separating into Model-View-Control classes. Model classes contain the data, View are the GUI components, and one Controller, the application, is called from the views, sets the data, and controls the views.
Being called from the views is for swing done using listeners.
A recipe:
- Make a main class being the Controller
- A Model class for data
- The top View, a GUI class, a JFrame (swing) or JavaFX scene
- The controller keeps model and view as fields
- The controller passes itself to the view
- Map your sequential logic to an enum State, in the controller
- Write transition function(s) switchState.
- Instead of waiting, add ActionListeners to a butten (swing) / ButtonHandlers (JavaFX) that call i.a. switchState.
- Best use method names expressing business logic:
startTranslating
(text dropped on application), manualTranslationDone
(button "translated" pressed after manual editing).