---
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: https://lh4.googleusercontent.com/-SBg5NOTGinM/UrcLHfPzXVI/AAAAAAAAB84/HD0k-sWiJGo/s800/TreeNodeProgressBar.png
---
* Summary [#summary]
`JTree`のノードに`JProgressBar`を表示する`TreeCellRenderer`を設定します。
#download(https://lh4.googleusercontent.com/-SBg5NOTGinM/UrcLHfPzXVI/AAAAAAAAB84/HD0k-sWiJGo/s800/TreeNodeProgressBar.png)
* Source Code Examples [#sourcecode]
#code(link){{
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;
}
}
}}
* Description [#explanation]
* Description [#description]
上記のサンプルでは、タスクが実行中の場合はノードの幅(アイコンと文字列の合計)と同じサイズの`JProgressBar`を配置する`TreeCellRenderer`を作成し、これを`JTree#setCellRenderer(...)`で設定しています。
- スタートボタンを押すとその`JButton`を選択不可に設定し、`SwingWorker`を起動して葉以外のノードをすべて捜査
- 取得した各ノードで`SwingWorker`を起動し、進捗を`JProgressBar`を配置した`TreeCellRenderer`で表示
-- 仮設定のタスクが終了するとそのノードを展開
- すべてのノードのタスクが終了したことを`ExecutorService#awaitTermination(...)`で検知したら`JButton`を選択可に変更
* Reference [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/tree/DefaultTreeCellRenderer.html DefaultTreeCellRenderer (Java Platform SE 8)]
[https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/ExecutorService.html ExecutorService (Java Platform SE 8)]
* Comment [#comment]
#comment
#comment