首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何根据鼠标指针从JLabel获取部分文本

如何根据鼠标指针从JLabel获取部分文本
EN

Stack Overflow用户
提问于 2015-08-25 05:43:26
回答 2查看 1.5K关注 0票数 1

有人知道如何从JLabel的开头到鼠标的指针获取文本的部分吗?例如,假设我们有一个文本为'C:\aaa\bbb\ccc‘的JLabel。用户将鼠标指针指向字符'bbb',所以我想得到文本'C:\aaa\bbb‘。现在,当我有这部分文字,我可以改变它的颜色。我想会用html。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-25 08:19:17

Java方便地包含了一个getIndexAtPoint方法,作为AccessibleText接口的一部分,该接口将位置(例如鼠标指针的位置)转换为该位置的字符索引:

给定局部坐标中的一个点,返回该点下字符的基于零的索引。如果点无效,则此方法返回-1。

下面是一个测试程序,它使用此方法获取所需字符串的一部分:

代码语言:javascript
运行
复制
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.accessibility.AccessibleText;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class JLabelMouseDemo {
    private static String labelText = "<html>C:\\aaa\\bbb\\ccc</html>";
    private static JLabel label;
    private static JLabel substringDisplayLabel;

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        label = new JLabel(labelText);
        label.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                AccessibleText accessibleText =
                        label.getAccessibleContext().getAccessibleText();
                Point p = e.getPoint();
                int index = accessibleText.getIndexAtPoint(p);
                if (index >= 0) {
                    // The index is with respect to the actually displayed
                    // characters rather than the entire HTML string, so we
                    // must add six to skip over "<html>", which is part of
                    // the labelText String but not actually displayed on
                    // the screen. Otherwise, the substrings could end up
                    // something like "tml>C:\aaa"
                    index += 6;

                    // Strangely, in my testing, index was a one-based index
                    // (for example, mousing over the 'C' resulted in an
                    // index of 1), but this makes getting the part of the
                    // string up to that character easier.
                    String partOfText = labelText.substring(0, index);

                    // Display for demonstration purposes; you could also
                    // figure out how to highlight it or use the string or
                    // just the index in some other way to suit your needs.
                    // For example, you might want to round the index to
                    // certain values so you will line up with groups of
                    // characters, only ever having things like
                    // "C:\aaa\bbb", and never "C:\aaa\b"
                    substringDisplayLabel.setText(partOfText);
                }
            }
        });
        frame.add(label);
        substringDisplayLabel = new JLabel();
        frame.add(substringDisplayLabel, BorderLayout.SOUTH);
        frame.setSize(200, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

实际上,获取与特定JLabel相对应的JLabel类型的对象可能并不总是有效的:据我所知,只有当JLabel显示HTML时才有可能。这似乎也得到了JLabel源的支持。

代码语言:javascript
运行
复制
public AccessibleText getAccessibleText() {
            View view = (View)JLabel.this.getClientProperty("html");
            if (view != null) {
                return this;
            } else {
                return null;
            }
        }

我并不完全理解该代码中发生了什么,也不知道为什么非HTML文本无法访问,但是当JLabel包含纯文本而不是HTML文本时,我的测试程序就无法工作:label.getAccessibleContext().getAccessibleText()将返回null,而使用强制的(AccessibleText) label.getAccessibleContext()转换将产生一个只从getIndexAtPoint返回-1的对象。

编辑:可以获得文本的一部分,而不必担心根据HTML标记的位置调整索引,而这些标记不是以可见文本的形式显示的。您只需在标签上维护两个字符串副本:一个只包含要显示的字符(下面的示例中是rawText),然后根据索引进行切片;另一个包含格式化的HTML版本,实际上将用作标签的文本(下面formatLabelText的结果)。因为getIndexAtPoint只返回相对于显示字符的索引,所以在第二个示例中获得所需的子字符串比获得原始的子字符串更容易。对index所做的唯一调整是将其舍入,以便用反斜杠分隔的组突出显示文本行。

代码语言:javascript
运行
复制
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.accessibility.AccessibleText;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class JLabelMouseHighlightDemo {
    private static String rawText = "C:\\aaa\\bbb\\ccc";
    private static JLabel label;

    private static String formatLabelText(int index) {
        if (index < 0) {
            index = 0;
        }
        if (index > rawText.length()) {
            index = rawText.length();
        }
        StringBuilder sb = new StringBuilder();
        sb.append("<html>");
        sb.append("<font color='red'>");
        sb.append(rawText.substring(0, index));
        sb.append("</font>");
        sb.append(rawText.substring(index));
        sb.append("</html>");
        return sb.toString();
    }

    private static int roundIndex(int index) {
        // This method rounds up index to always align with a group of
        // characters delimited by a backslash, so the red text will be
        // "C:\aaa\bbb" instead of just "C:\aaa\b".
        while (index < rawText.length() && rawText.charAt(index) != '\\') {
            index++;
        }
        return index;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        label = new JLabel(formatLabelText(0));
        label.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                AccessibleText accessibleText =
                        label.getAccessibleContext().getAccessibleText();
                Point p = e.getPoint();
                int index = accessibleText.getIndexAtPoint(p);
                index = roundIndex(index);
                label.setText(formatLabelText(index));
            }
        });
        frame.add(label);
        frame.setSize(200, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2016-05-06 08:58:54

这里有一种方法可以使@Alden的代码工作,而无需将原始文本存储在任何地方。事实证明,从JLabel获取视图使您可以访问文本的一个版本,并且去掉了所有的html。

代码语言:javascript
运行
复制
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.accessibility.AccessibleText;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.text.BadLocationException;
import javax.swing.text.View;

public class JLabelMouseDemo {
    private static String labelText = "<html>C:\\aaa\\bbb\\ccc</html>";
    private static JLabel label;
    private static JLabel substringDisplayLabel;

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        label = new JLabel(labelText);
        label.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                AccessibleText accessibleText =
                        label.getAccessibleContext().getAccessibleText();
                Point p = e.getPoint();
                int index = accessibleText.getIndexAtPoint(p);
                if (index >= 0) {
                    View view = (View) label.getClientProperty("html");
                    String strippedText = null;
                    try {
                        strippedText = view.getDocument().getText(0, accessibleText.getCharCount());
                    } catch (BadLocationException e1) {
                        e1.printStackTrace();
                        return;
                    }
                    // getIndexAtPoint seems to work from the end of a
                    // character, not the start, so you may want to add
                    // one to get the correct character
                    index++;
                    if (index > strippedText.length()) index = strippedText.length();
                    String partOfText = strippedText.substring(0, index);

                    // Display for demonstration purposes; you could also
                    // figure out how to highlight it or use the string or
                    // just the index in some other way to suit your needs.
                    substringDisplayLabel.setText(partOfText);
                }
            }
        });
        frame.add(label);
        substringDisplayLabel = new JLabel();
        frame.add(substringDisplayLabel, BorderLayout.SOUTH);
        frame.setSize(200, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32196327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档