GUI - 在JTextPane上逐个显示行并创建相关的JProgressBar

时间:2013-05-19 09:58:31

标签: java swing user-interface progress-bar jtextpane

如何在JTextPane上逐一显示行并制作相关的JProgressBar

我有这个循环:

  int k;
  for (k=0; k<array_TXT.length; k++) {
    if (array_TXT[k] != null) { 
      textPane.append( array_TXT[k] );
    }
 }

我想在几秒钟之后逐一将array_TXT[k](字符串)附加到JTextPane上,并且必须同步到JProgressBar

这样,每次k具有不同的值时,它将在文本窗格上打印,进度条将始终与这些打印相关。

我已阅读Thread.sleep(x);,但我不知道该放在哪里以达到我的目标。

2 个答案:

答案 0 :(得分:2)

您需要使用SwingWorker。它允许您在事件调度线程之外的后台执行更新。

SwingWorker提供了一些方法,允许您将publishprocess更新回事件调度线程。

它还允许您触发和监控进度更新

SwingWorker示例

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ProgressMonitor;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestProgress {

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

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

                JProgressBar pb = new JProgressBar();
                JTextArea ta = new JTextArea(10, 20);

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(ta));
                frame.add(pb, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                new BackgroundWorker(ta, pb).execute();
            }
        });
    }

    public class BackgroundWorker extends SwingWorker<Void, String> {

        private JProgressBar pb;
        private JTextArea ta;

        public BackgroundWorker(JTextArea ta, JProgressBar pb) {
            this.pb = pb;
            this.ta = ta;
            addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
                        BackgroundWorker.this.pb.setValue(getProgress());
                    }
                }

            });
        }

        @Override
        protected void done() {
        }

        @Override
        protected void process(List<String> chunks) {
            for (String text : chunks) {
                ta.append(text);
                ta.append("\n");
            }
        }

        @Override
        protected Void doInBackground() throws Exception {
            for (int index = 0; index < 100; index++) {
                publish("Line " + index);
                setProgress(index);
                Thread.sleep(125);
            }
            return null;
        }
    }
}

Swing Timer示例

正如Andrew所建议的那样,以下是使用SwingTimer的示例。如果您发现它有用,请将安德鲁信用为理念

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.List;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestProgress {

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

    private int index = 0;

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

                final JProgressBar pb = new JProgressBar();
                final JTextArea ta = new JTextArea(10, 20);

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(ta));
                frame.add(pb, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(250, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        index++;
                        if (index >= 100) {
                            ((Timer)(e.getSource())).stop();
                        }
                        ta.append("Line " + index + "\n");
                        pb.setValue(index);
                    }
                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();
            }
        });
    }

答案 1 :(得分:2)

不要阻止EDT(事件调度线程) - 当发生这种情况时,GUI将“冻结”。而不是调用Thread.sleep(n)为重复任务实现Swing Timer或为长时间运行的任务实现SwingWorker。有关详细信息,请参阅Concurrency in Swing