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

Mar*_*arv 8 java user-interface swing

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

在此输入图像描述

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

public enum UIState {
    MAKING_SELECTION, SELECTING_AXIS_POINTS, SETTING_VALUES, SELECTING_GRAPH_POINTS
}
Run Code Online (Sandbox Code Playgroud)

控制器有一个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);
}
Run Code Online (Sandbox Code Playgroud)

我的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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Tim*_*m B 3

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

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

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

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