* rewrote the checksum computation stuff to support multiple parallel computation queues

* refactoring
* svn properties
This commit is contained in:
Reinhard Pointner 2008-03-23 22:41:25 +00:00
parent 6d2ff4dfe4
commit 2b9c8e840a
13 changed files with 345 additions and 329 deletions

View File

@ -5,7 +5,6 @@ package net.sourceforge.filebot.ui.panel.sfv;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -26,7 +25,10 @@ public class Checksum {
public static enum State {
PENDING, INPROGRESS, READY, ERROR;
PENDING,
INPROGRESS,
READY,
ERROR;
}
@ -41,11 +43,10 @@ public class Checksum {
}
public Checksum(File file) {
computationTask = new ChecksumComputationTask(file);
computationTask.addPropertyChangeListener(new ComputationTaskPropertyChangeListener());
public Checksum(ChecksumComputationTask computationTask) {
this.computationTask = computationTask;
ChecksumComputationExecutor.getInstance().execute(computationTask);
this.computationTask.addPropertyChangeListener(new ComputationTaskPropertyChangeListener());
}

View File

@ -1,224 +0,0 @@
package net.sourceforge.filebot.ui.panel.sfv;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.concurrent.LinkedBlockingQueue;
import javax.swing.SwingUtilities;
import net.sourceforge.tuned.PausableThreadPoolExecutor;
public class ChecksumComputationExecutor {
public static final String PAUSED_PROPERTY = "PAUSED_PROPERTY";
public static final String ACTIVE_PROPERTY = "ACTIVE_PROPERTY";
public static final String REMAINING_TASK_COUNT_PROPERTY = "REMAINING_TASK_COUNT_PROPERTY";
public static final String ACTIVE_SESSION_TASK_COUNT_PROPERTY = "ACTIVE_SESSION_TASK_COUNT_PROPERTY";
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
private static final int MINIMUM_POOL_SIZE = 1;
private Boolean active = false;
private long lastTaskCount = 0;
private static ChecksumComputationExecutor instance = new ChecksumComputationExecutor();
private LinkedBlockingQueue<ChecksumComputationTask> workQueue = new LinkedBlockingQueue<ChecksumComputationTask>();
private PausableThreadPoolExecutor executor = new PausableThreadPoolExecutor(MINIMUM_POOL_SIZE, workQueue) {
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
fireRemainingTaskCountChange();
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
// afterExecute is called from the same thread, the runnable is called,
// so there is at least one active thread
if (workQueue.isEmpty() && getActiveCount() <= 1)
setActive(false);
}
};
public static ChecksumComputationExecutor getInstance() {
return instance;
}
public void execute(ChecksumComputationTask task) {
synchronized (workQueue) {
setActive(true);
adjustPoolSize();
executor.execute(task);
}
fireActiveSessionTaskCountChange();
}
/**
* increase/decrease the core pool size depending on number of queued tasks
*/
private void adjustPoolSize() {
// for only a few files, use only one thread
// for lots of files, use multiple threads
// e.g 200 files ~ 1 thread, 1000 files ~ 2 threads, 40000 files ~ 4 threads
int recommendedPoolSize = (int) Math.log10(Math.max(workQueue.size(), 1) + MINIMUM_POOL_SIZE);
if (executor.getCorePoolSize() != recommendedPoolSize)
executor.setCorePoolSize(recommendedPoolSize);
}
/**
* Only use in block that is synchronized to {@link ChecksumComputationExecutor#getInstance()} after {@link ChecksumComputationExecutor#pause()} has been called.
*/
public synchronized void resume() {
if (!isPaused())
return;
executor.resume();
// invoke property change events on EDT
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(PAUSED_PROPERTY, null, executor.isPaused()));
}
/**
* Synchronize to {@link ChecksumComputationExecutor#getInstance()} before using {@link ChecksumComputationExecutor#pause()}.
*
* <pre>
* synchronized (ChecksumComputationExecutor.getInstance()) {
* ChecksumComputationExecutor.getInstance().pause();
*
* // some code
*
* ChecksumComputationExecutor.getInstance().resume();
* }
* </pre>
*/
public synchronized void pause() {
if (isPaused())
return;
executor.pause();
// invoke property change events on EDT
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(PAUSED_PROPERTY, null, executor.isPaused()));
}
private void setActive(boolean b) {
synchronized (active) {
if (this.active == b)
return;
this.active = b;
if (!this.active) {
// end of active computing session
lastTaskCount = executor.getTaskCount();
// reset pool size
adjustPoolSize();
}
// invoke property change events on EDT
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(ACTIVE_PROPERTY, null, active));
}
}
private void fireRemainingTaskCountChange() {
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(REMAINING_TASK_COUNT_PROPERTY, null, getRemainingTaskCount()));
}
private void fireActiveSessionTaskCountChange() {
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(ACTIVE_SESSION_TASK_COUNT_PROPERTY, null, getActiveSessionTaskCount()));
}
public boolean isPaused() {
return executor.isPaused();
}
public boolean isActive() {
return active;
}
/**
*
* @return Number of remaining tasks
*/
public int getRemainingTaskCount() {
return workQueue.size() + executor.getActiveCount();
}
public int getActiveSessionTaskCount() {
return (int) (executor.getTaskCount() - lastTaskCount);
}
public void clear() {
synchronized (workQueue) {
executor.purge();
workQueue.clear();
adjustPoolSize();
fireRemainingTaskCountChange();
fireActiveSessionTaskCountChange();
if (executor.getActiveCount() == 0) {
setActive(false);
}
}
}
public void purge() {
executor.purge();
fireActiveSessionTaskCountChange();
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
private class FirePropertyChangeRunnable implements Runnable {
private String property;
private Object oldValue;
private Object newValue;
public FirePropertyChangeRunnable(String property, Object oldValue, Object newValue) {
this.property = property;
this.oldValue = oldValue;
this.newValue = newValue;
}
@Override
public void run() {
propertyChangeSupport.firePropertyChange(property, oldValue, newValue);
}
}
}

