我一般不是GUI程序员,但幸运的是,我无法为项目构建GUI。虽然我的问题很普遍,但语言是java。
我的问题是:
我有一个带有许多启用/禁用选项的GUI,复选框。
当前选择的选项与允许选择的选项之间的关系相当复杂。它不能建模为简单的决策树。这是在决策树的下方选择的选项可以对树上的选项施加限制,并且不应要求用户从顶级选项“按下”工作。
我以一种非常糟糕的方式实现了它,但它有效,但有很多地方大致看起来像:
if (checkboxA.isEnabled() && checkboxB.isSelected())
{
//enable/disable a bunch of checkboxs
//select/unselect a bunch of checkboxs
}
这远非理想,指定的初始选项集非常简单,但是由于大多数项目似乎都有用,所以添加的附加选项和选项配置的定义不断增长到代码,虽然功能齐全,但是到目前为止,时间不能正确地修复它。
我完全期望在项目的下一阶段有更多选项/变更,并完全期望变更请求是一个流动的过程。我想重建这段代码,使其更易于维护,最重要的是,易于更改。
我可以在多维数组中对选项进行建模,但我很容易做出更改以及数组索引的非描述性质。
是否有一个GUI程序员会建议处理这种情况的数据结构?我认为这是一个在以前优雅地解决的问题。
感谢您的回复。
答案 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设计(或至少减轻痛苦):
答案 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配置进行比较来计算配置,以确定应允许哪些选项。该代码非常类似于计算棋盘游戏中是否允许移动。