powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Вопрос по javafx.concurrent
18 сообщений из 18, страница 1 из 1
Вопрос по javafx.concurrent
    #38639118
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пара вопросов по сабжу:
1. В Task-потоке делается запрос к mysql и если в запросе есть ошибка, то поток exception'ов не выкидывает и соответственно висит. Конструкция
Код: java
1.
setOnFailed(event -> System.out.println(event.getSource().getException()));


возвращает "java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4", что логично и мало чего дает.
Если запрос к БД поместить в Platform.runLater(() -> { }); то проблема решается, но тогда теряется сам смысл выноса запроса в поток, т.к. выполняется он будет в "основном" потоке, верно ?
2. Если правильно понял, то с результатами работы потока мы работаем с помощью setOnSucceeded,setOnFailed и т.д.
А если потоков 5, 10, 50 и к каждому потребуется прописать хотя бы два вышеназванных события, то кода получится просто куча. Это как-то можно сократить ?

Собственно больше волнует первый вопрос.
Заранее благодарю!

Ниже простой пример использования потока для проверки аутентификации, если кто-то прокомментирует код, так же буду очень благодарен!

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
    private void loginIn(String login,String password){

        loginTask = new LoginTask(login,password);
        errorLabel.textProperty().bind(loginTask.messageProperty());
        new Thread(loginTask).start();

        loginTask.setOnSucceeded(event -> System.out.println(loginTask.getValue().get("level")));
        loginTask.setOnFailed(event -> System.out.println(event.getSource().getException()));

    }

    private class LoginTask
                extends Task<HashMap> {

        private String login,password;
        private HashMap<String,Object> userData = new HashMap<>();

        public LoginTask(String _login,String _password) {
            this.login = _login;
            this.password = _password;
            updateMessage("");
        }

        @Override
        protected HashMap call() throws Exception {

            if(login.length() > 0 & password.length() > 0) {

                rs = sql.queryToSql("SELECT * " +
                                    "FROM `users` " +
                                    "WHERE `login` = '" + login + "' " +
                                        "AND `pass` = '" + Function.md5(password) + Function.md5(Configuration.PASS_SALT) + "';");

                    if (rs.next()) {
                        userData.put("level", rs.getInt("level"));
                        userData.put("fullName", rs.getString("fullname"));
                        userData.put("packsFullName", rs.getString("fullnamedog"));

                        return userData;
                    }
                    else {
                        updateMessage("Введенные данные не верны");
                        return null;
                    }
            }
            else {
                updateMessage("Введите логин и пароль");
                return null;
            }
        }
    }


...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639563
danatriel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshun,
особо не вдумываясь, может так:
Код: java
1.
2.
3.
4.
5.
6.
7.
        Platform.runLater(new Runnable() {

            @Override
            public void run() {
                     //код
            }
        });
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639564
danatriel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshun,

сорри, не внимательно прочитал вопрос
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639627
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshun1. В Task-потоке делается запрос к mysql и если в запросе есть ошибка, то поток exception'ов не выкидывает и соответственно висит.

"Висит" здесь очень не точный и не корректный термин для описания того что на самом деле происходит.


korshunКонструкция
Код: java
1.
setOnFailed(event -> System.out.println(event.getSource().getException()));


возвращает "java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4", что логично и мало чего дает.

Чет не понял. А зачем вы биндинг вызываете асинхронно в своих потоках? Биндить надо в начале инициализации.

korshunЕсли запрос к БД поместить в Platform.runLater(() -> { }); то проблема решается, но тогда теряется сам смысл выноса запроса в поток, т.к. выполняется он будет в "основном" потоке, верно ?

Нет, не верно. Не понятно как IllegalStateException связан с вашим кодом. У вас loginIn тоже в каком-то странном потоке выполняется? Или как?
Обратите внимание, что у таски ещё можно переопределять методы такие как failed(). Правда, это не совсем красивый код выйдет.

korshun2. Если правильно понял, то с результатами работы потока мы работаем с помощью setOnSucceeded,setOnFailed и т.д.

Типа того.

korshunА если потоков 5, 10, 50 и к каждому потребуется прописать хотя бы два вышеназванных события, то кода получится просто куча. Это как-то можно сократить ?

