如何根据鼠标指针从JLabel中获取文本的一部分
How to get the part of the text from JLabel according mouse pointer
有谁知道如何获取从JLabel
开头到鼠标指针的那部分文字?例如,假设我们有一个带有文本 'C:\aaa\bbb\ccc' 的 JLabel
。用户将鼠标指针指向字符 'bbb',所以我想获取文本 'C:\aaa\bbb'。现在,当我有了这部分文本时,我可以改变它的颜色。我认为将为此使用 html。
Java 辅助功能 API 方便地包含一个 getIndexAtPoint
方法作为 AccessibleText
接口的一部分,将位置(例如鼠标指针的位置)转换为该位置的字符索引:
Given a point in local coordinates, return the zero-based index of the character under that Point. If the point is invalid, this method returns -1.
下面是一个测试程序,使用此方法获取您要求的字符串部分:
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 的 AccessibleText 类型的对象可能并不总是有效:据我所知,只有当 JLabel 显示 HTML 文本时才有可能。 JLabel source:
似乎也支持这一点
public AccessibleText getAccessibleText() {
View view = (View)JLabel.this.getClientProperty("html");
if (view != null) {
return this;
} else {
return null;
}
}
我并没有声称完全理解该代码中发生了什么,或者为什么非 HTML 文本无法使用辅助功能,但是当 JLabel 包含普通文本而不是 HTML 文本:label.getAccessibleContext().getAccessibleText()
将 return null
,并且使用 (AccessibleText) label.getAccessibleContext()
的强制转换将产生一个仅 returned [=18] 的对象=] 来自 getIndexAtPoint
.
编辑:可以获取文本的一部分,而不必担心根据未显示为可见文本的 HTML 标签的位置调整索引。您只需要维护标签上字符串的两份副本:一份仅包含要显示的字符(下例中的 rawText
),将根据索引进行切片,另一份包含格式化的 HTML 实际用作标签文本的版本(下面 formatLabelText
的结果)。因为 getIndexAtPoint
returns 是一个仅与显示的字符相关的索引,所以在第二个示例中获取所需的子字符串比我的原始示例更容易。对 index
所做的唯一调整是将其四舍五入,以便突出显示的文本与反斜杠分隔的组对齐。
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);
}
}
这是一种无需在任何地方存储原始文本即可使@Alden 的代码工作的方法。事实证明,从 JLabel 获取视图可以让您访问一个文本版本,其中所有 html 都被删除了。
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);
}
}
有谁知道如何获取从JLabel
开头到鼠标指针的那部分文字?例如,假设我们有一个带有文本 'C:\aaa\bbb\ccc' 的 JLabel
。用户将鼠标指针指向字符 'bbb',所以我想获取文本 'C:\aaa\bbb'。现在,当我有了这部分文本时,我可以改变它的颜色。我认为将为此使用 html。
Java 辅助功能 API 方便地包含一个 getIndexAtPoint
方法作为 AccessibleText
接口的一部分,将位置(例如鼠标指针的位置)转换为该位置的字符索引:
Given a point in local coordinates, return the zero-based index of the character under that Point. If the point is invalid, this method returns -1.
下面是一个测试程序,使用此方法获取您要求的字符串部分:
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 的 AccessibleText 类型的对象可能并不总是有效:据我所知,只有当 JLabel 显示 HTML 文本时才有可能。 JLabel source:
似乎也支持这一点public AccessibleText getAccessibleText() {
View view = (View)JLabel.this.getClientProperty("html");
if (view != null) {
return this;
} else {
return null;
}
}
我并没有声称完全理解该代码中发生了什么,或者为什么非 HTML 文本无法使用辅助功能,但是当 JLabel 包含普通文本而不是 HTML 文本:label.getAccessibleContext().getAccessibleText()
将 return null
,并且使用 (AccessibleText) label.getAccessibleContext()
的强制转换将产生一个仅 returned [=18] 的对象=] 来自 getIndexAtPoint
.
编辑:可以获取文本的一部分,而不必担心根据未显示为可见文本的 HTML 标签的位置调整索引。您只需要维护标签上字符串的两份副本:一份仅包含要显示的字符(下例中的 rawText
),将根据索引进行切片,另一份包含格式化的 HTML 实际用作标签文本的版本(下面 formatLabelText
的结果)。因为 getIndexAtPoint
returns 是一个仅与显示的字符相关的索引,所以在第二个示例中获取所需的子字符串比我的原始示例更容易。对 index
所做的唯一调整是将其四舍五入,以便突出显示的文本与反斜杠分隔的组对齐。
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);
}
}
这是一种无需在任何地方存储原始文本即可使@Alden 的代码工作的方法。事实证明,从 JLabel 获取视图可以让您访问一个文本版本,其中所有 html 都被删除了。
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);
}
}