Javafx, organising threads

I'm programming in javafx java 1.7, and i need help with a thread problem. All i need is for my program to write out "Pinging", while it gets the IP of the device and pings it. The problem is, that if i put both in a thread than only the first executes. If I only put one of them in a thread, than the one not in the thread executes. Any idea on how to run the first thread than do the second? Or any other way to geth the "Pinging" text to the Ping Label written out, while the program gets the ip and pings it?

@FXML
    private void ciscoButton(ActionEvent event) throws IOException {
        CiscoPing.setWrapText(true);
        Task<Void> task1 = new Task<Void>() {
            @Override public Void call() throws IOException {
        String text1;
        text1 = "Pinging";
        Ping.setWrapText(true);
                Ping.setText(text1);
                return null;

    }
};
new Thread(task1).start();

        Task<Void> task = new Task<Void>() {
            @Override public Void call() throws IOException {
                String text2 = PingIp.PingEtherAddr(GetIp.retIpEther()).toString();
                text2 = text2.substring(1, (text2.length() - 1));
                Ping.setWrapText(true);
                Ping.setText(text2);
                return null;
            }
        };
        new Thread(task).start();
    }

Thank you for your time :) PS: yes this is the first time i tried using threads and I have been trying for 3-4 days now...

Upvotes: 0

Views: 99

Answers (2)

James_D
James_D

Reputation: 209704

This is all well covered elsewhere on SO, but... The two most important things to know about threading in a JavaFX application are:

  1. Any long-running code should be performed off the FX Application Thread
  2. Any changes to the UI must be performed on the FX Application Thread

The Task class is an implementation of Runnable (so it can be passed to Threads) that provides various hooks for updating the UI on the FX Application thread. The Javadocs have copious clear examples.

In your particular case, the first Task is redundant. The only thing it does is update the UI (so it must not be performed in a background thread), and there is no code in there that takes a long time to execute. So this should be performed directly in the FX Application Thread.

The second Task performs a long-running call to find a String, and that String is used to update the UI. So this should be declared as a Task<String> whose call method returns the String. An onSucceeded handler can be used to update the UI when the call is complete:

@FXML
private void ciscoButton(ActionEvent event) throws IOException {
    CiscoPing.setWrapText(true);
    String text1;
    text1 = "Pinging";
    Ping.setWrapText(true);
    Ping.setText(text1);

    final Task<String> task = new Task<String>() {
        @Override 
        public String call() throws IOException {
            String text2 = PingIp.PingEtherAddr(GetIp.retIpEther()).toString();
            return text2.substring(1, (text2.length() - 1));
        }
    };

    task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle(WorkerStateEvent event) {
            Ping.setWrapText(true);
            String text = task.getValue(); // value returned from call()
            Ping.setText(text);
        }
    });
    new Thread(task).start();
}

Upvotes: 1

I finally found a solution, which does solve what i want, but it won't make it a multi thread code.

@FXML
private void Button(ActionEvent event) throws IOException {
    Ping.setWrapText(true);
    Task<Void> task2 = new Task<Void>() {
        @Override
        public Void call() throws IOException {
            updateMessage("Pinging");
            PingIp.PingIp(GetIp.retIp()).toString();
            text2 = text2.substring(1, (text2.length() - 1));
            updateMessage(text2);
            return null;
        }
    };

    Ping.textProperty().bind(task2.messageProperty());
    new Thread(task2).start();
}

Thanks for the help, though ^^ The Libk that was posted as a "possible duplicate" gave me the idea to experiment with this.

Upvotes: 1

Related Questions