50 потоков или фоновых задачь? Не путайте. Обратите внимание на класс Service.

Замечания в коментах.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
    private void loginIn(String login,String password){//Не хватает пробела

        loginTask = new LoginTask(login,password);//Не хватает пробела
        errorLabel.textProperty().bind(loginTask.messageProperty());//Не будет ли утечки памяти, если биндить каждый раз новый Task?
        new Thread(loginTask).start(); // new Thread(), ИМХО - моветон. Executors наше всё.

        loginTask.setOnSucceeded(event -> System.out.println(loginTask.getValue().get("level")));
        loginTask.setOnFailed(event -> System.out.println(event.getSource().getException()));

    }

    private class LoginTask
                extends Task<HashMap> {//HashMap не типизированый

        private String login,password; //Снова потерялся пробел. Такой стиль объявления полей не рекомендуется.
        private HashMap<String,Object> userData = new HashMap<>();

        public LoginTask(String _login,String _password) {//Опять потерялся пробел. Редко используемый стиль именования.
            this.login = _login;
            this.password = _password;
            updateMessage("");//Код сомнительной пользы.
        }

        @Override
        protected HashMap call() throws Exception {//HashMap не типизированый

            if(login.length() > 0 & password.length() > 0) {

                rs = sql.queryToSql("SELECT * " + 
                                    "FROM `users` " +  
                                    "WHERE `login` = '" + login + "' " + //Не используем binding variables с какой-то конкретной целью?
                                        "AND `pass` = '" + 
   Function.md5(password) + Function.md5(Configuration.PASS_SALT) + "';"); //Алгоритм кодирования пароля доступен в клиентском коде, а значит открыт злоумышленнику.

                    if (rs.next()) {
                       //Лень создать класс?
                        userData.put("level", rs.getInt("level"));
                        userData.put("fullName", rs.getString("fullname"));
                        userData.put("packsFullName", rs.getString("fullnamedog"));

                        return userData;
                    }
                    else {
                        updateMessage("Введенные данные не верны");//Unicode текст в коде
                        return null;
                    }
            }
            else {
                updateMessage("Введите логин и пароль");//Unicode текст в коде
                return null;
            }
        }
    }


...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639946
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczkorshun1. В Task-потоке делается запрос к mysql и если в запросе есть ошибка, то поток exception'ов не выкидывает и соответственно висит.

"Висит" здесь очень не точный и не корректный термин для описания того что на самом деле происходит.
Не прерывает своей работы, не смотря на ошибку - так можно выразиться ?:)

BlazkowiczkorshunКонструкция
Код: java
1.
setOnFailed(event -> System.out.println(event.getSource().getException()));


возвращает "java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4", что логично и мало чего дает.

Чет не понял. А зачем вы биндинг вызываете асинхронно в своих потоках? Биндить надо в начале инициализации.
Ага, он и висит отдельно от потока.

BlazkowiczkorshunЕсли запрос к БД поместить в Platform.runLater(() -> { }); то проблема решается, но тогда теряется сам смысл выноса запроса в поток, т.к. выполняется он будет в "основном" потоке, верно ?

Нет, не верно. Не понятно как IllegalStateException связан с вашим кодом. У вас loginIn тоже в каком-то странном потоке выполняется? Или как?
Обратите внимание, что у таски ещё можно переопределять методы такие как failed(). Правда, это не совсем красивый код выйдет.
LoginIn - это отдельная функция, которая вызывается при клике на кнопку (биндинг в fxml сделан), которая, в свою очередь, создает поток, который лезет в БД, проверяет данные и т.п.

В первым вопросом, в общем, разобрался сам. Вроде :)

BlazkowiczkorshunА если потоков 5, 10, 50 и к каждому потребуется прописать хотя бы два вышеназванных события, то кода получится просто куча. Это как-то можно сократить ?

50 потоков или фоновых задачь? Не путайте. Обратите внимание на класс Service.
Намек понял, забыл про этот класс!

За комментарии особая благодарность!

