我很有新意,而且我已经好几次撞墙了。
代码几乎描述了一切,但只是为了澄清:用户按下按钮,应用程序向db发送查询,同时statusLabel
设置为:
Veryfing。
200ms
非常......
200ms
非常......
200ms
查询结果
我设法实现了这一点,但现在,我需要在另一个类中使用查询结果(如果成功,则打开另一个窗口),但它永远不会。我得出结论,它只是在Task完成之前检查结果,所以结果总是假的,我不知道如何解决这个问题,所以另一个类在Task完成后检查条件。
首先,我的Authorization
班级
public class Authorization {
private static String query = "";
private static boolean isValid;
private static Task<Void> task;
public static void verifyLogin(String username, String password) throws SQLException{
Status.get().unbind();
isValid = false;
task = new Task<Void>() {
@Override
protected Void call() throws SQLException {
while(!isCancelled()) {
try {
updateMessage("Weryfikacja.");
Thread.sleep(200);
updateMessage("Weryfikacja..");
Thread.sleep(200);
updateMessage("Weryfikacja...");
Thread.sleep(200);
if(username.equals("") || password.equals("")) {
task.cancel();
updateMessage("Pola nie mogą być puste");
} else {
query = "SELECT login FROM users WHERE login = ?";
Query.execute(query, username);
if(!Query.resultSet.next()) {
task.cancel();
updateMessage("Nie ma takiego użytkownika");
} else {
query = "SELECT password FROM users WHERE login = ?";
Query.execute(query, username);
if(Query.resultSet.next()) {
String passwordValue = Query.resultSet.getString(1);
if(!password.equals(passwordValue)) {
task.cancel();
updateMessage("Podane hasło jest błędne");
} else {
task.cancel();
updateMessage("");
isValid = true;
}
}
}
}
} catch(InterruptedException e) {
if(isCancelled()) {
break;
}
}
}
return null;
}
};
Status.get().bind(task.messageProperty());
new Thread(task).start();
}
public static boolean isValid() {
return isValid;
}
}
从另一个类调用
private void login() {
if( SqlConnection.isConnected()) {
try{
Authorization.verifyLogin(String.valueOf(loginInput.getText()), String.valueOf(passwordInput.getText()));
if(Authorization.isValid()) {
//should go to next menu
//but never does
}
} catch (SQLException e) {
e.printStackTrace();
Debug.log(e.toString());
}
}
}
编辑#
很抱歉updateMessage()
中有光泽。
答案 0 :(得分:1)
您的verifyLogin()
方法只是在另一个线程中启动验证过程,然后立即退出。在该线程完成之前,isValid
标志不会被更改,这会在很晚之后发生。如果您想要执行验证过程然后执行其他操作,那么在verifyLogin()
中管理线程并不是真的有意义。
我不太了解你的代码应该做的很多事情;你有一个while(...)
循环,据我所知,它只能被执行一次(因此是冗余的)。您似乎也执行两个基本相同的SQL查询。 (第一次检查是否存在具有特定条件的行,如果有,则第二次检索该行。为什么不检索该行并检查它是否存在?)
我会重构这一点,以便validateLogin()
方法根本不处理线程,只返回验证结果(例如状态字符串,但也许其他东西是合适的)。
/**
* @return An empty string if the login is valid, or an error message otherwise
*/
public static String verifyLogin(String username, String password) throws SQLException{
isValid = false ;
if(username.equals("") || password.equals("")) {
return "Pola nie mogą być puste";
}
query = "SELECT login, password FROM users WHERE login = ?";
Query.execute(query, username);
if(!Query.resultSet.next()) {
return "Nie ma takiego użytkownika";
}
String passwordValue = Query.resultSet.getString(2);
if(!password.equals(passwordValue)) {
return "Podane hasło jest błędne" ;
}
isValid = true;
return "" ;
}
现在我将从login()
方法管理线程。这样,您可以使用任务的onSucceeded
处理程序在任务完成时执行代码:
private void login() {
if( SqlConnection.isConnected()) {
Task<String> verifyTask = new Task<String>() {
@Override
protected String call() throws SQLException {
return Authorization.verifyLogin(loginInput.getText(), passwordInput.getText());
}
};
// probably better to use a progress indicator or similar here, but:
Animation animation = new Timeline(
new KeyFrame(Duration.ZERO, e -> Status.get().set("Weryfikacja.")),
new KeyFrame(Duration.millis(200), e -> Status.get().set("Weryfikacja..")),
new KeyFrame(Duration.millis(400), e -> Status.get().set("Weryfikacja...")),
new KeyFrame(Duration.millis(600)));
animation.setCycleCount(Animation.INDEFINITE);
verifyTask.setOnSucceeded(event -> {
animation.stop();
Status.get().set(verifyTask.getValue());
if(Authorization.isValid()) { // or if (verifyTask.getValue().isEmpty())
// go to next menu
}
});
verifyTask.setOnFailed(event -> {
animation.stop();
verifyTask.getException().printStackTrace();
Debug.log(verifyTask.getException().toString());
}
animation.play();
new Thread(verifyTask()).start();
}
}