【发布时间】:2013-11-25 03:50:23
【问题描述】:
我的作品中有一个功能,我应该在其中显示一个巨大的文本文件。所以我想一旦文件超过一定大小,我会尝试在磁盘上映射文件。
文本至少是不可变的,这应该比编写支持相同大小的完整编辑器更容易。
这是我目前所拥有的:
public class CharBufferContent implements AbstractDocument.Content {
private final CharBuffer charBuffer;
private final int length;
public CharBufferContent(CharBuffer charBuffer) {
this.charBuffer = charBuffer;
length = charBuffer.length();
}
public Position createPosition(int offset) throws BadLocationException {
return new ImmutablePosition(offset);
}
public int length() {
return length;
}
public UndoableEdit insertString(int where, String string)
throws BadLocationException {
throw new UnsupportedOperationException("Document is immutable");
}
public UndoableEdit remove(int where, int nItems) throws BadLocationException {
throw new UnsupportedOperationException("Document is immutable");
}
public String getString(int where, int length) throws BadLocationException {
if (where < 0 || where + length > this.length) {
throw new BadLocationException("Invalid range", this.length);
}
char[] out = new char[length];
charBuffer.position(where);
charBuffer.get(out);
return new String(out);
}
public void getChars(int where, int length, Segment segment)
throws BadLocationException {
if (where < 0 || where + length > this.length) {
throw new BadLocationException("Invalid range", this.length);
}
// This will be inefficient, but I'm just trying to get it working first.
segment.array = new char[length];
charBuffer.position(where);
charBuffer.get(segment.array, 0, length);
segment.offset = 0;
segment.count = length;
}
private static class ImmutablePosition implements Position {
private final int offset;
private ImmutablePosition(int offset) {
this.offset = offset;
}
@Override
public int getOffset() {
return offset;
}
}
}
我写了一个小测试程序,它只使用一个内存缓冲区来测试它:
public class Test implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Test());
}
public void run() {
CharBuffer charBuffer = CharBuffer.wrap("This is a fairly simple test, " +
"so nothing should go wrong, right?\n");
AbstractDocument.Content content = new CharBufferContent(charBuffer);
final Document document = new PlainDocument(content);
JTextArea text = new JTextArea(document);
text.setEditable(false);
JScrollPane textScroll = new JScrollPane(text);
textScroll.setPreferredSize(new Dimension(600, 500));
JFrame frame = new JFrame("Test");
frame.setLayout(new BorderLayout());
frame.add(textScroll, BorderLayout.CENTER);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
当我运行它时,窗口显示“T”。在调试器中,我可以看到 Swing 只调用了length() 和getChars()。对getChars() 的每次调用都有where == 0 和length == 1。所以它只显示一个字符是有道理的,但是 Swing 会调用我的代码并且只要求第一个字符似乎很奇怪,即使我可以看到 length() 返回文本的完整长度.
当我使用 StringContent 作为实现运行相同的测试时,getChars() 会以文档的全长调用。
这个 API 中并没有太多看起来可能出错的地方,所以我很困惑。
这是怎么回事?
【问题讨论】:
标签: java swing document large-files