JavaFX Process indicator

0

Witam!

Ćwicząc wątki w JavieFX natknąłem się na problem z którym nie potrafię sobie poradzić. Stąd mój post i prośba o sugestię. Aplikacja posiada standardowy ekran logowania. Po wpisaniu przez usera danych łączy się z bazą pobiera dane i w zależności wykonuje następne czynności. Proces łączenia nie jest może czasochłonny ale w ramach ćwiczeń chciałem go udoskonalić wyświetlając w czasie oczekiwania na rezultat process indicator.

Przerzuciłem więc logowanie do podrzędnego wątku, który łączy się sqlem i aktualizuje scene dodając do niej process indikatora. I tu pojawia się problem ponieważ process indicator pojawia się już po zalogowaniu:

LoginController

private void Zaloguj() throws IOException {
		String cryptUser = null, cryptPass = null;
		
		cryptUser = Encrypt.encrypt(loginBox.getText());
		cryptPass = Encrypt.encrypt(passBox.getText());
			
		WaitFor newWait = new WaitFor(mainController, cryptUser, cryptPass);
		newWait.start();
}

Wątek obsługujący logowanie:

public class WaitFor extends Service<Void>{
	
	private MainController mainController;
	String cryptUser = null, cryptPass = null;
	public Byte LoginResult;

	public WaitFor(MainController mainController, String cryptUser, String cryptPass) {
		this.mainController = mainController;
		this.cryptUser = cryptUser;
		this.cryptPass = cryptPass;
	}
	protected Task<Void> createTask() {
        return new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                ProgressIndicator p = new ProgressIndicator();
                LoginSQL sql = new LoginSQL();
                
                	   	 Platform.runLater(new Runnable() {
                	         @Override public void run() {
                	        	 mainController.MainStackPane.getChildren().addAll(p);
                	        	 LoginResult = sql.SQLselect(cryptUser, cryptPass);
                	     }});
       return null;
     };};}}	

I może jeszcze SQL gdyby był potrzebny

    public Byte SQLselect(String user, String pass){  
    	
    	Connection conn = this.connect();
    	String sql = "SELECT * FROM user";  
    	Byte LoginResult = 0;

        try {  
           
            Statement stmt  = conn.createStatement();  
            ResultSet rs    = stmt.executeQuery(sql);
         
            while (rs.next()) {
        		if(rs.getString("user").equals(user)){
        			LoginResult = 2;
        			if(rs.getString("pass").equals(pass)){
        				LoginResult = 1;
        				break;
        			}	
        		}
			}
            conn.close();

        } catch (SQLException e) {System.out.println(e.getMessage());}
       return LoginResult;
    }
0

Tworzysz wątek a potem całą robotę i tak wykonujesz w wątku obsługi zdarzeń:

Platform.runLater(new Runnable() {
    @Override public void run() {
        mainController.MainStackPane.getChildren().addAll(p);
        LoginResult = sql.SQLselect(cryptUser, cryptPass);
}});

Podejrzewam, że dlatego to się nie wyświetla.
Ustaw sobie ten progressIndicator przed newWait.start() a na newWait.onReady() ustaw usuwanie.
Trzymaj się też konwencji nazewniczych (nazwy metod i pól od małej litery) bo kod źle się czyta.

0

Dzięki za sugestię. Faktycznie teraz działa znakomicie :)

WaitFor newWait = new WaitFor(mainController, cryptUser, cryptPass); 'Konstruktor nowego wątku
		ProgressIndicator p = new ProgressIndicator(); 'Konstruktor Process Indicator
		mainController.MainStackPane.getChildren().addAll(p); 'Dodanie do sceny
		
		newWait.setOnSucceeded(new EventHandler<WorkerStateEvent>() { 'Listener 
            @Override
            public void handle(WorkerStateEvent event) {
            	
            	mainController.mainStackPane.getChildren().remove(p);  'Jeżeli wątek zakończy pracę to otwórz/nie otwieraj następnego okna i skasuj Process Indicator
            	Byte loginResult = newWait.loginResult;
            	if(loginResult==1) { //Logowanie poprawne
        			loginError.setText("");
    	 				FXMLLoader loader = new FXMLLoader(this.getClass().getResource("/LoginForm/User.fxml"));
    	 				Pane pane = null;
    					pane = loader.load();

    	 				UserController login = loader.getController();
    	 				login.setMainController(mainController);
    	 				mainController.setScreen(pane, true);

        		}else{ //Logowanie niepoprawne
        			loginError.setTextFill(Color.RED);
        			loginError.setText("Login lub hasło niepoprawne!");
        		} } });
		newWait.start();

1 użytkowników online, w tym zalogowanych: 0, gości: 1