我有一个包含两个条目的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
//...
}
答案 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
完成,但我发现更清洁更易于维护。 (风险较小)