我有JComboBox
个项目很多。我在这个组合框中添加了一个项目监听器,用于存储所选项目:
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
option = (String) e.getItem();
}
});
我有一个按钮,当它被点击时,程序会根据该选择执行任务。
按钮:
public void actionPerformed(ActionEvent e) {
if (option.toLowerCase().compareTo("contrast stretching") == 0) { /* do sth */ }
else if (option.toLowerCase().compareTo("mean") == 0){ /* do sth else */ }
// And many other else if statements
actionPerformed功能太长了。编写代码的最佳方法是什么?我不想让单一功能太长。
答案 0 :(得分:2)
您可以创建表示需要执行的任务的界面(例如Task
)。然后为组合框中的每个值(ContrastTask
,MeanTask
,...)创建此接口的实现。最后,在actionPerformed
中,编写一个返回正确实现的工厂方法 - 它基本上是一个“switch”,返回正确的Task
实例。然后你可以运行这个任务......
Task
可能如下所示:
public interface Task {
[whatever result it should return] execute([whatever parameters it needs]);
}
实现可能如下所示:
public class MeanTask implements Task {
public int execute(int a, int b) {
return (a + b) / 2;
}
}
您的工厂将如下所示:
private Task create(String option) {
if (option.toLowerCase().compareTo("mean") == 0) {
return new MeanTask();
}
else if ....
}
这样做的好处是每个任务的逻辑都很好地封装在它自己的类中。
答案 1 :(得分:2)
这可以帮到你:
public class Main {
private Map<String, BaseStrategy> strategyMap = new HashMap<String, BaseStrategy>();
{
strategyMap.put("case1", new Strategy1());
strategyMap.put("case2", new Strategy2());
strategyMap.put("case3", new Strategy3());
}
//...
public void actionPerformed(ActionEvent e) {
strategyMap.get(option.toLowerCase()).processEvent();
}
abstract class BaseStrategy {
public abstract void processEvent();
}
class Strategy1 extends BaseStrategy {
@Override
public void processEvent() {
//case 1
}
}
class Strategy2 extends BaseStrategy {
@Override
public void processEvent() {
//case 2
}
}
class Strategy3 extends BaseStrategy {
@Override
public void processEvent() {
//case 3
}
}
}
您可以创建一个映射,其中键是一个定义命令的字符串,值是处理事件的策略。现在,您只需使用一行代码就可以将处理代码放到其他java文件和处理事件中。
实际上,如果你的案例太多 - Map
比if-else-if-...
更好,那么Map会更快地找到合适的策略 - O(ln n)而不是 O(n)的
答案 2 :(得分:0)
正如vektor和Eugene发布的那样,我会将两种解决方案结合起来:
public interface Task {
[whatever result it should return] execute([whatever parameters it needs]);
}
//call this method in your constructor
private void initTasks() {
this.tasks.put("option1", new Task() {
public int execute(int a, int b) {
return (a + b) / 2;
}
});
//init more tasks
//this.task.put(..., ...);
}
protected Task getTask(String option) {
return this.task(option);
}