0

I am currently using a static database class embedded within the application class and it works just fine. However, when I return the ObservableList<String> back from the function and try to set it to the ListView it throws Caused by: java.lang.reflect.InvocationTargetException. I know this is a threading issue and I just cannot figure out how to pass values back from application thread to the UI thread in this case. I am new to JavaFX.

Controller Class:

public class SampleController implements Initializable {

    @FXML
    public ListView<String> lvGroup;

    @FXML
    private void OpenDbClick(ActionEvent event){
        System.out.println("open db");
        ObservableList<String> ol;
        ol = WeddingGuestList.DatabaseConn.getGroups();
        lvGroup.setItems(ol);   <-error occurs here
    }
}

Database method:

public static ObservableList<String> getGroups(){
    ObservableList<String> groups = FXCollections.observableArrayList();

    try{
       Statement stmt = con.createStatement();
       stmt.setQueryTimeout(30);
       ResultSet rs = stmt.executeQuery("Select * from GuestGroup");
       while (rs.next()){
           groups.add(rs.getString("Name"));
       }

    }catch (SQLException e){
        e.printStackTrace();
    }catch (Exception e){
        e.printStackTrace();
    }
    return groups;
}

I do not understand how I am supposed to get the data back into the ListView.

EDIT:

StackTrace:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1440)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
    at javafx.event.Event.fireEvent(Event.java:171)
    at javafx.scene.Node.fireEvent(Node.java:6863)
    at javafx.scene.control.Button.fire(Button.java:179)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:193)
    at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:336)
    at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:329)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:64)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
    at javafx.event.Event.fireEvent(Event.java:171)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3328)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3168)
    at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3123)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1563)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2265)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:250)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:173)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:292)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:528)
    at com.sun.glass.ui.View.notifyMouse(View.java:922)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:82)
    at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:75)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:279)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1435)
    ... 51 more
Caused by: java.lang.NullPointerException
    at testguesslist.SampleController.OpenDbClick(SampleController.java:56)
    ... 61 more
ObieMD5
  • 2,684
  • 1
  • 16
  • 26
  • post a full stacktrace – GerritCap Sep 09 '13 at 07:16
  • See related question: [JavaFX - Background Thread for SQL Query](http://stackoverflow.com/questions/14878788/javafx-background-thread-for-sql-query), which contains answers which perform an SQL query off the JavaFX application thread and populate a `ListView` (backed by an `ObservableList`) on the JavaFX application thread. – jewelsea Sep 10 '13 at 17:44

2 Answers2

2

I do not think this is what is causing the above exception but:

Ideally, you should do your database call in a separate thread because it might take time, and you do not want to block the JavaFX thread.
The way to do this is to put the code being done in the OpenDbClick method inside a javafx.concurrent.Task (check http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm ).

`
public class SampleController {

    public ListView<String> lvGroup;
    private ExecutorService threadPool;



    private void OpenDbClick(ActionEvent event) {
        Task<Void> task = new Task<Void>() {

            @Override
            protected Void call() throws Exception {
                System.out.println("open db");
                final ObservableList<String> ol = WeddingGuestList.DatabaseConn.getGroups();
                Platform.runLater(new Runnable() {

                    @Override
                    public void run() {
                        lvGroup.setItems(ol);
                    }
                }); 
                return null;
            }
        };
        getPool().execute(task); 
    }

    private ExecutorService getPool() {
        if (threadPool == null) {
            threadPool = Executors.newCachedThreadPool();
        }
        return threadPool;
    }
}

`

The Plaftorm.runLater will force the execution of its code on the JavaFX thread not on the task thread. This is important, because setting the list of items of the listview will cause an update to the scene graph, which should be done on the UI thread. If you do not use the Platform.runLater code, the above will result in an exception.

Rasha
  • 565
  • 3
  • 7
0

The stack trace indicate issue here .. at testguesslist.SampleController.OpenDbClick(SampleController.java:56)

It looks like that one of the object is null here. Please check that. Laternatively please send line 55, 56 and 57 code of this method to review.

Gyanendra Dwivedi
  • 5,511
  • 2
  • 27
  • 53