【问题标题】:Get absolute position of character in JEditorPane获取 JEditorPane 中字符的绝对位置
【发布时间】:2017-05-27 18:55:48
【问题描述】:


我需要字符的绝对位置。与:
editorPane.getFontMetrics(f).getAscent()
我只得到到基线的相对距离。也许有办法获得基线的绝对位置?

编辑: 这是rect.y + rect.height - metrics.getDescent() - metrics.getAscent()的结果

【问题讨论】:

  • 调用JEditorPane的modelToView方法。
  • ModelToView 不起作用。它为 y 值返回 0。高度就像“世界”二字。我需要单词“Hello”开头的 y 坐标。
  • 你需要从视图矩形的底部计算它:rect.y + rect.height - metrics.getDescent() - metrics.getAscent()(其中rect是modelToView返回的值)
  • 对不起,它不起作用。上升 + 下降 + 领先 = 高度。它是荧光笔的高度。所以我错过了荧光笔下方的空间。
  • 您如何获得用于获取 FontMetrics 的字体?

标签: java swing fonts jeditorpane baseline


【解决方案1】:

由于一行中的所有字体共享一个基线*,您可以通过调用modelToView 并从矩形底部减去下降和上升来计算字符的视觉位置。

由于涉及到多种字体,显然JEditorPane的getFont方法是不够的。文档的原始元素属性也不够充分,因为 HTMLDocument 的属性只是对 HTML 元素本身进行建模。但是,任何文档位置的实际字体都可以从对应的View获取:

static Point getLocation(int pos,
                         JEditorPane editorPane)
throws BadLocationException {

    HTMLDocument doc = (HTMLDocument) editorPane.getDocument();

    View view = editorPane.getUI().getRootView(editorPane);
    int index;
    while ((index = view.getViewIndex(pos, Position.Bias.Backward)) >= 0) {
        view = view.getView(index);
    }

    AttributeSet attr = doc.getStyleSheet().getViewAttributes(view);
    Font f = doc.getStyleSheet().getFont(attr);

    FontMetrics metrics = editorPane.getFontMetrics(f);
    Rectangle rect = editorPane.modelToView(pos);

    return new Point(rect.x,
        rect.y + rect.height - metrics.getDescent() - metrics.getAscent());
}

* 为简单起见,我忽略了带有悬挂基线和垂直基线的字符。

编辑: 由于很少使用 RTFEditorKit,我错误地假设您使用的是 HTMLEditorKit。这适用于 RTF 文档:

static Point getLocation(int pos,
                     JEditorPane editorPane)
throws BadLocationException {
    StyledDocument doc = (StyledDocument) editorPane.getDocument();
    View view = editorPane.getUI().getRootView(editorPane);
    int index;
    while ((index = view.getViewIndex(pos, Position.Bias.Backward)) >= 0) {
        view = view.getView(index);
    }

    AttributeSet attr = view.getAttributes();
    Font f = doc.getFont(attr);

    FontMetrics metrics = editorPane.getFontMetrics(f);
    Rectangle rect = editorPane.modelToView(pos);

    return new Point(rect.x,
        rect.y + rect.height - metrics.getDescent() - metrics.getAscent());
}

【讨论】:

    【解决方案2】:

    我正在使用 RTFEditorKit。于是我改了代码:

    static Point getLocation(int pos,
                JEditorPane editorPane)
                throws BadLocationException {
    
            View view = editorPane.getUI().getRootView(editorPane);
            int index;
            while ((index = view.getViewIndex(pos, Position.Bias.Backward)) >= 0) {
                view = view.getView(index);
            }
    
            AttributeSet set = view.getAttributes();
            if (set != null && set.getAttribute(StyleConstants.FontFamily) != null) {
                Font f = new Font((String) set.getAttribute(StyleConstants.FontFamily), Font.PLAIN, (Integer) set.getAttribute(StyleConstants.FontSize));
                FontMetrics metrics = editorPane.getFontMetrics(f);
    
                Rectangle rect = editorPane.modelToView(pos);
                return new Point(rect.x,
                        rect.y + rect.height - metrics.getDescent() - metrics.getAscent());
            }
            else {
                return new Point(0, 0);
            }
        }
    

    但我总是得到当前字体的上升,而不是最大字体的上升。

    【讨论】:

    • 这不是你想要的吗?您是说您一直想要行中最大字体的上升,而不是所需位置的字体上升?
    • 是的,我需要最大字体的上升。但我总是能得到当前位置的上升。
    • 这似乎与您问题中的图像冲突,其中有一个红色箭头指向较小字体的顶部。此外,您评论道:“ModelToView 不起作用。它为 y 值返回 0。高度就像“世界”二字。我需要单词“Hello”开头的 y 坐标。”那么,你想要大字体文本的 y 坐标,还是小字体文本的 y 坐标?
    • 我想将插入符号设置到正确的位置(箭头)。 y 坐标为 r.y +(最大字体的上升 - 当前字体的上升)。
    • 如果我理解正确,您需要一个与行中最高字体一样高的文本光标,而不管光标所在位置的字体大小如何。对吗?
    猜你喜欢
    • 1970-01-01
    • 2014-08-29
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多