实时输出到jTextArea

Rob*_*ona 1 java user-interface refresh real-time jtextarea

我有一些代码需要花费几分钟来处理,它必须连接到web中的长数组中的每个字符串,每个字符串都是一个url.我希望这样做,以便每次连接时,都应该刷新jtextarea,这样用户就不会盯着看起来冻结20分钟的空白页面.或者需要多长时间.这是我尝试过的东西的一个例子:

try {
            ArrayList<String> myLinks = LinkParser.getmyLinksArray(jTextArea1.getText());
            for (String s : myLinks) {
                jTextArea2.append(LinkChecker.checkFileStatus(s) + "\n");
            }
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(jTextArea1, "Parsing Error", "Parsing Error", JOptionPane.ERROR_MESSAGE);
            Logger.getLogger(MYView.class.getName()).log(Level.SEVERE, null, ex);
        }
Run Code Online (Sandbox Code Playgroud)

Mic*_*yan 10

问题是您需要异步执行计算.您应该创建一个执行计算的后台线程,然后使用SwingUtilities.invokeLater更新JTextArea.

final ArrayList<String> myLinks = //...
(new Thread()
{
    public void run(){
        for (String s : myLinks) {
            try{
               final String result = LinkChecker.checkFileStatus(s) + "\n";
               SwingUtilities.invokeLater(new Runnable(){ 
                    public void run(){    
                      jtextArea2.append(result);
                    }
                });
             }catch(IOException error){
                // handle error
             }
        }
    }
}).start();

编辑
有人指出,JTextArea的追加函数实际上是线程安全的(与大多数Swing函数不同).因此,对于这种特殊情况,没有必要通过invokeLater更新它.但是,您仍然应该在后台线程中进行处理以允许GUI更新,因此代码为:

final ArrayList<String> myLinks = //...
(new Thread()
{
    public void run(){
        for (String s : myLinks) {
            try{
               jtextArea2.append(LinkChecker.checkFileStatus(s) + "\n");
             }catch(IOException error){
                // handle error
             }
        }
    }
}).start();

但是,对于修改Swing对象的几乎任何其他操作,您将需要使用invokeLater(以确保在GUI线程中进行修改),因为几乎所有Swing函数都不是线程安全的.

  • append(...)方法是线程安全的(根据方法的API文档),因此在此示例中,您不需要使用invokeLater. (2认同)