我正在使用 JTextPane(在 JScrollPane 中)作为自定义日志记录系统的一部分。(我需要多色输出,所以不能使用 JTextArea。)
我有它的日志部分工作,但我现在需要能够限制它的内容,以便它不只是在内存中不断增长。
没有直接的用户输入,因为所有日志都是系统生成的。
我需要做的是识别 JTextPane 何时达到指定的行数,然后能够在超过最大值时删除第一行。这将允许我在显示中保留最后“x”行的缓冲区。
我该怎么做呢?
使用 DocumentFilter 并检查文档的长度。您还可以使用 Document 的 getText() 方法并计算字符串中的“\n”个字符。或者您可以覆盖文档的 insertString() 方法。如果达到最大可能的行数,只需调用 remove() 然后 super.insertString()
试试这个小例子:
public class Example {
private static int MAX = 7;
static public void main( String[] s ) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
JFrame frame = new JFrame();
frame.setBounds( 50, 50, 200, 300 );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
final JTextPane pane = new JTextPane();
pane.setText( "1\n2\n3\n4" );
JPanel pnl = new JPanel(new BorderLayout());
pnl.add( pane, BorderLayout.CENTER );
pane.getDocument().addDocumentListener( new DocumentListener() {
public void removeUpdate( DocumentEvent e ) {
}
public void insertUpdate( DocumentEvent e ) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
try {
View baseView = pane.getUI().getRootView( pane );
View root = baseView.getView(0);
for( int i = 0; i < root.getViewCount()-MAX; i++ ) {
int line = root.getViewIndex( i, Bias.Forward );
View lineview = root.getView(line);
pane.getDocument().remove( lineview.getStartOffset(), lineview.getEndOffset() );
}
} catch( BadLocationException e1 ) {
e1.printStackTrace();
}
}
} );
}
public void changedUpdate( DocumentEvent e ) {
}
});
pnl.add(new JButton(new AbstractAction("Delete") {
public void actionPerformed( ActionEvent e ) {
try {
View baseView = pane.getUI().getRootView( pane );
View root = baseView.getView(0);
int line = root.getViewIndex( 0, Bias.Forward );
View lineview = root.getView(line);
pane.getDocument().remove( lineview.getStartOffset(), lineview.getEndOffset() );
} catch( BadLocationException e1 ) {
e1.printStackTrace();
}
}
}), BorderLayout.SOUTH);
pnl.add(new JButton(new AbstractAction("Add") {
@Override
public void actionPerformed( ActionEvent e ) {
try {
pane.getDocument().insertString(pane.getDocument().getEndPosition().getOffset(), new SimpleDateFormat("ss").format( new Date() )+": This is a new line\n", null);
} catch( BadLocationException e1 ) {
e1.printStackTrace();
}
}
}), BorderLayout.NORTH);
frame.setContentPane( pnl );
frame.setVisible( true );
}
}