JTextArea应该在什么时候不更新

时间:2017-09-28 15:21:29

标签: java multithreading swing model-view-controller

Hello StackOverflowers,

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

我正在为我的应用程序使用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!");
             }
      }
    };
    
  3. 我的问题是,view.updateServerNotice(new String("Server is starting..."));方法已执行但在服务器未启动之前未显示在GUI中。所以目前它就像点击按钮一样,然后有一点延迟(由于sleep())然后,在服务器启动后,GUI会更新为“服务器正在启动......”。

    这对我来说没有意义,因为GUI更新肯定是在创建新线程之前执行的。

    我希望有人看到我不喜欢的东西,可以帮助我。这不是一个大问题,但我真的很好奇为什么会这样。

    提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

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){/*...*/}
  }
};

漂亮,不是吗?