Если можно, еще один комментарий, по поводу Platform.runLater(() -> { });
Читая форумы и документацию мне казалось, что эта конструкция, если можно так выразиться, выносит то, что в ней прописано, из "дополнительного" в "основной" поток приложения. Но вы говорите, что это не так. Можно тогда пару слов о том, что это такое и в каких случаях используется ?
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639962
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще один момент:
Код: java
1.
errorLabel.textProperty().bind(loginTask.messageProperty());//Не будет ли утечки памяти, если биндить каждый раз новый Task?


Можно поподробнее ? Такой способ в офф. доках присутствует, да и в принципе в форумных примерах ничего другого не встречал.
Или вы клоните к тому, что нужно Service использовать ?
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639965
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshunНе прерывает своей работы, не смотря на ошибку - так можно выразиться ?:)

В чем это проявляется-то? Исключение приводит к завершению потока. Если вы видите что он где-то "висит" и что-то "делает", то опишите в чем это проявляется. Если вы не поймали исключения это ещё не значит что поток "висит".

korshunАга, он и висит отдельно от потока.
LoginIn - это отдельная функция, которая вызывается при клике на кнопку (биндинг в fxml сделан), которая, в свою очередь, создает поток, который лезет в БД, проверяет данные и т.п.

Тогда мне совершенно не понятен ваш код и его результат в виде IllegalStateException.

korshunЕсли можно, еще один комментарий, по поводу Platform.runLater(() -> { });
Читая форумы и документацию мне казалось, что эта конструкция, если можно так выразиться, выносит то, что в ней прописано, из "дополнительного" в "основной" поток приложения. Но вы говорите, что это не так. Можно тогда пару слов о том, что это такое и в каких случаях используется ?
Где я говорю, что это "не так"? GUI работает в одном единственном потоке. В нет происходит отрисовка, обработка событий и т.п.
Все события помещаются в отдельную очередь и обрабатываются в этом потоке. Platform.runLater помещает содержимое Runnable в эту очередь. И со временем этот Runnable обрабатывается в GUI потоке после других событий помещенных в очередь до него.

Я говорю что у вас первый вопрос не совпадает с кодом "под катом". Поэтому я не догоняю что вы сделали и зачем.
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639992
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczkorshunНе прерывает своей работы, не смотря на ошибку - так можно выразиться ?:)

В чем это проявляется-то? Исключение приводит к завершению потока. Если вы видите что он где-то "висит" и что-то "делает", то опишите в чем это проявляется. Если вы не поймали исключения это ещё не значит что поток "висит".
Запускаю проект в ide, и если ошибок нет, то закрытие "главного" Stage закрывает приложение (грубо говоря кнопка "стоп" становится неактивной и консоль говорит "Process finished with exit code 0").
Если же в запросе mysql сделать ошибку, то при закрытии Stage окно вроде бы закрывается, но кнопка "стоп" при этом остается активной и в консоли нет надписи о том, что процесс завершен. Ну и соответственно при принудительной остановке кнопкой "стоп" оно останавливается с сообщением "Process finished with exit code -1".
Оттого и казалось, что поток как бы "висит" :)


BlazkowiczkorshunАга, он и висит отдельно от потока.
LoginIn - это отдельная функция, которая вызывается при клике на кнопку (биндинг в fxml сделан), которая, в свою очередь, создает поток, который лезет в БД, проверяет данные и т.п.

Тогда мне совершенно не понятен ваш код и его результат в виде IllegalStateException.
Под катом весь код класса.
Если в нем сделать ошибку в запросе к БД (убрать кавычку к примеру), то вылазит java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
Если запрос выполнять в Platform.runLater(() -> { }); , то ошибка уже другая, более информативная:
java.lang.NullPointerException
at ru.korshun.coba.login.controllers.LoginController$LoginTask.call(LoginController.java:195)
at ru.korshun.coba.login.controllers.LoginController$LoginTask.call(LoginController.java:171)
Вот об этом речь, надеюсь теперь понятно объясняю :)




