JTreeのノードにJProgressBarを表示する
Total: 3597
, Today: 2
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
JTree
のノードにJProgressBar
を表示するTreeCellRenderer
を設定します。
Screenshot
Advertisement
サンプルコード
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, Kotlin解説
上記のサンプルでは、タスクが実行中の場合はノードの幅(アイコンと文字列の合計)と同じサイズのJProgressBar
を配置するTreeCellRenderer
を作成し、これをJTree#setCellRenderer(...)
で設定しています。
- スタートボタンを押すとその
JButton
を選択不可に設定し、SwingWorker
を起動して葉以外のノードをすべて捜査 - 取得した各ノードで
SwingWorker
を起動し、進捗をJProgressBar
を配置したTreeCellRenderer
で表示- 仮設定のタスクが終了するとそのノードを展開
- すべてのノードのタスクが終了したことを
ExecutorService#awaitTermination(...)
で検知したらJButton
を選択可に変更