* changed IconProvider to LabelProvider (provides text and icon)
* Changed EpisodeListClient and SubtitleClient from abstract classes to interfaces * OpenSubtitlesSubtitleClient: remove shutdownhook if not needed anymore * some refactoring
This commit is contained in:
parent
a341922a30
commit
a401a51c75
|
@ -4,11 +4,7 @@ package net.sourceforge.filebot;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -22,17 +18,17 @@ public class FileBotUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* invalid characters: \, /, :, *, ?, ", <, >, |, \r and \n
|
||||
* Invalid characters in filenames: \, /, :, *, ?, ", <, >, |, \r and \n
|
||||
*/
|
||||
public static final String INVALID_CHARACTERS = "\\/:*?\"<>|\r\n";
|
||||
public static final Pattern INVALID_CHARACTERS_PATTERN = Pattern.compile(String.format("[%s]+", Pattern.quote(INVALID_CHARACTERS)));
|
||||
|
||||
|
||||
/**
|
||||
* Strip string of invalid characters
|
||||
* Strip filename of invalid characters
|
||||
*
|
||||
* @param filename original filename
|
||||
* @return filename stripped of invalid characters
|
||||
* @return valid filename stripped of invalid characters
|
||||
*/
|
||||
public static String validateFileName(String filename) {
|
||||
// strip invalid characters from filename
|
||||
|
@ -47,7 +43,7 @@ public class FileBotUtil {
|
|||
private static final String[] TORRENT_FILE_EXTENSIONS = { "torrent" };
|
||||
private static final String[] SFV_FILE_EXTENSIONS = { "sfv" };
|
||||
private static final String[] LIST_FILE_EXTENSIONS = { "txt", "list", "" };
|
||||
private static final String[] SUBTITLE_FILE_EXTENSIONS = { "srt", "sub", "ssa" };
|
||||
private static final String[] SUBTITLE_FILE_EXTENSIONS = { "srt", "sub", "ssa", "smi" };
|
||||
|
||||
|
||||
public static boolean containsOnlyFolders(List<File> files) {
|
||||
|
@ -75,7 +71,7 @@ public class FileBotUtil {
|
|||
}
|
||||
|
||||
|
||||
private static boolean containsOnly(List<File> files, String[] extensions) {
|
||||
public static boolean containsOnly(List<File> files, String... extensions) {
|
||||
for (File file : files) {
|
||||
if (!FileUtil.hasExtension(file, extensions))
|
||||
return false;
|
||||
|
@ -111,12 +107,4 @@ public class FileBotUtil {
|
|||
|
||||
};
|
||||
|
||||
|
||||
//TODO needed??
|
||||
public static void writeToFile(File file, ByteBuffer data) throws IOException {
|
||||
FileChannel channel = new FileOutputStream(file).getChannel();
|
||||
channel.write(data);
|
||||
channel.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.swing.SwingWorker;
|
|||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.tuned.ExceptionUtil;
|
||||
import net.sourceforge.tuned.ui.LabelProvider;
|
||||
import net.sourceforge.tuned.ui.SelectButtonTextField;
|
||||
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
|
||||
import net.sourceforge.tuned.ui.TunedUtil;
|
||||
|
@ -45,7 +46,7 @@ public abstract class AbstractSearchPanel<S, E, T extends JComponent> extends Fi
|
|||
|
||||
private final HistoryPanel historyPanel = new HistoryPanel();
|
||||
|
||||
private final SelectButtonTextField<S> searchField;
|
||||
private final SelectButtonTextField<S> searchField = new SelectButtonTextField<S>();
|
||||
|
||||
private final EventList<String> searchHistory = new BasicEventList<String>();
|
||||
|
||||
|
@ -55,8 +56,6 @@ public abstract class AbstractSearchPanel<S, E, T extends JComponent> extends Fi
|
|||
|
||||
setLayout(new BorderLayout(10, 5));
|
||||
|
||||
searchField = new SelectButtonTextField<S>();
|
||||
|
||||
Box searchBox = Box.createHorizontalBox();
|
||||
searchBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
|
@ -92,12 +91,21 @@ public abstract class AbstractSearchPanel<S, E, T extends JComponent> extends Fi
|
|||
completionList.addMemberList(fetchHistory);
|
||||
*/
|
||||
|
||||
searchField.getSelectButton().setModel(createSearchEngines());
|
||||
searchField.getSelectButton().setLabelProvider(createSearchEngineLabelProvider());
|
||||
|
||||
AutoCompleteSupport.install(searchField.getEditor(), searchHistory);
|
||||
|
||||
TunedUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("ENTER"), searchAction);
|
||||
}
|
||||
|
||||
|
||||
protected abstract List<S> createSearchEngines();
|
||||
|
||||
|
||||
protected abstract LabelProvider<S> createSearchEngineLabelProvider();
|
||||
|
||||
|
||||
protected abstract SearchTask createSearchTask();
|
||||
|
||||
|
||||
|
@ -185,7 +193,7 @@ public abstract class AbstractSearchPanel<S, E, T extends JComponent> extends Fi
|
|||
|
||||
tab.setTitle(task.getSearchText());
|
||||
tab.setLoading(true);
|
||||
tab.setIcon(searchField.getSelectButton().getIconProvider().getIcon(task.getClient()));
|
||||
tab.setIcon(searchField.getSelectButton().getLabelProvider().getIcon(task.getClient()));
|
||||
|
||||
tab.addTo(tabbedPane);
|
||||
|
||||
|
@ -253,7 +261,7 @@ public abstract class AbstractSearchPanel<S, E, T extends JComponent> extends Fi
|
|||
|
||||
SelectDialog<SearchResult> selectDialog = new SelectDialog<SearchResult>(window, searchResults);
|
||||
|
||||
selectDialog.setIconImage(TunedUtil.getImage(searchField.getSelectButton().getIconProvider().getIcon(task.getClient())));
|
||||
selectDialog.setIconImage(TunedUtil.getImage(searchField.getSelectButton().getLabelProvider().getIcon(task.getClient())));
|
||||
|
||||
configureSelectDialog(selectDialog);
|
||||
selectDialog.setVisible(true);
|
||||
|
@ -372,7 +380,7 @@ public abstract class AbstractSearchPanel<S, E, T extends JComponent> extends Fi
|
|||
|
||||
String title = task.getSearchResult().toString();
|
||||
URI link = getLink(task.getClient(), task.getSearchResult());
|
||||
Icon icon = searchField.getSelectButton().getIconProvider().getIcon(task.getClient());
|
||||
Icon icon = searchField.getSelectButton().getLabelProvider().getIcon(task.getClient());
|
||||
String info = task.getStatusMessage();
|
||||
String duration = String.format("%,d ms", task.getDuration());
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package net.sourceforge.filebot.ui.panel.search;
|
|||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.SwingWorker;
|
||||
|
@ -33,12 +32,13 @@ class FetchEpisodeListTask extends SwingWorker<List<Episode>, Void> {
|
|||
protected List<Episode> doInBackground() throws Exception {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
Iterator<Episode> itr = searchEngine.getEpisodeList(searchResult, numberOfSeason).iterator();
|
||||
List<Episode> list = new ArrayList<Episode>();
|
||||
|
||||
ArrayList<Episode> list = new ArrayList<Episode>();
|
||||
|
||||
while (itr.hasNext())
|
||||
list.add(itr.next());
|
||||
if (numberOfSeason == SeasonSpinnerModel.ALL_SEASONS) {
|
||||
list.addAll(searchEngine.getEpisodeList(searchResult));
|
||||
} else {
|
||||
list.addAll(searchEngine.getEpisodeList(searchResult, numberOfSeason));
|
||||
}
|
||||
|
||||
duration = System.currentTimeMillis() - start;
|
||||
return list;
|
||||
|
|
|
@ -10,7 +10,9 @@ import java.beans.PropertyChangeEvent;
|
|||
import java.beans.PropertyChangeListener;
|
||||
import java.net.URI;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -24,7 +26,6 @@ import javax.swing.JSpinner;
|
|||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
|
@ -37,13 +38,17 @@ import net.sourceforge.filebot.ui.MessageManager;
|
|||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.ui.transfer.SaveAction;
|
||||
import net.sourceforge.filebot.ui.transfer.Saveable;
|
||||
import net.sourceforge.filebot.web.AnidbClient;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.filebot.web.EpisodeListClient;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.web.TVDotComClient;
|
||||
import net.sourceforge.filebot.web.TVRageClient;
|
||||
import net.sourceforge.tuned.ExceptionUtil;
|
||||
import net.sourceforge.tuned.ui.LabelProvider;
|
||||
import net.sourceforge.tuned.ui.SelectButton;
|
||||
import net.sourceforge.tuned.ui.SelectButtonTextField;
|
||||
import net.sourceforge.tuned.ui.SimpleIconProvider;
|
||||
import net.sourceforge.tuned.ui.SimpleLabelProvider;
|
||||
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
|
||||
import net.sourceforge.tuned.ui.TunedUtil;
|
||||
|
||||
|
@ -54,7 +59,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
private HistoryPanel historyPanel = new HistoryPanel();
|
||||
|
||||
private SpinnerNumberModel seasonSpinnerModel = new SpinnerNumberModel(SeasonSpinnerEditor.ALL_SEASONS, SeasonSpinnerEditor.ALL_SEASONS, Integer.MAX_VALUE, 1);
|
||||
private SeasonSpinnerModel seasonSpinnerModel = new SeasonSpinnerModel();
|
||||
|
||||
private SelectButtonTextField<EpisodeListClient> searchField;
|
||||
|
||||
|
@ -64,8 +69,8 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
searchField = new SelectButtonTextField<EpisodeListClient>();
|
||||
|
||||
searchField.getSelectButton().setModel(EpisodeListClient.getAvailableEpisodeListClients());
|
||||
searchField.getSelectButton().setIconProvider(SimpleIconProvider.forClass(EpisodeListClient.class));
|
||||
searchField.getSelectButton().setModel(createSearchEngines());
|
||||
searchField.getSelectButton().setLabelProvider(createSearchEngineLabelProvider());
|
||||
|
||||
searchField.getSelectButton().addPropertyChangeListener(SelectButton.SELECTED_VALUE, selectButtonListener);
|
||||
|
||||
|
@ -119,9 +124,19 @@ public class SearchPanel extends FileBotPanel {
|
|||
}
|
||||
|
||||
|
||||
public void setSeasonValue(Object value) {
|
||||
if (value != null)
|
||||
seasonSpinnerModel.setValue(value);
|
||||
protected List<EpisodeListClient> createSearchEngines() {
|
||||
List<EpisodeListClient> engines = new ArrayList<EpisodeListClient>(3);
|
||||
|
||||
engines.add(new TVDotComClient());
|
||||
engines.add(new AnidbClient());
|
||||
engines.add(new TVRageClient());
|
||||
|
||||
return engines;
|
||||
}
|
||||
|
||||
|
||||
protected LabelProvider<EpisodeListClient> createSearchEngineLabelProvider() {
|
||||
return SimpleLabelProvider.forClass(EpisodeListClient.class);
|
||||
}
|
||||
|
||||
private final PropertyChangeListener selectButtonListener = new PropertyChangeListener() {
|
||||
|
@ -130,12 +145,10 @@ public class SearchPanel extends FileBotPanel {
|
|||
EpisodeListClient client = searchField.getSelected();
|
||||
|
||||
if (!client.hasSingleSeasonSupport()) {
|
||||
seasonSpinnerModel.setValue(SeasonSpinnerEditor.ALL_SEASONS);
|
||||
seasonSpinnerModel.setMaximum(SeasonSpinnerEditor.ALL_SEASONS);
|
||||
seasonSpinnerModel.lock(SeasonSpinnerModel.ALL_SEASONS);
|
||||
} else {
|
||||
seasonSpinnerModel.setMaximum(Integer.MAX_VALUE);
|
||||
seasonSpinnerModel.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -145,7 +158,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
public void actionPerformed(ActionEvent e) {
|
||||
EpisodeListClient searchEngine = searchField.getSelected();
|
||||
|
||||
SearchTask task = new SearchTask(searchEngine, searchField.getText(), seasonSpinnerModel.getNumber().intValue());
|
||||
SearchTask task = new SearchTask(searchEngine, searchField.getText(), seasonSpinnerModel.getSeason());
|
||||
task.addPropertyChangeListener(new SearchTaskListener());
|
||||
|
||||
task.execute();
|
||||
|
@ -155,14 +168,14 @@ public class SearchPanel extends FileBotPanel {
|
|||
private final AbstractAction upAction = new AbstractAction("Up") {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setSeasonValue(seasonSpinnerModel.getNextValue());
|
||||
seasonSpinnerModel.setValue(seasonSpinnerModel.getNextValue());
|
||||
}
|
||||
};
|
||||
|
||||
private final AbstractAction downAction = new AbstractAction("Down") {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setSeasonValue(seasonSpinnerModel.getPreviousValue());
|
||||
seasonSpinnerModel.setValue(seasonSpinnerModel.getPreviousValue());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -216,7 +229,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
String title = task.query;
|
||||
|
||||
if (task.numberOfSeason != SeasonSpinnerEditor.ALL_SEASONS) {
|
||||
if (task.numberOfSeason != SeasonSpinnerModel.ALL_SEASONS) {
|
||||
title += String.format(" - Season %d", task.numberOfSeason);
|
||||
}
|
||||
|
||||
|
@ -292,7 +305,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
//TODO fix
|
||||
// Settings.getSettings().putStringList(Settings.SEARCH_HISTORY, searchFieldCompletion.getTerms());
|
||||
|
||||
if (task.numberOfSeason != SeasonSpinnerEditor.ALL_SEASONS) {
|
||||
if (task.numberOfSeason != SeasonSpinnerModel.ALL_SEASONS) {
|
||||
title += String.format(" - Season %d", task.numberOfSeason);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import javax.swing.BorderFactory;
|
|||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
@ -18,9 +17,7 @@ import javax.swing.event.ChangeListener;
|
|||
|
||||
class SeasonSpinnerEditor extends JPanel implements ChangeListener {
|
||||
|
||||
public static final int ALL_SEASONS = 0;
|
||||
|
||||
private JLabel text = new JLabel();
|
||||
private final JLabel text = new JLabel();
|
||||
|
||||
|
||||
public SeasonSpinnerEditor(JSpinner spinner) {
|
||||
|
@ -44,13 +41,11 @@ class SeasonSpinnerEditor extends JPanel implements ChangeListener {
|
|||
|
||||
|
||||
private void setValueFromSpinner(JSpinner spinner) {
|
||||
SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
|
||||
int i = model.getNumber().intValue();
|
||||
int season = ((SeasonSpinnerModel) spinner.getModel()).getSeason();
|
||||
|
||||
if (i == ALL_SEASONS)
|
||||
if (season == SeasonSpinnerModel.ALL_SEASONS)
|
||||
text.setText("All Seasons");
|
||||
else
|
||||
text.setText("Season " + i);
|
||||
text.setText("Season " + season);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
package net.sourceforge.filebot.ui.panel.search;
|
||||
|
||||
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
|
||||
|
||||
public class SeasonSpinnerModel extends SpinnerNumberModel {
|
||||
|
||||
public static final int ALL_SEASONS = 0;
|
||||
|
||||
|
||||
public SeasonSpinnerModel() {
|
||||
super(ALL_SEASONS, ALL_SEASONS, Integer.MAX_VALUE, 1);
|
||||
}
|
||||
|
||||
|
||||
public int getSeason() {
|
||||
return getNumber().intValue();
|
||||
}
|
||||
|
||||
|
||||
public void lock(int maxSeason) {
|
||||
setMaximum(maxSeason);
|
||||
}
|
||||
|
||||
|
||||
public void unlock() {
|
||||
setMaximum(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
}
|
|
@ -15,8 +15,8 @@ public class Checksum {
|
|||
|
||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
|
||||
public static final String STATE_PROPERTY = "DOWNLOAD_STATE";
|
||||
public static final String PROGRESS_PROPERTY = "DOWNLOAD_PROGRESS";
|
||||
public static final String STATE_PROPERTY = "state";
|
||||
public static final String PROGRESS_PROPERTY = "progress";
|
||||
|
||||
private Long checksum = null;
|
||||
private State state = State.PENDING;
|
||||
|
|
|
@ -93,10 +93,10 @@ class ChecksumTableModel extends AbstractTableModel {
|
|||
}
|
||||
|
||||
|
||||
public synchronized void addAll(List<Entry> list) {
|
||||
public synchronized void addAll(List<ChecksumCell> list) {
|
||||
int firstRow = getRowCount();
|
||||
|
||||
for (Entry entry : list) {
|
||||
for (ChecksumCell entry : list) {
|
||||
addChecksum(entry.getName(), entry.getChecksum(), entry.getColumnRoot());
|
||||
}
|
||||
|
||||
|
@ -185,16 +185,14 @@ class ChecksumTableModel extends AbstractTableModel {
|
|||
};
|
||||
|
||||
|
||||
public static class Entry {
|
||||
public static class ChecksumCell {
|
||||
|
||||
private String name;
|
||||
|
||||
private Checksum checksum;
|
||||
|
||||
private File columnRoot;
|
||||
private final String name;
|
||||
private final Checksum checksum;
|
||||
private final File columnRoot;
|
||||
|
||||
|
||||
public Entry(String name, Checksum checksum, File columnRoot) {
|
||||
public ChecksumCell(String name, Checksum checksum, File columnRoot) {
|
||||
this.name = name;
|
||||
this.checksum = checksum;
|
||||
this.columnRoot = columnRoot;
|
||||
|
|
|
@ -17,7 +17,7 @@ import net.sourceforge.filebot.FileBotUtil;
|
|||
import net.sourceforge.filebot.ui.transferablepolicies.BackgroundFileTransferablePolicy;
|
||||
|
||||
|
||||
class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumTableModel.Entry> {
|
||||
class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumTableModel.ChecksumCell> {
|
||||
|
||||
private ChecksumTableModel tableModel;
|
||||
|
||||
|
@ -34,7 +34,7 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumTab
|
|||
|
||||
|
||||
@Override
|
||||
protected void process(List<ChecksumTableModel.Entry> chunks) {
|
||||
protected void process(List<ChecksumTableModel.ChecksumCell> chunks) {
|
||||
tableModel.addAll(chunks);
|
||||
}
|
||||
|
||||
|
@ -58,13 +58,13 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumTab
|
|||
String filename = matcher.group(1);
|
||||
String checksumString = matcher.group(2);
|
||||
|
||||
publish(new ChecksumTableModel.Entry(filename, new Checksum(checksumString), sfvFile));
|
||||
publish(new ChecksumTableModel.ChecksumCell(filename, new Checksum(checksumString), sfvFile));
|
||||
|
||||
File compareColumnRoot = sfvFile.getParentFile();
|
||||
File compareFile = new File(compareColumnRoot, filename);
|
||||
|
||||
if (compareFile.exists()) {
|
||||
publish(new ChecksumTableModel.Entry(filename, ChecksumComputationService.getService().getChecksum(compareFile, compareColumnRoot), compareColumnRoot));
|
||||
publish(new ChecksumTableModel.ChecksumCell(filename, ChecksumComputationService.getService().getChecksum(compareFile, compareColumnRoot), compareColumnRoot));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumTab
|
|||
load(f, columnRoot, newPrefix);
|
||||
}
|
||||
} else if (file.isFile()) {
|
||||
publish(new ChecksumTableModel.Entry(prefix + file.getName(), ChecksumComputationService.getService().getChecksum(file, columnRoot), columnRoot));
|
||||
publish(new ChecksumTableModel.ChecksumCell(prefix + file.getName(), ChecksumComputationService.getService().getChecksum(file, columnRoot), columnRoot));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,13 @@ import net.sourceforge.filebot.Settings;
|
|||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.AbstractSearchPanel;
|
||||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesSubtitleClient;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.web.SubsceneSubtitleClient;
|
||||
import net.sourceforge.filebot.web.SubtitleClient;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.tuned.ui.SimpleIconProvider;
|
||||
import net.sourceforge.tuned.ui.LabelProvider;
|
||||
import net.sourceforge.tuned.ui.SimpleLabelProvider;
|
||||
|
||||
|
||||
public class SubtitlePanel extends AbstractSearchPanel<SubtitleClient, SubtitlePackage, SubtitleDownloadPanel> {
|
||||
|
@ -27,9 +30,6 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleClient, SubtitleP
|
|||
getHistoryPanel().setColumnHeader1("Show / Movie");
|
||||
getHistoryPanel().setColumnHeader2("Number of Subtitles");
|
||||
|
||||
getSearchField().getSelectButton().setModel(SubtitleClient.getAvailableSubtitleClients());
|
||||
getSearchField().getSelectButton().setIconProvider(SimpleIconProvider.forClass(SubtitleClient.class));
|
||||
|
||||
List<String> persistentSearchHistory = Settings.getSettings().asStringList(Settings.SUBTITLE_HISTORY);
|
||||
|
||||
getSearchHistory().addAll(persistentSearchHistory);
|
||||
|
@ -38,6 +38,23 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleClient, SubtitleP
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<SubtitleClient> createSearchEngines() {
|
||||
List<SubtitleClient> engines = new ArrayList<SubtitleClient>(2);
|
||||
|
||||
engines.add(new OpenSubtitlesSubtitleClient());
|
||||
engines.add(new SubsceneSubtitleClient());
|
||||
|
||||
return engines;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected LabelProvider<SubtitleClient> createSearchEngineLabelProvider() {
|
||||
return SimpleLabelProvider.forClass(SubtitleClient.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected SearchTask createSearchTask() {
|
||||
SubtitleDownloadPanel panel = new SubtitleDownloadPanel();
|
||||
|
|
|
@ -92,26 +92,20 @@ public class DefaultTransferHandler extends TransferHandler {
|
|||
if (clipboardHandler != null)
|
||||
clipboardHandler.exportToClipboard(comp, clip, action);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setImportHandler(ImportHandler importHandler) {
|
||||
this.importHandler = importHandler;
|
||||
}
|
||||
|
||||
public void setImportHandler(ImportHandler importHandler) {
|
||||
this.importHandler = importHandler;
|
||||
}
|
||||
|
||||
|
||||
public void setExportHandler(ExportHandler exportHandler) {
|
||||
this.exportHandler = exportHandler;
|
||||
}
|
||||
|
||||
public void setExportHandler(ExportHandler exportHandler) {
|
||||
this.exportHandler = exportHandler;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setClipboardHandler(ClipboardHandler clipboardHandler) {
|
||||
this.clipboardHandler = clipboardHandler;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setClipboardHandler(ClipboardHandler clipboardHandler) {
|
||||
this.clipboardHandler = clipboardHandler;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
@ -84,8 +83,6 @@ public abstract class FileTransferablePolicy implements TransferablePolicy {
|
|||
if ((files == null) || files.isEmpty())
|
||||
return;
|
||||
|
||||
Collections.sort(files);
|
||||
|
||||
if (!add)
|
||||
clear();
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ import java.util.Locale;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.tuned.XPathUtil;
|
||||
|
||||
|
@ -25,16 +27,23 @@ import org.w3c.dom.Node;
|
|||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
public class AnidbClient extends EpisodeListClient {
|
||||
public class AnidbClient implements EpisodeListClient {
|
||||
|
||||
private final SearchResultCache searchResultCache = new SearchResultCache();
|
||||
|
||||
private final String host = "anidb.net";
|
||||
|
||||
|
||||
public AnidbClient() {
|
||||
super("AniDB", ResourceManager.getIcon("search.anidb"));
|
||||
};
|
||||
@Override
|
||||
public String getName() {
|
||||
return "AniDB";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ResourceManager.getIcon("search.anidb");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,72 +3,34 @@ package net.sourceforge.filebot.web;
|
|||
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
|
||||
public abstract class EpisodeListClient {
|
||||
public interface EpisodeListClient {
|
||||
|
||||
private static List<EpisodeListClient> registry;
|
||||
|
||||
|
||||
public static synchronized List<EpisodeListClient> getAvailableEpisodeListClients() {
|
||||
if (registry == null) {
|
||||
registry = new ArrayList<EpisodeListClient>(3);
|
||||
|
||||
registry.add(new TVDotComClient());
|
||||
registry.add(new AnidbClient());
|
||||
registry.add(new TVRageClient());
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(registry);
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final Icon icon;
|
||||
|
||||
|
||||
public EpisodeListClient(String name, Icon icon) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
}
|
||||
public Collection<SearchResult> search(String searchterm) throws Exception;
|
||||
|
||||
|
||||
public abstract Collection<SearchResult> search(String searchterm) throws Exception;
|
||||
public boolean hasSingleSeasonSupport();
|
||||
|
||||
|
||||
public abstract boolean hasSingleSeasonSupport();
|
||||
public Collection<Episode> getEpisodeList(SearchResult searchResult) throws Exception;
|
||||
|
||||
|
||||
public abstract Collection<Episode> getEpisodeList(SearchResult searchResult) throws Exception;
|
||||
public Collection<Episode> getEpisodeList(SearchResult searchResult, int season) throws Exception;
|
||||
|
||||
|
||||
public abstract Collection<Episode> getEpisodeList(SearchResult searchResult, int season) throws Exception;
|
||||
public URI getEpisodeListLink(SearchResult searchResult);
|
||||
|
||||
|
||||
public abstract URI getEpisodeListLink(SearchResult searchResult);
|
||||
public URI getEpisodeListLink(SearchResult searchResult, int season);
|
||||
|
||||
|
||||
public abstract URI getEpisodeListLink(SearchResult searchResult, int season);
|
||||
public String getName();
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public Icon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
public Icon getIcon();
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import java.util.TimerTask;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
|
||||
|
@ -19,17 +21,22 @@ import net.sourceforge.filebot.resources.ResourceManager;
|
|||
* {@link SubtitleClient} for OpenSubtitles.
|
||||
*
|
||||
*/
|
||||
public class OpenSubtitlesSubtitleClient extends SubtitleClient {
|
||||
public class OpenSubtitlesSubtitleClient implements SubtitleClient {
|
||||
|
||||
private final OpenSubtitlesClient client = new OpenSubtitlesClient(String.format("%s v%s", Settings.NAME, Settings.VERSION));
|
||||
|
||||
private final LogoutTimer logoutTimer = new LogoutTimer();
|
||||
|
||||
|
||||
public OpenSubtitlesSubtitleClient() {
|
||||
super("OpenSubtitles", ResourceManager.getIcon("search.opensubtitles"));
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(doLogout));
|
||||
@Override
|
||||
public String getName() {
|
||||
return "OpenSubtitles";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ResourceManager.getIcon("search.opensubtitles");
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,6 +70,7 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
|
|||
private synchronized void login() throws Exception {
|
||||
if (!client.isLoggedOn()) {
|
||||
client.loginAnonymous();
|
||||
Runtime.getRuntime().addShutdownHook(logoutShutdownHook);
|
||||
}
|
||||
|
||||
logoutTimer.restart();
|
||||
|
@ -77,11 +85,13 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
|
|||
client.logout();
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, "Exception while deactivating session", e);
|
||||
} finally {
|
||||
Runtime.getRuntime().removeShutdownHook(logoutShutdownHook);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable doLogout = new Runnable() {
|
||||
private final Thread logoutShutdownHook = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.util.logging.Logger;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.tuned.FileUtil;
|
||||
import net.sourceforge.tuned.XPathUtil;
|
||||
|
@ -30,7 +32,7 @@ import org.w3c.dom.Node;
|
|||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
public class SubsceneSubtitleClient extends SubtitleClient {
|
||||
public class SubsceneSubtitleClient implements SubtitleClient {
|
||||
|
||||
private final SearchResultCache searchResultCache = new SearchResultCache();
|
||||
|
||||
|
@ -39,8 +41,15 @@ public class SubsceneSubtitleClient extends SubtitleClient {
|
|||
private final String host = "subscene.com";
|
||||
|
||||
|
||||
public SubsceneSubtitleClient() {
|
||||
super("Subscene", ResourceManager.getIcon("search.subscene"));
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Subscene";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ResourceManager.getIcon("search.subscene");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,62 +3,26 @@ package net.sourceforge.filebot.web;
|
|||
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
|
||||
public abstract class SubtitleClient {
|
||||
public interface SubtitleClient {
|
||||
|
||||
private static List<SubtitleClient> registry;
|
||||
|
||||
|
||||
public static synchronized List<SubtitleClient> getAvailableSubtitleClients() {
|
||||
if (registry == null) {
|
||||
registry = new ArrayList<SubtitleClient>(2);
|
||||
|
||||
registry.add(new OpenSubtitlesSubtitleClient());
|
||||
registry.add(new SubsceneSubtitleClient());
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(registry);
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final Icon icon;
|
||||
|
||||
|
||||
public SubtitleClient(String name, Icon icon) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
}
|
||||
public Collection<SearchResult> search(String searchterm) throws Exception;
|
||||
|
||||
|
||||
public abstract Collection<SearchResult> search(String searchterm) throws Exception;
|
||||
public Collection<SubtitleDescriptor> getSubtitleList(SearchResult searchResult, Locale language) throws Exception;
|
||||
|
||||
|
||||
public abstract Collection<SubtitleDescriptor> getSubtitleList(SearchResult searchResult, Locale language) throws Exception;
|
||||
public URI getSubtitleListLink(SearchResult searchResult);
|
||||
|
||||
|
||||
public abstract URI getSubtitleListLink(SearchResult searchResult);
|
||||
public String getName();
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public Icon getIcon();
|
||||
|
||||
|
||||
public Icon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.util.logging.Level;
|
|||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.tuned.XPathUtil;
|
||||
|
||||
|
@ -29,15 +31,22 @@ import org.w3c.dom.Node;
|
|||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
public class TVDotComClient extends EpisodeListClient {
|
||||
public class TVDotComClient implements EpisodeListClient {
|
||||
|
||||
private final SearchResultCache searchResultCache = new SearchResultCache();
|
||||
|
||||
private final String host = "www.tv.com";
|
||||
|
||||
|
||||
public TVDotComClient() {
|
||||
super("TV.com", ResourceManager.getIcon("search.tvdotcom"));
|
||||
@Override
|
||||
public String getName() {
|
||||
return "TV.com";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ResourceManager.getIcon("search.tvdotcom");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
|
@ -20,15 +21,22 @@ import org.w3c.dom.Node;
|
|||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
public class TVRageClient extends EpisodeListClient {
|
||||
public class TVRageClient implements EpisodeListClient {
|
||||
|
||||
private final SearchResultCache searchResultCache = new SearchResultCache();
|
||||
|
||||
private final String host = "www.tvrage.com";
|
||||
|
||||
|
||||
public TVRageClient() {
|
||||
super("TVRage", ResourceManager.getIcon("search.tvrage"));
|
||||
@Override
|
||||
public String getName() {
|
||||
return "TVRage";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return ResourceManager.getIcon("search.tvrage");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class BasicCachingList<E> extends AbstractList<E> {
|
||||
|
||||
private final List<E> source;
|
||||
private final ArrayList<E> cache;
|
||||
|
||||
|
||||
public BasicCachingList(List<E> source) {
|
||||
this.source = source;
|
||||
|
||||
int sourceSize = source.size();
|
||||
|
||||
this.cache = new ArrayList<E>(sourceSize);
|
||||
|
||||
// fill cache with null values
|
||||
for (int i = 0; i < sourceSize; i++) {
|
||||
cache.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized E get(int index) {
|
||||
E value = cache.get(index);
|
||||
|
||||
if (value == null) {
|
||||
value = source.get(index);
|
||||
cache.set(index, value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized boolean add(E value) {
|
||||
cache.add(value);
|
||||
return source.add(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized E remove(int index) {
|
||||
source.remove(index);
|
||||
return cache.remove(index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
return cache.size();
|
||||
}
|
||||
|
||||
}
|
|
@ -5,8 +5,11 @@ package net.sourceforge.tuned.ui;
|
|||
import javax.swing.Icon;
|
||||
|
||||
|
||||
public interface IconProvider<T> {
|
||||
public interface LabelProvider<T> {
|
||||
|
||||
public String getText(T value);
|
||||
|
||||
|
||||
public Icon getIcon(T value);
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
|
||||
public class NullIconProvider<T extends Object> implements IconProvider<T> {
|
||||
|
||||
@Override
|
||||
public Icon getIcon(Object value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
|
||||
public class NullLabelProvider<T extends Object> implements LabelProvider<T> {
|
||||
|
||||
@Override
|
||||
public Icon getIcon(T value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getText(T value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -41,7 +41,7 @@ public class SelectButton<T> extends JButton {
|
|||
private List<T> model = new ArrayList<T>(0);
|
||||
private SingleSelectionModel selectionModel = new DefaultSingleSelectionModel();
|
||||
|
||||
private IconProvider<T> iconProvider = new NullIconProvider<T>();
|
||||
private LabelProvider<T> labelProvider = new NullLabelProvider<T>();
|
||||
|
||||
private boolean hover = false;
|
||||
|
||||
|
@ -62,21 +62,23 @@ public class SelectButton<T> extends JButton {
|
|||
|
||||
|
||||
public void setModel(List<T> model) {
|
||||
this.model = model;
|
||||
this.model.clear();
|
||||
this.model.addAll(model);
|
||||
|
||||
setSelectedIndex(0);
|
||||
}
|
||||
|
||||
|
||||
public IconProvider<T> getIconProvider() {
|
||||
return iconProvider;
|
||||
public LabelProvider<T> getLabelProvider() {
|
||||
return labelProvider;
|
||||
}
|
||||
|
||||
|
||||
public void setIconProvider(IconProvider<T> iconProvider) {
|
||||
this.iconProvider = iconProvider;
|
||||
public void setLabelProvider(LabelProvider<T> labelProvider) {
|
||||
this.labelProvider = labelProvider;
|
||||
|
||||
// update icon
|
||||
this.setIcon(iconProvider.getIcon(getSelectedValue()));
|
||||
this.setIcon(labelProvider.getIcon(getSelectedValue()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -112,7 +114,7 @@ public class SelectButton<T> extends JButton {
|
|||
|
||||
T value = model.get(i);
|
||||
|
||||
setIcon(iconProvider.getIcon(value));
|
||||
setIcon(labelProvider.getIcon(value));
|
||||
|
||||
firePropertyChange(SELECTED_VALUE, null, value);
|
||||
}
|
||||
|
@ -179,7 +181,7 @@ public class SelectButton<T> extends JButton {
|
|||
JPopupMenu popup = new JPopupMenu();
|
||||
|
||||
for (T value : model) {
|
||||
SelectPopupMenuItem item = new SelectPopupMenuItem(value, iconProvider.getIcon(value));
|
||||
SelectPopupMenuItem item = new SelectPopupMenuItem(labelProvider.getText(value), labelProvider.getIcon(value), value);
|
||||
|
||||
if (value == getSelectedValue())
|
||||
item.setSelected(true);
|
||||
|
@ -197,8 +199,8 @@ public class SelectButton<T> extends JButton {
|
|||
private final T value;
|
||||
|
||||
|
||||
public SelectPopupMenuItem(T value, Icon icon) {
|
||||
super(value.toString(), icon);
|
||||
public SelectPopupMenuItem(String text, Icon icon, T value) {
|
||||
super(text, icon);
|
||||
|
||||
this.value = value;
|
||||
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import net.sourceforge.tuned.ExceptionUtil;
|
||||
|
||||
|
||||
/**
|
||||
* <code>IconProvider</code> based on reflection.
|
||||
*/
|
||||
public class SimpleIconProvider<T> implements IconProvider<T> {
|
||||
|
||||
private final Method getIconMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Same as <code>new SimpleIconProvider<T>(T.class)</code>.
|
||||
*
|
||||
* @return new <code>IconProvider</code>
|
||||
*/
|
||||
public static <T> SimpleIconProvider<T> forClass(Class<T> type) {
|
||||
return new SimpleIconProvider<T>(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new IconProvider which will use the <code>getIcon</code> method of the given
|
||||
* class.
|
||||
*
|
||||
* @param type a class with a <code>getIcon</code> method
|
||||
*/
|
||||
public SimpleIconProvider(Class<T> type) {
|
||||
this(type, "getIcon");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new IconProvider which will use a specified method of a given class
|
||||
*
|
||||
* @param type a class with the specified method
|
||||
* @param getIcon a method name such as <code>getIcon</code>
|
||||
*/
|
||||
public SimpleIconProvider(Class<T> type, String getIcon) {
|
||||
try {
|
||||
getIconMethod = type.getMethod(getIcon);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon(T value) {
|
||||
try {
|
||||
return (Icon) getIconMethod.invoke(value);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtil.asRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import net.sourceforge.tuned.ExceptionUtil;
|
||||
|
||||
|
||||
/**
|
||||
* <code>LabelProvider</code> based on reflection.
|
||||
*/
|
||||
public class SimpleLabelProvider<T> implements LabelProvider<T> {
|
||||
|
||||
private final Method getIconMethod;
|
||||
private final Method getNameMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Same as <code>new SimpleLabelProvider<T>(T.class)</code>.
|
||||
*
|
||||
* @return new <code>LabelProvider</code>
|
||||
*/
|
||||
public static <T> SimpleLabelProvider<T> forClass(Class<T> type) {
|
||||
return new SimpleLabelProvider<T>(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new LabelProvider which will use the <code>getName</code> and
|
||||
* <code>getIcon</code> method of the given class.
|
||||
*
|
||||
* @param type a class that has a <code>getName</code> and a <code>getIcon</code> method
|
||||
*/
|
||||
public SimpleLabelProvider(Class<T> type) {
|
||||
this(type, "getName", "getIcon");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new LabelProvider which will use a specified method of a given class
|
||||
*
|
||||
* @param type a class with the specified method
|
||||
* @param getName a method name such as <code>getName</code>
|
||||
* @param getIcon a method name such as <code>getIcon</code>
|
||||
*/
|
||||
public SimpleLabelProvider(Class<T> type, String getName, String getIcon) {
|
||||
try {
|
||||
getNameMethod = type.getMethod(getName);
|
||||
getIconMethod = type.getMethod(getIcon);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getText(T value) {
|
||||
try {
|
||||
return (String) getNameMethod.invoke(value);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtil.asRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon(T value) {
|
||||
try {
|
||||
return (Icon) getIconMethod.invoke(value);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtil.asRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue