Refactor ProgressDialog

This commit is contained in:
Reinhard Pointner 2016-05-08 04:45:48 +08:00
parent 0e126daace
commit b487f25361
3 changed files with 28 additions and 132 deletions

View File

@ -4,11 +4,9 @@ import static net.filebot.Logging.*;
import static net.filebot.UserFiles.*;
import static net.filebot.util.ExceptionUtilities.*;
import static net.filebot.util.FileUtilities.*;
import static net.filebot.util.ui.SwingUI.*;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
@ -18,16 +16,17 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CancellationException;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
@ -38,9 +37,8 @@ import net.filebot.cli.ConflictAction;
import net.filebot.util.FileUtilities;
import net.filebot.util.ui.GradientStyle;
import net.filebot.util.ui.LoadingOverlayPane;
import net.filebot.util.ui.ProgressDialog;
import net.filebot.util.ui.ProgressDialog.Cancellable;
import net.filebot.util.ui.SwingWorkerPropertyChangeAdapter;
import net.filebot.util.ui.ProgressMonitor;
import net.filebot.util.ui.ProgressMonitor.ProgressWorker;
import net.filebot.util.ui.notification.SeparatorBorder;
import net.filebot.vfs.FileInfo;
import net.filebot.vfs.SimpleFileInfo;
@ -124,33 +122,8 @@ class ExtractTool extends Tool<TableModel> {
if (selectedFile == null)
return;
final ExtractJob job = new ExtractJob(archives, selectedFile, null, true, ConflictAction.AUTO);
final ProgressDialog dialog = new ProgressDialog(getWindow(evt.getSource()), job);
dialog.setLocation(getOffsetLocation(dialog.getOwner()));
dialog.setTitle("Extracting files...");
dialog.setIcon((Icon) getValue(SMALL_ICON));
dialog.setIndeterminate(true);
// close progress dialog when worker is finished
job.addPropertyChangeListener(new SwingWorkerPropertyChangeAdapter() {
@Override
protected void event(String name, Object oldValue, Object newValue) {
if (name.equals("currentFile")) {
String note = "Extracting " + ((File) newValue).getName();
dialog.setNote(note);
dialog.setWindowTitle(note);
}
}
@Override
protected void done(PropertyChangeEvent evt) {
dialog.close();
}
});
job.execute();
dialog.setVisible(true);
ExtractWorker worker = new ExtractWorker(archives, selectedFile, null, true, ConflictAction.AUTO);
ProgressMonitor.runTask("Extract", "Extracting files...", worker);
}
};
@ -227,7 +200,7 @@ class ExtractTool extends Tool<TableModel> {
}
protected static class ExtractJob extends SwingWorker<Void, Void> implements Cancellable {
protected static class ExtractWorker implements ProgressWorker<Void> {
private final File[] archives;
private final File outputFolder;
@ -236,7 +209,7 @@ class ExtractTool extends Tool<TableModel> {
private final boolean forceExtractAll;
private final ConflictAction conflictAction;
public ExtractJob(Collection<File> archives, File outputFolder, FileFilter filter, boolean forceExtractAll, ConflictAction conflictAction) {
public ExtractWorker(Collection<File> archives, File outputFolder, FileFilter filter, boolean forceExtractAll, ConflictAction conflictAction) {
this.archives = archives.toArray(new File[archives.size()]);
this.outputFolder = outputFolder;
this.filter = filter;
@ -245,11 +218,11 @@ class ExtractTool extends Tool<TableModel> {
}
@Override
protected Void doInBackground() throws Exception {
public Void call(Consumer<String> message, BiConsumer<Long, Long> progress, Supplier<Boolean> cancelled) throws Exception {
for (File file : archives) {
try {
// update progress dialog
firePropertyChange("currentFile", null, file);
message.accept(String.format("Extracting %s", file.getName()));
Archive archive = Archive.open(file);
try {
@ -304,18 +277,13 @@ class ExtractTool extends Tool<TableModel> {
log.log(Level.WARNING, "Failed to extract archive: " + file.getName(), e);
}
if (isCancelled()) {
throw new CancellationException();
if (cancelled.get()) {
throw new CancellationException("Extract cancelled");
}
}
return null;
}
@Override
public boolean cancel() {
return cancel(true);
}
}
}

View File

@ -3,28 +3,19 @@ package net.filebot.ui.rename;
import static net.filebot.Logging.*;
import static net.filebot.util.ui.SwingUI.*;
import java.awt.Cursor;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.SwingWorker;
import net.filebot.ResourceManager;
import net.filebot.similarity.EpisodeMetrics;
import net.filebot.similarity.Match;
import net.filebot.similarity.Matcher;
import net.filebot.similarity.SimilarityMetric;
import net.filebot.util.ui.ProgressDialog;
import net.filebot.util.ui.ProgressDialog.Cancellable;
import net.filebot.util.ui.SwingWorkerPropertyChangeAdapter;
import net.filebot.util.ui.ProgressMonitor;
class MatchAction extends AbstractAction {
@ -48,88 +39,26 @@ class MatchAction extends AbstractAction {
return;
}
BackgroundMatcher backgroundMatcher = new BackgroundMatcher(model, EpisodeMetrics.defaultSequence(true));
backgroundMatcher.execute();
Window window = getWindow(evt.getSource());
window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
// wait a for little while (matcher might finish in less than a second)
backgroundMatcher.get(2, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// matcher will probably take a while
ProgressDialog dialog = createProgressDialog(window, backgroundMatcher);
dialog.setLocation(getOffsetLocation(dialog.getOwner()));
// display progress dialog and stop blocking EDT
dialog.setVisible(true);
} catch (Exception e) {
debug.log(Level.SEVERE, e.getMessage(), e);
} finally {
window.setCursor(Cursor.getDefaultCursor());
}
}
protected ProgressDialog createProgressDialog(Window parent, final BackgroundMatcher worker) {
final ProgressDialog progressDialog = new ProgressDialog(parent, worker);
// configure dialog
progressDialog.setTitle("Matching...");
progressDialog.setNote("Processing...");
progressDialog.setIcon((Icon) getValue(SMALL_ICON));
// close progress dialog when worker is finished
worker.addPropertyChangeListener(new SwingWorkerPropertyChangeAdapter() {
@Override
protected void done(PropertyChangeEvent evt) {
progressDialog.close();
}
});
return progressDialog;
}
protected class BackgroundMatcher extends SwingWorker<List<Match<Object, File>>, Void> implements Cancellable {
private final Matcher<Object, File> matcher;
public BackgroundMatcher(MatchModel<Object, File> model, SimilarityMetric[] metrics) {
// match names against files
this.matcher = new Matcher<Object, File>(model.values(), model.candidates(), false, metrics);
}
@Override
protected List<Match<Object, File>> doInBackground() throws Exception {
return matcher.match();
}
@Override
protected void done() {
if (isCancelled())
return;
try {
List<Match<Object, File>> matches = get();
model.clear();
withWaitCursor(evt.getSource(), () -> {
Matcher<Object, File> matcher = new Matcher<Object, File>(model.values(), model.candidates(), false, EpisodeMetrics.defaultSequence(true));
List<Match<Object, File>> matches = ProgressMonitor.runTask("Match", "Find optimal alignment. This may take a while.", (message, progress, cancelled) -> {
message.accept(String.format("Checking %d combinations...", matcher.remainingCandidates().size() * matcher.remainingValues().size()));
return matcher.match();
}).get();
// put new data into model
model.clear();
model.addAll(matches);
// insert objects that could not be matched at the end of the model
model.addAll(matcher.remainingValues(), matcher.remainingCandidates());
} catch (Exception e) {
debug.log(Level.SEVERE, e.getMessage(), e);
}
});
} catch (CancellationException e) {
debug.finest(e::toString);
} catch (Throwable e) {
log.log(Level.WARNING, e.getMessage(), e);
}
@Override
public boolean cancel() {
return cancel(true);
}
}
}

View File

@ -97,9 +97,8 @@ class RenameAction extends AbstractAction {
} else {
// call and wait
RenameWorker worker = new RenameWorker(renameMap, renameLog, action);
String title = String.format("%s - %s", getApplicationName(), action.getDisplayName());
String message = String.format("%s %d %s. This may take a while.", action.getDisplayName() + "ing", renameMap.size(), renameMap.size() == 1 ? "file" : "files");
ProgressMonitor.runTask(title, message, worker).get();
ProgressMonitor.runTask(action.getDisplayName(), message, worker).get();
}
} catch (CancellationException e) {
debug.finest(e::toString);