6e1e44a9f7057748389047c5d7def8c0aabf7982
[nikiroo-utils.git] / src / be / nikiroo / utils / ui / ProgressBar.java
1 package be.nikiroo.utils.ui;
2
3 import java.awt.GridLayout;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.util.ArrayList;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 import javax.swing.JPanel;
12 import javax.swing.JProgressBar;
13 import javax.swing.SwingUtilities;
14
15 import be.nikiroo.utils.Progress;
16
17 /**
18 * A graphical control to show the progress of a {@link Progress}.
19 * <p>
20 * This control is <b>NOT</b> thread-safe.
21 *
22 * @author niki
23 */
24 public class ProgressBar extends JPanel {
25 private static final long serialVersionUID = 1L;
26
27 private Map<Progress, JProgressBar> bars;
28 private List<ActionListener> actionListeners;
29 private List<ActionListener> updateListeners;
30 private Progress pg;
31
32 public ProgressBar() {
33 bars = new HashMap<Progress, JProgressBar>();
34 actionListeners = new ArrayList<ActionListener>();
35 updateListeners = new ArrayList<ActionListener>();
36 }
37
38 public void setProgress(final Progress pg) {
39 this.pg = pg;
40
41 SwingUtilities.invokeLater(new Runnable() {
42 public void run() {
43 if (pg != null) {
44 final JProgressBar bar = new JProgressBar();
45 bar.setStringPainted(true);
46
47 bars.clear();
48 bars.put(pg, bar);
49
50 bar.setMinimum(pg.getMin());
51 bar.setMaximum(pg.getMax());
52 bar.setValue(pg.getProgress());
53 bar.setString(pg.getName());
54
55 pg.addProgressListener(new Progress.ProgressListener() {
56 public void progress(Progress progress, String name) {
57 final Progress.ProgressListener l = this;
58 SwingUtilities.invokeLater(new Runnable() {
59 public void run() {
60 Map<Progress, JProgressBar> newBars = new HashMap<Progress, JProgressBar>();
61 newBars.put(pg, bar);
62
63 bar.setMinimum(pg.getMin());
64 bar.setMaximum(pg.getMax());
65 bar.setValue(pg.getProgress());
66 bar.setString(pg.getName());
67
68 for (Progress pg : getChildrenAsOrderedList(pg)) {
69 JProgressBar bar = bars.get(pg);
70 if (bar == null) {
71 bar = new JProgressBar();
72 bar.setStringPainted(true);
73 }
74
75 newBars.put(pg, bar);
76
77 bar.setMinimum(pg.getMin());
78 bar.setMaximum(pg.getMax());
79 bar.setValue(pg.getProgress());
80 bar.setString(pg.getName());
81 }
82
83 if (ProgressBar.this.pg == null) {
84 bars.clear();
85 } else {
86 bars = newBars;
87
88 if (pg.isDone()) {
89 pg.removeProgressListener(l);
90 for (ActionListener listener : actionListeners) {
91 listener.actionPerformed(new ActionEvent(
92 ProgressBar.this, 0,
93 "done"));
94 }
95 }
96
97 update();
98 }
99 }
100 });
101 }
102 });
103 }
104
105 update();
106 }
107 });
108 }
109
110 public void addActionListener(ActionListener l) {
111 actionListeners.add(l);
112 }
113
114 public void clearActionListeners() {
115 actionListeners.clear();
116 }
117
118 public void addUpdateListener(ActionListener l) {
119 updateListeners.add(l);
120 }
121
122 public void clearUpdateListeners() {
123 updateListeners.clear();
124 }
125
126 public int getProgress() {
127 if (pg == null) {
128 return 0;
129 }
130
131 return pg.getProgress();
132 }
133
134 // only named ones
135 private List<Progress> getChildrenAsOrderedList(Progress pg) {
136 List<Progress> children = new ArrayList<Progress>();
137 for (Progress child : pg.getChildren()) {
138 if (child.getName() != null && !child.getName().isEmpty()) {
139 children.add(child);
140 }
141 children.addAll(getChildrenAsOrderedList(child));
142 }
143
144 return children;
145 }
146
147 private void update() {
148 invalidate();
149 removeAll();
150
151 if (pg != null) {
152 setLayout(new GridLayout(bars.size(), 1));
153 add(bars.get(pg), 0);
154 for (Progress child : getChildrenAsOrderedList(pg)) {
155 JProgressBar jbar = bars.get(child);
156 if (jbar != null) {
157 add(jbar);
158 }
159 }
160 }
161
162 validate();
163 repaint();
164
165 for (ActionListener listener : updateListeners) {
166 listener.actionPerformed(new ActionEvent(this, 0, "update"));
167 }
168 }
169 }