JListのセルのToolTipをMouseWheelEventに対応した表示位置に修正
Total: 1345
, Today: 1
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
JScrollPane
内のJList
をMouseWheel
で移動した後に表示されるToolTip
の対象セルとその位置に修正します。
Screenshot
Advertisement
サンプルコード
JList<String> list1 = new JList<String>(model) {
@Override public void updateUI() {
super.updateUI();
setCellRenderer(new TooltipListCellRenderer<>());
}
};
JScrollPane scroll1 = new JScrollPane(list1);
scroll1.addMouseWheelListener(e -> {
JScrollPane scrollPane = (JScrollPane) e.getComponent();
Component view = scrollPane.getViewport().getView();
MouseEvent event = SwingUtilities.convertMouseEvent(scrollPane, e, view);
ToolTipManager.sharedInstance().mouseMoved(event);
});
View in GitHub: Java, Kotlin解説
Default
- たとえば先頭の
0: 11111
セルにマウスカーソルを移動した直後にすばやくマウスホイールを下方向に回転して別セル上にマウスカーソルが配置された状態でもツールチップ表示される内容は0: 11111
で、その表示位置も現在のマウスカーソル付近ではなくJScrollPane
で隠されている0: 11111
セルの位置になる - マウスホイール対応以前の実装なのでマウス移動イベント以外でカーソル直下のセルが変化することは想定されていない
JTable
、JTree
などでも同様
- たとえば先頭の
MouseWheelListener
- 親
JScrollPane
にMouseWheelListener
を追加し、ホイールイベントをSwingUtilities.convertMouseEvent(...)
でJList
ソースのマウスイベントに変換してToolTipManager.sharedInstance().mouseMoved(...)
で実行 JToolTip
表示後、マウスカーソルを移動せずにマウスホイールのみ回転して直下のセルが変更された場合でも同位置でツールチップテキストの更新が可能ToolTipManager
ではMouseEvent
のID
は考慮せずに位置のみ使用しているのでイベントソースの変更のみで十分- Tooltips, the mouse wheel and JScrollPane — oracle-tech
- 親
getToolTipLocation
JList#getToolTipText()
とJList#getToolTipLocation()
をオーバーライドしてそれぞれMouseEvent#getPoint()
とComponent#getMousePosition()
(内部でMouseInfo.getPointerInfo()
を使用)で取得したマウス位置が異なる場合は後者で取得したマウス位置でMouseEvent
を再作成して実行- Screen上にあるMouseの位置を取得する
class TooltipList<E> extends JList<E> {
protected TooltipList(ListModel<E> m) {
super(m);
}
@Override public String getToolTipText(MouseEvent e) {
Point p0 = e.getPoint();
Point p1 = getMousePosition();
if (p1 != null && !p1.equals(p0)) {
int i = locationToIndex(p1);
Rectangle cellBounds = getCellBounds(i, i);
if (i >= 0 && cellBounds != null && cellBounds.contains(p1.x, p1.y)) {
MouseEvent event = new MouseEvent(
e.getComponent(),
MouseEvent.MOUSE_MOVED,
e.getWhen(),
e.getModifiers(),
p1.x,
p1.y,
e.getClickCount(),
e.isPopupTrigger()
);
return super.getToolTipText(event);;
}
}
return super.getToolTipText(e);
}
@Override public Point getToolTipLocation(MouseEvent e) {
Point p0 = e.getPoint();
Point p1 = getMousePosition();
if (p1 != null && !p1.equals(p0)) {
int i = locationToIndex(p1);
Rectangle cellBounds = getCellBounds(i, i);
if (i >= 0 && cellBounds != null && cellBounds.contains(p1.x, p1.y)) {
return new Point(p1.x, p1.y + cellBounds.height);
}
}
return null;
}
}
参考リンク
- Tooltips, the mouse wheel and JScrollPane — oracle-tech
- JListのセル上にToolTipを表示する
- Screen上にあるMouseの位置を取得する