* improved preferences handling

* SelectButton refactoring
This commit is contained in:
Reinhard Pointner 2008-02-29 01:16:52 +00:00
parent 36c0406ec6
commit 3a91757e3e
12 changed files with 237 additions and 126 deletions

View File

@ -4,9 +4,12 @@ package net.sourceforge.filebot;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
@ -14,6 +17,10 @@ public class Settings {
private static Settings settings = new Settings();
public static final String SELECTED_PANEL = "panel";
public static final String SEARCH_HISTORY = "history/search";
public static final String SUBTITLE_HISTORY = "history/subtitle";
public static Settings getSettings() {
return settings;
@ -23,74 +30,91 @@ public class Settings {
private Settings() {
this.prefs = Preferences.userNodeForPackage(this.getClass());
}
private String defaultDelimiter = ";";
private void putStringList(String key, Collection<String> values) {
try {
StringBuffer sb = new StringBuffer();
for (String value : values) {
sb.append(value.replaceAll(defaultDelimiter, " "));
sb.append(defaultDelimiter);
}
prefs.put(key, sb.toString());
} catch (IllegalArgumentException e) {
// value might exceed max length
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
}
this.prefs = Preferences.userRoot().node("filebot");
}
private Collection<String> getStringList(String key) {
String[] values = prefs.get(key, "").split(defaultDelimiter);
public void putString(String key, String value) {
prefs.put(key, value);
}
public String getString(String key, String def) {
return prefs.get(key, def);
}
public void putInt(String key, int value) {
prefs.putInt(key, value);
}
public int getInt(String key, int def) {
return prefs.getInt(key, def);
}
public void putBoolean(String key, boolean value) {
prefs.putBoolean(key, value);
}
public boolean getBoolean(String key, boolean def) {
return prefs.getBoolean(key, def);
}
public Collection<String> getStringList(String key) {
Preferences listNode = prefs.node(key);
List<String> list = new ArrayList<String>();
for (String value : values) {
if (!value.isEmpty())
list.add(value);
try {
for (String nodeKey : listNode.keys()) {
list.add(listNode.get(nodeKey, null));
}
} catch (BackingStoreException e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
}
return list;
}
private static enum Key {
panel, tvshowcompletionterms, subtitlecompletionterms;
}
public int getSelectedPanel() {
return prefs.getInt(Key.panel.name(), 3);
public void putStringList(String key, Collection<String> list) {
Preferences listNode = prefs.node(key);
int i = 0;
for (String entry : list) {
listNode.put(Integer.toString(i), entry);
i++;
}
}
public void setSelectedPanel(int index) {
prefs.putInt(Key.panel.name(), index);
public Map<String, String> getStringMap(String key) {
Preferences mapNode = prefs.node(key);
Map<String, String> map = new HashMap<String, String>();
try {
for (String mapNodeKey : mapNode.keys()) {
map.put(mapNodeKey, mapNode.get(mapNodeKey, null));
}
} catch (BackingStoreException e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
}
return map;
}
public void setTvShowCompletionTerms(Collection<String> terms) {
putStringList(Key.tvshowcompletionterms.name(), terms);
}
public Collection<String> getTvShowCompletionTerms() {
return getStringList(Key.tvshowcompletionterms.name());
}
public void setSubtitleCompletionTerms(Collection<String> terms) {
putStringList(Key.subtitlecompletionterms.name(), terms);
}
public Collection<String> getSubtitleCompletionTerms() {
return getStringList(Key.subtitlecompletionterms.name());
public void putStringMap(String key, Map<String, String> map) {
Preferences mapNode = prefs.node(key);
for (Map.Entry<String, String> entry : map.entrySet()) {
mapNode.put(entry.getKey(), entry.getValue());
}
}
}

View File

@ -6,6 +6,8 @@ import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
@ -27,8 +29,10 @@ public class ResourceManager {
try {
return ImageIO.read(getResource(name));
} catch (IOException e) {
return null;
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
}
return null;
}
@ -37,6 +41,11 @@ public class ResourceManager {
}
public static ImageIcon getFlagIcon(String countryCode) {
return new ImageIcon(ResourceManager.class.getResource(String.format("flags/%s.gif", countryCode)));
}
private static URL getResource(String name) {
String resource = null;

View File

@ -57,7 +57,7 @@ public class FileBotWindow extends JFrame implements ListSelectionListener {
setSize(760, 615);
selectionListPanel.setSelectedIndex(Settings.getSettings().getSelectedPanel());
selectionListPanel.setSelectedIndex(Settings.getSettings().getInt(Settings.SELECTED_PANEL, 3));
}
@ -71,7 +71,7 @@ public class FileBotWindow extends JFrame implements ListSelectionListener {
JComponent c = (JComponent) getContentPane();
c.updateUI();
Settings.getSettings().setSelectedPanel(selectionListPanel.getSelectedIndex());
Settings.getSettings().putInt(Settings.SELECTED_PANEL, selectionListPanel.getSelectedIndex());
}

View File

@ -20,6 +20,8 @@ class RenameListCellRenderer extends FancyListCellRenderer {
public RenameListCellRenderer(ListModel names, ListModel files) {
this.names = names;
this.files = files;
setHighlightingEnabled(false);
}
private Color noMatchGradientBeginColor = Color.decode("#B7B7B7");
@ -44,7 +46,7 @@ class RenameListCellRenderer extends FancyListCellRenderer {
private int getMinLength() {
if (names == null || files == null)
if ((names == null) || (files == null))
return 0;
int n1 = names.getSize();

View File

@ -12,7 +12,6 @@ import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -21,7 +20,6 @@ import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
@ -41,11 +39,8 @@ import net.sourceforge.filebot.ui.FileBotList;
import net.sourceforge.filebot.ui.FileBotPanel;
import net.sourceforge.filebot.ui.MessageManager;
import net.sourceforge.filebot.ui.transfer.SaveAction;
import net.sourceforge.filebot.web.AnidbClient;
import net.sourceforge.filebot.web.Episode;
import net.sourceforge.filebot.web.EpisodeListClient;
import net.sourceforge.filebot.web.TVRageClient;
import net.sourceforge.filebot.web.TvdotcomClient;
import net.sourceforge.tuned.ui.SelectButton;
import net.sourceforge.tuned.ui.SelectDialog;
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
@ -65,30 +60,24 @@ public class SearchPanel extends FileBotPanel {
private TextCompletion searchFieldCompletion;
private List<EpisodeListClient> episodeListClients = new ArrayList<EpisodeListClient>();
private JSpinner seasonSpinner;
public SearchPanel() {
super("Search", ResourceManager.getIcon("panel.search"));
episodeListClients.add(new TvdotcomClient());
episodeListClients.add(new AnidbClient());
episodeListClients.add(new TVRageClient());
List<SelectButton.Entry<EpisodeListClient>> episodeListClients = new ArrayList<SelectButton.Entry<EpisodeListClient>>();
HashMap<EpisodeListClient, ImageIcon> icons = new HashMap<EpisodeListClient, ImageIcon>();
for (EpisodeListClient searchEngine : episodeListClients) {
icons.put(searchEngine, searchEngine.getIcon());
for (EpisodeListClient client : EpisodeListClient.getAvailableEpisodeListClients()) {
episodeListClients.add(new SelectButton.Entry<EpisodeListClient>(client, client.getIcon()));
}
searchField = new TextFieldWithSelect<EpisodeListClient>(episodeListClients, icons);
searchField = new TextFieldWithSelect<EpisodeListClient>(episodeListClients);
searchField.getSelectButton().addPropertyChangeListener(SelectButton.SELECTED_VALUE_PROPERTY, searchFieldListener);
searchField.getTextField().setColumns(25);
searchFieldCompletion = new TextCompletion(searchField.getTextField());
searchFieldCompletion.addCompletionTerms(Settings.getSettings().getTvShowCompletionTerms());
searchFieldCompletion.addCompletionTerms(Settings.getSettings().getStringList(Settings.SEARCH_HISTORY));
searchFieldCompletion.hook();
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
@ -224,27 +213,17 @@ public class SearchPanel extends FileBotPanel {
private class SpinSearchEngineAction extends AbstractAction {
private int spinOffset;
private int spin;
public SpinSearchEngineAction(int spinOffset) {
public SpinSearchEngineAction(int spin) {
super("Spin Search Engine");
this.spinOffset = spinOffset;
this.spin = spin;
}
public void actionPerformed(ActionEvent e) {
EpisodeListClient current = searchField.getSelectedValue();
int nextIndex = episodeListClients.indexOf(current) + spinOffset;
int maxIndex = episodeListClients.size() - 1;
if (nextIndex < 0)
nextIndex = maxIndex;
else if (nextIndex > maxIndex)
nextIndex = 0;
searchField.getSelectButton().setSelectedValue(episodeListClients.get(nextIndex));
searchField.getSelectButton().spinValue(spin);
}
}
@ -327,8 +306,9 @@ public class SearchPanel extends FileBotPanel {
} catch (Exception e) {
tabbedPane.remove(episodeList);
MessageManager.showWarning(FileBotUtil.getRootCause(e).getMessage());
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
Throwable cause = FileBotUtil.getRootCause(e);
MessageManager.showWarning(cause.getMessage());
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, cause.toString());
return;
}
@ -356,9 +336,10 @@ public class SearchPanel extends FileBotPanel {
}
searchFieldCompletion.addCompletionTerm(showname);
Settings.getSettings().setTvShowCompletionTerms(searchFieldCompletion.getCompletionTerms());
Settings.getSettings().putStringList(Settings.SEARCH_HISTORY, searchFieldCompletion.getCompletionTerms());
String title = showname;
if (task.getNumberOfSeason() != SeasonSpinnerEditor.ALL_SEASONS)
title += " - Season " + task.getNumberOfSeason();

View File

@ -134,4 +134,5 @@ public class AnidbClient extends EpisodeListClient {
return new URL("http", host, file);
}
}

View File

@ -3,6 +3,7 @@ package net.sourceforge.filebot.web;
import java.net.URL;
import java.util.LinkedHashSet;
import java.util.List;
import javax.swing.ImageIcon;
@ -10,6 +11,30 @@ import javax.swing.ImageIcon;
public abstract class EpisodeListClient {
private static LinkedHashSet<EpisodeListClient> registry = new LinkedHashSet<EpisodeListClient>();
static {
registry.add(new TvdotcomClient());
registry.add(new AnidbClient());
registry.add(new TVRageClient());
}
public static Iterable<EpisodeListClient> getAvailableEpisodeListClients() {
return registry;
}
public static EpisodeListClient forName(String name) {
for (EpisodeListClient client : registry) {
if (name.equals(client.getName()))
return client;
}
return null;
}
/**
* List of shows
*/
@ -25,7 +50,7 @@ public abstract class EpisodeListClient {
public abstract List<Episode> getEpisodeList(String showname, int season) throws Exception;
public abstract URL getEpisodeListUrl(String showname, int season) throws Exception;
public abstract URL getEpisodeListUrl(String showname, int season);
public boolean isSingleSeasonSupported() {

View File

@ -88,7 +88,7 @@ public class TVRageClient extends EpisodeListClient {
Matcher seasonMatcher = Pattern.compile("Season (\\d+)").matcher(seasonHeader);
if (seasonMatcher.matches()) {
if (season == 0 || season == Integer.parseInt(seasonMatcher.group(1))) {
if ((season == 0) || (season == Integer.parseInt(seasonMatcher.group(1)))) {
Matcher saeMatcher = Pattern.compile("(\\d+)x(\\d+)").matcher(seasonAndEpisodeNumber);
String seasonNumber = null;
@ -133,4 +133,5 @@ public class TVRageClient extends EpisodeListClient {
String file = "/search.php?search=" + qs;
return new URL("http", host, file);
}
}

View File

@ -119,7 +119,7 @@ public class TvdotcomClient extends EpisodeListClient {
@Override
public URL getEpisodeListUrl(String showname, int season) {
public URL getEpisodeListUrl(String showname, int season) {
try {
String summaryFile = cache.get(showname).getFile();
@ -139,4 +139,5 @@ public class TvdotcomClient extends EpisodeListClient {
return new URL("http", host, file);
}
}

View File

@ -24,8 +24,6 @@ public class FancyListCellRenderer extends DefaultListCellRenderer {
private Color gradientEndColor;
private boolean highlightingEnabled;
private Border defaultBorder;
private Border selectedBorder;
@ -36,9 +34,11 @@ public class FancyListCellRenderer extends DefaultListCellRenderer {
private Insets padding;
private boolean highlightingEnabled;
public FancyListCellRenderer() {
this(GradientStyle.TOP_TO_BOTTOM, false, new Insets(7, 7, 7, 7), new Insets(1, 1, 0, 1), null);
this(GradientStyle.TOP_TO_BOTTOM, true, new Insets(7, 7, 7, 7), new Insets(1, 1, 0, 1), null);
}

View File

@ -15,8 +15,9 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JButton;
@ -35,17 +36,18 @@ public class SelectButton<T> extends JButton implements ActionListener {
private Color beginColorHover = beginColor;
private Color endColorHover = Color.decode("#D8D7CD");
private T selectedValue = null;
private Entry<T> selectedEntry = null;
private List<T> options;
private Map<T, ? extends Icon> icons;
private List<Entry<T>> entries = new ArrayList<Entry<T>>();
public static final String SELECTED_VALUE_PROPERTY = "SELECTED_VALUE_PROPERTY";
public SelectButton(List<T> options, Map<T, ? extends Icon> icons) {
this.options = options;
this.icons = icons;
public SelectButton(Collection<Entry<T>> entries) {
if (entries.isEmpty())
throw new IllegalArgumentException("Entries must not be empty");
this.entries.addAll(entries);
setContentAreaFilled(false);
setFocusable(false);
@ -57,36 +59,70 @@ public class SelectButton<T> extends JButton implements ActionListener {
addMouseListener(new MouseInputListener());
// select first option
setSelectedValue(options.iterator().next());
setPreferredSize(new Dimension(32, 22));
// select first entry
setSelectedIndex(0);
}
public void setSelectedValue(T value) {
if (selectedValue == value)
Entry<T> entry = find(value);
if (entry == null)
return;
T oldSelectedValue = selectedValue;
selectedEntry = entry;
setIcon(new SelectIcon(selectedEntry.getIcon()));
selectedValue = value;
Icon icon = icons.get(selectedValue);
setIcon(new SelectIcon(icon));
firePropertyChange(SELECTED_VALUE_PROPERTY, oldSelectedValue, selectedValue);
firePropertyChange(SELECTED_VALUE_PROPERTY, null, selectedEntry);
}
public T getSelectedValue() {
return selectedValue;
public T getSelectedEntry() {
return selectedEntry.getValue();
}
public void setSelectedIndex(int i) {
setSelectedValue(entries.get(i).getValue());
}
public int getSelectedIndex() {
return entries.indexOf(selectedEntry);
}
private Entry<T> find(T value) {
for (Entry<T> entry : entries) {
if (entry.value == value)
return entry;
}
return null;
}
public void spinValue(int spin) {
spin = spin % entries.size();
int next = getSelectedIndex() + spin;
if (next < 0)
next += entries.size();
else if (next >= entries.size())
next -= entries.size();
setSelectedIndex(next);
}
public void actionPerformed(ActionEvent e) {
JPopupMenu popup = new JPopupMenu();
for (T option : options) {
popup.add(new SelectMenuIem(option));
for (Entry<T> entry : entries) {
popup.add(new SelectMenuItem(entry));
}
popup.show(this, 0, getHeight() - 1);
@ -108,22 +144,24 @@ public class SelectButton<T> extends JButton implements ActionListener {
}
private class SelectMenuIem extends JMenuItem implements ActionListener {
private class SelectMenuItem extends JMenuItem implements ActionListener {
private T value;
public SelectMenuIem(T value) {
super(value.toString(), icons.get(value));
this.value = value;
public SelectMenuItem(Entry<T> entry) {
super(entry.toString(), entry.getIcon());
this.value = entry.getValue();
this.setMargin(new Insets(3, 0, 3, 0));
this.addActionListener(this);
if (this.value == getSelectedValue())
if (this.value == getSelectedEntry())
this.setFont(this.getFont().deriveFont(Font.BOLD));
}
@Override
public void actionPerformed(ActionEvent e) {
setSelectedValue(value);
}
@ -189,4 +227,33 @@ public class SelectButton<T> extends JButton implements ActionListener {
}
public static class Entry<T> {
private T value;
private Icon icon;
public Entry(T value, Icon icon) {
this.value = value;
this.icon = icon;
}
public T getValue() {
return value;
}
public Icon getIcon() {
return icon;
}
@Override
public String toString() {
return value.toString();
}
}
}

View File

@ -6,15 +6,15 @@ import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.Border;
import net.sourceforge.tuned.ui.SelectButton.Entry;
public class TextFieldWithSelect<T> extends JPanel {
@ -24,10 +24,10 @@ public class TextFieldWithSelect<T> extends JPanel {
private Color borderColor = Color.decode("#A4A4A4");
public TextFieldWithSelect(List<T> options, Map<T, ? extends Icon> icons) {
public TextFieldWithSelect(Collection<Entry<T>> options) {
setLayout(new BorderLayout(0, 0));
selectButton = new SelectButton<T>(options, icons);
selectButton = new SelectButton<T>(options);
selectButton.addActionListener(textFieldFocusOnClick);
Border lineBorder = BorderFactory.createLineBorder(borderColor, 1);
@ -54,7 +54,7 @@ public class TextFieldWithSelect<T> extends JPanel {
public T getSelectedValue() {
return selectButton.getSelectedValue();
return selectButton.getSelectedEntry();
}