Вставка LeafElement самостоятельно
Я пытаюсь вставить LeafElement в переопределенный DefaultStyledDocument (также предоставляя пользовательский EditorKit) для JEditorPane: но я получаю javax.swing.text.StateInvariantError. Поэтому, следуя указаниям форума JGuru, я добавил вызовы writeLock() и writeUnlock(), но на этот раз мой JEditorPane остается пустым. Итак, как мне переопределить методы fireXXX() класса AbstractDocument, чтобы уведомить всех слушателей документа?
Вот мой основной класс: MyFrame.java
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
public class MyFrame extends JFrame {
public MyFrame(){
setSize(400, 300);
JEditorPane editorPane = new JEditorPane();
editorPane.setEditorKit(new MyEditorKit());
add(new JScrollPane(editorPane));
}
public static void main(String[] args) {
new MyFrame().setVisible(true);
}
private static final long serialVersionUID = -2122161377842820073L;
}
Вот мой класс MyEditorKit.java
import javax.swing.text.Document;
import javax.swing.text.StyledEditorKit;
public class MyEditorKit extends StyledEditorKit {
@Override
public Document createDefaultDocument() {
return new MyDocument();
}
private static final long serialVersionUID = -5973765338689236766L;
}
И мой класс MyDocument.java
import javax.swing.JLabel;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
public class MyDocument extends DefaultStyledDocument {
public MyDocument(){
BranchElement rootElement = (BranchElement) getDefaultRootElement();
writeLock();
LeafElement black10Element = (LeafElement) createLeafElement(rootElement, new SimpleAttributeSet(),0, 1);
JLabel black10 = new JLabel("10 ...");
StyleConstants.setComponent(black10Element, black10);
writeUnlock();
}
private static final long serialVersionUID = -7424640574620960694L;
}
Это ошибка трассировки стека, когда я комментирую строки с помощью writeLock() и writeUnlock():
Exception in thread "main" javax.swing.text.StateInvariantError: Illegal cast to MutableAttributeSet
at javax.swing.text.AbstractDocument$AbstractElement.checkForIllegalCast(AbstractDocument.java:2050)
at javax.swing.text.AbstractDocument$AbstractElement.addAttributes(AbstractDocument.java:1983)
at javax.swing.text.AbstractDocument$AbstractElement.<init>(AbstractDocument.java:1777)
at javax.swing.text.AbstractDocument$LeafElement.<init>(AbstractDocument.java:2502)
at javax.swing.text.AbstractDocument.createLeafElement(AbstractDocument.java:1275)
at MyDocument.<init>(MyDocument.java:13)
at MyEditorKit.createDefaultDocument(MyEditorKit.java:9)
at javax.swing.JEditorPane.setEditorKit(JEditorPane.java:1058)
at MyFrame.<init>(MyFrame.java:11)
at MyFrame.main(MyFrame.java:16)
Заранее спасибо.
1 ответ
Я наконец решил свою проблему:
Просто измените MyDocument.java на это:
import javax.swing.JLabel;
import javax.swing.event.DocumentEvent.EventType;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
public class MyDocument extends DefaultStyledDocument {
public MyDocument(){
BranchElement rootElement = (BranchElement) getDefaultRootElement();
writeLock();
LeafElement black10Element = (LeafElement) createLeafElement(rootElement, new SimpleAttributeSet(), 0, 1);
JLabel black10 = new JLabel("10 ...");
StyleConstants.setComponent(black10Element, black10);
/////////////////// Added lines
DefaultDocumentEvent documentEvent = this.new DefaultDocumentEvent(0, 1, EventType.INSERT);
try {
getContent().insertString(0, " ");
} catch(BadLocationException e){
e.printStackTrace();
}
insertUpdate(documentEvent, black10Element);
documentEvent.end();
fireInsertUpdate(documentEvent);
/////////////////////////////////////
writeUnlock();
}
private static final long serialVersionUID = -7424640574620960694L;
}
Почему эти добавленные строки?
Ну, ссылки на темы JGuru предполагают, что должен быть создан новый DocumentEvent: в моем случае это событие вставки. Так:
- Я создаю этот экземпляр DocumentEvent
- При вставке строки в содержимое документа (в противном случае она не будет расти: это обязательно, даже если я просто использую JComponent) => getContent(). InsertString(offset, String)
- Я использую его для того, чтобы применить изменения в документе (insertUpdate())
- Я отмечаю это как "не в процессе" (end())
- Я уведомляю всех слушателей документа (fireInsertUpdate())