【问题标题】:Dynamic update of JTextArea as Console output during execution of a long program? [duplicate]在执行长程序期间动态更新 JTextArea 作为控制台输出? [复制]
【发布时间】:2017-06-27 09:34:25
【问题描述】:

假设一个程序要执行大量的方法。比如在安装一个软件的安装方法并且你想在JtextArea中跟踪进度。我正在执行一个需要 20 秒或更长时间才能执行的程序。我想在更新间隔为 50 到 100 毫秒的文本区域中显示输出。我该如何实施? 我使用了计时器,但它在程序执行后而不是在执行期间更新了文本区域,并且 java Thread 冻结了 GUI。

   temp1.redirectOutput( textArea );
   final int i = 0;

    Timer timer = new Timer(1000, new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            String str = "";
            int i = 0;
            while(i < 3000){
                str = "aaaa";
                System.out.println(str);
                i++;
            }
            System.out.println( new java.util.Date().toString() );
            System.err.println( System.currentTimeMillis() );
        }
    });
    timer.start();

【问题讨论】:

  • .append(String str)方法怎么样?
  • @AndriyRymar 最简单的方法。不,那是行不通的
  • 知道了。当我遇到同样的问题时,我只是使用了List&lt;String&gt;StringBuilder 之类的结构并在那里管理所有新行。然后,当我必须在 UI 上显示日志数据时,我只需将 JTextArea 中的内容替换为我的结构的最新内容。
  • 改用 SwingWorker

标签: java swing


【解决方案1】:

使用SwingWorker获取你的信息,也许缓存成可管理的块,使用worker来发布它

查看Worker Threads and SwingWorker了解更多详情

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements LongTimeConsumer {

        private JTextArea ta;

        public TestPane() {
            setLayout(new BorderLayout());
            ta = new JTextArea(10, 20);
            add(new JScrollPane(ta));
            JButton btn = new JButton("Start");
            add(btn, BorderLayout.SOUTH);
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    btn.setEnabled(false);
                    LongTimeWorker worker = new LongTimeWorker(TestPane.this);
                    worker.addPropertyChangeListener(new PropertyChangeListener() {
                        @Override
                        public void propertyChange(PropertyChangeEvent evt) {
                            LongTimeWorker worker = (LongTimeWorker) evt.getSource();
                            if ("state".equals(evt.getPropertyName())) {
                                btn.setEnabled(worker.isDone());
                            }
                        }
                    });
                    worker.execute();
                }
            });
        }

        @Override
        public void contentUpdated(List<String> values) {
            for (String text : values) {
                ta.append(text);
                ta.append("\n");
            }
            ta.setCaretPosition(ta.getDocument().getLength());
        }

    }

    public interface LongTimeConsumer {
        public void contentUpdated(List<String> values);
    }

    public class LongTimeWorker extends SwingWorker<List<String>, List<String>> {

        private LongTimeConsumer consumer;

        public LongTimeWorker(LongTimeConsumer consumer) {
            this.consumer = consumer;
        }

        @Override
        protected List<String> doInBackground() throws Exception {
            List<String> total = new ArrayList<>(1000);
            List<String> values = new ArrayList<>(100);
            for (int index = 0; index < 1000; index++) {
                values.add("Some more text " + index);
                if (index % 100 == 0) {
                    total.addAll(values);
                    publish(values);
                    values = new ArrayList<>(100);
                }
                Thread.sleep(1);
            }
            if (!values.isEmpty()) {
                    total.addAll(values);
                    publish(values);
            }
            return total;
        }

        @Override
        protected void process(List<List<String>> chunks) {
            for (List<String> values : chunks) {
                consumer.contentUpdated(values);
            }
        }

    }
}

如果您正在使用System.out,您还可以执行thisthis 之类的操作

【讨论】:

    猜你喜欢
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多