Java线程在视图中不起作用

时间:2017-05-22 23:44:58

标签: java multithreading javafx

我在JavaFX中有一个简单的登录窗口。当用户插入他的用户名和密码时,我想制作一个简单的字符串"进度条"在主线程处理输入时在另一个线程中。

当主线程进入if语句时(让我们说密码不匹配)我希望在抛出警报时停止进度。但是使用此代码,即使在抛出警报之后它也会继续。

public void validateLogin(ActionEvent actionEvent) throws Exception {
    Thread thread = new Thread(() -> {
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(loading_txt.getText().length() < 10)loading_txt.setText(loading_txt.getText() + "|");
            else loading_txt.setText("|");
        }
    });
    thread.start();

    String username = username_field.getText();
    String password = password_field.getText();

    if (!(BCrypt.checkpw(password_field.getText(), dbHandler.getLoginByUsername(username_field.getText()).getPassword()))) {
        throwAlert(Alert.AlertType.ERROR,"Login problem", "Password doesn't match.", "Wrong password. Please, check out and try it again. ");
        thread.join();
        return;
    }

    thread.join();
    //other code
}

所以我在if语句中做了一点改动,并在警报之前放了thread.join()。现在甚至看不到进展。

    if (!(BCrypt.checkpw(password_field.getText(), dbHandler.getLoginByUsername(username_field.getText()).getPassword()))) {
        thread.join();
        throwAlert(Alert.AlertType.ERROR,"Login problem", "Password doesn't match.", "Wrong password. Please, check out and try it again. ");
        return;
    }

这种微小的变化如何导致看到或不被看到进展?在抛出警报时,我需要更改什么才能停止进度?它可能是由JavaFX中的某些功能引起的吗?

1 个答案:

答案 0 :(得分:1)

这是一个示例,您可以接受这个想法并将其应用到您的程序中(评论中的说明)。

import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.TextField;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.control.ProgressBar;

public class ProgressBarExample extends Application{

    ProgressBar pb = new ProgressBar(); // your progress bar


    @Override
    public void start(Stage primaryStage) throws Exception {

        // The structure and components are for example only
        TextField password = new TextField();
        Button test = new Button("Test");
        HBox container = new HBox();
        container.getChildren().addAll(password, test);
        container.setAlignment(Pos.CENTER);
        VBox root = new VBox();
        root.setAlignment(Pos.CENTER);
        root.getChildren().addAll(container);


        // add action listener to the button
        test.setOnAction(e->{
            // when it's pressed add Progress bar and other stuff that are concerned with the GUI! 
            Platform.runLater(new Runnable(){ // always use this to update GUI components
                @Override
                public void run() {
                    root.getChildren().add(pb);
                    // you can add label to the root...etc
                    // or update your progress bar ..etc
                    // in a nutshell: anything needs to be updated in GUI.
                }
            });

            Task<Boolean> validatePassword = new Task<Boolean>(){ // always use Task to do complex-long calculations
                @Override
                protected Boolean call() throws Exception {
                    return validatePassword(password);  // method to validate password (see later)      
                }
            };

            validatePassword.setOnSucceeded(ee->{ // when Task finishes successfully
                System.out.println("Finished");
                root.getChildren().remove(pb); // remove the progress bar   
                if(!validatePassword.getValue()){
                  Alert alert = new Alert(AlertType.ERROR, "Wrong Password", ButtonType.OK);
                  alert.showAndWait();
                }
            });

            validatePassword.setOnFailed(eee->{ // if it fails
                 System.out.println("Failed");
                 root.getChildren().remove(pb); // remove it anyway                                 
            });

            new Thread(validatePassword).start(); // add the task to a thread and start it
        });

        Scene scene = new Scene(root, 300,300);
        primaryStage.setScene(scene);

        primaryStage.show();

    }

    // validate here in this method
    public static boolean validatePassword(TextField password){
        for(int i=0; i<99999; i++){ // suppose it is a long process
            System.out.println("Processing");
        }
        if(password.getText().equalsIgnoreCase("Invalid")){ // suppose it's invalid, just for testing
            return false
        }
        return true;
    }


    public static void main(String[] args) {
        launch();
    }   
}

<强>测试

enter image description here

enter image description here

enter image description here