我正在使用 JList 来显示元素。我想提供一个弹出菜单来与鼠标下的特定元素进行交互。我正在使用 MouseInputListener、isPopupTrigger()、locationToIndex()、getCellBounds() 等。我没有为此发布代码,因为这不是重点,只是问题的背景。我最终想要做的只是当正确的(平台和 UI 相关的)操作发生在 JList 单元格中的文本上时才发布弹出菜单 - 而不仅仅是行中的任何位置。我的 JList 位于 ScrollPane 中,而 ScrollPane 位于 SplitPane 中。 JList 单元格的宽度可以比文本大得多。如果当 SplitPane 远大于文本范围时,用户能够通过单击行中文本的最右侧来发布弹出窗口,则将不清楚正在操作哪一行。我不想使用弹出菜单选择用户将与之交互的行,因为选择在此上下文中具有不同的含义。所以基本问题是:如何确定弹出触发发生时鼠标位置是否实际上位于该行中的文本上方,而不仅仅是在该行中?
最佳答案
如果 JList 的单元格渲染器返回 JLabels(默认情况下会返回 JLabels,或者如果您已将渲染器设置为 DefaultListCellRenderer),则可以使用 SwingUtilities.layoutCompoundLabel确定文本的边界:
static <E> boolean isOverText(Point location,
JList<E> list) {
int index = list.locationToIndex(location);
if (index < 0) {
return false;
}
E value = list.getModel().getElementAt(index);
ListCellRenderer<? super E> renderer = list.getCellRenderer();
Component c = renderer.getListCellRendererComponent(list, value, index,
list.isSelectedIndex(index),
list.getSelectionModel().getLeadSelectionIndex() == index);
if (c instanceof JLabel) {
JLabel label = (JLabel) c;
Icon icon = null;
if (!label.isEnabled()) {
icon = label.getDisabledIcon();
}
if (icon == null) {
icon = label.getIcon();
}
Rectangle listItemBounds =
SwingUtilities.calculateInnerArea(label, null);
Rectangle cellBounds = list.getCellBounds(index, index);
listItemBounds.translate(cellBounds.x, cellBounds.y);
listItemBounds.width = cellBounds.width;
listItemBounds.height = cellBounds.height;
Rectangle textBounds = new Rectangle();
Rectangle iconBounds = new Rectangle();
SwingUtilities.layoutCompoundLabel(label,
label.getFontMetrics(label.getFont()),
label.getText(),
icon,
label.getVerticalAlignment(),
label.getHorizontalAlignment(),
label.getVerticalTextPosition(),
label.getHorizontalTextPosition(),
listItemBounds,
iconBounds,
textBounds,
label.getIconTextGap());
return textBounds.contains(location);
}
关于java - 如何检测鼠标(指针)何时位于 JList 中的文本上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26322503/