View File

@ -0,0 +1,277 @@
package net.sourceforge.filebot.ui.panel.sfv;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.SwingUtilities;
public class ChecksumComputationService {
public static final String ACTIVE_PROPERTY = "ACTIVE_PROPERTY";
public static final String REMAINING_TASK_COUNT_PROPERTY = "REMAINING_TASK_COUNT_PROPERTY";
private static final ChecksumComputationService service = new ChecksumComputationService();
public static ChecksumComputationService getService() {
return service;
}
private final Map<File, ChecksumComputationExecutor> executors = new HashMap<File, ChecksumComputationExecutor>();
private final AtomicInteger activeSessionTaskCount = new AtomicInteger(0);
private final AtomicInteger remainingTaskCount = new AtomicInteger(0);
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
private ChecksumComputationService() {
}
public ChecksumComputationTask submit(File file, File workerQueueKey) {
ChecksumComputationTask task = new ChecksumComputationTask(file);
getExecutor(workerQueueKey).execute(task);
return task;
}
public void cancelAll() {
synchronized (executors) {
for (ChecksumComputationExecutor executor : executors.values()) {
executor.shutdownNow();
}
setActive(false);
}
}
public boolean isActive() {
return activeSessionTaskCount.get() > 0;
}
public int getRemainingTaskCount() {
return remainingTaskCount.get();
}
public int getActiveSessionTaskCount() {
return activeSessionTaskCount.get();
}
public void purge() {
synchronized (executors) {
for (ChecksumComputationExecutor executor : executors.values()) {
executor.purge();
}
}
}
private ChecksumComputationExecutor getExecutor(File workerQueueKey) {
synchronized (executors) {
ChecksumComputationExecutor executor = executors.get(workerQueueKey);
if (executor == null) {
executor = new ChecksumComputationExecutor();
executors.put(workerQueueKey, executor);
}
return executor;
}
}
private class ChecksumComputationExecutor extends ThreadPoolExecutor {
private static final int MINIMUM_POOL_SIZE = 1;
public ChecksumComputationExecutor() {
super(MINIMUM_POOL_SIZE, MINIMUM_POOL_SIZE, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new ChecksumComputationThreadFactory());
}
private void adjustPoolSize() {
// for only a few files, use one thread
// for lots of files, use multiple threads
// e.g 50 files ~ 1 thread, 1000 files ~ 3 threads, 40000 files ~ 5 threads
int preferredPoolSize = MINIMUM_POOL_SIZE;
int queueSize = getQueue().size();
if (queueSize > 0) {
preferredPoolSize += Math.log10(Math.max(queueSize / 10, 1));
}
if (getCorePoolSize() != preferredPoolSize) {
setCorePoolSize(preferredPoolSize);
}
}
@Override
public void execute(Runnable command) {
if (activeSessionTaskCount.getAndIncrement() <= 0) {
setActive(true);
}
super.execute(command);
adjustPoolSize();
remainingTaskCount.incrementAndGet();
fireRemainingTaskCountChange();
}
@Override
public void purge() {
try {
List<ChecksumComputationTask> cancelledTasks = new ArrayList<ChecksumComputationTask>();
for (Runnable entry : getQueue()) {
ChecksumComputationTask task = (ChecksumComputationTask) entry;
if (task.isCancelled()) {
cancelledTasks.add(task);
}
}
for (ChecksumComputationTask task : cancelledTasks) {
remove(task);
}
} catch (ConcurrentModificationException ex) {
}
}
@Override
public boolean remove(Runnable task) {
boolean success = super.remove(task);
if (success) {
activeSessionTaskCount.decrementAndGet();
if (remainingTaskCount.decrementAndGet() <= 0) {
setActive(false);
}
fireRemainingTaskCountChange();
}
return success;
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (remainingTaskCount.decrementAndGet() <= 0) {
setActive(false);
}
fireRemainingTaskCountChange();
}
}
private void setActive(boolean active) {
if (!active) {
activeSessionTaskCount.set(0);
remainingTaskCount.set(0);
synchronized (executors) {
executors.clear();
}
}
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(ACTIVE_PROPERTY, active));
}
private void fireRemainingTaskCountChange() {
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(REMAINING_TASK_COUNT_PROPERTY, getRemainingTaskCount()));
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
private class FirePropertyChangeRunnable implements Runnable {
private final String property;
private final Object oldValue;
private final Object newValue;
public FirePropertyChangeRunnable(String property, Object oldValue, Object newValue) {
this.property = property;
this.oldValue = oldValue;
this.newValue = newValue;
}
public FirePropertyChangeRunnable(String property, Object newValue) {
this(property, null, newValue);
}
@Override
public void run() {
propertyChangeSupport.firePropertyChange(property, oldValue, newValue);
}
}
private static class ChecksumComputationThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(0);
private final ThreadGroup group = new ThreadGroup("ChecksumComputationPool");
private final AtomicInteger threadNumber = new AtomicInteger(0);
private final String namePrefix = String.format("%s-%d-thread-", group.getName(), poolNumber.incrementAndGet());
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.incrementAndGet(), 0);
t.setDaemon(false);
t.setPriority(Thread.MIN_PRIORITY);
return t;
}
}
}

