数据结构,用于在GUI中存储复杂的选项关系

时间:2010-01-28 15:05:09

标签: user-interface data-structures

我一般不是GUI程序员,但幸运的是,我无法为项目构建GUI。虽然我的问题很普遍,但语言是java。

我的问题是:

我有一个带有许多启用/禁用选项的GUI,复选框。

当前选择的选项与允许选择的选项之间的关系相当复杂。它不能建模为简单的决策树。这是在决策树的下方选择的选项可以对树上的选项施加限制,并且不应要求用户从顶级选项“按下”工作。

我以一种非常糟糕的方式实现了它,但它有效,但有很多地方大致看起来像:

if (checkboxA.isEnabled() && checkboxB.isSelected()) 
{
   //enable/disable a bunch of checkboxs
   //select/unselect a bunch of checkboxs
}

这远非理想,指定的初始选项集非常简单,但是由于大多数项目似乎都有用,所以添加的附加选项和选项配置的定义不断增长到代码,虽然功能齐全,但是到目前为止,时间不能正确地修复它。

我完全期望在项目的下一阶段有更多选项/变更,并完全期望变更请求是一个流动的过程。我想重建这段代码,使其更易于维护,最重要的是,易于更改。

我可以在多维数组中对选项进行建模,但我很容易做出更改以及数组索引的非描述性质。

是否有一个GUI程序员会建议处理这种情况的数据结构?我认为这是一个在以前优雅地解决的问题。

感谢您的回复。

6 个答案:

答案 0 :(得分:1)

您在这里寻找的代码和理智的重要节省是声明性方法和 DRY (不要重复自己)。

[以下示例:假设同时启用所有3个复选框A,B和C是非法的。]

Bryan Batchelder完成了整理的第一步:为每个复选框的有效性写一条规则:

if(B.isSelected() && C.isSelected()) {
   A.forceOff();  // making methods up - disable & unselected
} else {
   A.enable();
}
// similar rules for B and C...

// similar code for other relationships...

并随时重新评估。这比在许多地方散布对A状态的更改要好(当B改变时,当C改变时)。

但是我们仍然有重复:A,B,C组合合法的单一概念规则被分解为3条规则,当你可以允许A,B和C的自由更改时。理想情况下你会写只有这个:

bool validate() {
    if(A.isSelected() && B.isSelected() && C.isSelected()) {
        return false;
    }
    // other relationships...
}

并自动从中扣除所有复选框启用/强制!

您可以从单个validate()规则执行此操作吗?我想你可以!您模拟可能的更改 - 如果A打开,validate()将返回true吗?关闭?如果两者都可以,请启用A;如果只有A的一个状态是可能的,则禁用它并强制其值;如果没有可能 - 目前的情况本身是非法的。对A =其他复选框重复上述模拟...

我内心的想法是要求对所有可能的变化组合进行模拟。想想“A不应该禁用B的情况,因为虽然非法目前正在使用C,但是B会强制C关闭,并且B是合法的”......问题在于,那条道路完全是疯狂和不可预测的UI行为。我相信只模拟一个小部件相对于当前状态的变化是正确的事情,但我现在懒得去证明它。所以采取这种方式有一种怀疑态度。


我还应该说,所有这些听起来充其量让用户感到困惑! Sevaral随机想法可能(?)引导您进行更多可用的GUI设计(或至少减轻痛苦):

  • 尽可能使用GUI结构!
    • 依赖于常见条件的小组小部件。
    • 尽可能在复选框和下拉选项上使用单选按钮 单选按钮可以单独禁用,这样可以获得更好的反馈。
    • 使用单选按钮拼合组合:而不是一次无法打开的复选框“A”和“B”,提供“A”/“B”/“none”单选按钮。
  • 列出GUI /工具提示中的兼容性限制!
    • 自动生成已禁用小部件的工具提示,解释哪些规则强制它们? 这个实际上很容易做到。
  • 考虑允许矛盾,但在状态区域列出违规规则,要求用户在按OK之前解决。
  • 实施撤消(& redo?),以便导致窗口小部件被禁用是非破坏性的?
    • 在禁用复选框时,请记住用户指定的复选框状态,在启用时还原? [但要注意在没有用户注意的情况下改变事物!]

答案 1 :(得分:0)

我不得不处理类似的GUI并遇到同样的问题。我从来没有找到一个好的数据结构,所以我会兴趣地看到这个问题的其他答案。当您处理几种不同类型的控件(组合框,列表视图,复选框,面板等)时,它会变得特别棘手。我发现有用的是为控件使用描述性名称,以便在查看每个控件的功能或用途时非常清楚。此外,组织代码以便将相互影响的控件组合在一起。在制作udpates时,不要仅仅修复函数底部的一些代码,这些代码会影响函数中早期处理的其他内容。花点时间把新代码放在正确的位置。

答案 2 :(得分:0)

通常对于像这样的非常复杂的逻辑问题,我会使用基于推理的规则引擎并简单地陈述我的规则并让它排序。

这通常比尝试编写迷宫更好,如果那么逻辑你有; 2.当业务规则发生变化时,稍后修改迷宫。

检查java的是:JBoss Drools

答案 3 :(得分:0)

我会想到它与验证规则通常如何工作类似。

创建规则(方法/函数/代码块/ lambda / whatever),描述要启用/禁用特定控件必须满足的条件。然后,当进行任何更改时,您执行每个方法,以便每个控件都可以响应更改的状态。

答案 4 :(得分:0)

我同意Bryan Batchelder的建议。我的初始响应将是一个很长的规则系统,每次复选框都会被触发。

  • 首先,当选中复选框时,它会根据自己的一组条件验证(并允许或不允许检查)。如果允许,则传播更改事件。
  • 其次,作为事件的结果,现在每个其他复选框都必须根据自己的规则重新验证自己,考虑到全局状态现已发生变化。

假设每个复选框将根据状态的变化执行操作(保持不变,切换我的检查状态,切换我的启用状态),我认为为每个复选框编写操作是合理的。复选框(如何将它们关联起来取决于你),这些值要么硬编码,要么我可能要做的是让它们从XML文件读入。

答案 5 :(得分:0)

为了澄清这一点,我最终做的是提供选项的组合。

对于我的应用程序,可用的开源规则引擎只是大量杀戮而且不值得臃肿,因为这个应用程序正在进行实时信号处理。我确实喜欢这个一般的想法。

我也不喜欢在不同地方使用验证码的想法,我想要一个位置进行更改。

所以我所做的就是构建一个简单的规则/验证系统。

输入是一个字符串数组,对我来说这是硬编码的,但如果你愿意,你可以从文件中读取它。

每个字符串都为所有复选框定义了有效配置。

在程序启动时,我构建了一个复选框配置列表,每个允许配置1个,用于存储每个复选框的选定状态和启用状态。这样,对UI进行的每次更改都只需要查找正确的配置。

通过将当前UI配置与其他允许的UI配置进行比较来计算配置,以确定应允许哪些选项。该代码非常类似于计算棋盘游戏中是否允许移动。