JComboBox中项目的最佳方式

时间:2023-01-27 13:14:10

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);
}