GUI - Display lines one by one on a JTextPane and

2019-07-31 16:46发布

How to display lines one by one on a JTextPane and make a related JProgressBar?

I have this loop:

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

I'd like to append every line array_TXT[k] (string) on the JTextPane one by one after few seconds and it has to be synchronized to a JProgressBar.

In this way every time k has a different value it will print on the text pane and the progress bar will always be related to those prints.

I have read about Thread.sleep(x); but I don't know where to put it in order to reach my aim.

2条回答
姐就是有狂的资本
2楼-- · 2019-07-31 17:14

Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling Thread.sleep(n) implement a Swing Timer for repeating tasks or a SwingWorker for long running tasks. See Concurrency in Swing for more details.

查看更多
虎瘦雄心在
3楼-- · 2019-07-31 17:23

You'll want to use a SwingWorker. It will allow you to execute the updates in the background, off the Event Dispatching Thread.

The SwingWorker has methods to allow you to publish and process updates back to the Event Dispatching Thread.

It also allows you to fire and monitor progress updates

SwingWorker Example

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 Example

As suggest by Andrew, the following is an example of using a SwingTimer. If you find it useful, please give Andrew credit for the idea

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();
            }
        });
    }
查看更多
登录 后发表回答