java - JTextArea 在应该更新的时候没有更新

标签 java multithreading swing model-view-controller

你好 StackOverflowers,

我目前正在开发我的第一个客户端/服务器应用程序,并面临一个对我来说根本没有意义的问题。请注意,我是网络编程和可运行对象/线程的新手。

我的应用程序使用 MVC 模式,因此我有一个 ServerControllerServerViewServerModel

现在我的 ServerController 中有一个方法,它基本上有 2 个任务。

  1. 更新服务器 GUI - 应该在 JTextArea 中写入字符串“服务器正在启动...”,以便用户知道应用程序没有崩溃

  2. 调用服务器

    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/

相关文章:

java - 如何反序列化以 Jackson 中的数组开头的 JSON 文件 - 仅使用注释?

C# (WPF) 异步线程与 GUI 接口(interface)

java - 对单个线程的多个同时访问

java - ThreadPoolExecutor - ArrayBlockingQueue ... 在从队列中删除元素之前等待

java - 单击时使用 MouseListener 移动图像

java - 从 servlet 访问 JSF session 范围的 bean,该 servlet 由 JSF webapp 中嵌入的 applet 调用

java - react-native deploy to android device error 3 Activity 类不存在

java - Spring 是否使 SecurityContext 可用于执行 Hystrix 命令的线程

java - 如何从 JTextField 获取输入,然后将其存储在变量中?

java - 不要重新绘制或重新验证