4

我不认为这是一个新问题。但是,每当使用退格键从一直到顶部删除 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>

这将导致在文本窗格内插入有序/无序列表。

这个错误的奇怪部分如下:

  1. 一旦你开始删除字符(如果你碰巧在项目符号列表下面有行),这些字符将被删除,直到你点击最后一个项目符号的最后一个字符。一旦达到这一点,插入符号就会拒绝向上移动,并且会抛出 GlyphView 的错误。

  2. 有时发生的情况是,在您删除了大部分字符之后 - 您仍然无法删除列表的第一个项目符号。它只会挂起,直到您执行 ctrl+a 然后退格。

我在几乎所有在线可用的基于 Java 的 HTML 编辑器中都看到了这些错误,但 JWebEngine 除外,其中不存在这种行为。不幸的是,JWebEngine 不是开源的,因此我无法查看他们的代码以了解他们是如何解决这个问题的。

我的猜测是来自 HTML 文档模型的通知有一些问题,因为光标定位代码不能正常工作。我还搜索了 Sun 错误数据库以检查是否已提出此特定问题但找不到任何问题(尽管我已经看到了很多与此非常相似的错误)。此外,我非常确定之前一定有人注意到了这一点,并且一定已经引起了 Swing 团队的注意。

使用 Swing(尤其是文本)部分的人是否知道 Sun 是否已提出此问题,或者是否已找到任何已知的解决方法来缓解该问题?

尽管用户仍然可以使用鼠标选择从窗格中删除列表,但没有使用退格键执行相同操作的选项似乎很奇怪。

SSCCE 现在已附加。重现错误请。按照附图中所示的步骤进行操作。

  1. 添加一行文本。然后通过单击文本窗格上方的按钮添加 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());
        }
    }
}

TextPane 项目符号删除问题

4

1 回答 1

1

我用这个

action=new HTMLEditorKit.InsertHTMLTextAction("test", "<UL><LI><P>\n</P></LI></UL>", HTML.Tag.BODY, HTML.Tag.UL);

而不是您示例中的默认操作以提供正确的结构。

对我来说很好。(赢 7,Java 1.6)

于 2012-03-02T11:55:14.747 回答