Почему JavaFX зависает при запуске процесса? - PullRequest
0 голосов
/ 15 октября 2019

Я создаю приложение, используя JavaFX. Приложение выполняет некоторые операции CRUD с базой данных MySQL. Поэтому в настоящее время у меня есть 2 функции.

  1. Регистрация пользователя.
  2. Проверка электронной почты (проверьте, существует ли электронная почта в базе данных).

Регистрация пользователявызывается в событии JFoenix Button. Когда он щелкает, он вызывает отдельные 3 функции в другом классе следующим образом:

public static int insertUser(User user) {
    int status = 0;

    try {
        Connection con = DbConnection.getConnection();  
        PreparedStatement ps = con.prepareStatement("INSERT INTO users (name, password, email, country) VALUES (?, ?, ?, ?)");  
        ps.setString(1, user.getName());  
        ps.setString(2, user.getPassword());  
        ps.setString(3, user.getEmail());  
        ps.setString(4, user.getCountry());

        status = ps.executeUpdate();  

        con.close();  
    }catch(Exception ex) {
        ex.printStackTrace();
    }
    return status;  
}

public static int updateTime(String email, String timestamp) {
    int status = 0;

    try {
        Connection con = DbConnection.getConnection();  
        PreparedStatement ps = con.prepareStatement("UPDATE users SET timestamp = ? WHERE email = ?");
        ps.setString(1, timestamp);
        ps.setString(2, email);

        status = ps.executeUpdate();  

        con.close();  
    }catch(Exception ex) {
        ex.printStackTrace();
    }
    return status;  
}

Проблема в том, что когда я нажимаю кнопку, я вижу, что она застревает во время выполнения этого процесса. Поэтому я поместил этот код внутрь следующего кода:

Platform.runLater(() -> {
    try {

    } catch (Exception ex) {
        Exceptions.printStackTrace(ex);
    }
});

Теперь все в порядке, но я вижу, что после нажатия он немного застревает (эффект Риппл не работает хорошо, а также не работает эффект наведения мыши)как обычно).

Проверка электронной почты выполняется, когда пользователь вводит электронную почту в текстовое поле, и запускается событие освобожденного ключа, и оно проверяет результат базы данных. Код для проверки электронной почты выглядит следующим образом:

public static boolean emailAvailability(String email) {
    boolean status = false;

    try {
        Connection con = DbConnection.getConnection();  
        PreparedStatement ps = con.prepareStatement("SELECT email FROM users WHERE email = ?");
        ps.setString(1, email);

        ResultSet rs = ps.executeQuery();

        status = rs.next();

        con.close();  
    }catch(Exception ex) {
        ex.printStackTrace();
    }
    return status;  
}

В ключевом событии также застревает больше. Не могу набрать символ в течение нескольких миллисекунд.

Я не вижу проблем с моим кодом, потому что я делал это много раз с Java Swing, и все отлично работают в Swing. И если кнопка застревает с запущенным процессом, я просто помещаю эти коды в следующее, и она отлично работает:

new Thread(new Runnable() {
   public void run() {

   }
}).start();

Я не собираюсь или пытаюсь сравнивать Java Swing и JavaFX, но мне нужнознаете, почему JavaFX ведет себя так? Что я должен сделать, чтобы избежать этого и плавно запустить программу с эффектами CSS, если это огромный процесс или нет? Очень ценю, если кто-нибудь может мне помочь. Заранее спасибо.

ОБНОВЛЕНИЕ

Вот мой signUp код. Выполняется при нажатии кнопки,

private void signUp(ActionEvent event) {
    if (name.getText.equals("") && name.getText().isEmpty()) {
        if (!name.getStyleClass().contains("error-class")) {
            name.getStyleClass().add("error-class");
            nameImageValidation.setImage(new Image("danger.png"));
            nameImageValidation.setVisible(true);
        }
    } else {
        name.getStyleClass().removeIf(style -> style.equals("error-class"));
        nameImageValidation.setVisible(false);
    }

    if (password.getText.equals("") && password.getText().isEmpty()) {
        if (!password.getStyleClass().contains("error-class")) {
            password.getStyleClass().add("error-class");
            passwordImageValidation.setImage(new Image("danger.png"));
            passwordImageValidation.setVisible(false);
        }
    } else {
        password.getStyleClass().removeIf(style -> style.equals("error-class"));
        passwordImageValidation.setVisible(false);
    }

    if (email.getText.equals("") && email.getText().isEmpty()) {
        if (!email.getStyleClass().contains("error-class")) {
            email.getStyleClass().add("error-class");
            emailImageValidation.setImage(new Image("danger.png"));
            emailImageValidation.setVisible(false);
        }
    } else {
        email.getStyleClass().removeIf(style -> style.equals("error-class"));
        emailImageValidation.setVisible(false);
    }

    if (country.getText.equals("") && country.getText().isEmpty()) {
        if (!country.getStyleClass().contains("error-class")) {
            country.getStyleClass().add("error-class");
            countryImageValidation.setImage(new Image("danger.png"));
            countryImageValidation.setVisible(false);
        }
    } else {
        country.getStyleClass().removeIf(style -> style.equals("error-class"));
        countryImageValidation.setVisible(false);
    }

    if(emailValidation() && passwordValidation() && fieldsValidation()) {
        User user = new User(name.getText(), email.getText(), password.getText(), country.getText());

        int insertStatus = UserController.insertUser(user);

        Timestamp timestamp = new Timestamp(System.currentTimeMillis());

        if (insertStatus > 0) {
            int updateStatus = UserController.updateTime(email.getText(), timestamp.toString());

                if(updateStatus > 0) {
                    // Go to Login Page
                } else {
                    showAlert(); // Error Message
                }
        } else {
            showAlert(); // Error Message
        }
    } else {
        showAlert(); // Error Message
    }
}

Здесь код validateEmail. Выполняется, когда пользователь вводит электронную почту. Срабатывает при отпускании клавиши и при выполнении этого после ввода символа, придется подождать некоторое время, а затем появиться следующий символ и перейти ...

private void validateEmail(KeyEvent event) {
    boolean status = UserController.emailAvailability(email.getText());

    if (!status) {
        email.getStyleClass().removeIf(style -> style.equals("success-class"));
        emailImageValidation.setImage(new Image("safe.png"));
        emailImageValidation.setVisible(true);
    } else {
        email.getStyleClass().removeIf(style -> style.equals("error-class"));
        emailImageValidation.setImage(new Image("danger.png"));
        emailImageValidation.setVisible(true);
    }
}

1 Ответ

2 голосов
/ 15 октября 2019

Когда вы запускаете функцию из графического интерфейса, выполнение происходит в основном потоке. Теперь эти вызовы блокируются, что означает, что до тех пор, пока они не вернутся, основной поток не сможет обновить графический интерфейс.

Обычно это можно решить двумя способами:

  1. Асинхронные функции, которые дают (позволяют запускать другой код), пока ресурс, который они ждут, не станет доступным
  2. Потоки, что означает параллельное выполнение части программы, что, скорее всего, потребует от вас подумать о блокировках и т. Д.

Я предлагаю вам взглянуть на эти две вещипоскольку они играют центральную роль в создании хороших приложений, подключенных к другим службам и IO

...