* improved preferences handling
* SelectButton refactoring
This commit is contained in:
parent
36c0406ec6
commit
3a91757e3e
|
@ -4,9 +4,12 @@ package net.sourceforge.filebot;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.prefs.BackingStoreException;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +17,10 @@ public class Settings {
|
||||||
|
|
||||||
private static Settings settings = new 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() {
|
public static Settings getSettings() {
|
||||||
return settings;
|
return settings;
|
||||||
|
@ -23,74 +30,91 @@ public class Settings {
|
||||||
|
|
||||||
|
|
||||||
private Settings() {
|
private Settings() {
|
||||||
this.prefs = Preferences.userNodeForPackage(this.getClass());
|
this.prefs = Preferences.userRoot().node("filebot");
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Collection<String> getStringList(String key) {
|
public void putString(String key, String value) {
|
||||||
String[] values = prefs.get(key, "").split(defaultDelimiter);
|
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>();
|
List<String> list = new ArrayList<String>();
|
||||||
|
|
||||||
for (String value : values) {
|
try {
|
||||||
if (!value.isEmpty())
|
for (String nodeKey : listNode.keys()) {
|
||||||
list.add(value);
|
list.add(listNode.get(nodeKey, null));
|
||||||
|
}
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static enum Key {
|
public void putStringList(String key, Collection<String> list) {
|
||||||
panel, tvshowcompletionterms, subtitlecompletionterms;
|
Preferences listNode = prefs.node(key);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (String entry : list) {
|
||||||
|
listNode.put(Integer.toString(i), entry);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 int getSelectedPanel() {
|
public void putStringMap(String key, Map<String, String> map) {
|
||||||
return prefs.getInt(Key.panel.name(), 3);
|
Preferences mapNode = prefs.node(key);
|
||||||
}
|
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||||
public void setSelectedPanel(int index) {
|
mapNode.put(entry.getKey(), entry.getValue());
|
||||||
prefs.putInt(Key.panel.name(), index);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import java.awt.Image;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
@ -27,8 +29,10 @@ public class ResourceManager {
|
||||||
try {
|
try {
|
||||||
return ImageIO.read(getResource(name));
|
return ImageIO.read(getResource(name));
|
||||||
} catch (IOException e) {
|
} 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) {
|
private static URL getResource(String name) {
|
||||||
String resource = null;
|
String resource = null;
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class FileBotWindow extends JFrame implements ListSelectionListener {
|
||||||
|
|
||||||
setSize(760, 615);
|
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();
|
JComponent c = (JComponent) getContentPane();
|
||||||
c.updateUI();
|
c.updateUI();
|
||||||
|
|
||||||
Settings.getSettings().setSelectedPanel(selectionListPanel.getSelectedIndex());
|
Settings.getSettings().putInt(Settings.SELECTED_PANEL, selectionListPanel.getSelectedIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ class RenameListCellRenderer extends FancyListCellRenderer {
|
||||||
public RenameListCellRenderer(ListModel names, ListModel files) {
|
public RenameListCellRenderer(ListModel names, ListModel files) {
|
||||||
this.names = names;
|
this.names = names;
|
||||||
this.files = files;
|
this.files = files;
|
||||||
|
|
||||||
|
setHighlightingEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color noMatchGradientBeginColor = Color.decode("#B7B7B7");
|
private Color noMatchGradientBeginColor = Color.decode("#B7B7B7");
|
||||||
|
@ -44,7 +46,7 @@ class RenameListCellRenderer extends FancyListCellRenderer {
|
||||||
|
|
||||||
|
|
||||||
private int getMinLength() {
|
private int getMinLength() {
|
||||||
if (names == null || files == null)
|
if ((names == null) || (files == null))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int n1 = names.getSize();
|
int n1 = names.getSize();
|
||||||
|
|
|
@ -12,7 +12,6 @@ import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -21,7 +20,6 @@ import javax.swing.AbstractAction;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
import javax.swing.DefaultListModel;
|
import javax.swing.DefaultListModel;
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JScrollPane;
|
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.FileBotPanel;
|
||||||
import net.sourceforge.filebot.ui.MessageManager;
|
import net.sourceforge.filebot.ui.MessageManager;
|
||||||
import net.sourceforge.filebot.ui.transfer.SaveAction;
|
import net.sourceforge.filebot.ui.transfer.SaveAction;
|
||||||
import net.sourceforge.filebot.web.AnidbClient;
|
|
||||||
import net.sourceforge.filebot.web.Episode;
|
import net.sourceforge.filebot.web.Episode;
|
||||||
import net.sourceforge.filebot.web.EpisodeListClient;
|
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.SelectButton;
|
||||||
import net.sourceforge.tuned.ui.SelectDialog;
|
import net.sourceforge.tuned.ui.SelectDialog;
|
||||||
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
|
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
|
||||||
|
@ -65,30 +60,24 @@ public class SearchPanel extends FileBotPanel {
|
||||||
|
|
||||||
private TextCompletion searchFieldCompletion;
|
private TextCompletion searchFieldCompletion;
|
||||||
|
|
||||||
private List<EpisodeListClient> episodeListClients = new ArrayList<EpisodeListClient>();
|
|
||||||
|
|
||||||
private JSpinner seasonSpinner;
|
private JSpinner seasonSpinner;
|
||||||
|
|
||||||
|
|
||||||
public SearchPanel() {
|
public SearchPanel() {
|
||||||
super("Search", ResourceManager.getIcon("panel.search"));
|
super("Search", ResourceManager.getIcon("panel.search"));
|
||||||
|
|
||||||
episodeListClients.add(new TvdotcomClient());
|
List<SelectButton.Entry<EpisodeListClient>> episodeListClients = new ArrayList<SelectButton.Entry<EpisodeListClient>>();
|
||||||
episodeListClients.add(new AnidbClient());
|
|
||||||
episodeListClients.add(new TVRageClient());
|
|
||||||
|
|
||||||
HashMap<EpisodeListClient, ImageIcon> icons = new HashMap<EpisodeListClient, ImageIcon>();
|
for (EpisodeListClient client : EpisodeListClient.getAvailableEpisodeListClients()) {
|
||||||
|
episodeListClients.add(new SelectButton.Entry<EpisodeListClient>(client, client.getIcon()));
|
||||||
for (EpisodeListClient searchEngine : episodeListClients) {
|
|
||||||
icons.put(searchEngine, searchEngine.getIcon());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
searchField = new TextFieldWithSelect<EpisodeListClient>(episodeListClients, icons);
|
searchField = new TextFieldWithSelect<EpisodeListClient>(episodeListClients);
|
||||||
searchField.getSelectButton().addPropertyChangeListener(SelectButton.SELECTED_VALUE_PROPERTY, searchFieldListener);
|
searchField.getSelectButton().addPropertyChangeListener(SelectButton.SELECTED_VALUE_PROPERTY, searchFieldListener);
|
||||||
searchField.getTextField().setColumns(25);
|
searchField.getTextField().setColumns(25);
|
||||||
|
|
||||||
searchFieldCompletion = new TextCompletion(searchField.getTextField());
|
searchFieldCompletion = new TextCompletion(searchField.getTextField());
|
||||||
searchFieldCompletion.addCompletionTerms(Settings.getSettings().getTvShowCompletionTerms());
|
searchFieldCompletion.addCompletionTerms(Settings.getSettings().getStringList(Settings.SEARCH_HISTORY));
|
||||||
searchFieldCompletion.hook();
|
searchFieldCompletion.hook();
|
||||||
|
|
||||||
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
|
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
|
||||||
|
@ -224,27 +213,17 @@ public class SearchPanel extends FileBotPanel {
|
||||||
|
|
||||||
private class SpinSearchEngineAction extends AbstractAction {
|
private class SpinSearchEngineAction extends AbstractAction {
|
||||||
|
|
||||||
private int spinOffset;
|
private int spin;
|
||||||
|
|
||||||
|
|
||||||
public SpinSearchEngineAction(int spinOffset) {
|
public SpinSearchEngineAction(int spin) {
|
||||||
super("Spin Search Engine");
|
super("Spin Search Engine");
|
||||||
this.spinOffset = spinOffset;
|
this.spin = spin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
EpisodeListClient current = searchField.getSelectedValue();
|
searchField.getSelectButton().spinValue(spin);
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,8 +306,9 @@ public class SearchPanel extends FileBotPanel {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
tabbedPane.remove(episodeList);
|
tabbedPane.remove(episodeList);
|
||||||
|
|
||||||
MessageManager.showWarning(FileBotUtil.getRootCause(e).getMessage());
|
Throwable cause = FileBotUtil.getRootCause(e);
|
||||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
MessageManager.showWarning(cause.getMessage());
|
||||||
|
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, cause.toString());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -356,9 +336,10 @@ public class SearchPanel extends FileBotPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
searchFieldCompletion.addCompletionTerm(showname);
|
searchFieldCompletion.addCompletionTerm(showname);
|
||||||
Settings.getSettings().setTvShowCompletionTerms(searchFieldCompletion.getCompletionTerms());
|
Settings.getSettings().putStringList(Settings.SEARCH_HISTORY, searchFieldCompletion.getCompletionTerms());
|
||||||
|
|
||||||
String title = showname;
|
String title = showname;
|
||||||
|
|
||||||
if (task.getNumberOfSeason() != SeasonSpinnerEditor.ALL_SEASONS)
|
if (task.getNumberOfSeason() != SeasonSpinnerEditor.ALL_SEASONS)
|
||||||
title += " - Season " + task.getNumberOfSeason();
|
title += " - Season " + task.getNumberOfSeason();
|
||||||
|
|
||||||
|
|
|
@ -134,4 +134,5 @@ public class AnidbClient extends EpisodeListClient {
|
||||||
|
|
||||||
return new URL("http", host, file);
|
return new URL("http", host, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package net.sourceforge.filebot.web;
|
||||||
|
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
@ -10,6 +11,30 @@ import javax.swing.ImageIcon;
|
||||||
|
|
||||||
public abstract class EpisodeListClient {
|
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
|
* List of shows
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +50,7 @@ public abstract class EpisodeListClient {
|
||||||
public abstract List<Episode> getEpisodeList(String showname, int season) throws Exception;
|
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() {
|
public boolean isSingleSeasonSupported() {
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class TVRageClient extends EpisodeListClient {
|
||||||
Matcher seasonMatcher = Pattern.compile("Season (\\d+)").matcher(seasonHeader);
|
Matcher seasonMatcher = Pattern.compile("Season (\\d+)").matcher(seasonHeader);
|
||||||
|
|
||||||
if (seasonMatcher.matches()) {
|
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);
|
Matcher saeMatcher = Pattern.compile("(\\d+)x(\\d+)").matcher(seasonAndEpisodeNumber);
|
||||||
|
|
||||||
String seasonNumber = null;
|
String seasonNumber = null;
|
||||||
|
@ -133,4 +133,5 @@ public class TVRageClient extends EpisodeListClient {
|
||||||
String file = "/search.php?search=" + qs;
|
String file = "/search.php?search=" + qs;
|
||||||
return new URL("http", host, file);
|
return new URL("http", host, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,4 +139,5 @@ public class TvdotcomClient extends EpisodeListClient {
|
||||||
|
|
||||||
return new URL("http", host, file);
|
return new URL("http", host, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,6 @@ public class FancyListCellRenderer extends DefaultListCellRenderer {
|
||||||
|
|
||||||
private Color gradientEndColor;
|
private Color gradientEndColor;
|
||||||
|
|
||||||
private boolean highlightingEnabled;
|
|
||||||
|
|
||||||
private Border defaultBorder;
|
private Border defaultBorder;
|
||||||
|
|
||||||
private Border selectedBorder;
|
private Border selectedBorder;
|
||||||
|
@ -36,9 +34,11 @@ public class FancyListCellRenderer extends DefaultListCellRenderer {
|
||||||
|
|
||||||
private Insets padding;
|
private Insets padding;
|
||||||
|
|
||||||
|
private boolean highlightingEnabled;
|
||||||
|
|
||||||
|
|
||||||
public FancyListCellRenderer() {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,9 @@ import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.geom.GeneralPath;
|
import java.awt.geom.GeneralPath;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
|
@ -35,17 +36,18 @@ public class SelectButton<T> extends JButton implements ActionListener {
|
||||||
private Color beginColorHover = beginColor;
|
private Color beginColorHover = beginColor;
|
||||||
private Color endColorHover = Color.decode("#D8D7CD");
|
private Color endColorHover = Color.decode("#D8D7CD");
|
||||||
|
|
||||||
private T selectedValue = null;
|
private Entry<T> selectedEntry = null;
|
||||||
|
|
||||||
private List<T> options;
|
private List<Entry<T>> entries = new ArrayList<Entry<T>>();
|
||||||
private Map<T, ? extends Icon> icons;
|
|
||||||
|
|
||||||
public static final String SELECTED_VALUE_PROPERTY = "SELECTED_VALUE_PROPERTY";
|
public static final String SELECTED_VALUE_PROPERTY = "SELECTED_VALUE_PROPERTY";
|
||||||
|
|
||||||
|
|
||||||
public SelectButton(List<T> options, Map<T, ? extends Icon> icons) {
|
public SelectButton(Collection<Entry<T>> entries) {
|
||||||
this.options = options;
|
if (entries.isEmpty())
|
||||||
this.icons = icons;
|
throw new IllegalArgumentException("Entries must not be empty");
|
||||||
|
|
||||||
|
this.entries.addAll(entries);
|
||||||
|
|
||||||
setContentAreaFilled(false);
|
setContentAreaFilled(false);
|
||||||
setFocusable(false);
|
setFocusable(false);
|
||||||
|
@ -57,36 +59,70 @@ public class SelectButton<T> extends JButton implements ActionListener {
|
||||||
|
|
||||||
addMouseListener(new MouseInputListener());
|
addMouseListener(new MouseInputListener());
|
||||||
|
|
||||||
// select first option
|
|
||||||
setSelectedValue(options.iterator().next());
|
|
||||||
setPreferredSize(new Dimension(32, 22));
|
setPreferredSize(new Dimension(32, 22));
|
||||||
|
|
||||||
|
// select first entry
|
||||||
|
setSelectedIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setSelectedValue(T value) {
|
public void setSelectedValue(T value) {
|
||||||
if (selectedValue == value)
|
Entry<T> entry = find(value);
|
||||||
|
|
||||||
|
if (entry == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
T oldSelectedValue = selectedValue;
|
selectedEntry = entry;
|
||||||
|
setIcon(new SelectIcon(selectedEntry.getIcon()));
|
||||||
|
|
||||||
selectedValue = value;
|
firePropertyChange(SELECTED_VALUE_PROPERTY, null, selectedEntry);
|
||||||
Icon icon = icons.get(selectedValue);
|
|
||||||
setIcon(new SelectIcon(icon));
|
|
||||||
|
|
||||||
firePropertyChange(SELECTED_VALUE_PROPERTY, oldSelectedValue, selectedValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public T getSelectedValue() {
|
public T getSelectedEntry() {
|
||||||
return selectedValue;
|
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) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
JPopupMenu popup = new JPopupMenu();
|
JPopupMenu popup = new JPopupMenu();
|
||||||
|
|
||||||
for (T option : options) {
|
for (Entry<T> entry : entries) {
|
||||||
popup.add(new SelectMenuIem(option));
|
popup.add(new SelectMenuItem(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
popup.show(this, 0, getHeight() - 1);
|
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;
|
private T value;
|
||||||
|
|
||||||
|
|
||||||
public SelectMenuIem(T value) {
|
public SelectMenuItem(Entry<T> entry) {
|
||||||
super(value.toString(), icons.get(value));
|
super(entry.toString(), entry.getIcon());
|
||||||
this.value = value;
|
this.value = entry.getValue();
|
||||||
|
|
||||||
this.setMargin(new Insets(3, 0, 3, 0));
|
this.setMargin(new Insets(3, 0, 3, 0));
|
||||||
this.addActionListener(this);
|
this.addActionListener(this);
|
||||||
|
|
||||||
if (this.value == getSelectedValue())
|
if (this.value == getSelectedEntry())
|
||||||
this.setFont(this.getFont().deriveFont(Font.BOLD));
|
this.setFont(this.getFont().deriveFont(Font.BOLD));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
setSelectedValue(value);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,15 @@ import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.List;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.Icon;
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
|
|
||||||
|
import net.sourceforge.tuned.ui.SelectButton.Entry;
|
||||||
|
|
||||||
|
|
||||||
public class TextFieldWithSelect<T> extends JPanel {
|
public class TextFieldWithSelect<T> extends JPanel {
|
||||||
|
|
||||||
|
@ -24,10 +24,10 @@ public class TextFieldWithSelect<T> extends JPanel {
|
||||||
private Color borderColor = Color.decode("#A4A4A4");
|
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));
|
setLayout(new BorderLayout(0, 0));
|
||||||
|
|
||||||
selectButton = new SelectButton<T>(options, icons);
|
selectButton = new SelectButton<T>(options);
|
||||||
selectButton.addActionListener(textFieldFocusOnClick);
|
selectButton.addActionListener(textFieldFocusOnClick);
|
||||||
|
|
||||||
Border lineBorder = BorderFactory.createLineBorder(borderColor, 1);
|
Border lineBorder = BorderFactory.createLineBorder(borderColor, 1);
|
||||||
|
@ -54,7 +54,7 @@ public class TextFieldWithSelect<T> extends JPanel {
|
||||||
|
|
||||||
|
|
||||||
public T getSelectedValue() {
|
public T getSelectedValue() {
|
||||||
return selectButton.getSelectedValue();
|
return selectButton.getSelectedEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue