1

HTMLEditorKit によってサポートされる JEditorPane に<br>タグとそれに続く空の行が含まれている場合、その行は正しくレンダリングされず、キャレットも正しく処理されません。次のサンプル コードを検討してください。

import java.awt.*;
import java.io.*;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

public class HTMLEditorTest {

    public static void main(String[] args) throws IOException, BadLocationException {
        JFrame frame = new JFrame();

        Reader stringReader = new StringReader("test<br><p>a");
        HTMLEditorKit htmlKit = new HTMLEditorKit();
        HTMLDocument htmlDoc = (HTMLDocument) htmlKit.createDefaultDocument();
        htmlKit.read(stringReader, htmlDoc, 0);
        JEditorPane editorPane = new JEditorPane();
        editorPane.setEditorKit(htmlKit);
        editorPane.setDocument(htmlDoc);

        frame.getContentPane().add(BorderLayout.CENTER, new JScrollPane(editorPane));
        frame.setBounds(100, 100, 500, 400);
        frame.setVisible(true);
    }
}

<br>タグの後の空行は表示されません。キャレットが「a」文字の左側に配置され、上矢印キーが押されると、キャレットが消えます。

「上」を押す前に:

ここに画像の説明を入力

「上」を押した後:

「上」を押した後

「test」と「a」の間の距離が小さすぎて、キャレットが消えていることに注意してください。

次にテキストを入力すると、欠落している空の行が表示されます。

「b」を押した後

問題は、空の行が高さ 0px でレンダリングされるため、キャレットがその行にある場合はキャレットを含めて表示されないことです。行にコンテンツが含まれると、そのコンテンツはゼロ以外の行の高さを強制します。

この問題の簡単な回避策/修正方法を知っていますか? 最悪の場合、独自のエディター キット( JEditorPane でのカスタム行ラッピングについてはこちらこちらも参照) やカスタム タグ(こちらも参照) を作成する必要があると思います。

4

1 に答える 1

2

カスタムエディターキットを使用して解決策を見つけました:

public class MyEditorKit extends HTMLEditorKit {

    private static final int MIN_HEIGHT_VIEWS = 10;

    @Override
    public ViewFactory getViewFactory() {

        return new HTMLFactory() {

            @Override
            public View create(Element e) {
                View v = super.create(e);
                // Test for BRView must use String comparison, as the class is package-visible and not available to us
                if ((v instanceof InlineView) && !v.getClass().getSimpleName().equals("BRView")) {

                    View v2 = new InlineView(e) {

                        @Override
                        public float getMaximumSpan(int axis) {
                            float result = super.getMaximumSpan(axis);
                            if (axis == Y_AXIS) {
                                result = Math.max(result, MIN_HEIGHT_VIEWS);
                            }
                            return result;
                        }

                        @Override
                        public float getMinimumSpan(int axis) {
                            float result = super.getMinimumSpan(axis);
                            if (axis == Y_AXIS) {
                                result = Math.max(result, MIN_HEIGHT_VIEWS);
                            }
                            return result;
                        }

                        @Override
                        public float getPreferredSpan(int axis) {
                            float result = super.getPreferredSpan(axis);
                            if (axis == Y_AXIS) {
                                result= Math.max(result, MIN_HEIGHT_VIEWS);
                            }

                            return result;
                        }
                    };

                    v = v2;
                }

                return v;
            }
        };
    }
}

エディター キットはカスタム HTMLFactory を返します。このファクトリは、InlineView の高さを 0 にすることができないリーフ要素のカスタム InlineView オブジェクトを作成します。少なくとも MIN_HEIGHT_VIEW を常に持ち、これを 10 ピクセルに設定します (デフォルトのフォント サイズで適切に動作します)。HTML を表示するためだけにレンダリングする場合、元の実装は理にかなっています<br>。タグの後の空行は無視する必要があるからです。ただし、編集の場合、ユーザーは改行を挿入した後、次の行にキャレットが表示されることを期待します。

于 2016-10-19T11:06:49.440 に答える