Swing/TreeRowSelection のバックアップ(No.6)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TreeRowSelection へ行く。
- 1 (2011-01-17 (月) 15:24:56)
- 2 (2012-12-23 (日) 05:30:22)
- 3 (2013-01-13 (日) 16:41:29)
- 4 (2013-09-03 (火) 01:27:15)
- 5 (2014-11-04 (火) 15:56:35)
- 6 (2014-11-25 (火) 03:03:31)
- 7 (2014-12-02 (火) 01:22:43)
- 8 (2015-12-03 (木) 17:27:59)
- 9 (2015-12-07 (月) 02:47:50)
- 10 (2016-02-06 (土) 18:18:39)
- 11 (2017-07-05 (水) 14:00:09)
- 12 (2018-02-24 (土) 19:51:30)
- 13 (2018-07-06 (金) 16:35:23)
- 14 (2018-08-30 (木) 18:05:50)
- 15 (2020-08-28 (金) 15:51:15)
- 16 (2022-02-10 (木) 00:37:23)
- 17 (2022-02-11 (金) 15:21:56)
- 18 (2022-08-19 (金) 17:57:44)
- 19 (2022-08-20 (土) 22:15:25)
- 20 (2022-10-17 (月) 03:10:25)
- title: JTreeを行クリックで選択し、行全体を選択状態の背景色で描画 tags: [JTree, TreeCellRenderer, FocusListener] author: aterai pubdate: 2011-01-17T15:24:56+09:00 description: JTreeの行をクリックして選択し、行全体を選択状態の背景色で描画します。
概要
JTree
の行をクリックして選択し、行全体を選択状態の背景色で描画します。
Screenshot
Advertisement
サンプルコード
class RowSelectionTree extends JTree {
private static final Color SELC = new Color(100, 150, 200);
private Handler handler;
@Override public void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
if (getSelectionCount() > 0) {
g.setColor(SELC);
for (int i : getSelectionRows()) {
Rectangle r = getRowBounds(i);
g.fillRect(0, r.y, getWidth(), r.height);
}
}
super.paintComponent(g);
if (getLeadSelectionPath() != null) {
Rectangle r = getRowBounds(getRowForPath(getLeadSelectionPath()));
g.setColor(hasFocus() ? SELC.darker() : SELC);
g.drawRect(0, r.y, getWidth() - 1, r.height - 1);
}
}
@Override public void updateUI() {
removeFocusListener(handler);
super.updateUI();
setUI(new BasicTreeUI() {
@Override public Rectangle getPathBounds(JTree tree, TreePath path) {
if (tree != null && treeState != null) {
return getPathBounds(path, tree.getInsets(), new Rectangle());
}
return null;
}
private Rectangle getPathBounds(
TreePath path, Insets insets, Rectangle bounds) {
Rectangle rect = treeState.getBounds(path, bounds);
if (rect != null) {
rect.width = tree.getWidth();
rect.y += insets.top;
}
return rect;
}
});
handler = new Handler();
addFocusListener(handler);
setCellRenderer(handler);
setOpaque(false);
}
static class Handler extends DefaultTreeCellRenderer implements FocusListener {
@Override public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
JLabel l = (JLabel) super.getTreeCellRendererComponent(
tree, value, selected, expanded, leaf, row, hasFocus);
l.setBackground(selected ? SELC : tree.getBackground());
l.setOpaque(true);
return l;
}
@Override public void focusGained(FocusEvent e) {
e.getComponent().repaint();
}
@Override public void focusLost(FocusEvent e) {
e.getComponent().repaint();
}
}
}
View in GitHub: Java, Kotlin解説
以下のような設定で、JTree
を行選択できるように変更し、表示もNimbusLookAndFeel
風に行全体を選択状態の背景色で描画するようにしています。
BasicTreeUI#getPathBounds(...)
をオーバーライドして、ノードではなく、行のクリックで選択可能に変更JTree
の背景をsetOpaque(false)
で透明(非描画)にし、JTree#paintComponent(...)
をオーバーライドして選択された行を背景色で描画- 不透明にした
TreeCellRenderer
を使用して、ノードの選択色をJTree#paintComponent(...)
の背景色と同じものに変更 - 別コンポーネントにフォーカスが移動した場合、
LeadSelection
のBorder
を描画しない(選択背景色で上書き)ように設定- デフォルトではノードのみ再描画されるので、
FocusListener
を追加して、JTree
全体を再描画
- デフォルトではノードのみ再描画されるので、
参考リンク
- JTable でセルのないところに行っぽい表示を出せますか? - KrdLabの不定期日記
- Highlight a node's descendants in JTree - Santhosh Kumar's Weblog