-
Notifications
You must be signed in to change notification settings - Fork 914
Improve quick search behavior in OutlineView, TreeTable, and ListView #8319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -36,6 +36,7 @@ | |||||||||
| import org.netbeans.api.annotations.common.StaticResource; | ||||||||||
| import org.openide.util.ImageUtilities; | ||||||||||
| import org.openide.util.RequestProcessor; | ||||||||||
| import org.openide.util.Utilities; | ||||||||||
|
|
||||||||||
| /** | ||||||||||
| * Quick search infrastructure for an arbitrary component. | ||||||||||
|
|
@@ -52,7 +53,9 @@ public class QuickSearch { | |||||||||
| @StaticResource | ||||||||||
| private static final String ICON_FIND_WITH_MENU = "org/openide/awt/resources/quicksearch/findMenu.png"; // NOI18N | ||||||||||
| private static final Object CLIENT_PROPERTY_KEY = new Object(); | ||||||||||
|
|
||||||||||
| private static final KeyStroke NEXT_ALTERNATIVE_KEY_STROKE = Utilities.stringToKey("D-G"); | ||||||||||
| private static final KeyStroke PREVIOUS_ALTERNATIVE_KEY_STROKE = Utilities.stringToKey("DS-G"); | ||||||||||
|
|
||||||||||
| private final JComponent component; | ||||||||||
| private final Object constraints; | ||||||||||
| private final Callback callback; | ||||||||||
|
|
@@ -288,10 +291,12 @@ private void fireQuickSearchUpdate(String searchText) { | |||||||||
| } | ||||||||||
|
|
||||||||||
| private void fireShowNextSelection(boolean forward) { | ||||||||||
| if (asynchronous) { | ||||||||||
| rp.post(new LazyFire(QS_FIRE.NEXT, forward)); | ||||||||||
| } else { | ||||||||||
| callback.showNextSelection(forward); | ||||||||||
| if (hasSearchText) { | ||||||||||
| if (asynchronous) { | ||||||||||
| rp.post(new LazyFire(QS_FIRE.NEXT, forward)); | ||||||||||
| } else { | ||||||||||
| callback.showNextSelection(forward); | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
|
|
@@ -354,6 +359,23 @@ public void keyTyped(KeyEvent e) { | |||||||||
| if(isAlwaysShown()) { | ||||||||||
| displaySearchField(); | ||||||||||
| } | ||||||||||
| component.getActionMap().put("openQuickSearch", new AbstractAction() { | ||||||||||
| @Override | ||||||||||
| public void actionPerformed(ActionEvent evt) { | ||||||||||
| if (searchPanel != null && isEnabled()) { | ||||||||||
| searchTextField.selectAll(); | ||||||||||
| return; | ||||||||||
| } | ||||||||||
| if (searchPanel != null || !isEnabled()) { | ||||||||||
| return; | ||||||||||
| } | ||||||||||
| searchTextField.setText(""); | ||||||||||
| displaySearchField(); | ||||||||||
| } | ||||||||||
| }); | ||||||||||
| InputMap im = component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); | ||||||||||
| im.put(Utilities.stringToKey("D-F"), "openQuickSearch"); | ||||||||||
| im.put(Utilities.stringToKey("F3"), "openQuickSearch"); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| private void displaySearchField() { | ||||||||||
|
|
@@ -678,7 +700,7 @@ public void run() { | |||||||||
| } | ||||||||||
| ); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| @Override | ||||||||||
| public boolean isManagingFocus() { | ||||||||||
| return true; | ||||||||||
|
|
@@ -707,9 +729,14 @@ public void processKeyEvent(KeyEvent ke) { | |||||||||
| } else { | ||||||||||
| if (!hasSearchText) { | ||||||||||
| int keyCode = ke.getKeyCode(); | ||||||||||
| KeyStroke ks = KeyStroke.getKeyStrokeForEvent(ke); | ||||||||||
| if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_UP || | ||||||||||
| keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_RIGHT || | ||||||||||
| keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_F3) { | ||||||||||
| keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_F3 || | ||||||||||
| keyCode == KeyEvent.VK_ENTER && ke.getModifiersEx() == KeyEvent.SHIFT_DOWN_MASK || | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
| NEXT_ALTERNATIVE_KEY_STROKE.equals(ks) || | ||||||||||
| PREVIOUS_ALTERNATIVE_KEY_STROKE.equals(ks)) | ||||||||||
| { | ||||||||||
| // Ignore movement events when search text was not set | ||||||||||
| return ; | ||||||||||
| } | ||||||||||
|
|
@@ -748,6 +775,7 @@ public void removeUpdate(DocumentEvent e) { | |||||||||
| @Override | ||||||||||
| public void keyPressed(KeyEvent e) { | ||||||||||
| int keyCode = e.getKeyCode(); | ||||||||||
| KeyStroke ks = KeyStroke.getKeyStrokeForEvent(e); | ||||||||||
|
|
||||||||||
| if (keyCode == KeyEvent.VK_ESCAPE) { | ||||||||||
| removeSearchField(); | ||||||||||
|
|
@@ -763,12 +791,22 @@ public void keyPressed(KeyEvent e) { | |||||||||
| callback.quickSearchCanceled(); | ||||||||||
| hasSearchText = false; | ||||||||||
| e.consume(); | ||||||||||
| } else if (keyCode == KeyEvent.VK_UP || (keyCode == KeyEvent.VK_F3 && e.isShiftDown())) { | ||||||||||
| } else if (keyCode == KeyEvent.VK_UP || | ||||||||||
| keyCode == KeyEvent.VK_F3 && e.getModifiersEx() == KeyEvent.SHIFT_DOWN_MASK || | ||||||||||
| keyCode == KeyEvent.VK_ENTER && e.getModifiersEx() == KeyEvent.SHIFT_DOWN_MASK || | ||||||||||
|
Comment on lines
+795
to
+796
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
| PREVIOUS_ALTERNATIVE_KEY_STROKE.equals(ks)) | ||||||||||
| { | ||||||||||
| fireShowNextSelection(false); | ||||||||||
| // Stop processing the event here. Otherwise it's dispatched | ||||||||||
| // to the tree too (which scrolls) | ||||||||||
| e.consume(); | ||||||||||
| } else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_F3) { | ||||||||||
| } else if (keyCode == KeyEvent.VK_DOWN || | ||||||||||
| keyCode == KeyEvent.VK_F3 && e.getModifiersEx() == 0 || | ||||||||||
| /* We can't use ENTER to go to the next match, as this keystroke is used to | ||||||||||
| invoke the row's default action. */ | ||||||||||
| /* keyCode == KeyEvent.VK_ENTER && e.getModifiersEx() == 0 || */ | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it really make sense to handle Shift-Enter, but not Enter? |
||||||||||
| NEXT_ALTERNATIVE_KEY_STROKE.equals(ks)) | ||||||||||
| { | ||||||||||
| fireShowNextSelection(true); | ||||||||||
| // Stop processing the event here. Otherwise it's dispatched | ||||||||||
| // to the tree too (which scrolls) | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,8 +87,10 @@ public void quickSearchUpdate(String searchText) { | |
| quickSearchInitialColumn = 0; | ||
| } | ||
| } | ||
| quickSearchLastRow = quickSearchInitialRow; | ||
| quickSearchLastColumn = quickSearchInitialColumn; | ||
| if (quickSearchLastRow < 0 || quickSearchLastColumn < 0) { | ||
| quickSearchLastRow = quickSearchInitialRow; | ||
| quickSearchLastColumn = quickSearchInitialColumn; | ||
| } | ||
| doSearch(searchText, true); | ||
| } | ||
|
|
||
|
|
@@ -152,14 +154,18 @@ public void quickSearchConfirmed() { | |
| quickSearchInitialColumn = -1; | ||
| } | ||
|
|
||
| private static final boolean RESTORE_PRIOR_SELECTION_AFTER_QUICK_SEARCH = false; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the idea here? Is this a fancy way of commenting out code?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, sorry I left that in. I'll remove it... (Yes, fancy way to comment out code, especially when I need to experiment with different UI behaviors for a while before deciding what works or not. It also survives later refactoring.) |
||
|
|
||
| @Override | ||
| public void quickSearchCanceled() { | ||
| // Check whether the cancel was explicit or implicit. | ||
| // Implicit cancel has undefined focus owner | ||
| // TODO: After switch to JDK 8, we can e.g. add a static method to Callback providing the info. | ||
| Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); | ||
| if (focusOwner != null) { | ||
| displaySearchResult(quickSearchInitialRow, quickSearchInitialColumn); | ||
| if (RESTORE_PRIOR_SELECTION_AFTER_QUICK_SEARCH) { | ||
| Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); | ||
| if (focusOwner != null) { | ||
| displaySearchResult(quickSearchInitialRow, quickSearchInitialColumn); | ||
| } | ||
| } | ||
| quickSearchInitialRow = -1; | ||
| quickSearchInitialColumn = -1; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a problem in Project and Files views in the IDE as it overrides the project wide searches.