I'm looking to create a graph reader program that will take any scanned graph and convert it's values to a CSV with little effort. The following graph describes the basic control flow
I've got a prototype up and running that fulfills my basic requirements, but before proceeding with developement I want to know the best way to maintain GUI states and substates. Right now I'm using an enum:
public enum UIState {
MAKING_SELECTION, SELECTING_AXIS_POINTS, SETTING_VALUES, SELECTING_GRAPH_POINTS
}
The controller has one UIState
that can be set by buttons and mouse listeners by calling
public void setUiState(UIState uiState) {
switch (this.uiState = uiState) {
case MAKING_SELECTION:
frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
break;
case SELECTING_AXIS_POINTS:
clearSelection();
frame.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
break;
case SETTING_VALUES:
clearSelection();
break;
case SELECTING_GRAPH_POINTS:
frame.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
clearSelection();
break;
}
updateView(); //Repaints frame
setChanged();
notifyObservers(uiState);
}
My OptionsPanel, the panel that contains all buttons and input fields, observes the controller and calls a huge switch if it observes change:
@Override
public void update(Observable o, Object arg) {
if (arg instanceof UIState) {
switch ((UIState)arg) {
case MAKING_SELECTION:
//Set component statuses
break;
case SELECTING_AXIS_POINTS:
//Set component statuses
break;
case SETTING_VALUES:
//Set component statuses
break;
case SELECTING_GRAPH_POINTS:
//Set component statuses
break;
}
}
}
The setting of the components is done just by calling setEnabled()
on every single one of my buttons and text fields which becomes unclear already with a small amount of components. My mouse listeners also have similar switches in addition to the isLeftMouseButton()
and isRightMouseButton()
queries which make the whole thing really confusing.
My implementation doesn't even include substates and even though I've kinda got it working right now, there already is inconsistency with the setting of the cursor.
So my question is: Is there a better solution to maintaining those GUI states and substates and set the UI components status based on user input, especially one that allows for more consistency easier?
The best way to handle this is to use the State design pattern:
http://en.wikipedia.org/wiki/State_pattern
You have general purpose input listeners which delegate task execution to your concrete States. Then whichever is the current concrete state handles the input in its own unique way. There are plenty of variations on how to apply the concept. The key idea though is that when the application state changes, a different State object becomes the "current State" and is responsible for handling the input.
For example: in a mouseMove()
event handler call currentState.mouseMove(evt)
and let the current state object handle the mouseMove
with no need for switch statements at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With