これは新しい問題ではないと思います。しかし、JTextPane の順序付き/順序なしリスト (EditorKit -> HTMLEditorKit、Document -> HTMLDocument) をバックスペース キーを使用して一番上まで削除すると、常にエラーが発生するようです。以下は、GlyphView の getText() メソッドからスローされる例外です。
Exception in thread "AWT-EventQueue-0" javax.swing.text.StateInvariantError: GlyphView: Stale view: javax.swing.text.BadLocationException: Invalid location
これには SSCCE を提供できます。しかし、シミュレートするのはそれほど難しくありません。HTMLEditorKit と HTMLDOcument モデルが内部に設定された JTextPane を使用するだけです。カスタムの「InsertOrderedList」アクションを使用するか、何らかの方法で文字列を挿入します
<HTML><HEAD></HEAD><BODY><UL><LI></LI></UL></BODY></HTML>
これにより、テキスト ペイン内に順序付き/順序なしリストが挿入されます。
このバグの奇妙な部分は次のとおりです。
文字の削除を開始すると (箇条書きの下に行がある場合)、最後の箇条書き項目の最後の文字に到達するまで、文字は削除されます。これに到達すると、キャレットは上に移動することを拒否し、GlyphView からのエラーがスローされます。
ほとんどの文字を削除した後でも、リストの最初の箇条書きを削除できない場合があります。ctrl+a を押してから backspace を押すまでそのままです。
この動作が存在しない JWebEngine を除いて、オンラインで入手可能なほぼすべての Java ベースの HTML エディターでこれらのバグを見てきました。残念ながら、JWebEngine はオープン ソース化されていないため、この問題をどのように解決したかを確認するためにコードを覗くことはできません。
私の推測では、HTML ドキュメント モデルからの通知には、カーソル位置コードが正しく機能していないという問題があると思われます。また、Sun のバグ データベースを検索して、この特定の問題が発生したかどうかを確認しましたが、何も見つかりませんでした (ただし、これと非常によく似たバグをかなり見てきました)。また、誰かが以前にこれに気付き、Swing チームの注意を喚起したに違いないと確信しています。
Swing (特にテキスト) 部分を扱っている人は、この問題が Sun で発生したかどうか、または問題を軽減する既知の回避策があるかどうかを知っていますか?
ユーザーがマウス選択を使用してペインからリストを削除できる可能性はありますが、バックスペース キーを使用して同じことを行うオプションがないのは非常に奇妙に思えます。
SSCCEが取り付けられました。バグを再現するには、pls. 添付の図に示す手順に従ってください。
- テキスト行を追加します。次に、テキスト ペインの上のボタンをクリックして、2/3 の箇条書き項目を追加します。ここで、最後の箇条書きの最後の文字の末尾にキャレットを置き、すべての文字が削除されるまでバックスペース キー全体を押し続けます。
観察された動作: 最後の箇条書きがハングアップし (削除されません)、例外がスローされます (上記のとおり)。
予想: 例外はなく、テキスト ペインの内容はクリアされるはずです。
public class Test {
static final JFrame frame = new JFrame ();
static final JTextPane textPane = new JTextPane ();
static EditorKit kit;
static JButton listButton;
public static void createAndShowGUI () {
//Create frame
frame.setSize(400, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
//Customize text pane visual properties
textPane.setSize(300, 500);
textPane.setLocation(50, 50);
//customize text pane non visual properties
kit = new CustomEditorKit ();
textPane.setEditorKitForContentType("text/html", kit);
textPane.setContentType("text/html");
Action[] actions = ((HTMLEditorKit) kit).getActions();
Action action = null;
for (int i = 0; i < actions.length; i++) {
action = actions [i];
if (action.getValue(Action.NAME).equals("InsertUnorderedList")) {
break;
}
}
listButton = new JButton (action);
listButton.setText("List");
listButton.setSize(100, 20);
listButton.setLocation(100, 10);
listButton.setVisible(true);
/* Add button and text pane to frame */
frame.add(listButton);
frame.add(textPane);
}
public static void main(String[] args) {
try {
EventQueue.invokeAndWait(new Runnable () {
@Override
public void run() {
createAndShowGUI ();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
static class CustomEditorKit extends HTMLEditorKit {
@Override
public Document createDefaultDocument () {
return new HTMLDocument (this.getStyleSheet());
}
}
}