public class LoginController
implements Initializable {

@FXML private Button loginButton;
@FXML private Button cancelButton;
@FXML private TextField loginField;
@FXML private PasswordField passwordField;
@FXML private Label errorLabel;
@FXML private Pane loadPane;

private LoginTask loginTask;

private Sql sql;
private ResultSet rs;

private volatile boolean loginComplite = false;

@Override
public void initialize(URL location, ResourceBundle resources) {

sql = new Sql();

/*
*
* БИНДИНГИ ЭЛЕМЕНТОВ ОКНА
*
*/

/*
* Клик в поле с логином
*/
loginField.setOnMouseClicked(event -> {
loginField.requestFocus();
loginField.positionCaret(0);
loginField.selectAll();
});
loginField.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER)) {
loginIn(loginField.getText(), passwordField.getText());
}
});

/*
* Клик в поле с паролем
*/
passwordField.setOnMouseClicked(event -> {
passwordField.requestFocus();
passwordField.positionCaret(0);
passwordField.selectAll();
});
passwordField.setOnKeyPressed(event -> {
if(event.getCode().equals(KeyCode.ENTER)) {
loginIn(loginField.getText(), passwordField.getText());
}
});

/*
* Кнопка "Логин"
*/
loginButton.setOnMouseClicked(mouseEvent -> loginIn(loginField.getText(),passwordField.getText()));

/*
* Закрытие окна
*/
cancelButton.setOnMouseClicked(mouseEvent -> StageController.closeStage("loginStage"));
/*
* ========================================================
* БИНДИНГИ КНОПОК ЛОГИНА И ЗАКРЫТИЯ ОКНА
* <КОНЕЦ>
*/


}

/*
* ФУНКЦИЯ ПРОВЕРКИ ДАННЫХ ДЛЯ ВХОДА
*/
private void loginIn(String login,String password){

loadPane.setVisible(true);
cancelButton.setDisable(true);
loginField.setDisable(true);
passwordField.setDisable(true);

loginTask = new LoginTask(login,password);
errorLabel.textProperty().bind(loginTask.messageProperty());
new Thread(loginTask).start();

/*
* Действия при успешном выполнении потока
*/
loginTask.setOnSucceeded(event -> {

if(loginTask.getValue() != null) {
Var.userLevel = (int) loginTask.getValue().get("level");
Var.userFullName = (String) loginTask.getValue().get("fullName");
Var.userPacksFullName = (String) loginTask.getValue().get("packsFullName");
Var.userFilialID = (int) loginTask.getValue().get("filial");
Var.userType = (int) loginTask.getValue().get("type");
Var.userPOA = (String) loginTask.getValue().get("POA");

try {
StageController
.createStage("clientInfoStage", new Stage())
.setTitle("COBA")
.showStage("clientInfo/fxml/ClientInfoFXML.fxml");
StageController.closeStage("loginStage");
} catch (Exception e) {
Dialogs.create()
.title("Ошибка")
.message(null)
.masthead(null)
.showException(e);
}
}

loadPane.setVisible(false);
cancelButton.setDisable(false);
loginField.setDisable(false);
passwordField.setDisable(false);
});

/*
* Действия при ошибке в потоке
*/
loginTask.setOnFailed(event -> {
loadPane.setVisible(false);
cancelButton.setDisable(false);
loginField.setDisable(false);
passwordField.setDisable(false);
Dialogs.create()
.title("Ошибка")
.message(null)
.masthead(null)
.showException(event.getSource().getException());
});

}



