JTextArea 在 SwingWorker 中打印时不会自动滚动
JTextArea is not automatically scrolled on printing in SwingWorker
我的问题是添加了 JScrollPane
的 JTextArea
没有滚动到打印的最新行(滚动条停留在顶部)。
需要注意的是,行是在单独的 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 了解有关此问题的更多信息。
我的问题是添加了 JScrollPane
的 JTextArea
没有滚动到打印的最新行(滚动条停留在顶部)。
需要注意的是,行是在单独的 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 了解有关此问题的更多信息。