Swing/CursorOfCellComponent のバックアップ(No.8)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/CursorOfCellComponent へ行く。
- 1 (2014-09-17 (水) 02:24:35)
- 2 (2014-10-21 (火) 01:51:55)
- 3 (2015-11-13 (金) 00:54:53)
- 4 (2017-05-10 (水) 16:00:54)
- 5 (2018-02-20 (火) 17:28:52)
- 6 (2019-10-15 (火) 17:32:07)
- 7 (2021-05-22 (土) 04:39:47)
- 8 (2023-11-16 (木) 15:05:26)
- 9 (2023-12-14 (木) 10:27:18)
- 10 (2025-01-03 (金) 08:57:02)
- 11 (2025-01-03 (金) 09:01:23)
- 12 (2025-01-03 (金) 09:02:38)
- 13 (2025-01-03 (金) 09:03:21)
- 14 (2025-01-03 (金) 09:04:02)
- category: swing
folder: CursorOfCellComponent
title: JListのセル中に配置したコンポーネント毎にカーソルを変更する
tags: [JList, Cursor, ListCellRenderer]
author: aterai
pubdate: 2013-10-21T00:16:35+09:00
description: JListのセルに配置されているコンポーネントをマウスの座標から検索し、それに設定されたカーソルをJListに適用します。
image:
概要
JList
のセルに配置されているコンポーネントをマウスの座標から検索し、それに設定されたカーソルをJList
に適用します。
Screenshot

Advertisement
サンプルコード
class LinkCellList<E> extends JList<E> {
private int prevIndex = -1;
protected LinkCellList(ListModel<E> model) {
super(model);
}
@Override public void updateUI() {
setForeground(null);
setBackground(null);
setSelectionForeground(null);
setSelectionBackground(null);
super.updateUI();
setFixedCellHeight(32);
setCellRenderer(new LinkCellRenderer<>());
// TEST: putClientProperty("List.isFileList", Boolean.TRUE);
}
@Override protected void processMouseMotionEvent(MouseEvent e) {
Point pt = e.getPoint();
int i = locationToIndex(pt);
E s = getModel().getElementAt(i);
Component c = getCellRenderer().getListCellRendererComponent(
this, s, i, false, false);
Rectangle r = getCellBounds(i, i);
c.setBounds(r);
if (prevIndex != i) {
c.doLayout();
}
prevIndex = i;
pt.translate(-r.x, -r.y);
setCursor(
Optional.ofNullable(SwingUtilities.getDeepestComponentAt(c, pt.x, pt.y))
.map(Component::getCursor)
.orElse(Cursor.getDefaultCursor()));
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、以下の手順でイベントを取得しないセルレンダラー中のコンポーネントに応じたカーソルの変更を行っています。
JList
上をマウスカーソルを移動した時にカーソルのある行を取得- セルレンダラーに行番号や文字列などの値を渡して描画用のコンポーネントを取得
- 描画用コンポーネントの位置とサイズを
JList#getCellBounds()
で取得したセル領域に変更Component#setBounds(...)
で描画用コンポーネントの位置とサイズを変更してもその子コンポーネントのレイアウトは更新されない
Component#doLayout()
でレイアウトを更新- このサンプルで使用している
FlowLayout
ではJLabel
に設定する文字列の長さで後続のコンポーネントの位置が変化するので、Component#doLayout()
を実行してレイアウトの更新を行う必要がある - ただし、同じ行の場合は描画用コンポーネントも前回と同じはずなのでレイアウトを更新する必要はない
- JListのセル内にJButtonを配置するのように、すべての行のレイアウトが同じ(内容に応じて変化しない)場合もレイアウトを更新する必要はない
- このサンプルで使用している
JList
基準のカーソル位置座標を描画用コンポーネント基準に変更SwingUtilities.getDeepestComponentAt(...);
で描画用コンポーネントから変更した座標の下にある子コンポーネントを取得- 取得した子コンポーネントのカーソルを
JList
のカーソルとして設定
参考リンク
JListのセルレンダラーとして設定したJEditorPaneからHyperlinkEventを取得する