/*
* ФОНОВЫЙ КЛАСС ДЛЯ РАБОТЫ С БД И ПРОВЕРКОЙ ДАННЫХ ДЛЯ ВХОДА
*/
private class LoginTask
extends Task<HashMap<String,Object>> {

private String login,password;
private HashMap<String,Object> userData = new HashMap<>();

public LoginTask(String _login,String _password) {
this.login = _login;
this.password = _password;
updateMessage("");
}

@Override
protected HashMap<String,Object> call() throws Exception {

if(login.length() > 0 & password.length() > 0) {

rs = sql.queryToSql("SELECT * " +
"FROM `users` " +
"WHERE `login` = '" + login + "' " +
"AND `pass` = '" + Function.md5(password) + Function.md5(Configuration.PASS_SALT) + "';");

if (rs.next()) {
userData.put("level", rs.getInt("level"));
userData.put("fullName", rs.getString("fullname"));
userData.put("packsFullName", rs.getString("fullnamedog"));
userData.put("filial", rs.getInt("idfilial"));
userData.put("type", rs.getInt("type"));
userData.put("POA", rs.getString("doveren"));

return userData;
}
else {
updateMessage("Введенные данные не верны");
return null;
}

}
else {
updateMessage("Введите логин и пароль");
return null;
}

}

}

}
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639997
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stacktrace для IllegalStateException покажите.
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38639998
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, сорри, в тэг "Java" забыл код поместить, дублирую тут:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
public class LoginController
        implements Initializable {

    @FXML private Button loginButton;
    @FXML private Button cancelButton;
    @FXML private TextField loginField;
    @FXML private PasswordField passwordField;
    @FXML private Label errorLabel;
    @FXML private Pane loadPane;

    private LoginTask loginTask;

    private Sql sql;
    private ResultSet rs;

    private volatile boolean loginComplite = false;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        sql = new Sql();

        /*
        *
        *   БИНДИНГИ ЭЛЕМЕНТОВ ОКНА
        *
        */

        /*
        *   Клик в поле с логином
        */
        loginField.setOnMouseClicked(event -> {
            loginField.requestFocus();
            loginField.positionCaret(0);
            loginField.selectAll();
        });
        loginField.setOnKeyPressed(event ->  {
            if(event.getCode().equals(KeyCode.ENTER)) {
                LoginIn(loginField.getText(), passwordField.getText());
            }
        });

        /*
        *   Клик в поле с паролем
        */
        passwordField.setOnMouseClicked(event -> {
            passwordField.requestFocus();
            passwordField.positionCaret(0);
            passwordField.selectAll();
        });
        passwordField.setOnKeyPressed(event -> {
            if(event.getCode().equals(KeyCode.ENTER)) {
                LoginIn(loginField.getText(), passwordField.getText());
            }
        });

        /*
        *   Кнопка "Логин"
        */
        loginButton.setOnMouseClicked(mouseEvent -> LoginIn(loginField.getText(),passwordField.getText()));

        /*
        *   Закрытие окна
        */
        cancelButton.setOnMouseClicked(mouseEvent -> StageController.closeStage("loginStage"));
        /*
        *   ========================================================
        *   БИНДИНГИ КНОПОК ЛОГИНА И ЗАКРЫТИЯ ОКНА
        *   <КОНЕЦ>
        */


    }

    /*
    *   ФУНКЦИЯ ПРОВЕРКИ ДАННЫХ ДЛЯ ВХОДА
    */
    private void LoginIn(String login,String password){

        loadPane.setVisible(true);
        cancelButton.setDisable(true);
        loginField.setDisable(true);
        passwordField.setDisable(true);

        loginTask = new LoginTask(login,password);
        errorLabel.textProperty().bind(loginTask.messageProperty());
        new Thread(loginTask).start();

        /*
        *   Действия при успешном выполнении потока
        */
        loginTask.setOnSucceeded(event -> {

                if(loginTask.getValue() != null) {
                    Var.userLevel = (int) loginTask.getValue().get("level");
                    Var.userFullName = (String) loginTask.getValue().get("fullName");
                    Var.userPacksFullName = (String) loginTask.getValue().get("packsFullName");
                    Var.userFilialID = (int) loginTask.getValue().get("filial");
                    Var.userType = (int) loginTask.getValue().get("type");
                    Var.userPOA = (String) loginTask.getValue().get("POA");

                        try {
                            StageController
                                    .createStage("clientInfoStage", new Stage())
                                    .setTitle("COBA")
                                    .showStage("clientInfo/fxml/ClientInfoFXML.fxml");
                            StageController.closeStage("loginStage");
                        } catch (Exception e) {
                            Dialogs.create()
                                    .title("Ошибка")
                                    .message(null)
                                    .masthead(null)
                                    .showException(e);
                        }
                }

            loadPane.setVisible(false);
            cancelButton.setDisable(false);
            loginField.setDisable(false);
            passwordField.setDisable(false);
        });

        /*
        *   Действия при ошибке в потоке
        */
        loginTask.setOnFailed(event -> {
            loadPane.setVisible(false);
            cancelButton.setDisable(false);
            loginField.setDisable(false);
            passwordField.setDisable(false);
            Dialogs.create()
                    .title("Ошибка")
                    .message(null)
                    .masthead(null)
                    .showException(event.getSource().getException());
        });

    }



    /*
    *   ФОНОВЫЙ КЛАСС ДЛЯ РАБОТЫ С БД И ПРОВЕРКОЙ ДАННЫХ ДЛЯ ВХОДА
    */
    private class LoginTask
                extends Task<HashMap<String,Object>> {

        private String login,password;
        private HashMap<String,Object> userData = new HashMap<>();

        public LoginTask(String _login,String _password) {
            this.login = _login;
            this.password = _password;
            updateMessage("");
        }

        @Override
        protected HashMap<String,Object> call() throws Exception {

            if(login.length() > 0 & password.length() > 0) {

                rs = sql.queryToSql("SELECT * " +
                                    "FROM `users` " +
                                    "WHERE `login` = '" + login + "' " +
                                        "AND `pass` = '" + Function.md5(password) + Function.md5(Configuration.PASS_SALT) + "';");

                    if (rs.next()) {
                        userData.put("level", rs.getInt("level"));
                        userData.put("fullName", rs.getString("fullname"));
                        userData.put("packsFullName", rs.getString("fullnamedog"));
                        userData.put("filial", rs.getInt("idfilial"));
                        userData.put("type", rs.getInt("type"));
                        userData.put("POA", rs.getString("doveren"));

                        return userData;
                    }
                    else {
                        updateMessage("Введенные данные не верны");
                        return null;
                    }

            }
            else {
                updateMessage("Введите логин и пароль");
                return null;
            }

        }

    }

}

