【发布时间】:2020-12-13 03:51:05
【问题描述】:
我正在尝试用 java 编写一个非常简单的客户端-服务器电子邮件项目。 我已经使用套接字编写了客户端和服务器之间的通信代码,现在我正在尝试编写一些测试代码,其中还包括一个非常简单的 UI。 我的想法是创建与我拥有的客户端一样多的线程,并且我希望每个单独的线程都开始打开一个使用 Java FX 创建的简单 UI 窗口,但我遇到了一些问题。
这是主类:
import java.io.*;
public class ClientController{
public static void main(String args[]) throws IOException {
ParallelClient c1=new ParallelClient("aaaa@gmail.com");
ParallelClient c2=new ParallelClient("bbbb@gmail.com");
c1.start();
c2.start();
}
}
这是 ParallelClient 类:
import ...
public class ParallelClient extends Thread{
private String user;
public ParallelClient(String user){
this.user=user;
}
public void run(){
ClientApp app=new ClientApp();
try {
app.start(new Stage());
} catch (Exception e) {
e.printStackTrace();
}
...
}
...
}
这是设置新窗口的 ClientApp 类:
import ...
public class ClientApp extends Application {
@Override
public void start(Stage stage) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("ui/client-management.fxml"));
stage.setTitle("ClientMail");
stage.setScene(new Scene(root, 1080, 720));
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
当我尝试运行代码时,我遇到了以下问题,我无法理解如何解决它:
Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.NoClassDefFoundError: Could not initialize class javafx.stage.Screen
at javafx.stage.Window.<init>(Window.java:1439)
at javafx.stage.Stage.<init>(Stage.java:252)
at javafx.stage.Stage.<init>(Stage.java:240)
at model.ParallelClient.run(ParallelClient.java:25)
java.lang.ExceptionInInitializerError
at javafx.stage.Window.<init>(Window.java:1439)
at javafx.stage.Stage.<init>(Stage.java:252)
at javafx.stage.Stage.<init>(Stage.java:240)
at model.ParallelClient.run(ParallelClient.java:25)
Caused by: java.lang.IllegalStateException: This operation is permitted on the event thread only; currentThread = Thread-1
at com.sun.glass.ui.Application.checkEventThread(Application.java:441)
at com.sun.glass.ui.Screen.setEventHandler(Screen.java:369)
at com.sun.javafx.tk.quantum.QuantumToolkit.setScreenConfigurationListener(QuantumToolkit.java:728)
at javafx.stage.Screen.<clinit>(Screen.java:74)
... 4 more
【问题讨论】:
-
UI 事件仅通过主事件线程进行序列化。执行此类操作的正确方法是将事件发布到事件循环并让事件线程处理它。
-
每个应用程序也应该只有一个
Application实例。该对象的目的是管理整个应用程序生命周期(通过init()、start()和stop()方法)。代表每个客户端/窗口的类不应是Application的子类。
标签: java multithreading javafx