Skip to content

Commit 0901b0d

Browse files
committed
Updated AsyncSwingWorker and ProgressMonitorDemo
1 parent b9e94e9 commit 0901b0d

File tree

10 files changed

+223
-103
lines changed

10 files changed

+223
-103
lines changed
2.05 MB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20200430164525
1+
20200501101751
2.05 MB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20200430164525
1+
20200501101751
748 Bytes
Binary file not shown.

sources/net.sf.j2s.java.core/src/javajs/async/AsyncSwingWorker.java

Lines changed: 116 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
*
2121
* Whereas a standard SwingWorker would execute done() long before the
2222
* asynchronous task completed, this class will wait until progress has been
23-
* asynchronously set to 100 or the task is cancelled before executing that
24-
* method.
23+
* asynchronously set greater or equal to its max value or the task is canceled
24+
* before executing that method.
2525
*
2626
* Three methods must be supplied by the subclass:
2727
*
@@ -31,11 +31,11 @@
3131
*
3232
* void doneAsync()
3333
*
34-
* Both initAsync() and doneAsync() are technically optional - they may be empty.
35-
* doInBackgroundAsync(), however, is the key method where, like SwingWorker's
36-
* doInBackground, the main work is done. The supplied progress parameter
37-
* reminds the subclass of where it is at, and the return value allows the
38-
* subclass to update the progress field in both the SwingWorker and the
34+
* Both initAsync() and doneAsync() are technically optional - they may be
35+
* empty. doInBackgroundAsync(), however, is the key method where, like
36+
* SwingWorker's doInBackground, the main work is done. The supplied progress
37+
* parameter reminds the subclass of where it is at, and the return value allows
38+
* the subclass to update the progress field in both the SwingWorker and the
3939
* ProgressMonitor.
4040
*
4141
*
@@ -45,7 +45,10 @@
4545
public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implements StateMachine {
4646

4747

48-
protected int progress = 0;
48+
public static final String DONE_ASYNC = "DONE_ASYNC";
49+
public static final String CANCELED_ASYNC = "CANCELED_ASYNC";
50+
51+
protected int progressAsync;
4952

5053
/**
5154
* Override to provide initial tasks.
@@ -54,23 +57,26 @@ public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implement
5457

5558
/**
5659
* Given the last progress, do some portion of the task that the SwingWorker would do in the background, and return the new progress.
57-
* returning 100 will complete the task.
60+
* returning max or above will complete the task.
5861
*
5962
* @param progress
6063
* @return new progress
6164
*/
6265
abstract public int doInBackgroundAsync(int progress);
6366

6467
/**
65-
* Do something when the task is finished or cancelled.
68+
* Do something when the task is finished or canceled.
6669
*
6770
*/
6871
abstract public void doneAsync();
6972

7073

71-
private ProgressMonitor progressMonitor;
72-
private int delayMillis;
73-
private String note;
74+
protected ProgressMonitor progressMonitor;
75+
protected int delayMillis;
76+
protected String note;
77+
protected int min;
78+
protected int max;
79+
protected int progressPercent;
7480

7581
/**
7682
* Construct an asynchronous SwingWorker task that optionally will display a
@@ -83,15 +89,55 @@ public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implement
8389
* @param title A non-null title indicates we want to use a ProgressMonitor with that title line.
8490
*
8591
* @param delayMillis A positive number indicating the delay we want before executions, during which progress will be reported.
92+
*
93+
* @param min The first progress value. No range limit.
94+
*
95+
* @param max The last progress value. No range limit; may be greater than min.
96+
*
8697
*/
87-
public AsyncSwingWorker(Component owner, String title, int delayMillis) {
98+
public AsyncSwingWorker(Component owner, String title, int delayMillis, int min, int max) {
8899
if (title != null) {
89-
progressMonitor = new ProgressMonitor(owner, title, "", 0, 100);
90-
progressMonitor.setProgress(0); // displays monitor
100+
progressMonitor = new ProgressMonitor(owner, title, "", Math.min(min, max), Math.max(min, max));
101+
progressMonitor.setProgress(Math.min(min, max)); // displays monitor
91102
}
92103
this.delayMillis = Math.max(1, delayMillis);
104+
this.min = min;
105+
this.max = max;
106+
}
107+
108+
public int getMinimum() {
109+
return min;
110+
}
111+
112+
public void setMinimum(int min) {
113+
this.min = min;
114+
if (progressMonitor != null)
115+
progressMonitor.setMinimum(min);
116+
}
117+
118+
public int getMaximum() {
119+
return max;
120+
}
121+
122+
public void setMaximum(int max) {
123+
if (progressMonitor != null)
124+
progressMonitor.setMaximum(max);
125+
this.max = max;
126+
}
127+
128+
129+
public int getProgressPercent() {
130+
return progressPercent;
131+
}
132+
133+
public void setNote(String note) {
134+
this.note = note;
135+
if (progressMonitor != null)
136+
progressMonitor.setNote(note);
93137
}
94138

139+
140+
95141
/**
96142
* Cancel the asynchronous process.
97143
*
@@ -101,12 +147,12 @@ public void cancelAsync() {
101147
}
102148

103149
/**
104-
* Check to see if the asynchronous process has been cancelled.
150+
* Check to see if the asynchronous process has been canceled.
105151
*
106152
* @return true if StateHelper is not alive anymore
107153
*
108154
*/
109-
public boolean isCancelledAsync() {
155+
public boolean isCanceledAsync() {
110156
return !helper.isAlive();
111157
}
112158

@@ -126,7 +172,7 @@ public boolean isDoneAsync() {
126172
* @param progress
127173
* @return
128174
*/
129-
public String setNote(int progress) {
175+
public String getNote(int progress) {
130176
return String.format("Completed %d%%.\n", progress);
131177
}
132178

@@ -140,9 +186,25 @@ public String getNote() {
140186
}
141187

142188
public int getProgressAsync() {
143-
return progress;
189+
return progressAsync;
144190
}
145191

192+
/**
193+
* Set the [min,max] progress safely.
194+
*
195+
* SwingWorker only allows progress between 0 and 100.
196+
* This method safely translates [min,max] to [0,100].
197+
*
198+
* @param n
199+
*/
200+
public void setProgressAsync(int n) {
201+
n = (max > min ? Math.max(min, Math.min(n, max))
202+
: Math.max(max, Math.min(n, min)));
203+
progressAsync = n;
204+
n = (int) ((n - min) * 100 / (max - min));
205+
n = (n < 0 ? 0 : n > 100 ? 100 : n);
206+
progressPercent = n;
207+
}
146208

147209

148210
///// the StateMachine /////
@@ -179,36 +241,41 @@ public boolean stateLoop() {
179241
while (helper.isAlive()) {
180242
switch (helper.getState()) {
181243
case STATE_INIT:
244+
setProgressAsync(min);
182245
initAsync();
183246
helper.setState(STATE_WAIT);
184247
continue;
185248
case STATE_LOOP:
186-
progress = doInBackgroundAsync(progress);
187-
progress = Math.min(progress, 100);
188-
note = setNote(progress);
189-
if (progressMonitor != null) {
190-
progressMonitor.setNote(note);
191-
progressMonitor.setProgress(progress);
192-
}
193-
if (progress >= 100 || isCancelled()) {
249+
if (checkCanceled()) {
194250
helper.setState(STATE_DONE);
251+
firePropertyChange("state", null, CANCELED_ASYNC);
252+
continue;
195253
} else {
196-
helper.setState(STATE_WAIT);
254+
progressAsync = doInBackgroundAsync(progressAsync);
255+
setProgressAsync(progressAsync);
256+
setNote(getNote(progressAsync));
257+
setProgress(progressPercent);
258+
if (progressMonitor != null)
259+
progressMonitor.setProgress(max > min ? progressAsync : max + min - progressAsync);
260+
helper.setState(progressAsync == max ? STATE_DONE : STATE_WAIT);
261+
continue;
197262
}
198-
setProgress(progress);
199-
continue;
200263
case STATE_WAIT:
201264
helper.setState(STATE_LOOP);
202265
helper.sleep(delayMillis);
203266
return true;
267+
default:
204268
case STATE_DONE:
205-
// Put the reallyDone() method on the AWTEventQueue
206-
// just as the done() method was.
269+
if (progressMonitor != null)
270+
progressMonitor.close();
271+
// Put the doneAsync() method on the AWTEventQueue
272+
// just as for SwingWorker.done().
207273
SwingUtilities.invokeLater(new Runnable() {
208274

209275
@Override
210276
public void run() {
211277
doneAsync();
278+
firePropertyChange("state", null, DONE_ASYNC);
212279
}
213280

214281
});
@@ -218,16 +285,28 @@ public void run() {
218285
return false;
219286
}
220287

221-
//// final SwingWorker methods not to be used by subclasses ////
222-
288+
private boolean checkCanceled() {
289+
if (isMonitorCanceled() || isCancelled()) {
290+
helper.interrupt();
291+
return true;
292+
}
293+
return false;
294+
}
295+
296+
//// final SwingWorker methods not to be used by subclasses ////
297+
298+
private boolean isMonitorCanceled() {
299+
return (progressMonitor != null && progressMonitor.isCanceled());
300+
}
301+
223302
/**
224303
* see SwingWorker, made final here.
225304
*
226305
*/
227306
@Override
228307
final protected Void doInBackground() throws Exception {
229-
helper = new StateHelper(AsyncSwingWorker.this);
230-
setProgress(0);
308+
helper = new StateHelper(this);
309+
setProgressAsync(min);
231310
helper.next(STATE_INIT);
232311
return null;
233312
}
@@ -240,5 +319,4 @@ final protected Void doInBackground() throws Exception {
240319
final public void done() {
241320
}
242321

243-
244322
}

sources/net.sf.j2s.java.core/src/javax/swing/JTextArea.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import javax.swing.text.JTextComponent;
4242
import javax.swing.text.PlainDocument;
4343

44+
import swingjs.plaf.JSTextAreaUI;
45+
4446
/**
4547
* A <code>JTextArea</code> is a multi-line area that displays plain text.
4648
* It is intended to be a lightweight component that provides source
@@ -765,7 +767,15 @@ public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, in
765767
}
766768
}
767769

770+
@Override
771+
public void scrollRectToVisible(Rectangle aRect) {
772+
if (parent instanceof JViewport) {
773+
((JViewport) parent).scrollRectToVisible(aRect);
774+
}
775+
((JSTextAreaUI) this.秘getUI()).scrollToVisible(aRect);
776+
}
768777

778+
769779
// --- variables -------------------------------------------------
770780

771781
public int rows;

sources/net.sf.j2s.java.core/src/javax/swing/ProgressMonitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public JDialog createDialog(Component parentComponent, String title) {
166166

167167
contentPane.setLayout(new BorderLayout());
168168
contentPane.add(this, BorderLayout.CENTER);
169-
contentPane.add(Box.createVerticalStrut(5), BorderLayout.SOUTH);
169+
//contentPane.add(Box.createVerticalStrut(5), BorderLayout.SOUTH);
170170
dialog.pack();
171171
dialog.setLocationRelativeTo(parentComponent);
172172
dialog.addWindowListener(new WindowAdapter() {

sources/net.sf.j2s.java.core/src/swingjs/plaf/JSTextAreaUI.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.awt.Dimension;
44
import java.awt.Point;
5+
import java.awt.Rectangle;
56
import java.beans.PropertyChangeEvent;
67

78
import javax.swing.JComponent;
@@ -204,5 +205,9 @@ public void caretUpdatedByProgram(CaretEvent e) {
204205
* @j2sNative this.domNode.scrollTo && this.domNode.scrollTo(0, pt);
205206
*/
206207
}
208+
public void scrollToVisible(Rectangle aRect) {
209+
DOMNode.setAttrInt(domNode, "scrollLeft", aRect.x);
210+
DOMNode.setAttrInt(domNode, "scrollTop", aRect.y);
211+
}
207212

208213
}

0 commit comments

Comments
 (0)