Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a class based on the selected item in a listview in javafx

Tags:

I have a ListView and every time the selection is changed, I want to call a class with that name. For example, if the item is called "Text String" then the class TextString should be called. The code that I currently have is giving me an error saying The method insert(ArrayList<Element>) is undefined for the type Object ... Eclipse gives me a suggestion to cast the object as Element, but that doesn't do anything. The Element class is a superclass and TextString would implement that class.

Here is the code I have so far:

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

}

How can I cast the object to whatever object is being selected by the listview?

like image 905
ShoeLace1291 Avatar asked Nov 06 '17 11:11

ShoeLace1291


1 Answers

  1. You should use explicit casting.
  2. Use clazz.getMethod(...) instead of clazz.getClass().getMethod(...)
  3. Watchout objects to be ArrayList instance, not List.

Your code should like next:

 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) {

Tip. I'd suggest changing the type of ArrayList parameter in insert method to List. And also to catch only one generic Exception, instead of bunch of specific one.

Let me know if you any further issues with that.

like image 88
Taras Velykyy Avatar answered Sep 20 '22 13:09

Taras Velykyy