1

JEdi​​torPaneのオーバーライドされたDefaultStyledDocument(カスタムEditorKitも提供)内にLeafElementを挿入しようとしていますが、javax.swing.text.StateInvariantErrorが発生します。そのため、 JGuruフォーラムのトピックのガイドに従って、writeLock ()呼び出しとwriteUnlock()呼び出しを追加しましたが、今回はJEditorPaneは空のままです。では、ドキュメントのすべてのリスナーに通知するために、AbstractDocumentのfireXXX()メソッドをオーバーライドするにはどうすればよいですか?

ここに私のメインクラス: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)

前もって感謝します。

4

1 に答える 1

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 を生成する必要があることを示唆しています。私の場合、それは挿入イベントです。そう :

  1. この DocumentEvent インスタンスを作成します
  2. ドキュメントのコンテンツに文字列を挿入します (そうしないと、大きくなりません。JComponent を使用しているだけでも必須です) => getContent().insertString(offset, String)
  3. ドキュメントに変更を適用するために使用します (insertUpdate())
  4. 「これ以上進行していません」とマークします (end())
  5. すべてのドキュメント リスナーに通知します (fireInsertUpdate())
于 2013-03-10T21:31:10.857 に答える