簡體   English   中英

根據javafx中listview中的選定項調用類

[英]Calling a class based on the selected item in a listview in javafx

我有一個ListView,每次更改選擇時,我想調用具有該名稱的類。 例如,如果該項稱為“文本字符串”,則應調用類TextString。 我目前擁有的代碼給出了一個錯誤,說明The method insert(ArrayList<Element>) is undefined for the type Object ... Eclipse給了我一個建議將對象強制轉換為Element,但這沒有做任何事情。 Element類是一個超類,TextString將實現該類。

這是我到目前為止的代碼:

   elementList.itemsProperty().bind(listProperty);
        listProperty.set(FXCollections.observableArrayList(elementListItems));
        elementList.setOnMouseClicked(new EventHandler<MouseEvent>() {

            public String selectedElement = "Text String";
            @Override
            public void handle(MouseEvent event) {
                selectedElement  = (String)elementList.getSelectionModel().getSelectedItem();
                selectedElement = selectedElement.replace(" ", "");
                Class<?> clazz;
                try {
                    clazz = Class.forName("elements."+selectedElement);
                    Constructor<?> ctor = clazz.getConstructor();
                    Object object = ctor.newInstance();
                    Method meth = clazz.getClass().getMethod("insert", new Class<?>[] { Canvas.class, ArrayList.class, GraphicsContext.class });
                    meth.invoke(object, canvas, objects, gc);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        });

Element.java

   public abstract class Element {
    public String name;
    public String description;
    public Canvas canvas;
    public ArrayList<Element> objects;
    public GraphicsContext gc;

    void remove(){

    }
    void toggle(){

    }
    void setBounds(int x, int y, int w, int h){

    }
    public abstract void insert(Canvas canvas, ArrayList<Element> objects, GraphicsContext gc);
}

TextString.java

   public class TextString extends Element {
    private GraphicsContext gc;

    TextString() {
        super();
        this.name = "Text String";
        this.description = "A literal readable string of text.";
    }
    @Override
    public void insert(Canvas canvas, ArrayList<Element> objects, GraphicsContext gc) {
        this.gc = gc;
        this.canvas = canvas;
        this.objects = objects;
        System.out.println("Text string created.");
    }

}

如何將對象轉換為listview選擇的任何對象?

  1. 你應該使用顯式鑄造。
  2. 使用clazz.getMethod(...)代替clazz.getClass().getMethod(...)
  3. Watchout objectsArrayList實例,而不是List

你的代碼應該是下一個:

 try {
                    clazz = Class.forName("elements."+selectedElement);
                    Constructor<?> ctor = clazz.getConstructor();
                    Element object = (Element) ctor.newInstance();
                    Method meth = clazz.getMethod("insert", new Class<?>[] { Canvas.class, ArrayList.class, GraphicsContext.class });
                    meth.invoke(object, canvas, objects, gc);
} catch (ClassNotFoundException e) {

提示 我建議將insert方法中的ArrayList參數類型更改為List。 並且還只捕獲一個通用的異常,而不是一堆特定的異常。

如果您有任何進一步的問題,請告訴我。

我相信你通過嘗試使用反射來使一切變得復雜。 這是最佳的,但有時我通常只是做事更簡單。

為什么不制作一個工廠幫助程序來導入您可能需要的所有類,然后使用開關返回您需要的實例?

喜歡:

public MyInterface returnClass(String type){

   switch (type){

   case: "Text String":
   return new TextString():

//And so on

}

}

還有另一種方法可以處理這個問題,使用HashMap存儲所有實現,如下所示(這可以在應用程序啟動時完成,性能會更好)。

Map<String, Element> objects = new HashMap<>();
objects.put("Text String", new TextString());

並且句柄方法變成..

@Override
public void handle(MouseEvent event) {
    selectedElement = (String) elementList.getSelectionModel().getSelectedItem();
//      selectedElement = selectedElement.replace(" ", "");

    objects.get(selectedElement).insert(Canvas.class, ArrayList.class, GraphicsContext.class);

}

由於我們沒有使用Reflection,因此這將更具可讀性和清晰度

你需要做的就是擁有一個帶有方法執行的接口MyElement,它將在“execute()”中調用你需要的任何東西

基本上我建議使用命令模式,這是執行BE時所有UI操作的基礎

我的2美分,來自我以前的舊項目的實施示例

    CommandFactory factory = CommandFactory.getInstance();
    Command command = factory.createCommand(relativeURL);
    if(command != null){
        command.execute( /* Object */ input);
    }
}

進工廠

/**
 * Factory for commands
 * 
 * @author andre
 */
public class CommandFactory {
// singleton instance
protected static CommandFactory instance = new CommandFactory();

//cache of objects
Map<String, Command> cache = new HashMap<>();

// protected constructor prevents creating object outside
protected CommandFactory(){    
}

// return signleton instance of factory
public static CommandFactory getInstance(){
    return instance;
}

/**
 * create and return appropriate command
 * 
 * @return found command
 * @throws exception if something bad happened
 */
public Command createCommand(String classname){
    try {
        Command com = cache.get(URL);
        if(com == null){
            Command temp = (Command) Class.forName(classname).newInstance();
            if(temp != null){
                cache.put(URL, temp);
                com = cache.get(URL);
            }
        }
        return com;
    } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
        Logger.getLogger(getClass().getName()).error(ex);
        return new Error404();
    }
}


}

進入界面

public interface Command{

void execute(Object input);
}

和實現示例

public class EditUserInfo implements Command {

@Override
public void execute(Object object) {
     callWhatever((String) object);
    }

private void callWhatever(String textFromField){
// inner logic example
}



}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM