维护和控制GUI状态和子状态

时间:2014-12-17 00:32:06

标签: java swing user-interface

我正在寻找创建一个图形阅读器程序,它将采用任何扫描图形并轻松地将其值转换为CSV。下图描述了基本控制流程

enter image description here

我有一个原型启动并运行满足我的基本要求,但在继续开发之前,我想知道维护GUI状态和子状态的最佳方法。现在我正在使用枚举:

public enum UIState {
    MAKING_SELECTION, SELECTING_AXIS_POINTS, SETTING_VALUES, SELECTING_GRAPH_POINTS
}

控制器有一个UIState,可以通过调用

按钮和鼠标监听器来设置
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);
}

我的OptionsPanel,包含所有按钮和输入字段的面板,观察控制器并在它观察到变化时调用一个巨大的开关:

@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;
        }
    }
}

只需在我的每个按钮和文本字段上调用setEnabled()即可完成组件的设置,而这些按钮和文本字段已经用少量组件变得不清楚。除了isLeftMouseButton()isRightMouseButton()查询之外,我的鼠标监听器也有类似的开关,这使得整个事情真的很混乱。

我的实现甚至没有包含子状态,即使我现在有点工作,但是已经存在与光标设置的不一致。

所以我的问题是:是否有更好的解决方案来维护这些GUI状态和子状态,并根据用户输入设置UI组件状态,尤其是允许更加一致的更简单的方法?

1 个答案:

答案 0 :(得分:3)

处理此问题的最佳方法是使用状态设计模式:

http://en.wikipedia.org/wiki/State_pattern

您有通用输入侦听器,它将任务执行委派给您的具体状态。然后,当前的具体状态以其自己独特的方式处理输入。如何应用这个概念有很多变化。但关键的想法是,当应用程序状态发生变化时,不同的State对象将成为“当前状态”并负责处理输入。

例如:在mouseMove()事件处理程序中调用currentState.mouseMove(evt)并让当前状态对象处理mouseMove,而根本不需要switch语句。