Ali Ahmed
Ali Ahmed

Reputation: 183

Javafx UI not responding after it runs Task

I am working on a javafx application. Since I need to display some data from my database, I came to know about using Task in Javafx. I tried implementing it after seeing a solution on SO. To check if it works, I am just printing a list of teams which I get from my database in a HashTable.

When I first start the application, the data is successfully fetched and it displays on my console, but when I change through scenes and try to switch back to the homepage (where the data is being fetched), the UI totally freezes and it doesn't even display the scene.

Home.java

public class Home implements Initializable {

    private Executor executor;
    private TeamsDAO teamsDAO;

@Override
    public void initialize(URL url, ResourceBundle resourceBundle)  {

        try{
            teamsDAO = new TeamsDAO();
        }catch (SQLException e){
            e.printStackTrace();}

        executor = Executors.newCachedThreadPool(runnable -> {
            Thread th = new Thread(runnable);
            th.setDaemon(true);
            return th;
        });

        printTeams();
    }

public void printTeams() {
        Task<Hashtable<Integer, String>> displayTask = new Task<Hashtable<Integer, String>>() {
            @Override
            protected Hashtable<Integer, String> call() throws Exception {
                return teamsDAO.getTeams();
            }
        };

        displayTask.setOnFailed(e -> {
            displayTask.getException().printStackTrace();
        });

        displayTask.setOnSucceeded(e -> {
            cricProTitle.setText(displayTask.getValue().get(2));
        });

        executor.execute(displayTask);
    }
}

I am using HikariCP for database connection pool with postgresql.

TeamsDAO.java

public class TeamsDAO {

    private Connection conn;

    public TeamsDAO() throws SQLException {
        this.conn = DataSource.getConnection();
    }

    public Hashtable<Integer, String> getTeams() throws SQLException {
        try (PreparedStatement pst = conn.prepareStatement("SELECT * FROM TEAMS")) {
            ResultSet rs = pst.executeQuery();
            Hashtable<Integer, String> teams = new Hashtable<>();
            while (rs.next()) {
                teams.put(rs.getInt("team_id"), rs.getString("name"));
            }
            return teams;
        }
    }
}

No error stack trace is displayed when the UI freezes. I would like these teams to be displayed on the homepage (after the thread works successfully) . Please suggest where am I going wrong?

Upvotes: 0

Views: 330

Answers (1)

Ali Ahmed
Ali Ahmed

Reputation: 183

As I was initiating the TeamsDAO object in initialize method, It was creating a new database connection every time I switched back to Home controller, and hence filling up the connection pool. To fix this I created a static block in Home.java and fetched the data I needed only once.

Updated Home.java:

public class Home implements Initializable {

    private static TeamsDAO teamsDAO;

    @FXML
    private BorderPane borderPane;
    @FXML
    private Label cricProTitle;
    @FXML
    private Label homepageLabel;
    @FXML
    private Label banner;
    @FXML
    private GridPane buttonContainer;

    static {
        try {
            teamsDAO = new TeamsDAO();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        Task<Hashtable<Integer, String>> task = new Task<>() {
            @Override
            protected Hashtable<Integer, String> call() throws Exception {
                return teamsDAO.getTeams();
            }
        };

        task.setOnSucceeded(e -> {
            System.out.println(task.getValue());
        });

        Thread x = new Thread(task);
        x.setDaemon(true);
        x.start();
        System.out.println(x.getState());
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle)  {
    //setting UI properties here..
    }

}

Upvotes: 1

Related Questions