我正在尝试使用JTextPane在swing中实现消息控制台。我发现了一些实现,但遇到了大量的内存泄漏。
II进行了大量研究并确保(至少我希望我这样做)遵循AWT线程规则。我无法弄清楚我做错了什么...... 这包括彻底阅读看似相似的案例:
How to prevent memory leak in JTextPane.setCaretPosition(int)?
下面是再现泄漏的简单示例:在摆动(500毫秒重复)计时器中,添加了100行文本。只要有10000行,就会删除1000行。
请帮助解决这个问题
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class ConsoleTester {
private int m_totalRowsNum = 0;
StyledDocument m_document;
String lineText = "ONCE upon a time there were four little Rabbits, and their names were— Flopsy, Mopsy, Cotton-tail, \n";
Style styleGreen;
private int m_docLength = 0;
void createAndShowGUI() {
JFrame frame;
JTextPane textPane;
JTextField textField;
JScrollPane scrollPane;
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textPane = new JTextPane();
textPane.setEditable(false);
textPane.setFont(new Font("Courier New", Font.PLAIN, 16));
textPane.setOpaque(false);
m_document = textPane.getStyledDocument();
styleGreen = textPane.addStyle("styleGreen", null);
StyleConstants.setForeground(styleGreen, Color.green);
StyleConstants.setBold(styleGreen, true);
textField = new JTextField();
scrollPane = new JScrollPane(textPane);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
frame.add(textField, BorderLayout.SOUTH);
frame.add(scrollPane, BorderLayout.CENTER);
frame.getContentPane().setBackground(new Color(50, 50, 50));
frame.setSize(660, 350);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
javax.swing.Timer timer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("document length: " + m_docLength + " m_totalRowsNum: " + m_totalRowsNum);
for (int i = 0; i < 100; i++) {
AddLine();
}
textPane.setCaretPosition(m_document.getLength());
}
});
timer.start();
}
private void AddLine() {
m_totalRowsNum++;
try {
if (m_totalRowsNum % 10000 == 0) {
m_document.remove(0, 100000);
m_docLength -= 100000;
}
m_document.insertString(m_docLength, lineText, styleGreen);
m_docLength += lineText.length();
} catch (BadLocationException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ConsoleTester().createAndShowGUI();
}
});
}
}