I have a JComboBox
with many items. I added an item listener to this combo box which stores the selected item:
我有一个包含许多项目的JComboBox。我在这个存储所选项目的组合框中添加了一个项目监听器:
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
option = (String) e.getItem();
}
});
I have a button and when it is clicked, the program carries out the task on the basis of that selection.
我有一个按钮,当它被点击时,程序根据该选择执行任务。
Button:
按钮:
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
The actionPerformed function is way too long. What is the best way to write the code? I don't want to make single function too long.
actionPerformed函数太长了。编写代码的最佳方法是什么?我不想让单一功能太长。
3 个解决方案
#1
2
You can create an interface (e.g. Task
) representing the task that needs to be executed. Then create an implementation of this interface for each of the values in the combo box (ContrastTask
, MeanTask
, ...). Finally, in your actionPerformed
, write a factory method returning the correct implementation - it will be basically a "switch" returning the correct instance of Task
. Then you can just run this task...
您可以创建表示需要执行的任务的接口(例如,任务)。然后为组合框中的每个值创建此接口的实现(ContrastTask,MeanTask,...)。最后,在actionPerformed中,编写一个返回正确实现的工厂方法 - 它基本上是一个“switch”,返回正确的Task实例。然后你可以运行这个任务......
Task
might look like this:
任务可能如下所示:
public interface Task {
[whatever result it should return] execute([whatever parameters it needs]);
}
On of the implementations might look like this:
在实现可能看起来像这样:
public class MeanTask implements Task {
public int execute(int a, int b) {
return (a + b) / 2;
}
}
Your factory will look like this:
你的工厂看起来像这样:
private Task create(String option) {
if (option.toLowerCase().compareTo("mean") == 0) {
return new MeanTask();
}
else if ....
}
The advantage of this is that the logic of each task is nicely encapsulated in its own class.
这样做的好处是每个任务的逻辑都很好地封装在它自己的类中。
#2
2
This can help you:
这可以帮助您:
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
}
}
}
You can make a map where the key is a string that defines your command and the value is a strategy that processes your event. Now you can place your processing code even to other java files and process event with only 1 line of code.
您可以创建一个映射,其中键是一个定义命令的字符串,值是一个处理事件的策略。现在,只需1行代码,您就可以将处理代码放到其他java文件和处理事件中。
Actually if you have too many cases - Map
is a way better than if-else-if-...
Map will find a proper strategy a way faster - O(ln n) instead of O(n).
实际上如果你有太多的情况 - 地图比if-else-if -..更好。地图会找到一个更快的正确策略 - O(ln n)而不是O(n)。
#3
0
As vektor and Eugene posted I would combine both solutions to something like this:
正如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);
}
#1
2
You can create an interface (e.g. Task
) representing the task that needs to be executed. Then create an implementation of this interface for each of the values in the combo box (ContrastTask
, MeanTask
, ...). Finally, in your actionPerformed
, write a factory method returning the correct implementation - it will be basically a "switch" returning the correct instance of Task
. Then you can just run this task...
您可以创建表示需要执行的任务的接口(例如,任务)。然后为组合框中的每个值创建此接口的实现(ContrastTask,MeanTask,...)。最后,在actionPerformed中,编写一个返回正确实现的工厂方法 - 它基本上是一个“switch”,返回正确的Task实例。然后你可以运行这个任务......
Task
might look like this:
任务可能如下所示:
public interface Task {
[whatever result it should return] execute([whatever parameters it needs]);
}
On of the implementations might look like this:
在实现可能看起来像这样:
public class MeanTask implements Task {
public int execute(int a, int b) {
return (a + b) / 2;
}
}
Your factory will look like this:
你的工厂看起来像这样:
private Task create(String option) {
if (option.toLowerCase().compareTo("mean") == 0) {
return new MeanTask();
}
else if ....
}
The advantage of this is that the logic of each task is nicely encapsulated in its own class.
这样做的好处是每个任务的逻辑都很好地封装在它自己的类中。
#2
2
This can help you:
这可以帮助您:
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
}
}
}
You can make a map where the key is a string that defines your command and the value is a strategy that processes your event. Now you can place your processing code even to other java files and process event with only 1 line of code.
您可以创建一个映射,其中键是一个定义命令的字符串,值是一个处理事件的策略。现在,只需1行代码,您就可以将处理代码放到其他java文件和处理事件中。
Actually if you have too many cases - Map
is a way better than if-else-if-...
Map will find a proper strategy a way faster - O(ln n) instead of O(n).
实际上如果你有太多的情况 - 地图比if-else-if -..更好。地图会找到一个更快的正确策略 - O(ln n)而不是O(n)。
#3
0
As vektor and Eugene posted I would combine both solutions to something like this:
正如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);
}