Swing/TreeNodeProgressBar のバックアップ(No.3)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TreeNodeProgressBar へ行く。
- 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:
概要
JTree
のノードにJProgressBar
を表示するTreeCellRenderer
を設定します。
Screenshot
Advertisement
サンプルコード
class ProgressBarRenderer extends DefaultTreeCellRenderer {
private int nodeWidth = 100;
private static int barHeight = 4;
private final JProgressBar b = new JProgressBar(0, 100) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = barHeight;
d.width = nodeWidth;
return d;
}
@Override public void updateUI() {
super.updateUI();
setUI(new BasicProgressBarUI());
}
};
private final JPanel p = new JPanel(new BorderLayout());
public ProgressBarRenderer() {
super();
b.setOpaque(false);
p.setOpaque(false);
b.setStringPainted(true);
b.setString("");
b.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
@Override public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
Object o = ((DefaultMutableTreeNode) value).getUserObject();
JComponent c = (JComponent) super.getTreeCellRendererComponent(
tree, value, selected, expanded, leaf, row, hasFocus);
if (!(o instanceof ProgressObject)) {
return c;
}
ProgressObject n = (ProgressObject) o;
int i = n.getValue();
b.setValue(i);
FontMetrics metrics = c.getFontMetrics(c.getFont());
int ww = getX() + getIcon().getIconWidth() + getIconTextGap()
+ metrics.stringWidth(n.title);
nodeWidth = ww;
p.removeAll();
p.add(c);
p.add(i < 100 ? b : Box.createVerticalStrut(barHeight), BorderLayout.SOUTH);
return p;
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、タスクが実行中の場合、ノードの幅(アイコンと文字列)だけの長さを持つJProgressBar
を配置するTreeCellRenderer
を作成して、これをJTree#setCellRenderer(...)
で設定しています。
- スタートボタンを押すと、
JButton
を選択不可にし、SwingWorker
を起動して葉以外のノードをすべて捜査 - 取得した各ノードで、ダミーの
SwingWorker
をExecutorService#execute(...)
で起動し、進捗をJProgressBar
を配置したTreeCellRenderer
で表示- ダミータスクが終了するとそのノードを展開
- すべてのノードのタスクが終了したことを
ExecutorService#awaitTermination(...)
で検知したら、JButton
を選択可に戻す