...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38640001
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshunЗапускаю проект в ide, и если ошибок нет, то закрытие "главного" Stage закрывает приложение (грубо говоря кнопка "стоп" становится неактивной и консоль говорит "Process finished with exit code 0").
Если же в запросе mysql сделать ошибку, то при закрытии Stage окно вроде бы закрывается, но кнопка "стоп" при этом остается активной и в консоли нет надписи о том, что процесс завершен. Ну и соответственно при принудительной остановке кнопкой "стоп" оно останавливается с сообщением "Process finished with exit code -1".
Оттого и казалось, что поток как бы "висит" :)
Вот это уже по существу. Нажмите "паузу" в IDE и посмотрите stack потока, который "висит". Потому что не очень понятно с чего бы ему висеть.
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38640005
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczStacktrace для IllegalStateException покажите.
Под спойлером смотрите, если правильно понял, о чем речь.


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
	at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:210)
	at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:393)
	at javafx.stage.Stage.<init>(Stage.java:233)
	at org.controlsfx.dialog.HeavyweightDialog$1.<init>(HeavyweightDialog.java:93)
	at org.controlsfx.dialog.HeavyweightDialog.<init>(HeavyweightDialog.java:93)
	at org.controlsfx.dialog.DialogFactory.createDialog(DialogFactory.java:54)
	at org.controlsfx.dialog.Dialog.<init>(Dialog.java:296)
	at org.controlsfx.dialog.Dialogs.buildDialog(Dialogs.java:828)
	at org.controlsfx.dialog.Dialogs.showException(Dialogs.java:496)
	at ru.korshun.coba.Sql.queryToSql(Sql.java:72)
	at ru.korshun.coba.login.controllers.LoginController$LoginTask.call(LoginController.java:187)
	at ru.korshun.coba.login.controllers.LoginController$LoginTask.call(LoginController.java:170)
	at javafx.concurrent.Task$TaskCallable.call(Task.java:1426)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.lang.Thread.run(Thread.java:745)

...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38640013
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshun at org.controlsfx.dialog.Dialogs.showException(Dialogs.java:496)
at ru.korshun.coba.Sql.queryToSql(Sql.java:72)

