- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个应用程序,在登录时通过接口(interface)类访问数据库。登录过程导致应用程序在访问数据库时一段时间内没有响应,因此我一直在研究线程和等待游标以使其顺利运行。我尝试通过网络上的许多示例和堆栈溢出来使用线程,但我的方法似乎不起作用,我收到 java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4 异常,我不确定如何从这里继续。我试图做的是在后台线程运行 loginLoadEverything() 方法时将光标更改为 WAIT 模式(尽管我没有在其中包含代码,因为它太长了)。这是我的 Controller 类:
package main.java.gui;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Cursor;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
import main.java.databaseInterface.BackendInterface;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.CountDownLatch;
public class LoginController implements Initializable {
private BackendInterface backendInterface;
private DashboardController dashboardController;
private StudentsController studentsController;
private ConsultationController consultationController;
private CreateStudentController createStudentController;
private CreateConsultationController createConsultationController;
@FXML
TextField username;
@FXML
PasswordField password;
@FXML
Button loginButton;
@FXML
Label loginLabel;
@FXML
public void loginButtonPress(ActionEvent event) {
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
loginLoadEverything();
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
Scene s1 = loginLabel.getScene();
s1.setCursor(Cursor.WAIT);
} finally {
latch.countDown();
}
}
});
latch.await();
return null;
}
};
}
};
service.start();
}
public void loginLoadEverything() {
//chance to true when complete
if (username.getText().isEmpty() == false || password.getText().isEmpty() == false) {
loginLabel.setText("Please enter data in the fields below");
} else {
username.setText("-----");
password.setText("-----");
//initialises backend interface with username and password
backendInterface = new BackendInterface(username.getText(), password.getText().toCharArray());
// Open a connection to the database
if (backendInterface.openConnection()) {
//return and print response
System.out.println(backendInterface.getConnectionResponse());
//directs the user to the dashboard after successful login
try {
if (backendInterface.getAllStudents() &&
backendInterface.getAllConsultations() &&
backendInterface.getCourses() &&
backendInterface.getConsultationCategories() &&
backendInterface.getConsultationPriorities()) {
FXMLLoader loader1 = new FXMLLoader();
loader1.setLocation(getClass().getResource("/main/res/dashboard.fxml"));
loader1.load();
Parent p = loader1.getRoot();
Stage stage = new Stage();
stage.setScene(new Scene(p));
stage.show();
//set instances to the dashboard controller
dashboardController = loader1.getController();
dashboardController.setBackendInterface(backendInterface); //pass backendInterface object to controller
dashboardController.setDashboardController(loader1.getController()); //pass dashboard as reference
//load images
Image logoutImage = new Image(getClass().getResourceAsStream("images/logout.png"));
Image userImage = new Image(getClass().getResourceAsStream("images/users.png"));
Image calendarImage = new Image(getClass().getResourceAsStream("images/calendar.png"));
Image leftArrowImage = new Image(getClass().getResourceAsStream("images/leftArrow.png"));
Image notepadImage = new Image(getClass().getResourceAsStream("images/notepad.png"));
//set images
dashboardController.studentLabel.setGraphic(new ImageView(userImage));
dashboardController.logoutLabel.setGraphic(new ImageView(logoutImage));
dashboardController.consultationLabel.setGraphic(new ImageView(notepadImage));
} else {
system.out.println(backendInterface.getExceptionMessage);
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
最佳答案
这里您可能不需要Service
:您只需要一个Task
。
call()
方法是在后台线程上执行的方法。它应该执行需要很长时间才能执行的工作(即连接到数据库并从中获取数据),并且不得执行任何 UI 工作,因为对 UI 的更改必须 在 FX 应用程序线程上进行。您收到异常的原因是您正在从后台线程创建并显示一个 Stage
。
所以基本思想是让任务从数据库获取数据并返回;然后使用任务的 onSucceeded
处理程序来显示 UI,并使用任务的结果。 (onSucceeded
处理程序在 FX 应用程序线程上执行,允许您安全地修改此处的 UI。)
我不知道你的类是如何实现的,等等,但以下内容可能会起作用。重要的是,您不要在与 UI 交互的后台线程中执行任何操作。
@FXML
public void loginButtonPress(ActionEvent event) {
if (( ! username.getText().isEmpty()) || (! password.getText().isEmpty()) ) {
loginLabel.setText("Please enter data in the fields below");
} else {
// I assume you want these values before you set them to "-----", no???
final String uName = username.getText();
final char[] pw = password.getText().toCharArray();
username.setText("-----");
password.setText("-----");
// create task for retrieving data:
Task<BackendInterface> loadDataTask = new Task<BackendInterface>() {
@Override
public BackendInterface call() throws Exception {
BackendInterface backendInterface = new BackendInterface(uName, pw);
if (backendInterface.openConnection()) {
if (backendInterface.getAllStudents() &&
backendInterface.getAllConsultations() &&
backendInterface.getCourses() &&
backendInterface.getConsultationCategories() &&
backendInterface.getConsultationPriorities()) {
return backendInterface ;
}
}
// maybe throw an exception here, depending on your requirements...
return null ;
}
};
// show UI on task completion:
loadDataTask.setOnSucceeded(e -> {
BackendInterface backendInterface = loadDataTask.getValue();
if (backendInterface == null) {
// something went wrong... bail, or probably show error message...
return ;
}
FXMLLoader loader1 = new FXMLLoader();
loader1.setLocation(getClass().getResource("/main/res/dashboard.fxml"));
Parent p = loader1.load();
DashboardController controller = loader.getController();
controller.setBackendInterface(backendInterface);
Stage stage = new Stage();
stage.setScene(new Scene(p));
stage.show();
// etc etc with your Images, etc (not sure why this isn't done in DashboardController though...)
// set cursor back to default:
loginLabel.getScene().setCursor(Cursor.DEFAULT);
});
loadDataTask.setOnFailed(e -> {
// show error message or otherwise handle database exception here
});
// set cursor to WAIT:
loginLabel.getScene().setCursor(Cursor.WAIT);
// and run task in a background thread:
Thread t = new Thread(loadDataTask);
t.start();
}
关于java - 如何在 javaFX 中将光标更改为 WAIT 的同时线程化后台任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39441812/
我有一个功能是转换 ADO Recordset 进入html: class function RecordsetToHtml(const rs: _Recordset): WideString; 该函
经过几天的研究和讨论,我想出了这种方法来收集访客的熵(你可以看到我的研究历史here) 当用户访问时,我运行此代码: $entropy=sha1(microtime().$pepper.$_SERVE
给定一个无序列表 List ,我需要查找是否存在 String与提供的字符串匹配。 所以,我循环 for (String k : keys) { if (Utils.keysM
我已经搜索过这个问题,但没有找到我正在寻找的答案。 基本上,我想将类构造函数包装在 try/except 子句中,以便它忽略构造函数内特定类型的错误(但无论如何都会记录并打印它们)。我发现做到这一点的
我有一组三个数字,我想将一组数字与另一组数字进行比较。即,第一组中的每个数字小于另一组中的至少一个数字。需要注意的是,第一组中的下一个数字必须小于第二组中的不同数字(即,{6,1,6} 对 {8,8,
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
首先介绍一下背景: 我正在开发一个带有 EJB 模块和应用程序客户端模块的企业应用程序 (ear)。我还使用 hibernate JPA 来实现持久性,并使用 swingx 来实现 GUI。这些是唯一
我正在尝试在我的上网本上运行 Eclipse 以便能够为 Android 进行开发。 您可能已经猜到了,Eclipse 非常慢,并且不容易有效地开发。 我正在使用 Linux Ubuntu 并且我还有
for row, instrument in enumerate(instruments): for col, value in enumerate(instrument):
return not a and not b ^ 我如何以更好的格式表达它 最佳答案 DeMorgan's Law , 也许? return not (a or b) 我认为在这一点上已经足够简单了
我正在尝试让 Font Awesome 图标看起来更 slim https://jsfiddle.net/cliffeee/7L6ehw9r/1/ . 我尝试使用“-webkit-text-strok
假设我有一个名为 vals 的数据框,如下所示: id…………日期…………min_date…… .........最大日期 1…………2016/01/01…………2017/01/01…………2018/
是否有更 Pythonic 的方式来做到这一点?: if self.name2info[name]['prereqs'] is None: se
我有一个函数可以将一些文本打印到它接收到的 ostream&。如果 ostream 以终端为目标,我想让它适应终端宽度,否则默认为某个值。 我现在做的是: 从 ostream 中获取一个 ofstre
这个问题在这里已经有了答案: Should a retrieval method return 'null' or throw an exception when it can't produce
我有这个 bc = 'off' if c.page == 'blog': bc = 'on' print(bc) 有没有更 Pythonic(和/或更短)的方式在 Python 中编写? 最佳
输入:一个包含 50,000 行的 CSV;每行包含 910 列值 0/1。 输出:运行我的 CNN 的数据框。 我编写了一个逐行读取 CSV 的代码。对于每一行,我将数据分成两部分,称为神经元(90
据我所知,with block 会在您退出 block 后自动调用 close(),并且它通常用于确保不会忘记关闭一个文件。 好像没有技术上的区别 with open(file, 'r+') as f
我有一个使用 Entity Framework V6.1.1 的 MVC 5 网站。 Entity Framework DbContext 类和模型最初都在网站项目中。这个项目有 3 个 DbCont
我是编程新手,在尝试通过将 tableView 和关联 View 的创建移动到单独的类并将委托(delegate)和数据源从 VC 移动到单独的类来精简我的 ViewController 时遇到了一些
我是一名优秀的程序员,十分优秀!