From ab14e07924ba969ed67a05e0a154f4303edaa0d6 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Sun, 22 Feb 2009 19:52:07 +0000 Subject: [PATCH] * improved auto-completion --- .../filebot/ui/AbstractSearchPanel.java | 48 +++++++------- .../tuned/ui/SelectButtonTextField.java | 63 ++++++++++++++++++- 2 files changed, 83 insertions(+), 28 deletions(-) diff --git a/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java b/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java index 84ac554f..7ccb82cb 100644 --- a/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java +++ b/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java @@ -8,7 +8,6 @@ import java.awt.Window; import java.awt.event.ActionEvent; import java.net.URI; import java.util.Collection; -import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -34,6 +33,7 @@ import net.sourceforge.tuned.ui.LabelProvider; import net.sourceforge.tuned.ui.SelectButtonTextField; import net.sourceforge.tuned.ui.TunedUtilities; import ca.odell.glazedlists.EventList; +import ca.odell.glazedlists.matchers.TextMatcherEditor; import ca.odell.glazedlists.swing.AutoCompleteSupport; @@ -73,7 +73,7 @@ public abstract class AbstractSearchPanel extends FileBotPanel { searchTextField.getSelectButton().setModel(createSearchEngines()); searchTextField.getSelectButton().setLabelProvider(createSearchEngineLabelProvider()); - AutoCompleteSupport.install(searchTextField.getEditor(), searchHistory); + AutoCompleteSupport.install(searchTextField.getEditor(), searchHistory).setFilterMode(TextMatcherEditor.CONTAINS); TunedUtilities.putActionForKeystroke(this, KeyStroke.getKeyStroke("ENTER"), searchAction); } @@ -150,14 +150,30 @@ public abstract class AbstractSearchPanel extends FileBotPanel { return; try { - // choose search result - requestProcessor.setSearchResult(requestProcessor.selectSearchResult(get(), SwingUtilities.getWindowAncestor(AbstractSearchPanel.this))); + Collection results = get(); - if (requestProcessor.getSearchResult() == null) { + SearchResult selectedSearchResult = null; + + switch (results.size()) { + case 0: + Logger.getLogger("ui").log(Level.WARNING, String.format("'%s' has not been found.", requestProcessor.request.getSearchText())); + break; + case 1: + selectedSearchResult = results.iterator().next(); + break; + default: + selectedSearchResult = requestProcessor.selectSearchResult(results, SwingUtilities.getWindowAncestor(AbstractSearchPanel.this)); + break; + } + + if (selectedSearchResult == null) { tab.close(); return; } + // set search result + requestProcessor.setSearchResult(selectedSearchResult); + String historyEntry = requestProcessor.getHistoryEntry(); if (historyEntry != null && !searchHistory.contains(historyEntry)) { @@ -324,28 +340,6 @@ public abstract class AbstractSearchPanel extends FileBotPanel { protected SearchResult selectSearchResult(Collection searchResults, Window window) throws Exception { - - switch (searchResults.size()) { - case 0: - Logger.getLogger("ui").warning(String.format("'%s' has not been found.", request.getSearchText())); - return null; - case 1: - return searchResults.iterator().next(); - } - - List exactMatches = new LinkedList(); - - // find exact matches - for (SearchResult result : searchResults) { - if (result.getName().toLowerCase().startsWith(request.getSearchText().toLowerCase())) { - exactMatches.add(result); - } - } - - if (exactMatches.size() == 1) { - return exactMatches.get(0); - } - // multiple results have been found, user must select one SelectDialog selectDialog = new SelectDialog(window, searchResults); diff --git a/source/net/sourceforge/tuned/ui/SelectButtonTextField.java b/source/net/sourceforge/tuned/ui/SelectButtonTextField.java index 73dc194f..5735d808 100644 --- a/source/net/sourceforge/tuned/ui/SelectButtonTextField.java +++ b/source/net/sourceforge/tuned/ui/SelectButtonTextField.java @@ -8,14 +8,21 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.swing.AbstractAction; import javax.swing.BorderFactory; +import javax.swing.DefaultListCellRenderer; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; +import javax.swing.JList; import javax.swing.KeyStroke; +import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; import javax.swing.plaf.basic.BasicComboBoxUI; import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.plaf.basic.ComboPopup; @@ -41,6 +48,7 @@ public class SelectButtonTextField extends JComponent { add(selectButton, "h pref!, w pref!, sizegroupy this"); add(editor, "gap 0, w 195px!, sizegroupy this"); + editor.setRenderer(new CompletionCellRenderer()); editor.setUI(new TextFieldComboBoxUI()); TunedUtilities.putActionForKeystroke(this, KeyStroke.getKeyStroke("ctrl UP"), new SpinClientAction(-1)); @@ -87,6 +95,37 @@ public class SelectButtonTextField extends JComponent { } + private class CompletionCellRenderer extends DefaultListCellRenderer { + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + setBorder(new EmptyBorder(1, 4, 1, 4)); + + String highlightText = SelectButtonTextField.this.getText().substring(0, ((TextFieldComboBoxUI) editor.getUI()).getEditor().getSelectionStart()); + + // highlight the matching sequence + 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 + StringBuffer htmlText = new StringBuffer(""); + + if (matcher.find()) { + matcher.appendReplacement(htmlText, "$0"); + } + + matcher.appendTail(htmlText); + + htmlText.append(""); + + setText(htmlText.toString()); + + return this; + } + } + + private class TextFieldComboBoxUI extends BasicComboBoxUI { @Override @@ -114,6 +153,27 @@ public class SelectButtonTextField extends JComponent { editor.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3)); editor.addFocusListener(createFocusListener()); + + editor.getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void changedUpdate(DocumentEvent e) { + popup.getList().repaint(); + } + + + @Override + public void insertUpdate(DocumentEvent e) { + popup.getList().repaint(); + } + + + @Override + public void removeUpdate(DocumentEvent e) { + popup.getList().repaint(); + } + + }); } @@ -152,8 +212,9 @@ public class SelectButtonTextField extends JComponent { */ @Override public void focusLost(FocusEvent e) { - if (isPopupVisible(comboBox)) + if (isPopupVisible(comboBox)) { setPopupVisible(comboBox, false); + } } }; }