你好 StackOverflowers,
我目前正在开发我的第一个客户端/服务器应用程序,并面临一个对我来说根本没有意义的问题。请注意,我是网络编程和可运行对象/线程的新手。
我的应用程序使用 MVC 模式,因此我有一个 ServerController
、ServerView
和 ServerModel
。
现在我的 ServerController
中有一个方法,它基本上有 2 个任务。
更新服务器 GUI - 应该在
JTextArea
中写入字符串“服务器正在启动...”,以便用户知道应用程序没有崩溃调用服务器
public ActionListener startServerListener = new ActionListener() { public void actionPerformed(ActionEvent e) { try { //Update GUI view.updateServerNotice(new String("Server is starting...")); //Start Server in new thread Thread t1 = new Thread(model); t1.start(); Thread.sleep(1000); view.showNotification(model.hostAvailabilityCheck() + ""); } catch (Exception ex) { view.showNotification("Server is started already!"); } } };
我的问题是, view.updateServerNotice(new String("Server is running..."));
方法被执行,但在服务器未启动之前不会显示在 GUI 中。所以目前就像单击按钮一样,然后有一点延迟(由于 sleep()
),然后,服务器启动后,GUI 会更新为“服务器正在启动...”。
这对我来说没有意义,因为更新的 GUI 肯定是在创建新线程之前执行的。
我希望有人看到我看不到的东西并可以帮助我。这并不是一个大问题,但我真的很好奇为什么会发生这种情况。
提前感谢您的帮助!
最佳答案
Swing(和 AWT,事实上大多数环境中的许多 UI 框架,而不仅仅是 Java)是单线程的:只要 ActionListener 正在运行,就不会绘制任何内容。
您可以做的是在后台线程中运行代码,但是在这种情况下会出现另一个问题:单线程 UI 框架并不真正喜欢来自其他线程的随机交互。虽然直接访问有时可能有效,但“合法”方法是使用 SwingUtilities.invokeLater 或 invokeAndWait 发送打包到某种 Runnable 表单中的操作(我在这里使用后一种,因此您的消息肯定是可见的):
public ActionListener startServerListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
new Thread(new Runnable({
public void run(){
try{
// Update GUI #1
SwingUtilities.invokeAndWait(new Runnable(){
public void run(){
view.updateServerNotice(new String("Server is starting..."));
}
});
//Start Server in new thread
Thread t1 = new Thread(model);
t1.start();
Thread.sleep(1000);
// Update GUI #2
SwingUtilities.invokeAndWait(new Runnable(){
public void run(){
view.showNotification(model.hostAvailabilityCheck() + "");
}
});
}catch(Exception ex){/*...*/}
}
})).start();
}catch(Exception ex){/*...*/}
}
};
很漂亮,不是吗?
关于java - JTextArea 在应该更新的时候没有更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46472834/