JTextArea 在 SwingWorker 中打印时不会自动滚动

JTextArea is not automatically scrolled on printing in SwingWorker

我的问题是添加了 JScrollPaneJTextArea 没有滚动到打印的最新行(滚动条停留在顶部)。
需要注意的是,行是在单独的 SwingWorker 线程中打印的。

然而,如果我在 simulation() 中删除 SwingWorker,滚动似乎工作正常。

有人可以告诉我如何处理这个问题吗?

这是我正在测试的代码(省略import):

public class Test4 {

    private JFrame frame;
    private JTextArea textArea;
    private JButton btnNewButton;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test4 window = new Test4();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Test4() throws InterruptedException {
        initialize();
    }

    private void initialize() throws InterruptedException {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        textArea = new JTextArea();
        textArea.setEditable(false);

        JScrollPane scroll = new JScrollPane(textArea);
        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

        frame.getContentPane().add(scroll, BorderLayout.CENTER);

        btnNewButton = new JButton("Test Scrolling");
        frame.getContentPane().add(btnNewButton, BorderLayout.NORTH);
        btnNewButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                simulation();
            }
        });

    }

    private void simulation() {
        SwingWorker<Void, Void> swingWorker = new SwingWorker<Void, Void>() {

            @Override
            protected Void doInBackground() throws Exception {
                TestOutputStream customOutputStream = new TestOutputStream(
                        textArea);
                System.setOut(new PrintStream(customOutputStream, true, "UTF-8"));
                for (int i = 0; i < 30; i++) {
                    System.out.println("TEST");
                }
                return null;
            }
        };
        swingWorker.execute();
    }
}

class TestOutputStream extends OutputStream {
    private final ByteArrayOutputStream buf = new ByteArrayOutputStream();
    private final JTextArea consoleOutput;

    public TestOutputStream(JTextArea consoleOutput) {
        super();
        this.consoleOutput = consoleOutput;
    }

    @Override
    public void flush() throws IOException {
        consoleOutput.append(buf.toString("UTF-8"));
        buf.reset();
    }

    @Override
    public void write(int b) throws IOException {
        buf.write(b);
    }
}

Here is the code I am testing on (imports omitted):

为什么? Post 我们可以 copy/paste/test 的代码。我不使用 IDE,不应该花时间输入导入。

你的代码在我测试时没有做任何事情。我在 Windows 7.

上使用 JDK8

我必须在 SwingWorker 中的循环之后添加以下内容:

customOutputStream.flush();

is not scrolling to the newest line printed (the scroll bar stays at the top).

它不滚动,因为文本没有附加到 EDT 上的文本区域。

JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

上面的代码对我有用。

查看 Text Area Scrolling 了解有关此问题的更多信息。