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