• category: swing folder: ToolTipAfterMouseWheelEvent title: JListのセルのToolTipをMouseWheelEventに対応した表示位置に修正 tags: [JToolTip, JList, JScrollPane, MouseWheelListener, ToolTipManager] author: aterai pubdate: 2022-01-24T09:33:09+09:00 description: JScrollPane内のJListをMouseWheelで移動した後に表示されるToolTipの対象セルとその位置に修正します。 image: https://drive.google.com/uc?id=1wqY3utjMezRBlJ9j8WIest2ResTWWTMF

概要

JScrollPane内のJListMouseWheelで移動した後に表示されるToolTipの対象セルとその位置に修正します。

サンプルコード

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;
  }
}
View in GitHub: Java, Kotlin

解説

  • Default
    • たとえば先頭の0: 11111セルにマウスカーソルを移動した直後にすばやくマウスホイールを下方向に回転して別セル上にマウスカーソルが配置された状態でもツールチップ表示される内容は0: 11111で、その表示位置も現在のマウスカーソル付近ではなくJScrollPaneで隠されている0: 11111セルの位置になる
    • マウスホイール対応以前の実装なのでマウス移動イベント以外でカーソル直下のセルが変化することは想定されていない
    • JTableJTreeなどでも同様
  • MouseWheelListener
    • JScrollPaneMouseWheelListenerを追加し、ホイールイベントをSwingUtilities.convertMouseEvent(...)JListソースのマウスイベントに変換してToolTipManager.sharedInstance().mouseMoved(...)で実行
    • ToolTipManagerではMouseEventIDは考慮せずに位置のみ使用しているのでイベントソースの変更のみで十分
    • Tooltips, the mouse wheel and JScrollPane — oracle-tech
  • getToolTipLocation
    • JList#getToolTipText()JList#getToolTipLocation()をオーバーライドしてそれぞれMouseEvent#getPoint()Component#getMousePosition()(内部でMouseInfo.getPointerInfo()を使用)で取得したマウス位置が異なる場合は後者で取得したマウス位置でMouseEventを再作成して実行
    • Screen上にあるMouseの位置を取得する

参考リンク

コメント