Problems with Thread in Javafx

Asked

Viewed 59 times

0

I am creating an application to receive serial ports in computer use using the library jSerialCom.

For this, I would like to keep updating this information in a ComboBox. But I can’t implement the Thread correctly.

I used the Service and the Task. But to no avail.

Follows the code:

import com.fazecast.jSerialComm.SerialPort;

import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;


public class Main extends Application {
    private static ComboBox<String> cbPortas = new ComboBox<String>();

    @Override
    public void start(Stage primaryStage) {
        AnchorPane root = new AnchorPane();

        Label lblPort = new Label("Selecione a porta:");
        AnchorPane.setTopAnchor(lblPort, 10.0);
        AnchorPane.setRightAnchor(lblPort, 50.0);
        AnchorPane.setLeftAnchor(lblPort, 95.0);

        AnchorPane.setTopAnchor(cbPortas, 40.0);
        AnchorPane.setRightAnchor(cbPortas, 65.0);
        AnchorPane.setLeftAnchor(cbPortas, 65.0);

        Button btnConectar = new Button();
        btnConectar.setText("Conectar");
        AnchorPane.setTopAnchor(btnConectar, 100.0);
        AnchorPane.setRightAnchor(btnConectar, 50.0);
        AnchorPane.setLeftAnchor(btnConectar, 50.0);

        Button btnIniciar = new Button();
        btnIniciar.setText("Iniciar Controle");
        AnchorPane.setTopAnchor(btnIniciar, 150.0);
        AnchorPane.setRightAnchor(btnIniciar, 50.0);
        AnchorPane.setLeftAnchor(btnIniciar, 50.0);

        root.getChildren().addAll(lblPort,cbPortas,btnConectar,btnIniciar);     

        Scene scene = new Scene(root,320,220);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        Service<Void> service = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
                return new Task<Void>() {           
                    @Override
                    protected Void call() throws Exception {
                        //Background work                       
                        SerialPort[] portNames = SerialPort.getCommPorts();
                        for(SerialPort portName:portNames){
                            cbPortas.getItems().add(portName.getSystemPortName());
                        }

                        return null;
                    }
                };
            }
        };
        service.start();

        launch(args);

    }
}

How to proceed?

1 answer

0


I believe the problem is in changing the combobox items you are doing, let’s try to use a ObservableList.

Attributes:

private ObservableList<String> items;
private Service<Void> service;

Start method:

@Override
public void start(Stage primaryStage) {
    // [...] Código omitido
    items = FXCollections.observableArrayList();
    cbPortas = new ComboBox<String>(items);

    service = new Service<Void>() {
        @Override
        protected Task<Void> createTask() {
            return new Task<Void>() {           
                @Override
                protected Void call() throws Exception {
                    //Background work
                    items.clear();                       
                    SerialPort[] portNames = SerialPort.getCommPorts();

                    for(SerialPort portName:portNames){
                        items.add(portName.getSystemPortName());
                    }

                    return null;
                }
            };
        }
    };
    service.start();

    root.getChildren().addAll(lblPort,cbPortas,btnConectar,btnIniciar);     

    Scene scene = new Scene(root,320,220);
    primaryStage.setScene(scene);
    primaryStage.show();
}

The main method is only with the launch(args), it is maintained for compatibility reasons, everything stays in the start method. This service will also only run once, if your intention is to run periodically you can try the Scheduledservice.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.