Ну, дык бага совсем в другом месте.
В вашем классе Sql вы выполняете в фоновом потоке запрос.
И оттуда же зачем-то дергаете Dialogs.showException, напрямую, что естественно нельзя делать из этого потока.
Вместо этого стоило ловить failure, которые отработает в JavaFX потоке и уже оттуда показывать ошибку.
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38640014
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczkorshunЗапускаю проект в ide, и если ошибок нет, то закрытие "главного" Stage закрывает приложение (грубо говоря кнопка "стоп" становится неактивной и консоль говорит "Process finished with exit code 0").
Если же в запросе mysql сделать ошибку, то при закрытии Stage окно вроде бы закрывается, но кнопка "стоп" при этом остается активной и в консоли нет надписи о том, что процесс завершен. Ну и соответственно при принудительной остановке кнопкой "стоп" оно останавливается с сообщением "Process finished with exit code -1".
Оттого и казалось, что поток как бы "висит" :)
Вот это уже по существу. Нажмите "паузу" в IDE и посмотрите stack потока, который "висит". Потому что не очень понятно с чего бы ему висеть.
Stack такой же, как и в сообщении выше.


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-6
	at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:210)
	at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:393)
	at javafx.stage.Stage.<init>(Stage.java:233)
	at org.controlsfx.dialog.HeavyweightDialog$1.<init>(HeavyweightDialog.java:93)
	at org.controlsfx.dialog.HeavyweightDialog.<init>(HeavyweightDialog.java:93)
	at org.controlsfx.dialog.DialogFactory.createDialog(DialogFactory.java:54)
	at org.controlsfx.dialog.Dialog.<init>(Dialog.java:296)
	at org.controlsfx.dialog.Dialogs.buildDialog(Dialogs.java:828)
	at org.controlsfx.dialog.Dialogs.showException(Dialogs.java:496)
	at ru.korshun.coba.Sql.queryToSql(Sql.java:72)
	at ru.korshun.coba.clientInfo.controllers.ClientInfoController$LoadMiniTables.call(ClientInfoController.java:221)
	at ru.korshun.coba.clientInfo.controllers.ClientInfoController$LoadMiniTables.call(ClientInfoController.java:207)
	at javafx.concurrent.Task$TaskCallable.call(Task.java:1426)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.lang.Thread.run(Thread.java:745)

...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38640020
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczkorshun at org.controlsfx.dialog.Dialogs.showException(Dialogs.java:496)
at ru.korshun.coba.Sql.queryToSql(Sql.java:72)

Ну, дык бага совсем в другом месте.
В вашем классе Sql вы выполняете в фоновом потоке запрос.
И оттуда же зачем-то дергаете Dialogs.showException, напрямую, что естественно нельзя делать из этого потока.
Вместо этого стоило ловить failure, которые отработает в JavaFX потоке и уже оттуда показывать ошибку.
Эх блин.. Спасибище одним словом!))
Получается в классе Sql из блока catch нужно убрать вызов Dialogs.showException, получается нужно просто оставить catch пустым, в этом нет ничего страшного ?
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38640253
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshunПолучается в классе Sql из блока catch нужно убрать вызов Dialogs.showException,

Да.

korshunполучается нужно просто оставить catch пустым
Нет. Либо заменить catch блок на throws объявление метода. Либо залогировать и выборосить через throw. Либо обернуть в RuntimeException чтобы нигде больше не париться с перепрокидыванием (не самый оптимальный вариант для новичка).
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38640478
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо!
...
Рейтинг: 0 / 0
Вопрос по javafx.concurrent
    #38661485
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Новую тему создавать не хочется, надеюсь можно задать пару вопросов в этой.

Возник вопрос: а как вообще по-правильному определять, что все потоки (task'и или service'ы) завершились ?
Самый простой пример: при открытии формы показываем пользователю либо анимированную картинку, либо выводим надпись "Ждите, загрузка..." и одновременно с этим запускаем несколько фоновых задач. По их окончанию надо надпись\картинку убрать, а как определять, что все задачи завершились ?

В мой нубский ум приходит только одна мысль - это создание доп. класса, который бы принимал в конструктор кол-во запущенных потоков, а каждый из запущенных потоков при завершении увеличивал бы некую переменную на единицу. И соответственно когда эта переменная становилось бы равной количеству потоков, то выполнялись бы необходимые действия.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Вопрос по javafx.concurrent
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]