将方法添加到TupleList

时间:2016-11-29 12:26:07

标签: java list arraylist

我有一个包含两个条目的TupleList,我想添加第三个(比如对方法的引用),我的TupleList看起来像:

public class NodeList<T, I> {
    public T type;
    public I id;

    public NodeList (T type, I id){
        this.type = type;
        this.id = id;
    }

    public void setT(T type){
        this.type = type;
    }
    public void setI(I id){
        this.id = id;
    }
    public T getT() { 
        return type; 
    }
    public I getI() { 
        return id; 
    }
}

我内心有两个字符串:

public static List<NodeList<String,String>> nodeList = new ArrayList<NodeList<String,String>>();

每次我有一个特定的类型,我想调用一个相关的方法/引用我的方法。有关如何做到这一点的任何建议?我不想使用if或切换,因为我有一些方法。

我在ButtonClick事件上的父AnchorPane中创建自定义节点。所有节点在开头都有相同的布局,所有节点上都有一个按钮,我在创建时为每个节点添加一个唯一的ID(按钮是动态创建的)。

现在我想将我的类型链接到不同的方法,这些方法将在我点击Button时执行。为此,我想添加一个与我的类型相关的函数的引用。

编辑1:

例如为: 我的按钮被称为“RGB to Greyscale”,我的Node的String type是rgbgrey。当我点击按钮时,我创建一个节点(只有一个可拖动的AnchorPane,其上有一个Button,顶部带有我的类型的String)。我有一个Button事件,我想执行不同的方法,具体取决于我点击创建我的节点的按钮。因此,我创建了一个包含不同条目的List。创建节点后,我添加了一个唯一的String id并将String type名称设置为rgbgrey。现在,当我点击我的节点按钮时,我想调用方法rgbtogrey();

另一个Button被称为“旋转图像”,String type现在是rotimg。我的Node的布局完全相同。当我现在点击我的节点上的按钮时,我想在我的Button事件中执行一个不同的函数并调用方法rotateimg();

我在Node类中创建了这样的节点:

void addRotateNode(ActionEvent event){
    Node nde = new Node();

    id = nde.getId();
    type = new String("rotimg");
    nodeList.add(new NodeList<String, String>(type, id)); //add id and type to list
    nde.nodeLayout(); // This is where I set my Layout
    //...
}

现在我试试这个,但我想避免切换,因为我会添加更多功能。

@Override
public void handle(MouseEvent event) {
    for(int i = 0; i <= ViewController.nodeList.size(); i++){
        String func = ViewController.nodeList.get(i).getT();
            switch(func){
            case "rgbgray":
                //rgbtogrey();
                break;
            case "rotimg":
                //rotateimg();
                break;
        }   
    }
}});

我有一个自定义的EventHandler类:

public class ActionEventHandler implements EventHandler<ActionEvent> {

    private final EventHandler<ActionEvent> eventHandler;
    private final String name;

    public ActionEventHandler(String name, EventHandler<ActionEvent> eventHandler) {
        Objects.requireNonNull(name);
        Objects.requireNonNull(eventHandler);
        this.name = name;
        this.eventHandler = eventHandler;
    }

    @Override
    public String toString() {
        return name;
    }

    @Override
    public void handle(ActionEvent event) {
        eventHandler.handle(event);
    }

}

编辑2:

我将列表更改为:

public static List<NodeList<String,String, EventHandler<ActionEvent>>> nodeList = new ArrayList<NodeList<String,String, EventHandler<ActionEvent>>>();

我将节点创建修改为:

void addRotateNode(ActionEvent event){
    Node nde = new Node();

    id = nde.getId();
    type = new String("rotimg");
    EventHandler<ActionEvent> handler = new ActionEventHandler(type, this::rotimg);
    nodeList.add(new NodeList<String, String, EventHandler<ActionEvent>>(type, id, handler));
    nde.nodeLayout(); // This is where I set my Layout
    //...
}

1 个答案:

答案 0 :(得分:1)

根据我的理解,你应该使用Command pattern模式。由于我们无法传递方法的引用,如C(或其他),因此该模式是用于解决此问题的模式。

这基本上是一个接口

interface Command {
    void execute(); //Could take parameter, return something, your choice.
}

对于每个“函数”,我们将实现一个Command版本。从这个实例中,我们有一种可以调用方法的引用。

然后,您可以将此接口的任何实现存储到Collection中。

只是一个简单的例子:

List<Command> list = new ArrayList<>();
list.add(new ForwardCommand()); //An implementation of the interface
list.add(new RecordCommand());  //An other one
list.add(new ClearCommand());   //An other one

你只需要调用那些实例调用接口方法来执行函数。

Command c = list.get(0); //Get forwarCommand
c.execute(); //That will execute the functionnality of the instance selected

注意:这可以使用Reflexion完成,但我发现更清洁更易于维护。 (风险较小)