mirror of
https://github.com/mitb-archive/filebot
synced 2025-01-11 22:08:01 -05:00
* AutoCompleteSupport now works with the full movie/series/anime index in the back
* update movie/series/anime index files and exclude bad entries
This commit is contained in:
parent
94ceccf966
commit
f466546788
@ -76,6 +76,7 @@ def getNamePermutations(names) {
|
|||||||
res = res.findResults{ fn(it) }
|
res = res.findResults{ fn(it) }
|
||||||
}
|
}
|
||||||
out += res
|
out += res
|
||||||
|
out = out.findAll{ it.length() >= 2 && !(it =~ /^[a-z]/) && it =~ /^[.\p{L}\p{Digit}]/ } // MUST START WITH UNICODE LETTER
|
||||||
out = out.unique{ it.toLowerCase().normalizePunctuation() }.findAll{ it.length() > 0 }.toList()
|
out = out.unique{ it.toLowerCase().normalizePunctuation() }.findAll{ it.length() > 0 }.toList()
|
||||||
out = out.size() <= 4 ? out : out.subList(0, 4)
|
out = out.size() <= 4 ? out : out.subList(0, 4)
|
||||||
return out
|
return out
|
||||||
|
@ -12,6 +12,8 @@ import java.util.Map.Entry;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import net.sourceforge.filebot.Language;
|
||||||
|
|
||||||
import org.kohsuke.args4j.Argument;
|
import org.kohsuke.args4j.Argument;
|
||||||
import org.kohsuke.args4j.Option;
|
import org.kohsuke.args4j.Option;
|
||||||
import org.kohsuke.args4j.spi.ExplicitBooleanOptionHandler;
|
import org.kohsuke.args4j.spi.ExplicitBooleanOptionHandler;
|
||||||
@ -169,6 +171,10 @@ public class ArgumentBean {
|
|||||||
return new Locale(lang);
|
return new Locale(lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Language getLanguage() {
|
||||||
|
return Language.findLanguage(lang);
|
||||||
|
}
|
||||||
|
|
||||||
public Level getLogLevel() {
|
public Level getLogLevel() {
|
||||||
return Level.parse(log.toUpperCase());
|
return Level.parse(log.toUpperCase());
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,11 @@ import java.awt.Dimension;
|
|||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -32,13 +33,11 @@ import javax.swing.event.ChangeListener;
|
|||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sourceforge.filebot.ResourceManager;
|
import net.sourceforge.filebot.ResourceManager;
|
||||||
import net.sourceforge.filebot.Settings;
|
import net.sourceforge.filebot.Settings;
|
||||||
import net.sourceforge.filebot.similarity.SeriesNameMatcher;
|
|
||||||
import net.sourceforge.filebot.web.SearchResult;
|
import net.sourceforge.filebot.web.SearchResult;
|
||||||
import net.sourceforge.tuned.ExceptionUtilities;
|
import net.sourceforge.tuned.ExceptionUtilities;
|
||||||
import net.sourceforge.tuned.ListChangeSynchronizer;
|
|
||||||
import net.sourceforge.tuned.ui.LabelProvider;
|
import net.sourceforge.tuned.ui.LabelProvider;
|
||||||
|
import net.sourceforge.tuned.ui.SelectButton;
|
||||||
import ca.odell.glazedlists.BasicEventList;
|
import ca.odell.glazedlists.BasicEventList;
|
||||||
import ca.odell.glazedlists.EventList;
|
|
||||||
import ca.odell.glazedlists.matchers.TextMatcherEditor;
|
import ca.odell.glazedlists.matchers.TextMatcherEditor;
|
||||||
import ca.odell.glazedlists.swing.AutoCompleteSupport;
|
import ca.odell.glazedlists.swing.AutoCompleteSupport;
|
||||||
|
|
||||||
@ -52,7 +51,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
|||||||
|
|
||||||
protected final SelectButtonTextField<S> searchTextField = new SelectButtonTextField<S>();
|
protected final SelectButtonTextField<S> searchTextField = new SelectButtonTextField<S>();
|
||||||
|
|
||||||
protected final EventList<String> searchHistory = createSearchHistory();
|
protected final BasicEventList<String> searchHistory = new BasicEventList<String>(100000);
|
||||||
|
|
||||||
public AbstractSearchPanel() {
|
public AbstractSearchPanel() {
|
||||||
historyPanel.setColumnHeader(2, "Duration");
|
historyPanel.setColumnHeader(2, "Duration");
|
||||||
@ -74,6 +73,35 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
|||||||
searchTextField.getSelectButton().setModel(Arrays.asList(getSearchEngines()));
|
searchTextField.getSelectButton().setModel(Arrays.asList(getSearchEngines()));
|
||||||
searchTextField.getSelectButton().setLabelProvider(getSearchEngineLabelProvider());
|
searchTextField.getSelectButton().setLabelProvider(getSearchEngineLabelProvider());
|
||||||
|
|
||||||
|
searchTextField.getSelectButton().addPropertyChangeListener(SelectButton.SELECTED_VALUE, new PropertyChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
new SwingWorker<Collection<String>, Void>() {
|
||||||
|
|
||||||
|
private final S engine = searchTextField.getSelectButton().getSelectedValue();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Collection<String> doInBackground() throws Exception {
|
||||||
|
return getHistory(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
if (engine == searchTextField.getSelectButton().getSelectedValue()) {
|
||||||
|
try {
|
||||||
|
searchHistory.clear();
|
||||||
|
searchHistory.addAll(get());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// restore selected subtitle client
|
// restore selected subtitle client
|
||||||
searchTextField.getSelectButton().setSelectedIndex(Integer.parseInt(getSettings().get("engine.selected", "0")));
|
searchTextField.getSelectButton().setSelectedIndex(Integer.parseInt(getSettings().get("engine.selected", "0")));
|
||||||
@ -91,10 +119,18 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AutoCompleteSupport.install(searchTextField.getEditor(), searchHistory).setFilterMode(TextMatcherEditor.CONTAINS);
|
// high-performance auto-completion
|
||||||
|
AutoCompleteSupport<String> acs = AutoCompleteSupport.install(searchTextField.getEditor(), searchHistory);
|
||||||
|
acs.setTextMatchingStrategy(TextMatcherEditor.IDENTICAL_STRATEGY);
|
||||||
|
acs.setFilterMode(TextMatcherEditor.CONTAINS);
|
||||||
|
acs.setCorrectsCase(true);
|
||||||
|
acs.setStrict(false);
|
||||||
|
|
||||||
installAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), searchAction);
|
installAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), searchAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract Collection<String> getHistory(S engine) throws Exception;
|
||||||
|
|
||||||
protected abstract S[] getSearchEngines();
|
protected abstract S[] getSearchEngines();
|
||||||
|
|
||||||
protected abstract LabelProvider<S> getSearchEngineLabelProvider();
|
protected abstract LabelProvider<S> getSearchEngineLabelProvider();
|
||||||
@ -118,23 +154,6 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
|||||||
new SearchTask(requestProcessor).execute();
|
new SearchTask(requestProcessor).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EventList<String> createSearchHistory() {
|
|
||||||
// create in-memory history
|
|
||||||
BasicEventList<String> history = new BasicEventList<String>();
|
|
||||||
|
|
||||||
// get the preferences node that contains the history entries
|
|
||||||
// and get a StringList that read and writes directly from and to the preferences
|
|
||||||
List<String> persistentHistory = getSettings().node("history").asList();
|
|
||||||
|
|
||||||
// add history from the preferences to the current in-memory history (for completion)
|
|
||||||
history.addAll(persistentHistory);
|
|
||||||
|
|
||||||
// perform all insert/add/remove operations on the in-memory history on the preferences node as well
|
|
||||||
ListChangeSynchronizer.syncEventListToList(history, persistentHistory);
|
|
||||||
|
|
||||||
return history;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final AbstractAction searchAction = new AbstractAction("Find", ResourceManager.getIcon("action.find")) {
|
private final AbstractAction searchAction = new AbstractAction("Find", ResourceManager.getIcon("action.find")) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -200,12 +219,6 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
|||||||
// set search result
|
// set search result
|
||||||
requestProcessor.setSearchResult(selectedSearchResult);
|
requestProcessor.setSearchResult(selectedSearchResult);
|
||||||
|
|
||||||
String historyEntry = requestProcessor.getHistoryEntry();
|
|
||||||
|
|
||||||
if (historyEntry != null && !searchHistory.contains(historyEntry)) {
|
|
||||||
searchHistory.add(historyEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
tab.setTitle(requestProcessor.getTitle());
|
tab.setTitle(requestProcessor.getTitle());
|
||||||
|
|
||||||
// fetch elements of the selected search result
|
// fetch elements of the selected search result
|
||||||
@ -330,14 +343,6 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
|||||||
return request.getSearchText();
|
return request.getSearchText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHistoryEntry() {
|
|
||||||
SeriesNameMatcher nameMatcher = new SeriesNameMatcher();
|
|
||||||
|
|
||||||
// the common word sequence of query and search result
|
|
||||||
// common name will maintain the exact word characters (incl. case) of the first argument
|
|
||||||
return nameMatcher.matchByFirstCommonWordSequence(searchResult.getName(), request.getSearchText());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Icon getIcon() {
|
public Icon getIcon() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -362,7 +367,6 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
|
|||||||
public long getDuration() {
|
public long getDuration() {
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
|
|
||||||
package net.sourceforge.filebot.ui;
|
package net.sourceforge.filebot.ui;
|
||||||
|
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
@ -34,185 +32,170 @@ import net.sourceforge.filebot.ResourceManager;
|
|||||||
import net.sourceforge.tuned.ui.SelectButton;
|
import net.sourceforge.tuned.ui.SelectButton;
|
||||||
import net.sourceforge.tuned.ui.TunedUtilities;
|
import net.sourceforge.tuned.ui.TunedUtilities;
|
||||||
|
|
||||||
|
|
||||||
public class SelectButtonTextField<T> extends JComponent {
|
public class SelectButtonTextField<T> extends JComponent {
|
||||||
|
|
||||||
private SelectButton<T> selectButton = new SelectButton<T>();
|
private SelectButton<T> selectButton = new SelectButton<T>();
|
||||||
|
|
||||||
private JComboBox editor = new JComboBox();
|
private JComboBox editor = new JComboBox();
|
||||||
|
|
||||||
|
|
||||||
public SelectButtonTextField() {
|
public SelectButtonTextField() {
|
||||||
selectButton.addActionListener(textFieldFocusOnClick);
|
selectButton.addActionListener(textFieldFocusOnClick);
|
||||||
|
|
||||||
editor.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, ((LineBorder) selectButton.getBorder()).getLineColor()));
|
editor.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, ((LineBorder) selectButton.getBorder()).getLineColor()));
|
||||||
|
|
||||||
setLayout(new MigLayout("nogrid, fill"));
|
setLayout(new MigLayout("nogrid, fill"));
|
||||||
add(selectButton, "h pref!, w pref!, sizegroupy this");
|
add(selectButton, "h pref!, w pref!, sizegroupy this");
|
||||||
add(editor, "gap 0, w 195px!, sizegroupy this");
|
add(editor, "gap 0, w 195px!, sizegroupy this");
|
||||||
|
|
||||||
editor.setRenderer(new CompletionCellRenderer());
|
editor.setRenderer(new CompletionCellRenderer());
|
||||||
|
editor.setPrototypeDisplayValue("X");
|
||||||
editor.setUI(new TextFieldComboBoxUI());
|
editor.setUI(new TextFieldComboBoxUI());
|
||||||
|
|
||||||
TunedUtilities.installAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.CTRL_MASK), new SpinClientAction(-1));
|
TunedUtilities.installAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.CTRL_MASK), new SpinClientAction(-1));
|
||||||
TunedUtilities.installAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.CTRL_MASK), new SpinClientAction(1));
|
TunedUtilities.installAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.CTRL_MASK), new SpinClientAction(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return ((TextFieldComboBoxUI) editor.getUI()).getEditor().getText();
|
return ((TextFieldComboBoxUI) editor.getUI()).getEditor().getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public JComboBox getEditor() {
|
public JComboBox getEditor() {
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SelectButton<T> getSelectButton() {
|
public SelectButton<T> getSelectButton() {
|
||||||
return selectButton;
|
return selectButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ActionListener textFieldFocusOnClick = new ActionListener() {
|
private final ActionListener textFieldFocusOnClick = new ActionListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
getEditor().requestFocus();
|
getEditor().requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private class SpinClientAction extends AbstractAction {
|
private class SpinClientAction extends AbstractAction {
|
||||||
|
|
||||||
private int spin;
|
private int spin;
|
||||||
|
|
||||||
|
|
||||||
public SpinClientAction(int spin) {
|
public SpinClientAction(int spin) {
|
||||||
super(String.format("Spin%+d", spin));
|
super(String.format("Spin%+d", spin));
|
||||||
this.spin = spin;
|
this.spin = spin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
selectButton.spinValue(spin);
|
selectButton.spinValue(spin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class CompletionCellRenderer extends DefaultListCellRenderer {
|
private class CompletionCellRenderer extends DefaultListCellRenderer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||||
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||||
|
|
||||||
setBorder(new EmptyBorder(1, 4, 1, 4));
|
setBorder(new EmptyBorder(1, 4, 1, 4));
|
||||||
|
|
||||||
String highlightText = SelectButtonTextField.this.getText().substring(0, ((TextFieldComboBoxUI) editor.getUI()).getEditor().getSelectionStart());
|
String highlightText = SelectButtonTextField.this.getText().substring(0, ((TextFieldComboBoxUI) editor.getUI()).getEditor().getSelectionStart());
|
||||||
|
|
||||||
// highlight the matching sequence
|
// highlight the matching sequence
|
||||||
Matcher matcher = Pattern.compile(highlightText, Pattern.LITERAL | Pattern.CASE_INSENSITIVE).matcher(value.toString());
|
Matcher matcher = Pattern.compile(highlightText, Pattern.LITERAL | Pattern.CASE_INSENSITIVE).matcher(value.toString());
|
||||||
|
|
||||||
// use no-break, because we really don't want line-wrapping in our table cells
|
// use no-break, because we really don't want line-wrapping in our table cells
|
||||||
StringBuffer htmlText = new StringBuffer("<html><nobr>");
|
StringBuffer htmlText = new StringBuffer("<html><nobr>");
|
||||||
|
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
matcher.appendReplacement(htmlText, "<span style='font-weight: bold; text-decoration: underline;'>$0</span>");
|
matcher.appendReplacement(htmlText, "<span style='font-weight: bold; text-decoration: underline;'>$0</span>");
|
||||||
}
|
}
|
||||||
|
|
||||||
matcher.appendTail(htmlText);
|
matcher.appendTail(htmlText);
|
||||||
|
|
||||||
htmlText.append("</nobr></html>");
|
htmlText.append("</nobr></html>");
|
||||||
|
|
||||||
setText(htmlText.toString());
|
setText(htmlText.toString());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class TextFieldComboBoxUI extends BasicComboBoxUI {
|
private class TextFieldComboBoxUI extends BasicComboBoxUI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JButton createArrowButton() {
|
protected JButton createArrowButton() {
|
||||||
return new JButton(ResourceManager.getIcon("action.list"));
|
return new JButton(ResourceManager.getIcon("action.list"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configureArrowButton() {
|
public void configureArrowButton() {
|
||||||
super.configureArrowButton();
|
super.configureArrowButton();
|
||||||
|
|
||||||
arrowButton.setContentAreaFilled(false);
|
arrowButton.setContentAreaFilled(false);
|
||||||
arrowButton.setFocusable(false);
|
arrowButton.setFocusable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configureEditor() {
|
protected void configureEditor() {
|
||||||
JTextComponent editor = getEditor();
|
JTextComponent editor = getEditor();
|
||||||
|
|
||||||
editor.setEnabled(comboBox.isEnabled());
|
editor.setEnabled(comboBox.isEnabled());
|
||||||
editor.setFocusable(comboBox.isFocusable());
|
editor.setFocusable(comboBox.isFocusable());
|
||||||
editor.setFont(comboBox.getFont());
|
editor.setFont(comboBox.getFont());
|
||||||
editor.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
|
editor.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
|
||||||
|
|
||||||
editor.addFocusListener(createFocusListener());
|
editor.addFocusListener(createFocusListener());
|
||||||
|
|
||||||
editor.getDocument().addDocumentListener(new DocumentListener() {
|
editor.getDocument().addDocumentListener(new DocumentListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void changedUpdate(DocumentEvent e) {
|
public void changedUpdate(DocumentEvent e) {
|
||||||
popup.getList().repaint();
|
popup.getList().repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void insertUpdate(DocumentEvent e) {
|
public void insertUpdate(DocumentEvent e) {
|
||||||
popup.getList().repaint();
|
popup.getList().repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeUpdate(DocumentEvent e) {
|
public void removeUpdate(DocumentEvent e) {
|
||||||
popup.getList().repaint();
|
popup.getList().repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
popup.getList().setPrototypeCellValue("X");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public JTextComponent getEditor() {
|
public JTextComponent getEditor() {
|
||||||
return (JTextComponent) editor;
|
return (JTextComponent) editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ComboPopup createPopup() {
|
protected ComboPopup createPopup() {
|
||||||
return new BasicComboPopup(comboBox) {
|
return new BasicComboPopup(comboBox) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void show(Component invoker, int x, int y) {
|
public void show(Component invoker, int x, int y) {
|
||||||
super.show(invoker, x - selectButton.getWidth(), y);
|
super.show(invoker, x - selectButton.getWidth(), y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Rectangle computePopupBounds(int px, int py, int pw, int ph) {
|
protected Rectangle computePopupBounds(int px, int py, int pw, int ph) {
|
||||||
Rectangle bounds = super.computePopupBounds(px, py, pw, ph);
|
Rectangle bounds = super.computePopupBounds(px, py, pw, ph);
|
||||||
bounds.width += selectButton.getWidth();
|
bounds.width += selectButton.getWidth();
|
||||||
|
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FocusListener createFocusListener() {
|
protected FocusListener createFocusListener() {
|
||||||
return new FocusHandler() {
|
return new FocusHandler() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent action events from being fired on focusLost.
|
* Prevent action events from being fired on focusLost.
|
||||||
*/
|
*/
|
||||||
@ -224,7 +207,7 @@ public class SelectButtonTextField<T> extends JComponent {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,12 @@ import java.beans.PropertyChangeListener;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
@ -26,13 +28,15 @@ import javax.swing.JSpinner;
|
|||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import net.sourceforge.filebot.Analytics;
|
import net.sourceforge.filebot.Analytics;
|
||||||
|
import net.sourceforge.filebot.Language;
|
||||||
import net.sourceforge.filebot.Settings;
|
import net.sourceforge.filebot.Settings;
|
||||||
import net.sourceforge.filebot.WebServices;
|
import net.sourceforge.filebot.WebServices;
|
||||||
|
import net.sourceforge.filebot.media.MediaDetection;
|
||||||
|
import net.sourceforge.filebot.similarity.Normalization;
|
||||||
import net.sourceforge.filebot.ui.AbstractSearchPanel;
|
import net.sourceforge.filebot.ui.AbstractSearchPanel;
|
||||||
import net.sourceforge.filebot.ui.FileBotList;
|
import net.sourceforge.filebot.ui.FileBotList;
|
||||||
import net.sourceforge.filebot.ui.FileBotListExportHandler;
|
import net.sourceforge.filebot.ui.FileBotListExportHandler;
|
||||||
import net.sourceforge.filebot.ui.FileBotTab;
|
import net.sourceforge.filebot.ui.FileBotTab;
|
||||||
import net.sourceforge.filebot.Language;
|
|
||||||
import net.sourceforge.filebot.ui.LanguageComboBox;
|
import net.sourceforge.filebot.ui.LanguageComboBox;
|
||||||
import net.sourceforge.filebot.ui.SelectDialog;
|
import net.sourceforge.filebot.ui.SelectDialog;
|
||||||
import net.sourceforge.filebot.ui.transfer.ArrayTransferable;
|
import net.sourceforge.filebot.ui.transfer.ArrayTransferable;
|
||||||
@ -77,6 +81,18 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
|
|||||||
TunedUtilities.installAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.SHIFT_MASK), new SpinSeasonAction(-1));
|
TunedUtilities.installAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.SHIFT_MASK), new SpinSeasonAction(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Collection<String> getHistory(EpisodeListProvider engine) throws Exception {
|
||||||
|
final List<String> names = new ArrayList<String>(100000);
|
||||||
|
final SearchResult[] index = (engine == WebServices.AniDB) ? MediaDetection.releaseInfo.getAnidbIndex() : MediaDetection.releaseInfo.getTheTVDBIndex();
|
||||||
|
for (SearchResult it : index) {
|
||||||
|
for (String n : it.getEffectiveNames()) {
|
||||||
|
names.add(Normalization.removeTrailingBrackets(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TreeSet<String>(names);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected EpisodeListProvider[] getSearchEngines() {
|
protected EpisodeListProvider[] getSearchEngines() {
|
||||||
return WebServices.getEpisodeListProviders();
|
return WebServices.getEpisodeListProviders();
|
||||||
|
@ -17,6 +17,7 @@ import java.net.URI;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
@ -32,13 +33,16 @@ import javax.swing.JTextField;
|
|||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import net.sourceforge.filebot.Language;
|
||||||
import net.sourceforge.filebot.ResourceManager;
|
import net.sourceforge.filebot.ResourceManager;
|
||||||
import net.sourceforge.filebot.Settings;
|
import net.sourceforge.filebot.Settings;
|
||||||
import net.sourceforge.filebot.WebServices;
|
import net.sourceforge.filebot.WebServices;
|
||||||
|
import net.sourceforge.filebot.media.MediaDetection;
|
||||||
|
import net.sourceforge.filebot.similarity.Normalization;
|
||||||
import net.sourceforge.filebot.ui.AbstractSearchPanel;
|
import net.sourceforge.filebot.ui.AbstractSearchPanel;
|
||||||
import net.sourceforge.filebot.Language;
|
|
||||||
import net.sourceforge.filebot.ui.LanguageComboBox;
|
import net.sourceforge.filebot.ui.LanguageComboBox;
|
||||||
import net.sourceforge.filebot.ui.SelectDialog;
|
import net.sourceforge.filebot.ui.SelectDialog;
|
||||||
|
import net.sourceforge.filebot.web.Movie;
|
||||||
import net.sourceforge.filebot.web.OpenSubtitlesClient;
|
import net.sourceforge.filebot.web.OpenSubtitlesClient;
|
||||||
import net.sourceforge.filebot.web.SearchResult;
|
import net.sourceforge.filebot.web.SearchResult;
|
||||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||||
@ -138,6 +142,19 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleProvider, Subtitl
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected Collection<String> getHistory(SubtitleProvider engine) throws Exception {
|
||||||
|
final List<String> names = new ArrayList<String>(200000);
|
||||||
|
for (Movie it : MediaDetection.releaseInfo.getMovieList()) {
|
||||||
|
names.addAll(it.getEffectiveNamesWithoutYear());
|
||||||
|
}
|
||||||
|
for (SearchResult it : MediaDetection.releaseInfo.getTheTVDBIndex()) {
|
||||||
|
for (String n : it.getEffectiveNames()) {
|
||||||
|
names.add(Normalization.removeTrailingBrackets(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TreeSet<String>(names);
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SubtitleProvider[] getSearchEngines() {
|
protected SubtitleProvider[] getSearchEngines() {
|
||||||
return WebServices.getSubtitleProviders();
|
return WebServices.getSubtitleProviders();
|
||||||
|
@ -155,7 +155,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is (and must be!) overridden by {@link WebServices.AnidbClientWithLocalSearch} to use our own anime index from sourceforge (as to not abuse anidb servers)
|
* This method is (and must be!) overridden by WebServices.AnidbClientWithLocalSearch to use our own anime index from sourceforge (as to not abuse anidb servers)
|
||||||
*/
|
*/
|
||||||
public synchronized List<AnidbSearchResult> getAnimeTitles() throws Exception {
|
public synchronized List<AnidbSearchResult> getAnimeTitles() throws Exception {
|
||||||
URL url = new URL("http", host, "/api/anime-titles.dat.gz");
|
URL url = new URL("http", host, "/api/anime-titles.dat.gz");
|
||||||
@ -176,6 +176,11 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||||||
languageOrder.add("en");
|
languageOrder.add("en");
|
||||||
languageOrder.add("ja");
|
languageOrder.add("ja");
|
||||||
|
|
||||||
|
List<String> typeOrder = new ArrayList<String>();
|
||||||
|
typeOrder.add("1");
|
||||||
|
typeOrder.add("4");
|
||||||
|
typeOrder.add("2");
|
||||||
|
|
||||||
// fetch data
|
// fetch data
|
||||||
Map<Integer, List<Object[]>> entriesByAnime = new HashMap<Integer, List<Object[]>>(65536);
|
Map<Integer, List<Object[]>> entriesByAnime = new HashMap<Integer, List<Object[]>>(65536);
|
||||||
|
|
||||||
@ -190,7 +195,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||||||
String language = matcher.group(3);
|
String language = matcher.group(3);
|
||||||
String title = matcher.group(4);
|
String title = matcher.group(4);
|
||||||
|
|
||||||
if (aid > 0 && title.length() > 0 && languageOrder.contains(language)) {
|
if (aid > 0 && title.length() > 0 && typeOrder.contains(type) && languageOrder.contains(language)) {
|
||||||
List<Object[]> names = entriesByAnime.get(aid);
|
List<Object[]> names = entriesByAnime.get(aid);
|
||||||
if (names == null) {
|
if (names == null) {
|
||||||
names = new ArrayList<Object[]>();
|
names = new ArrayList<Object[]>();
|
||||||
@ -200,7 +205,7 @@ public class AnidbClient extends AbstractEpisodeListProvider {
|
|||||||
// resolve HTML entities
|
// resolve HTML entities
|
||||||
title = Jsoup.parse(title).text();
|
title = Jsoup.parse(title).text();
|
||||||
|
|
||||||
names.add(new Object[] { Integer.parseInt(type), languageOrder.indexOf(language), title });
|
names.add(new Object[] { typeOrder.indexOf(type), languageOrder.indexOf(language), title });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
|
|
||||||
package net.sourceforge.tuned.ui;
|
package net.sourceforge.tuned.ui;
|
||||||
|
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
@ -29,82 +27,72 @@ import javax.swing.JPopupMenu;
|
|||||||
import javax.swing.SingleSelectionModel;
|
import javax.swing.SingleSelectionModel;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
|
|
||||||
|
|
||||||
public class SelectButton<T> extends JButton {
|
public class SelectButton<T> extends JButton {
|
||||||
|
|
||||||
public static final String SELECTED_VALUE = "selected value";
|
public static final String SELECTED_VALUE = "selected value";
|
||||||
|
|
||||||
private final Color beginColor = new Color(0xF0EEE4);
|
private final Color beginColor = new Color(0xF0EEE4);
|
||||||
private final Color endColor = new Color(0xE0DED4);
|
private final Color endColor = new Color(0xE0DED4);
|
||||||
|
|
||||||
private final Color beginColorHover = beginColor;
|
private final Color beginColorHover = beginColor;
|
||||||
private final Color endColorHover = new Color(0xD8D7CD);
|
private final Color endColorHover = new Color(0xD8D7CD);
|
||||||
|
|
||||||
private final SelectIcon selectIcon = new SelectIcon();
|
private final SelectIcon selectIcon = new SelectIcon();
|
||||||
|
|
||||||
private List<T> model = Collections.emptyList();
|
private List<T> model = Collections.emptyList();
|
||||||
private SingleSelectionModel selectionModel = new DefaultSingleSelectionModel();
|
private SingleSelectionModel selectionModel = new DefaultSingleSelectionModel();
|
||||||
|
|
||||||
private LabelProvider<T> labelProvider = new NullLabelProvider<T>();
|
private LabelProvider<T> labelProvider = new NullLabelProvider<T>();
|
||||||
|
|
||||||
private boolean hover = false;
|
private boolean hover = false;
|
||||||
|
|
||||||
|
|
||||||
public SelectButton() {
|
public SelectButton() {
|
||||||
setContentAreaFilled(false);
|
setContentAreaFilled(false);
|
||||||
setFocusable(false);
|
setFocusable(false);
|
||||||
|
|
||||||
super.setIcon(selectIcon);
|
super.setIcon(selectIcon);
|
||||||
|
|
||||||
setHorizontalAlignment(SwingConstants.CENTER);
|
setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
setVerticalAlignment(SwingConstants.CENTER);
|
setVerticalAlignment(SwingConstants.CENTER);
|
||||||
|
|
||||||
setBorder(BorderFactory.createLineBorder(new Color(0xA4A4A4), 1));
|
setBorder(BorderFactory.createLineBorder(new Color(0xA4A4A4), 1));
|
||||||
setPreferredSize(new Dimension(32, 22));
|
setPreferredSize(new Dimension(32, 22));
|
||||||
|
|
||||||
addActionListener(new OpenPopupOnClick());
|
addActionListener(new OpenPopupOnClick());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setModel(Collection<T> model) {
|
public void setModel(Collection<T> model) {
|
||||||
this.model = new ArrayList<T>(model);
|
this.model = new ArrayList<T>(model);
|
||||||
|
|
||||||
setSelectedIndex(0);
|
setSelectedIndex(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public LabelProvider<T> getLabelProvider() {
|
public LabelProvider<T> getLabelProvider() {
|
||||||
return labelProvider;
|
return labelProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setLabelProvider(LabelProvider<T> labelProvider) {
|
public void setLabelProvider(LabelProvider<T> labelProvider) {
|
||||||
this.labelProvider = labelProvider;
|
this.labelProvider = labelProvider;
|
||||||
|
|
||||||
// update icon
|
// update icon
|
||||||
this.setIcon(labelProvider.getIcon(getSelectedValue()));
|
this.setIcon(labelProvider.getIcon(getSelectedValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIcon(Icon icon) {
|
public void setIcon(Icon icon) {
|
||||||
selectIcon.setInnerIcon(icon);
|
selectIcon.setInnerIcon(icon);
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setSelectedValue(T value) {
|
public void setSelectedValue(T value) {
|
||||||
setSelectedIndex(model.indexOf(value));
|
setSelectedIndex(model.indexOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public T getSelectedValue() {
|
public T getSelectedValue() {
|
||||||
if (!selectionModel.isSelected())
|
if (!selectionModel.isSelected())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return model.get(selectionModel.getSelectedIndex());
|
return model.get(selectionModel.getSelectedIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setSelectedIndex(int i) {
|
public void setSelectedIndex(int i) {
|
||||||
if (i < 0 || i >= model.size()) {
|
if (i < 0 || i >= model.size()) {
|
||||||
@ -112,171 +100,150 @@ public class SelectButton<T> extends JButton {
|
|||||||
setIcon(null);
|
setIcon(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != selectionModel.getSelectedIndex()) {
|
selectionModel.setSelectedIndex(i);
|
||||||
selectionModel.setSelectedIndex(i);
|
T value = model.get(i);
|
||||||
|
setIcon(labelProvider.getIcon(value));
|
||||||
T value = model.get(i);
|
firePropertyChange(SELECTED_VALUE, null, value);
|
||||||
|
|
||||||
setIcon(labelProvider.getIcon(value));
|
|
||||||
|
|
||||||
firePropertyChange(SELECTED_VALUE, null, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getSelectedIndex() {
|
public int getSelectedIndex() {
|
||||||
return selectionModel.getSelectedIndex();
|
return selectionModel.getSelectedIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SingleSelectionModel getSelectionModel() {
|
public SingleSelectionModel getSelectionModel() {
|
||||||
return selectionModel;
|
return selectionModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void spinValue(int spin) {
|
public void spinValue(int spin) {
|
||||||
int size = model.size();
|
int size = model.size();
|
||||||
|
|
||||||
spin = spin % size;
|
spin = spin % size;
|
||||||
|
|
||||||
int next = getSelectedIndex() + spin;
|
int next = getSelectedIndex() + spin;
|
||||||
|
|
||||||
if (next < 0)
|
if (next < 0)
|
||||||
next += size;
|
next += size;
|
||||||
else if (next >= size)
|
else if (next >= size)
|
||||||
next -= size;
|
next -= size;
|
||||||
|
|
||||||
setSelectedIndex(next);
|
setSelectedIndex(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics g) {
|
protected void paintComponent(Graphics g) {
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
Rectangle bounds = new Rectangle(getSize());
|
Rectangle bounds = new Rectangle(getSize());
|
||||||
|
|
||||||
if (hover)
|
if (hover)
|
||||||
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(bounds, beginColorHover, endColorHover));
|
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(bounds, beginColorHover, endColorHover));
|
||||||
else
|
else
|
||||||
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(bounds, beginColor, endColor));
|
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(bounds, beginColor, endColor));
|
||||||
|
|
||||||
g2d.fill(bounds);
|
g2d.fill(bounds);
|
||||||
|
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processMouseEvent(MouseEvent e) {
|
protected void processMouseEvent(MouseEvent e) {
|
||||||
switch (e.getID()) {
|
switch (e.getID()) {
|
||||||
case MouseEvent.MOUSE_ENTERED:
|
case MouseEvent.MOUSE_ENTERED:
|
||||||
hover = true;
|
hover = true;
|
||||||
repaint();
|
repaint();
|
||||||
break;
|
break;
|
||||||
case MouseEvent.MOUSE_EXITED:
|
case MouseEvent.MOUSE_EXITED:
|
||||||
hover = false;
|
hover = false;
|
||||||
repaint();
|
repaint();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.processMouseEvent(e);
|
super.processMouseEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class OpenPopupOnClick implements ActionListener {
|
private class OpenPopupOnClick implements ActionListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
JPopupMenu popup = new JPopupMenu();
|
JPopupMenu popup = new JPopupMenu();
|
||||||
|
|
||||||
for (T value : model) {
|
for (T value : model) {
|
||||||
SelectPopupMenuItem item = new SelectPopupMenuItem(labelProvider.getText(value), labelProvider.getIcon(value), value);
|
SelectPopupMenuItem item = new SelectPopupMenuItem(labelProvider.getText(value), labelProvider.getIcon(value), value);
|
||||||
|
|
||||||
if (value == getSelectedValue())
|
if (value == getSelectedValue())
|
||||||
item.setSelected(true);
|
item.setSelected(true);
|
||||||
|
|
||||||
popup.add(item);
|
popup.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
popup.show(SelectButton.this, 0, getHeight() - 1);
|
popup.show(SelectButton.this, 0, getHeight() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class SelectPopupMenuItem extends JMenuItem implements ActionListener {
|
private class SelectPopupMenuItem extends JMenuItem implements ActionListener {
|
||||||
|
|
||||||
private final T value;
|
private final T value;
|
||||||
|
|
||||||
|
|
||||||
public SelectPopupMenuItem(String text, Icon icon, T value) {
|
public SelectPopupMenuItem(String text, Icon icon, T value) {
|
||||||
super(text, icon);
|
super(text, icon);
|
||||||
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
||||||
setMargin(new Insets(3, 0, 3, 0));
|
setMargin(new Insets(3, 0, 3, 0));
|
||||||
addActionListener(this);
|
addActionListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSelected(boolean selected) {
|
public void setSelected(boolean selected) {
|
||||||
setFont(getFont().deriveFont(selected ? Font.BOLD : Font.PLAIN));
|
setFont(getFont().deriveFont(selected ? Font.BOLD : Font.PLAIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
setSelectedValue(value);
|
setSelectedValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class SelectIcon implements Icon {
|
private static class SelectIcon implements Icon {
|
||||||
|
|
||||||
private final GeneralPath arrow;
|
private final GeneralPath arrow;
|
||||||
|
|
||||||
private Icon icon;
|
private Icon icon;
|
||||||
|
|
||||||
|
|
||||||
public SelectIcon() {
|
public SelectIcon() {
|
||||||
arrow = new GeneralPath(Path2D.WIND_EVEN_ODD, 3);
|
arrow = new GeneralPath(Path2D.WIND_EVEN_ODD, 3);
|
||||||
int x = 25;
|
int x = 25;
|
||||||
int y = 10;
|
int y = 10;
|
||||||
|
|
||||||
arrow.moveTo(x - 2, y);
|
arrow.moveTo(x - 2, y);
|
||||||
arrow.lineTo(x, y + 3);
|
arrow.lineTo(x, y + 3);
|
||||||
arrow.lineTo(x + 3, y);
|
arrow.lineTo(x + 3, y);
|
||||||
arrow.lineTo(x - 2, y);
|
arrow.lineTo(x - 2, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setInnerIcon(Icon icon) {
|
public void setInnerIcon(Icon icon) {
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
icon.paintIcon(c, g2d, 4, 3);
|
icon.paintIcon(c, g2d, 4, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
g2d.setPaint(Color.BLACK);
|
g2d.setPaint(Color.BLACK);
|
||||||
g2d.fill(arrow);
|
g2d.fill(arrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getIconWidth() {
|
public int getIconWidth() {
|
||||||
return 30;
|
return 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getIconHeight() {
|
public int getIconHeight() {
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
^Video$
|
^Video$
|
||||||
^VIDEO_TS$
|
^VIDEO_TS$
|
||||||
^Videos$
|
^Videos$
|
||||||
^volume[0-9]?$
|
^volume\D?\d?$
|
||||||
^Volumes$
|
^Volumes$
|
||||||
^watch$
|
^watch$
|
||||||
^www$
|
^www$
|
||||||
|
Loading…
Reference in New Issue
Block a user