• category: swing folder: AboveCellTreeToolTips title: JTreeのノードセル上にJToolTipを重ねて表示する tags: [JToolTip, JTree] author: aterai pubdate: 2019-05-20T15:44:11+09:00 description: JTreeのノードからアイコンやテキストを取得してJToolTipを生成し、それをノードセル上に重ねて表示します。 image: https://drive.google.com/uc?id=1tZNDwTfyPmQ6OctKkz3Badsbl0DSSO6L1A

概要

JTreeのノードからアイコンやテキストを取得してJToolTipを生成し、それをノードセル上に重ねて表示します。

サンプルコード

class TooltipTree extends JTree {
  protected final JLabel label = new JLabel() {
    @Override public Dimension getPreferredSize() {
      Dimension d = super.getPreferredSize();
      d.height = getRowHeight();
      return d;
    }
  };

  protected TooltipTree(TreeModel model) {
    super(model);
  }

  @Override public void updateUI() {
    super.updateUI();
    // setRowHeight(24);
    setCellRenderer(new TooltipTreeCellRenderer());
  }

  @Override public Point getToolTipLocation(MouseEvent e) {
    Point p = e.getPoint();
    int i = getRowForLocation(p.x, p.y);
    Rectangle cellBounds = getRowBounds(i);
    if (i >= 0 && Objects.nonNull(cellBounds) && cellBounds.contains(p.x, p.y)) {
      TreeSelectionModel tsm = getSelectionModel();
      Object node = getPathForRow(i).getLastPathComponent();
      // System.out.println(node);
      boolean hasFocus = hasFocus() && tsm.getLeadSelectionRow() == i;
      boolean isLeaf = getModel().isLeaf(node);
      TreeCellRenderer r = getCellRenderer();
      Component tcr = r.getTreeCellRendererComponent(
          this, node, isRowSelected(i), isExpanded(i), isLeaf, i, hasFocus);
      if (tcr instanceof JComponent
          && Objects.nonNull(((JComponent) tcr).getToolTipText())) {
        Point pt = cellBounds.getLocation();
        Insets ins = label.getInsets();
        pt.translate(-ins.left, -ins.top);
        label.setIcon(new RendererIcon(tcr, cellBounds));
        return pt;
      }
    }
    return null;
  }

  @Override public JToolTip createToolTip() {
    JToolTip tip = new JToolTip() {
      @Override public Dimension getPreferredSize() {
        return label.getPreferredSize();
      }
    };
    tip.setBorder(BorderFactory.createEmptyBorder());
    tip.setLayout(new BorderLayout());
    tip.setComponent(this);
    tip.add(label);
    return tip;
  }
}
View in GitHub: Java, Kotlin

解説

  • Draw directly above the cell
    • JTreeのノードセル上に重ねてJToolTipを表示
    • JTree#getRowBounds(int index)メソッドで取得した領域上にJToolTipを表示する
      • TreeCellRendererからノードアイコンを含めてJToolTipを生成
    • 参考: JListのセル上にToolTipを表示する
    • WindowsLookAndFeel以外で動作しない?
    • 葉ノードから親ノードにマウスカーソルを移動したときJToolTipの内容が変更されない場合がある?
      • 再現する条件がまだはっきりしない
  • Default location

参考リンク

コメント