5

文字と記号を表示するために を使用しています。JTextPane後者はカスタム ペイントで表されますJComponents。たとえば、テキスト ペインは次 ここに画像の説明を入力 のように表示されます。テキスト ペインはユーザーが編集可能であり、ユーザーは任意の位置のボタンを使用して、選択したテキストの代わりにシンボルを追加できます。私はJTextPane.insertComponent()メソッドを介してこれを行います。アプリケーションのある時点で、テキスト ペインに現在何が表示されているかを知る必要があります。これは、入力されたテキストだけでなく、含まれている正確なコンポーネントも意味します。

Positionsテキスト ペインのコンテンツを管理するために、さまざまなトラブルを経験しましDocumentListenersたが、解決するよりも多くの問題を引き起こし続けました。そのため、問題はおそらく私の側の設計上の欠陥によるものであると最終的に判断したので、テキストペインからコンポーネントにアクセスできないかどうかを確認することにしました。

AbstractDocumentおよびその他の関連クラスのドキュメントとソース コードを検索すると、 interface が見つかりましたjavax.swing.text.Element。次に、アプリケーションに出力させます

for(int i = 0; i < textPane.getDocument().getLength(); i++) {
    System.out.println(((StyledDocument) textPane.getDocument()).getCharacterElement(i));
}

それは私に与えました:

LeafElement(コンテンツ) 0,4

LeafElement(コンテンツ) 0,4

LeafElement(コンテンツ) 0,4

LeafElement(コンテンツ) 0,4

LeafElement(コンポーネント) 4,5

LeafElement(コンテンツ) 5,9

LeafElement(コンテンツ) 5,9

LeafElement(コンテンツ) 5,9

LeafElement(コンテンツ) 5,9

LeafElement(コンポーネント) 9,10

取得しLeafElementsた には、 のどの位置に何が表示されているかについて何らかの情報が含まれているように見えるので、Documentその位置にある実際のコンテンツを取得できるはずだと考えました。各要素が表すコンテンツを取得する方法をさらに 30 分検索した後、私はあきらめて、ここに質問を投稿することにしました。

誰かが を介してコンポーネントにアクセスしようとするこの質問を見たことがtextPane.getComponents()あります。これは、 に実際に含まれているコンポーネントの正確な数を含むコンポーネントの配列を返しますJTextPaneが、それらはすべて型javax.swing.text.ComponentView$Invalidatorであり、明らかに役に立ちません。シンボルの元のタイプへのキャストが機能しないため、ここから適切に続行する方法がわからないだけかもしれません。

tl;dr

JComponentのテキスト内にあるJTextPaneとテキスト ペインからの位置を取得するにはどうすればよいですか?

4

2 に答える 2

11

以下に示すように、テキスト ペインを走査して、StyledDocumentコンポーネントまたはアイコンを表す要素を見つけることができます。

画像

BranchElement(セクション) 0,7

BranchElement(段落) 0,7

LeafElement(コンテンツ) 0,4

LeafElement(アイコン) 4,5

クラス javax.swing.plaf.IconUIResource
LeafElement(コンポーネント) 5,6

クラス javax.swing.JLabel
LeafElement(コンテンツ) 6,7

SSCCE:

/**
 * @see http://stackoverflow.com/a/15669307/230513
 * @see http://stackoverflow.com/questions/2883413
 */
public class DocumentParse {

    private static final String ELEM = AbstractDocument.ElementNameAttribute;
    private static final String ICON = StyleConstants.IconElementName;
    private static final String COMP = StyleConstants.ComponentElementName;

    public static void main(String args[]) throws Exception {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JTextPane jtp = new JTextPane();
        StyledDocument doc = (StyledDocument) jtp.getDocument();
        SimpleAttributeSet normal = new SimpleAttributeSet();
        StyleConstants.setFontFamily(normal, "Serif");
        StyleConstants.setFontSize(normal, 72);
        StyleConstants.setForeground(normal, Color.blue);
        doc.insertString(doc.getLength(), "Test", normal);
        jtp.setSelectionStart(doc.getLength());
        jtp.insertIcon(UIManager.getIcon("OptionPane.warningIcon"));
        jtp.setSelectionStart(doc.getLength());
        jtp.insertComponent(new JLabel("Label"));
        jtp.setSelectionStart(doc.getLength());

        ElementIterator iterator = new ElementIterator(doc);
        Element element;
        while ((element = iterator.next()) != null) {
            System.out.println(element);
            AttributeSet as = element.getAttributes();
            if (as.containsAttribute(ELEM, ICON)) {
                System.out.println(StyleConstants.getIcon(as).getClass());
            }
            if (as.containsAttribute(ELEM, COMP)) {
                System.out.println(StyleConstants.getComponent(as).getClass());
            }
        }

        f.add(jtp);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}
于 2013-03-27T20:57:09.427 に答える
4

javax.swing.text.ComponentView$InvalidatorComponentView からわかるように、元のコンポーネントは の最初の (そして唯一の) 子です。

無効化のリストを取得し、それらの子を使用して挿入されたコンポーネントにアクセスできます。

于 2013-03-28T06:54:08.747 に答える