Swing/TreeNodeProgressBar のバックアップ(No.12)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TreeNodeProgressBar へ行く。
- 1 (2014-10-02 (木) 19:50:57)
- 2 (2015-03-05 (木) 00:35:38)
- 3 (2017-01-27 (金) 18:57:58)
- 4 (2017-12-16 (土) 20:32:20)
- 5 (2019-12-09 (月) 21:00:28)
- 6 (2021-06-11 (金) 15:05:01)
- 7 (2022-08-22 (月) 17:40:31)
- 8 (2025-01-03 (金) 08:57:02)
- 9 (2025-01-03 (金) 09:01:23)
- 10 (2025-01-03 (金) 09:02:38)
- 11 (2025-01-03 (金) 09:03:21)
- 12 (2025-01-03 (金) 09:04:02)
- category: swing
folder: TreeNodeProgressBar
title: JTreeのノードにJProgressBarを表示する
tags: [JTree, JProgressBar, DefaultTreeCellRenderer, SwingWorker, ExecutorService]
author: aterai
pubdate: 2013-12-23T01:15:16+09:00
description: JTreeのノードにJProgressBarを表示するTreeCellRendererを設定します。
image:
Summary
JTree
のノードにJProgressBar
を表示するTreeCellRenderer
を設定します。
Screenshot

Advertisement
Source Code Examples
class ProgressBarRenderer extends DefaultTreeCellRenderer {
// protected int nodeWidth = 100;
protected static final int BAR_HEIGHT = 4;
private final JProgressBar progress = new JProgressBar() {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
// d.setSize(nodeWidth, BAR_HEIGHT);
d.height = BAR_HEIGHT;
return d;
}
@Override public void updateUI() {
super.updateUI();
setUI(new BasicProgressBarUI());
setStringPainted(true);
setString("");
setOpaque(false);
setBorder(BorderFactory.createEmptyBorder());
}
};
private final Container renderer = new JPanel(new BorderLayout()) {
@Override public void updateUI() {
super.updateUI();
setOpaque(false);
}
};
@Override public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
Component c = super.getTreeCellRendererComponent(
tree, value, selected, expanded, leaf, row, hasFocus);
Object o = ((DefaultMutableTreeNode) value).getUserObject();
if (o instanceof ProgressObject) {
ProgressObject n = (ProgressObject) o;
int i = n.getValue();
progress.setValue(i);
// int titleWidth = c.getFontMetrics(c.getFont()).stringWidth(n.getTitle());
// int ww = getX() + getIcon().getIconWidth() + getIconTextGap() + titleWidth;
// nodeWidth = ww;
renderer.removeAll();
renderer.add(c);
if (i < progress.getMaximum()) {
renderer.add(progress, BorderLayout.SOUTH);
}
c = renderer;
}
return c;
}
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 18;
return d;
}
}
View in GitHub: Java, KotlinExplanation
上記のサンプルでは、タスクが実行中の場合はノードの幅(アイコンと文字列の合計)と同じサイズのJProgressBar
を配置するTreeCellRenderer
を作成し、これをJTree#setCellRenderer(...)
で設定しています。
- スタートボタンを押すとその
JButton
を選択不可に設定し、SwingWorker
を起動して葉以外のノードをすべて捜査 - 取得した各ノードで
SwingWorker
を起動し、進捗をJProgressBar
を配置したTreeCellRenderer
で表示- 仮設定のタスクが終了するとそのノードを展開
- すべてのノードのタスクが終了したことを
ExecutorService#awaitTermination(...)
で検知したらJButton
を選択可に変更