View File

@ -14,7 +14,7 @@ public class ChecksumComputationTask extends SwingWorker<Long, Object> {
private static final int BUFFER_SIZE = 32 * 1024;
private File file;
private final File file;
public ChecksumComputationTask(File file) {
@ -36,7 +36,7 @@ public class ChecksumComputationTask extends SwingWorker<Long, Object> {
int bytesRead = 0;
while ((bytesRead = cis.read(buffer)) >= 0) {
if (isCancelled())
if (isCancelled() || Thread.currentThread().isInterrupted())
break;
done += bytesRead;
@ -54,7 +54,6 @@ public class ChecksumComputationTask extends SwingWorker<Long, Object> {
@Override
public String toString() {
return getClass().getSimpleName() + " (" + file.getName() + ")";
return String.format("%s (%s)", getClass().getSimpleName(), file.getName());
}
}

View File

@ -17,13 +17,9 @@ import javax.swing.table.AbstractTableModel;
import net.sourceforge.filebot.FileFormat;
class SfvTableModel extends AbstractTableModel {
class ChecksumTableModel extends AbstractTableModel {
private List<ChecksumRow> rows = new ArrayList<ChecksumRow>();
/**
* Used for Name->Checksum mapping (for performance reasons)
*/
private Map<String, ChecksumRow> rowMap = new HashMap<String, ChecksumRow>();
private List<File> checksumColumnRoots = new ArrayList<File>();
@ -145,7 +141,7 @@ class SfvTableModel extends AbstractTableModel {
rows.removeAll(rowsToRemove);
fireTableRowsDeleted(rowIndices[0], rowIndices[rowIndices.length - 1]);
ChecksumComputationExecutor.getInstance().purge();
ChecksumComputationService.getService().purge();
}
@ -158,7 +154,7 @@ class SfvTableModel extends AbstractTableModel {
}
}
ChecksumComputationExecutor.getInstance().clear();
ChecksumComputationService.getService().cancelAll();
checksumColumnRoots.clear();
rows.clear();
@ -174,7 +170,7 @@ class SfvTableModel extends AbstractTableModel {
}
public LinkedHashMap<String, Checksum> getChecksumColumn(File columnRoot) {
public Map<String, Checksum> getChecksumColumn(File columnRoot) {
LinkedHashMap<String, Checksum> checksumMap = new LinkedHashMap<String, Checksum>();
for (ChecksumRow row : rows) {

View File

@ -94,7 +94,7 @@ public class SfvPanel extends FileBotPanel {
@Override
public void actionPerformed(ActionEvent e) {
SfvTableModel model = (SfvTableModel) sfvTable.getModel();
ChecksumTableModel model = (ChecksumTableModel) sfvTable.getModel();
ArrayList<File> options = new ArrayList<File>();

View File

@ -39,7 +39,7 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
public SfvTable() {
final SfvTableModel model = (SfvTableModel) getModel();
final ChecksumTableModel model = (ChecksumTableModel) getModel();
model.addPropertyChangeListener(repaintListener);
setFillsViewportHeight(true);
@ -69,7 +69,7 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
@Override
protected TableModel createDefaultDataModel() {
return new SfvTableModel();
return new ChecksumTableModel();
}
@ -93,7 +93,7 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
public void clear() {
((BackgroundFileTransferablePolicy<?>) getTransferablePolicy()).cancelAll();
((SfvTableModel) getModel()).clear();
((ChecksumTableModel) getModel()).clear();
}
private PropertyChangeListener repaintListener = new PropertyChangeListener() {
@ -115,7 +115,7 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
public String getDefaultFileName() {
SfvTableModel model = (SfvTableModel) getModel();
ChecksumTableModel model = (ChecksumTableModel) getModel();
File columnRoot = model.getChecksumColumnRoot(0);
String name = "";
@ -136,7 +136,7 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
public void removeRows(int... rowIndices) {
SfvTableModel model = (SfvTableModel) getModel();
ChecksumTableModel model = (ChecksumTableModel) getModel();
model.removeRows(rowIndices);
}
@ -145,7 +145,7 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
try {
PrintStream out = new PrintStream(file);
SfvTableModel model = (SfvTableModel) getModel();
ChecksumTableModel model = (ChecksumTableModel) getModel();
File columnRoot = model.getChecksumColumnRoot(checksumColumnIndex);
if (columnRoot != null) {

View File

@ -17,12 +17,12 @@ import net.sourceforge.filebot.FileBotUtil;
import net.sourceforge.filebot.ui.transferablepolicies.BackgroundFileTransferablePolicy;
class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<SfvTableModel.Entry> {
class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumTableModel.Entry> {
private SfvTableModel tableModel;
private ChecksumTableModel tableModel;
public SfvTransferablePolicy(SfvTableModel tableModel) {
public SfvTransferablePolicy(ChecksumTableModel tableModel) {
this.tableModel = tableModel;
}
@ -41,7 +41,7 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<SfvTableMod
@Override
protected void process(List<SfvTableModel.Entry> chunks) {
protected void process(List<ChecksumTableModel.Entry> chunks) {
tableModel.addAll(chunks);
}
@ -65,13 +65,13 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<SfvTableMod
String filename = matcher.group(1);
String checksumString = matcher.group(2);
publish(new SfvTableModel.Entry(filename, new Checksum(checksumString), sfvFile));
publish(new ChecksumTableModel.Entry(filename, new Checksum(checksumString), sfvFile));
File compareColumnRoot = sfvFile.getParentFile();
File compareFile = new File(compareColumnRoot, filename);
if (compareFile.exists()) {
publish(new SfvTableModel.Entry(filename, new Checksum(compareFile), compareColumnRoot));
publish(new ChecksumTableModel.Entry(filename, new Checksum(ChecksumComputationService.getService().submit(compareFile, compareColumnRoot)), compareColumnRoot));
}
}
@ -91,29 +91,23 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<SfvTableMod
@Override
protected void load(List<File> files) {
synchronized (ChecksumComputationExecutor.getInstance()) {
ChecksumComputationExecutor.getInstance().pause();
if (FileBotUtil.containsOnlySfvFiles(files)) {
// one or more sfv files
for (File file : files) {
loadSfvFile(file);
}
} else if ((files.size() == 1) && files.get(0).isDirectory()) {
// one single folder
File file = files.get(0);
for (File f : file.listFiles()) {
load(f, file, "");
}
} else {
// bunch of files
for (File f : files) {
load(f, f.getParentFile(), "");
}
if (FileBotUtil.containsOnlySfvFiles(files)) {
// one or more sfv files
for (File file : files) {
loadSfvFile(file);
}
} else if ((files.size() == 1) && files.get(0).isDirectory()) {
// one single folder
File file = files.get(0);
ChecksumComputationExecutor.getInstance().resume();
for (File f : file.listFiles()) {
load(f, file, "");
}
} else {
// bunch of files
for (File f : files) {
load(f, f.getParentFile(), "");
}
}
}
@ -129,7 +123,7 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<SfvTableMod
load(f, columnRoot, newPrefix);
}
} else if (file.isFile()) {
publish(new SfvTableModel.Entry(prefix + file.getName(), new Checksum(file), columnRoot));
publish(new ChecksumTableModel.Entry(prefix + file.getName(), new Checksum(ChecksumComputationService.getService().submit(file, columnRoot)), columnRoot));
}
}

View File

@ -36,59 +36,44 @@ class TotalProgressPanel extends Box {
setBorder(BorderFactory.createCompoundBorder(margin, title));
add(progressBar);
ChecksumComputationExecutor.getInstance().addPropertyChangeListener(executorListener);
ChecksumComputationService.getService().addPropertyChangeListener(executorListener);
}
private PropertyChangeListener executorListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
ChecksumComputationExecutor executor = ChecksumComputationExecutor.getInstance();
String property = evt.getPropertyName();
if (property == ChecksumComputationExecutor.ACTIVE_PROPERTY) {
if (property == ChecksumComputationService.ACTIVE_PROPERTY) {
Boolean active = (Boolean) evt.getNewValue();
setVisible(active);
return;
}
if (property == ChecksumComputationExecutor.PAUSED_PROPERTY) {
Boolean paused = (Boolean) evt.getNewValue();
if (paused) {
progressBar.setString("Updating ...");
if (active) {
new SetVisibleTimer().start();
}
} else if (property == ChecksumComputationService.REMAINING_TASK_COUNT_PROPERTY) {
int taskCount = ChecksumComputationService.getService().getActiveSessionTaskCount();
int progress = taskCount - ChecksumComputationService.getService().getRemainingTaskCount();
return;
}
if (property == ChecksumComputationExecutor.ACTIVE_SESSION_TASK_COUNT_PROPERTY) {
progressBar.setMaximum(executor.getActiveSessionTaskCount());
}
if (property == ChecksumComputationExecutor.REMAINING_TASK_COUNT_PROPERTY) {
int progress = executor.getActiveSessionTaskCount() - executor.getRemainingTaskCount();
progressBar.setValue(progress);
progressBar.setMaximum(taskCount);
progressBar.setString(progressBar.getValue() + " / " + progressBar.getMaximum());
}
progressBar.setString(progressBar.getValue() + " / " + progressBar.getMaximum());
if (!ChecksumComputationService.getService().isActive()) {
setVisible(false);
}
}
};
@Override
public void setVisible(boolean flag) {
if (flag) {
new SetVisibleTimer().start();
} else {
super.setVisible(false);
}
}
private int millisToSetVisible = 200;
private class SetVisibleTimer extends Timer implements ActionListener {
private static final int millisToSetVisible = 200;
public SetVisibleTimer() {
super(millisToSetVisible, null);
addActionListener(this);
@ -97,8 +82,7 @@ class TotalProgressPanel extends Box {
public void actionPerformed(ActionEvent e) {
if (ChecksumComputationExecutor.getInstance().isActive())
TotalProgressPanel.super.setVisible(true);
setVisible(ChecksumComputationService.getService().isActive());
}
}

View File

@ -5,12 +5,9 @@ package net.sourceforge.filebot.ui.transfer;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.Transferable;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.TransferHandler;
import net.sourceforge.filebot.resources.ResourceManager;
public class DefaultTransferHandler extends TransferHandler {

View File

@ -150,7 +150,7 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
@Override
public void run() {
firePropertyChange(LOADING_PROPERTY, false, true);
propertyChangeSupport.firePropertyChange(LOADING_PROPERTY, false, true);
}
});
}
@ -168,7 +168,7 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
@Override
public void run() {
firePropertyChange(LOADING_PROPERTY, true, false);
propertyChangeSupport.firePropertyChange(LOADING_PROPERTY, true, false);
}
});
}
@ -184,17 +184,8 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
}
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
}

View File

@ -5,6 +5,8 @@ package net.sourceforge.filebot.web;
import java.net.URL;
import java.util.Map;
import net.sourceforge.tuned.DownloadTask;
public class SubsceneSubtitleDescriptor {

View File

@ -1,5 +1,5 @@
package net.sourceforge.filebot.web;
package net.sourceforge.tuned;
import java.io.ByteArrayOutputStream;
@ -55,8 +55,7 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
public DownloadTask(URL url, Map<String, String> postdata) {
this.url = url;
this.postdata = encodeParameters(postdata);
this(url, encodeParameters(postdata));
}