15dca6cce1655352e72ebba268086c6c239cdcca
[fanfix.git] / ui / WaitingDialog.java
1 package be.nikiroo.utils.ui;
2
3 import java.awt.Window;
4
5 import javax.swing.JDialog;
6 import javax.swing.JLabel;
7 import javax.swing.SwingWorker;
8 import javax.swing.border.EmptyBorder;
9
10 import be.nikiroo.utils.Progress;
11 import be.nikiroo.utils.Progress.ProgressListener;
12
13 /**
14 * A small waiting dialog that will show only if more than X milliseconds passed
15 * before we dismiss it.
16 *
17 * @author niki
18 */
19 public class WaitingDialog extends JDialog {
20 private static final long serialVersionUID = 1L;
21
22 private boolean waitScreen;
23 private Object waitLock = new Object();
24
25 private Progress pg;
26 private ProgressListener pgl;
27
28 /**
29 * Create a new {@link WaitingDialog}.
30 *
31 * @param parent
32 * the parent/owner of this {@link WaitingDialog}
33 * @param delayMs
34 * the delay after which to show the dialog if it is still not
35 * dismiss (see {@link WaitingDialog#dismiss()})
36 */
37 public WaitingDialog(Window parent, long delayMs) {
38 this(parent, delayMs, null, null);
39 }
40
41 /**
42 * Create a new {@link WaitingDialog}.
43 *
44 * @param parent
45 * the parent/owner of this {@link WaitingDialog}
46 * @param delayMs
47 * the delay after which to show the dialog if it is still not
48 * dismiss (see {@link WaitingDialog#dismiss()})
49 * @param pg
50 * the {@link Progress} to listen on -- when it is
51 * {@link Progress#done()}, this {@link WaitingDialog} will
52 * automatically be dismissed as if
53 * {@link WaitingDialog#dismiss()} was called
54 */
55 public WaitingDialog(Window parent, long delayMs, Progress pg) {
56 this(parent, delayMs, pg, null);
57 }
58
59 /**
60 * Create a new {@link WaitingDialog}.
61 *
62 * @param parent
63 * the parent/owner of this {@link WaitingDialog}
64 * @param delayMs
65 * the delay after which to show the dialog if it is still not
66 * dismiss (see {@link WaitingDialog#dismiss()})
67 * @param waitingText
68 * a waiting text to display (note: you may want to subclass it
69 * for nicer UI)
70 */
71 public WaitingDialog(Window parent, long delayMs, String waitingText) {
72 this(parent, delayMs, null, waitingText);
73 }
74
75 /**
76 * Create a new {@link WaitingDialog}.
77 *
78 * @param parent
79 * the parent/owner of this {@link WaitingDialog}
80 * @param delayMs
81 * the delay after which to show the dialog if it is still not
82 * dismiss (see {@link WaitingDialog#dismiss()})
83 * @param pg
84 * the {@link Progress} to listen on -- when it is
85 * {@link Progress#done()}, this {@link WaitingDialog} will
86 * automatically be dismissed as if
87 * {@link WaitingDialog#dismiss()} was called
88 * @param waitingText
89 * a waiting text to display (note: you may want to subclass it
90 * for nicer UI)
91 */
92 public WaitingDialog(Window parent, long delayMs, Progress pg,
93 String waitingText) {
94 super(parent);
95
96 this.pg = pg;
97
98 if (waitingText != null) {
99 JLabel waitingTextLabel = new JLabel(waitingText);
100 this.add(waitingTextLabel);
101 waitingTextLabel.setBorder(new EmptyBorder(10, 10, 10, 10));
102 this.pack();
103 }
104
105 if (pg != null) {
106 pgl = new ProgressListener() {
107 @Override
108 public void progress(Progress progress, String name) {
109 if (WaitingDialog.this.pg.isDone()) {
110 // Must be done out of this thread (cannot remove a pgl
111 // from a running pgl)
112 new SwingWorker<Void, Void>() {
113 @Override
114 protected Void doInBackground() throws Exception {
115 return null;
116 }
117
118 @Override
119 public void done() {
120 dismiss();
121 }
122 }.execute();
123 }
124 }
125 };
126
127 pg.addProgressListener(pgl);
128
129 if (pg.isDone()) {
130 dismiss();
131 return;
132 }
133 }
134
135 final long delay = delayMs;
136 new Thread(new Runnable() {
137 @Override
138 public void run() {
139 try {
140 Thread.sleep(delay);
141 } catch (InterruptedException e) {
142 }
143
144 synchronized (waitLock) {
145 if (!waitScreen) {
146 waitScreen = true;
147 setVisible(true);
148 }
149 }
150 }
151 }).start();
152 }
153
154 /**
155 * Notify this {@link WaitingDialog} that the job is done, and dismiss it if
156 * it was already showing on screen (or never show it if it was not).
157 */
158 public void dismiss() {
159 synchronized (waitLock) {
160 if (waitScreen) {
161 setVisible(false);
162 }
163 waitScreen = true;
164 }
165
166 if (pg != null) {
167 pg.removeProgressListener(pgl);
168 }
169 }
170 }