improvement:
* BackgroundFileTransferablePolicy uses ThreadLocal<Worker> now * support exception handling in BackgroundFileTransferablePolicy changes: * ChecksumComputationTask will only calculate one HashType * added ChecksumRow.dispose() fix: * honor convertValueToString() in SelectDialog
This commit is contained in:
parent
5674173417
commit
dac55956f6
|
@ -44,10 +44,7 @@ public class SelectDialog<T> extends JDialog {
|
|||
list = new JList(new ArrayListModel(options));
|
||||
list.setSelectedIndex(0);
|
||||
|
||||
DefaultFancyListCellRenderer cellRenderer = new DefaultFancyListCellRenderer(4);
|
||||
cellRenderer.setHighlightingEnabled(false);
|
||||
|
||||
list.setCellRenderer(cellRenderer);
|
||||
list.setCellRenderer(new SelectListCellRenderer());
|
||||
list.addMouseListener(mouseListener);
|
||||
|
||||
JComponent c = (JComponent) getContentPane();
|
||||
|
@ -121,4 +118,20 @@ public class SelectDialog<T> extends JDialog {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected class SelectListCellRenderer extends DefaultFancyListCellRenderer {
|
||||
|
||||
public SelectListCellRenderer() {
|
||||
super(4);
|
||||
setHighlightingEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
super.configureListCellRendererComponent(list, convertValueToString(value), index, isSelected, cellHasFocus);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,11 +4,13 @@ package net.sourceforge.filebot.ui.panel.analyze;
|
|||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sourceforge.filebot.ui.panel.analyze.FileTree.AbstractTreeNode;
|
||||
import net.sourceforge.filebot.ui.panel.analyze.FileTree.FileNode;
|
||||
import net.sourceforge.filebot.ui.panel.analyze.FileTree.FolderNode;
|
||||
import net.sourceforge.filebot.ui.transfer.BackgroundFileTransferablePolicy;
|
||||
import net.sourceforge.tuned.ExceptionUtilities;
|
||||
import net.sourceforge.tuned.FileUtilities;
|
||||
|
||||
|
||||
|
@ -46,6 +48,12 @@ class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<Abstra
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void process(Exception e) {
|
||||
Logger.getLogger("ui").warning(ExceptionUtilities.getRootCause(e).getMessage());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void load(List<File> files) {
|
||||
try {
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.awt.event.ActionEvent;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
|
@ -215,7 +214,7 @@ public class RenamePanel extends FileBotPanel {
|
|||
model.names().addAll(names);
|
||||
model.files().addAll(files);
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger("ui").log(Level.WARNING, ExceptionUtilities.getRootCause(e).getMessage(), e);
|
||||
Logger.getLogger("ui").warning(ExceptionUtilities.getRootCause(e).getMessage());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -49,7 +49,7 @@ public class ChecksumCell {
|
|||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
super.propertyChange(evt);
|
||||
|
||||
propertyChangeSupport.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
pcs.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,17 +95,6 @@ public class ChecksumCell {
|
|||
}
|
||||
|
||||
|
||||
public void dispose() {
|
||||
if (task != null) {
|
||||
task.cancel(true);
|
||||
}
|
||||
|
||||
hashes = null;
|
||||
error = null;
|
||||
task = null;
|
||||
}
|
||||
|
||||
|
||||
public State getState() {
|
||||
if (hashes != null)
|
||||
return State.READY;
|
||||
|
@ -121,21 +110,38 @@ public class ChecksumCell {
|
|||
}
|
||||
|
||||
|
||||
public void dispose() {
|
||||
// clear property change support first
|
||||
for (PropertyChangeListener listener : pcs.getPropertyChangeListeners()) {
|
||||
pcs.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
if (task != null) {
|
||||
task.cancel(true);
|
||||
}
|
||||
|
||||
hashes = null;
|
||||
error = null;
|
||||
task = null;
|
||||
pcs = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s %s", name, hashes);
|
||||
}
|
||||
|
||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
propertyChangeSupport.addPropertyChangeListener(listener);
|
||||
pcs.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
propertyChangeSupport.removePropertyChangeListener(listener);
|
||||
pcs.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,9 +5,8 @@ package net.sourceforge.filebot.ui.panel.sfv;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
|
||||
|
@ -16,21 +15,18 @@ class ChecksumComputationTask extends SwingWorker<Map<HashType, String>, Void> {
|
|||
private static final int BUFFER_SIZE = 32 * 1024;
|
||||
|
||||
private final File file;
|
||||
private final HashType type;
|
||||
|
||||
|
||||
public ChecksumComputationTask(File file) {
|
||||
public ChecksumComputationTask(File file, HashType type) {
|
||||
this.file = file;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Map<HashType, String> doInBackground() throws Exception {
|
||||
Map<HashType, Hash> hashes = new EnumMap<HashType, Hash>(HashType.class);
|
||||
|
||||
for (HashType type : HashType.values()) {
|
||||
hashes.put(type, type.newInstance());
|
||||
}
|
||||
|
||||
Hash hash = type.newInstance();
|
||||
long length = file.length();
|
||||
|
||||
if (length > 0) {
|
||||
|
@ -38,22 +34,20 @@ class ChecksumComputationTask extends SwingWorker<Map<HashType, String>, Void> {
|
|||
|
||||
try {
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
|
||||
long position = 0;
|
||||
int len = 0;
|
||||
|
||||
while ((len = in.read(buffer)) >= 0) {
|
||||
position += len;
|
||||
|
||||
for (Hash hash : hashes.values()) {
|
||||
hash.update(buffer, 0, len);
|
||||
}
|
||||
hash.update(buffer, 0, len);
|
||||
|
||||
// update progress
|
||||
setProgress((int) ((position * 100) / length));
|
||||
|
||||
// check abort status
|
||||
if (isCancelled() || Thread.interrupted()) {
|
||||
if (isCancelled()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -62,18 +56,7 @@ class ChecksumComputationTask extends SwingWorker<Map<HashType, String>, Void> {
|
|||
}
|
||||
}
|
||||
|
||||
return digest(hashes);
|
||||
}
|
||||
|
||||
|
||||
private Map<HashType, String> digest(Map<HashType, Hash> hashes) {
|
||||
Map<HashType, String> results = new EnumMap<HashType, String>(HashType.class);
|
||||
|
||||
for (Entry<HashType, Hash> entry : hashes.entrySet()) {
|
||||
results.put(entry.getKey(), entry.getValue().digest());
|
||||
}
|
||||
|
||||
return results;
|
||||
return Collections.singletonMap(type, hash.digest());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
package net.sourceforge.filebot.ui.panel.sfv;
|
||||
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -56,30 +58,43 @@ public class ChecksumRow {
|
|||
}
|
||||
|
||||
|
||||
public Collection<ChecksumCell> values() {
|
||||
return Collections.unmodifiableCollection(hashes.values());
|
||||
}
|
||||
|
||||
|
||||
public void add(ChecksumCell entry) {
|
||||
hashes.put(entry.getRoot(), entry);
|
||||
public void put(ChecksumCell cell) {
|
||||
ChecksumCell old = hashes.put(cell.getRoot(), cell);
|
||||
|
||||
// dispose of old map entry
|
||||
if (old != null) {
|
||||
old.dispose();
|
||||
}
|
||||
|
||||
// update state immediately
|
||||
updateState();
|
||||
|
||||
// keep state up-to-date
|
||||
cell.addPropertyChangeListener(updateStateListener);
|
||||
}
|
||||
|
||||
|
||||
public void updateState() {
|
||||
// update state
|
||||
state = getState(hashes.values());
|
||||
}
|
||||
|
||||
|
||||
protected State getState(Collection<ChecksumCell> entries) {
|
||||
public void dispose() {
|
||||
for (ChecksumCell cell : hashes.values()) {
|
||||
cell.dispose();
|
||||
}
|
||||
|
||||
hashes.clear();
|
||||
}
|
||||
|
||||
|
||||
protected State getState(Collection<ChecksumCell> cells) {
|
||||
// check states before we bother comparing the hash values
|
||||
for (ChecksumCell entry : entries) {
|
||||
if (entry.getState() == ChecksumCell.State.ERROR) {
|
||||
for (ChecksumCell cell : cells) {
|
||||
if (cell.getState() == ChecksumCell.State.ERROR) {
|
||||
// one error cell -> error state
|
||||
return State.ERROR;
|
||||
} else if (entry.getState() != ChecksumCell.State.READY) {
|
||||
} else if (cell.getState() != ChecksumCell.State.READY) {
|
||||
// one cell that is not ready yet -> unknown state
|
||||
return State.UNKNOWN;
|
||||
}
|
||||
|
@ -92,8 +107,8 @@ public class ChecksumRow {
|
|||
for (HashType type : HashType.values()) {
|
||||
checksumSet.clear();
|
||||
|
||||
for (ChecksumCell entry : entries) {
|
||||
String checksum = entry.getChecksum(type);
|
||||
for (ChecksumCell cell : cells) {
|
||||
String checksum = cell.getChecksum(type);
|
||||
|
||||
if (checksum != null) {
|
||||
checksumSet.add(checksum);
|
||||
|
@ -134,4 +149,12 @@ public class ChecksumRow {
|
|||
public String toString() {
|
||||
return String.format("%s %s", name, hashes);
|
||||
}
|
||||
|
||||
private final PropertyChangeListener updateStateListener = new PropertyChangeListener() {
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
updateState();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -24,19 +24,19 @@ public class ChecksumTableExportHandler extends TextFileExportHandler {
|
|||
|
||||
@Override
|
||||
public boolean canExport() {
|
||||
return model.getRowCount() > 0 && model.getChecksumList().size() > 0;
|
||||
return model.getRowCount() > 0 && model.getChecksumColumns().size() > 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void export(Formatter out) {
|
||||
export(out, model.getChecksumList().get(0));
|
||||
export(out, model.getChecksumColumns().get(0));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDefaultFileName() {
|
||||
return getDefaultFileName(model.getChecksumList().get(0));
|
||||
return getDefaultFileName(model.getChecksumColumns().get(0));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ class ChecksumTableModel extends AbstractTableModel implements Iterable<Checksum
|
|||
}
|
||||
|
||||
|
||||
public List<File> getChecksumList() {
|
||||
public List<File> getChecksumColumns() {
|
||||
return Collections.unmodifiableList(columns);
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ class ChecksumTableModel extends AbstractTableModel implements Iterable<Checksum
|
|||
rows.add(row);
|
||||
}
|
||||
|
||||
row.add(entry);
|
||||
row.put(entry);
|
||||
|
||||
// listen to changes (progress, state)
|
||||
entry.addPropertyChangeListener(progressListener);
|
||||
|
@ -139,10 +139,7 @@ class ChecksumTableModel extends AbstractTableModel implements Iterable<Checksum
|
|||
|
||||
public void remove(int... index) {
|
||||
for (int i : index) {
|
||||
for (ChecksumCell entry : rows.get(i).values()) {
|
||||
entry.removePropertyChangeListener(progressListener);
|
||||
entry.dispose();
|
||||
}
|
||||
rows.get(i).dispose();
|
||||
}
|
||||
|
||||
// remove rows
|
||||
|
|
|
@ -5,19 +5,24 @@ package net.sourceforge.filebot.ui.panel.sfv;
|
|||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.FileBotPanel;
|
||||
import net.sourceforge.filebot.ui.FileTransferableMessageHandler;
|
||||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.ui.transfer.LoadAction;
|
||||
import net.sourceforge.filebot.ui.transfer.SaveAction;
|
||||
import net.sourceforge.tuned.FileUtilities;
|
||||
import net.sourceforge.tuned.MessageHandler;
|
||||
import net.sourceforge.tuned.ui.TunedUtilities;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.filebot.ui.transfer.BackgroundFileTransferablePolicy;
|
||||
import net.sourceforge.tuned.ExceptionUtilities;
|
||||
|
||||
|
||||
class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumCell> {
|
||||
|
@ -52,6 +53,12 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumCel
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void process(Exception e) {
|
||||
Logger.getLogger("ui").warning(ExceptionUtilities.getRootCause(e).getMessage());
|
||||
}
|
||||
|
||||
|
||||
protected void loadSfvFile(File sfvFile, Executor executor) {
|
||||
try {
|
||||
// don't use new Scanner(File) because of BUG 6368019 (http://bugs.sun.com/view_bug.do?bug_id=6368019)
|
||||
|
@ -60,6 +67,9 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumCel
|
|||
try {
|
||||
Pattern pattern = Pattern.compile("(.+)\\s+(\\p{XDigit}{8})");
|
||||
|
||||
// root for relative file paths in sfv file
|
||||
File root = sfvFile.getParentFile();
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
|
||||
|
@ -71,21 +81,13 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumCel
|
|||
if (!matcher.matches())
|
||||
continue;
|
||||
|
||||
String filename = matcher.group(1);
|
||||
String name = matcher.group(1);
|
||||
String checksum = matcher.group(2);
|
||||
|
||||
publish(new ChecksumCell(filename, sfvFile, Collections.singletonMap(HashType.CRC32, checksum)));
|
||||
ChecksumCell correct = new ChecksumCell(name, sfvFile, Collections.singletonMap(HashType.CRC32, checksum));
|
||||
ChecksumCell current = createChecksumCell(name, root, new File(root, name), executor);
|
||||
|
||||
File column = sfvFile.getParentFile();
|
||||
File file = new File(column, filename);
|
||||
|
||||
if (file.exists()) {
|
||||
ChecksumComputationTask task = new ChecksumComputationTask(file);
|
||||
|
||||
publish(new ChecksumCell(filename, column, task));
|
||||
|
||||
executor.execute(task);
|
||||
}
|
||||
publish(correct, current);
|
||||
|
||||
if (Thread.interrupted()) {
|
||||
break;
|
||||
|
@ -150,11 +152,17 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumCel
|
|||
load(f, root, newPrefix, executor);
|
||||
}
|
||||
} else if (file.isFile()) {
|
||||
ChecksumComputationTask task = new ChecksumComputationTask(file);
|
||||
|
||||
publish(new ChecksumCell(prefix + file.getName(), root, task));
|
||||
|
||||
executor.execute(task);
|
||||
publish(createChecksumCell(prefix + file.getName(), root, file, executor));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected ChecksumCell createChecksumCell(String name, File root, File file, Executor executor) {
|
||||
ChecksumCell cell = new ChecksumCell(name, root, new ChecksumComputationTask(new File(root, name), HashType.CRC32));
|
||||
|
||||
// start computation task
|
||||
executor.execute(cell.getTask());
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,100 +7,94 @@ import java.beans.PropertyChangeEvent;
|
|||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
|
||||
|
||||
|
||||
public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferablePolicy {
|
||||
|
||||
public static final String LOADING_PROPERTY = "loading";
|
||||
|
||||
private BackgroundWorker worker = null;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean accept(Transferable tr) {
|
||||
if (isActive())
|
||||
return false;
|
||||
private final ThreadLocal<BackgroundWorker> threadLocalWorker = new ThreadLocal<BackgroundWorker>() {
|
||||
|
||||
return super.accept(tr);
|
||||
}
|
||||
@Override
|
||||
protected BackgroundWorker initialValue() {
|
||||
// fail if a non-background-worker thread is trying to access the thread-local worker object
|
||||
throw new IllegalThreadStateException("Illegal access thread");
|
||||
}
|
||||
};
|
||||
|
||||
private final List<BackgroundWorker> workers = new ArrayList<BackgroundWorker>(2);
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void handleTransferable(Transferable tr, TransferAction action) {
|
||||
public void handleTransferable(Transferable tr, TransferAction action) {
|
||||
List<File> files = getFilesFromTransferable(tr);
|
||||
|
||||
if (action != TransferAction.ADD)
|
||||
clear();
|
||||
|
||||
worker = new BackgroundWorker(files);
|
||||
worker.addPropertyChangeListener(backgroundWorkerListener);
|
||||
worker.execute();
|
||||
// create and start worker
|
||||
new BackgroundWorker(files).execute();
|
||||
}
|
||||
|
||||
|
||||
public synchronized boolean isActive() {
|
||||
return worker != null && !worker.isDone();
|
||||
}
|
||||
|
||||
|
||||
public synchronized void reset() {
|
||||
if (isActive()) {
|
||||
worker.cancel(true);
|
||||
public void reset() {
|
||||
synchronized (workers) {
|
||||
for (BackgroundWorker worker : workers) {
|
||||
worker.cancel(true);
|
||||
}
|
||||
|
||||
workers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receives data chunks from the publish method asynchronously on the Event Dispatch
|
||||
* Thread.
|
||||
*
|
||||
* @param chunks
|
||||
*/
|
||||
protected abstract void process(List<V> chunks);
|
||||
|
||||
|
||||
/**
|
||||
* Sends data chunks to the process method.
|
||||
*
|
||||
* @param chunks
|
||||
*/
|
||||
protected synchronized void publish(V... chunks) {
|
||||
if (worker != null) {
|
||||
worker.publishChunks(chunks);
|
||||
}
|
||||
protected abstract void process(Exception e);
|
||||
|
||||
|
||||
protected final void publish(V... chunks) {
|
||||
threadLocalWorker.get().offer(chunks);
|
||||
}
|
||||
|
||||
|
||||
private class BackgroundWorker extends SwingWorker<Void, V> {
|
||||
protected class BackgroundWorker extends SwingWorker<Object, V> {
|
||||
|
||||
private final List<File> files;
|
||||
|
||||
|
||||
public BackgroundWorker(List<File> files) {
|
||||
this.files = files;
|
||||
// register this worker
|
||||
synchronized (workers) {
|
||||
if (workers.add(this) && workers.size() == 1) {
|
||||
swingPropertyChangeSupport.firePropertyChange(LOADING_PROPERTY, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Void doInBackground() {
|
||||
protected Object doInBackground() {
|
||||
// associate this worker with the current (background) thread
|
||||
threadLocalWorker.set(this);
|
||||
|
||||
try {
|
||||
load(files);
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger("global").log(Level.WARNING, e.getMessage(), e);
|
||||
} finally {
|
||||
threadLocalWorker.remove();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void publishChunks(V... chunks) {
|
||||
public void offer(V... chunks) {
|
||||
if (!isCancelled()) {
|
||||
publish(chunks);
|
||||
}
|
||||
|
@ -113,31 +107,54 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
|
|||
BackgroundFileTransferablePolicy.this.process(chunks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final PropertyChangeListener backgroundWorkerListener = new SwingWorkerPropertyChangeAdapter() {
|
||||
|
||||
@Override
|
||||
public void started(PropertyChangeEvent evt) {
|
||||
propertyChangeSupport.firePropertyChange(LOADING_PROPERTY, false, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void done(PropertyChangeEvent evt) {
|
||||
propertyChangeSupport.firePropertyChange(LOADING_PROPERTY, true, false);
|
||||
protected void done() {
|
||||
// unregister worker
|
||||
synchronized (workers) {
|
||||
if (workers.remove(this) && workers.isEmpty()) {
|
||||
swingPropertyChangeSupport.firePropertyChange(LOADING_PROPERTY, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCancelled()) {
|
||||
try {
|
||||
// check for exception
|
||||
get();
|
||||
} catch (Exception e) {
|
||||
BackgroundFileTransferablePolicy.this.process(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
protected final PropertyChangeSupport swingPropertyChangeSupport = new PropertyChangeSupport(this) {
|
||||
|
||||
@Override
|
||||
public void firePropertyChange(final PropertyChangeEvent evt) {
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
super.firePropertyChange(evt);
|
||||
} else {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
swingPropertyChangeSupport.firePropertyChange(evt);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
propertyChangeSupport.addPropertyChangeListener(listener);
|
||||
swingPropertyChangeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
propertyChangeSupport.removePropertyChangeListener(listener);
|
||||
swingPropertyChangeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.swing.ListModel;
|
||||
|
@ -11,23 +10,23 @@ import javax.swing.event.ListDataListener;
|
|||
|
||||
public class ArrayListModel implements ListModel {
|
||||
|
||||
private final ArrayList<Object> data;
|
||||
private final Object[] data;
|
||||
|
||||
|
||||
public ArrayListModel(Collection<? extends Object> data) {
|
||||
this.data = new ArrayList<Object>(data);
|
||||
this.data = data.toArray();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
return data.get(index);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return data.size();
|
||||
return data.length;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ public class LoadingOverlayPane extends JComponent {
|
|||
animationComponent = new ProgressIndicator();
|
||||
animationComponent.setVisible(false);
|
||||
|
||||
add(animationComponent, String.format("pos n %s 100%%-%s n", offsetY != null ? offsetY : "8px", offsetX != null ? offsetX : "18px"));
|
||||
add(animationComponent, String.format("pos n %s 100%%-%s n", offsetY != null ? offsetY : "8px", offsetX != null ? offsetX : "20px"));
|
||||
add(component, "grow");
|
||||
|
||||
if (propertyChangeSource != null) {
|
||||
|
|
|
@ -37,22 +37,9 @@ public class ProgressIndicator extends JComponent {
|
|||
private final Dimension baseSize = new Dimension(32, 32);
|
||||
|
||||
private double alpha = 0;
|
||||
private double speed = 1.2;
|
||||
private double speed = 24;
|
||||
|
||||
private final Timer updateTimer = new Timer(20, new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Timer timer = (Timer) e.getSource();
|
||||
|
||||
alpha += (timer.getDelay() * speed) / 1000;
|
||||
|
||||
if (alpha >= 1)
|
||||
alpha -= Math.floor(alpha);
|
||||
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
private Timer updateTimer;
|
||||
|
||||
|
||||
public ProgressIndicator() {
|
||||
|
@ -74,6 +61,13 @@ public class ProgressIndicator extends JComponent {
|
|||
}
|
||||
|
||||
|
||||
public void animateOnce() {
|
||||
if ((alpha += (speed / 1000)) >= 1) {
|
||||
alpha -= Math.floor(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
@ -123,12 +117,26 @@ public class ProgressIndicator extends JComponent {
|
|||
|
||||
|
||||
public void startAnimation() {
|
||||
updateTimer.restart();
|
||||
if (updateTimer == null) {
|
||||
updateTimer = new Timer(20, new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
animateOnce();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
|
||||
updateTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopAnimation() {
|
||||
updateTimer.stop();
|
||||
if (updateTimer != null) {
|
||||
updateTimer.stop();
|
||||
updateTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue