This is an automated email from the git hooks/post-receive script. ben pushed a commit to branch master in repository autocomplete.
commit b9fdfe4cd0bbfbaf187dfc178dddb821686116b2 Author: bobbylight <[email protected]> Date: Tue Jan 13 23:36:18 2009 +0000 Runtime LaF changes are now handled properly. Refactored demo to work as both an applet and standalone app. Demo now allows you to switch LaF. --- .../ui/autocomplete/AutoCompleteDescWindow.java | 106 ++++---- .../ui/autocomplete/AutoCompletePopupWindow.java | 252 +++++++++++++------- .../ui/autocomplete/DelegatingCellRenderer.java | 11 + .../ParameterizedCompletionDescriptionToolTip.java | 38 ++- 4 files changed, 270 insertions(+), 137 deletions(-) diff --git a/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java index 60b5794..32567a1 100644 --- a/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java +++ b/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java @@ -48,6 +48,7 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToolBar; import javax.swing.JWindow; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; @@ -74,6 +75,11 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener { private JEditorPane descArea; /** + * The scroll pane that {@link #descArea} is in. + */ + private JScrollPane scrollPane; + + /** * The toolbar with "back" and "forward" buttons. */ private JToolBar descWindowNavBar; @@ -127,12 +133,13 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener { JPanel cp = new JPanel(new BorderLayout()); cp.setBorder(BorderFactory.createLineBorder(Color.BLACK)); - descArea = createDescArea(); - JScrollPane sp = new JScrollPane(descArea); - sp.setViewportBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - sp.setBackground(descArea.getBackground()); - sp.getViewport().setBackground(descArea.getBackground()); - cp.add(sp); + descArea = new JEditorPane("text/html", null); + tweakDescArea(); + scrollPane = new JScrollPane(descArea); + scrollPane.setViewportBorder(BorderFactory.createEmptyBorder(5,5,5,5)); + scrollPane.setBackground(descArea.getBackground()); + scrollPane.getViewport().setBackground(descArea.getBackground()); + cp.add(scrollPane); descWindowNavBar = new JToolBar(); backAction = new ToolBarBackAction(); @@ -193,43 +200,6 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener { /** - * Creates the customized JEditorPane used to render HTML documentation. - * - * @return The JEditorPane. - */ - private JEditorPane createDescArea() { - - JEditorPane descArea = new JEditorPane("text/html", null); - - // Jump through a few hoops to get things looking nice in Nimbus - if (UIManager.getLookAndFeel().getName().equals("Nimbus")) { - System.out.println("DEBUG: Creating Nimbus-specific changes"); - Color selBG = descArea.getSelectionColor(); - Color selFG = descArea.getSelectedTextColor(); - descArea.setUI(new javax.swing.plaf.basic.BasicEditorPaneUI()); - descArea.setSelectedTextColor(selFG); - descArea.setSelectionColor(selBG); - } - - descArea.getCaret().setSelectionVisible(true); - descArea.setEditable(false); - descArea.addHyperlinkListener(this); - - // Make it use "tooltip" background color. - descArea.setBackground(getDefaultBackground()); - - // Force JEditorPane to use a certain font even in HTML. - Font font = UIManager.getFont("Label.font"); - HTMLDocument doc = (HTMLDocument)descArea.getDocument(); - doc.getStyleSheet().addRule("body { font-family: " + font.getFamily() + - "; font-size: " + font.getSize() + "pt; }"); - - return descArea; - - } - - - /** * Returns the default background color to use for the description * window. * @@ -366,6 +336,56 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener { /** + * Tweaks the description text area to look good in the current Look + * and Feel. + */ + private void tweakDescArea() { + + // Jump through a few hoops to get things looking nice in Nimbus + if (UIManager.getLookAndFeel().getName().equals("Nimbus")) { + System.out.println("DEBUG: Creating Nimbus-specific changes"); + Color selBG = descArea.getSelectionColor(); + Color selFG = descArea.getSelectedTextColor(); + descArea.setUI(new javax.swing.plaf.basic.BasicEditorPaneUI()); + descArea.setSelectedTextColor(selFG); + descArea.setSelectionColor(selBG); + } + + descArea.setEditable(false); + + // Make selection visible even though we are not editable. + descArea.getCaret().setSelectionVisible(true); + + descArea.addHyperlinkListener(this); + + // Make it use "tooltip" background color. + descArea.setBackground(getDefaultBackground()); + + // Force JEditorPane to use a certain font even in HTML. + // All standard LookAndFeels, even Nimbus (!), define Label.font. + Font font = UIManager.getFont("Label.font"); + if (font==null) { // Try to make a sensible default + font = new Font("SansSerif", Font.PLAIN, 12); + } + HTMLDocument doc = (HTMLDocument)descArea.getDocument(); + doc.getStyleSheet().addRule("body { font-family: " + font.getFamily() + + "; font-size: " + font.getSize() + "pt; }"); + + } + + + /** + * Called by the parent completion popup window the LookAndFeel is updated. + */ + public void updateUI() { + SwingUtilities.updateComponentTreeUI(this); + tweakDescArea(); // Update the editor pane (font in HTML, etc.) + scrollPane.setBackground(descArea.getBackground()); + scrollPane.getViewport().setBackground(descArea.getBackground()); + } + + + /** * Action that moves to the previous description displayed. */ class ToolBarBackAction extends AbstractAction { diff --git a/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java b/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java index 6b04b18..6d4adc3 100644 --- a/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java +++ b/src/org/fife/ui/autocomplete/AutoCompletePopupWindow.java @@ -34,6 +34,8 @@ import java.awt.event.MouseListener; import java.util.List; import javax.swing.AbstractAction; import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.InputMap; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; @@ -46,7 +48,6 @@ import javax.swing.event.CaretListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.text.Caret; -import javax.swing.text.Keymap; import javax.swing.text.JTextComponent; @@ -66,11 +67,22 @@ class AutoCompletePopupWindow extends JWindow implements CaretListener, private AutoCompletion ac; private JList list; private /*DefaultListModel*/CompletionListModel model; - private Action oldUpAction, oldDownAction, oldLeftAction, oldRightAction, - oldEnterAction, oldTabAction, oldEscapeAction, oldHomeAction, - oldEndAction, oldPageUpAction, oldPageDownAction; - private Action upAction, downAction, leftAction ,rightAction, enterAction, - escapeAction, homeAction, endAction, pageUpAction, pageDownAction; + + private KeyActionPair escapeKap; + private KeyActionPair upKap; + private KeyActionPair downKap; + private KeyActionPair leftKap; + private KeyActionPair rightKap; + private KeyActionPair enterKap; + private KeyActionPair tabKap; + private KeyActionPair homeKap; + private KeyActionPair endKap; + private KeyActionPair pageUpKap; + private KeyActionPair pageDownKap; + + private KeyActionPair oldEscape, oldUp, oldDown, oldLeft, oldRight, + oldEnter, oldTab, oldHome, oldEnd, oldPageUp, oldPageDown; + private int lastLine; private AutoCompleteDescWindow descWindow; @@ -140,22 +152,39 @@ lastLine = -1; } -// public void clear() { -// model.clear(); -// } - + /** + * Creates the mappings from keys to Actions we'll be putting into the + * text component's ActionMap and InputMap. + */ + private void createKeyActionPairs() { + + // Actions we'll install. + EnterAction enterAction = new EnterAction(); + escapeKap = new KeyActionPair("Escape", new EscapeAction()); + upKap = new KeyActionPair("Up", new UpAction()); + downKap = new KeyActionPair("Down", new DownAction()); + leftKap = new KeyActionPair("Left", new LeftAction()); + rightKap = new KeyActionPair("Right", new RightAction()); + enterKap = new KeyActionPair("Enter", enterAction); + tabKap = new KeyActionPair("Tab", enterAction); + homeKap = new KeyActionPair("Home", new HomeAction()); + endKap = new KeyActionPair("End", new EndAction()); + pageUpKap = new KeyActionPair("PageUp", new PageUpAction()); + pageDownKap = new KeyActionPair("PageDown", new PageDownAction()); + + // Buffers for the actions we replace. + oldEscape = new KeyActionPair(); + oldUp = new KeyActionPair(); + oldDown = new KeyActionPair(); + oldLeft = new KeyActionPair(); + oldRight = new KeyActionPair(); + oldEnter = new KeyActionPair(); + oldTab = new KeyActionPair(); + oldHome = new KeyActionPair(); + oldEnd = new KeyActionPair(); + oldPageUp = new KeyActionPair(); + oldPageDown = new KeyActionPair(); - private void createActions() { - escapeAction = new EscapeAction(); - upAction = new UpAction(); - downAction = new DownAction(); - leftAction = new LeftAction(); - rightAction = new RightAction(); - enterAction = new EnterAction(); - homeAction = new HomeAction(); - endAction = new EndAction(); - pageUpAction = new PageUpAction(); - pageDownAction = new PageDownAction(); } @@ -199,6 +228,46 @@ lastLine = -1; } + /** + * Registers keyboard actions to listen for in the text component and + * intercept. + * + * @see #uninstallKeyBindings() + */ + private void installKeyBindings() { + + if (DEBUG) { + System.out.println("PopupWindow: Installing keybindings"); + } + + if (escapeKap==null) { // Lazily create actions. + createKeyActionPairs(); + } + + JTextComponent comp = ac.getTextComponent(); + InputMap im = comp.getInputMap(); + ActionMap am = comp.getActionMap(); + + replaceAction(im, am, KeyEvent.VK_ESCAPE, escapeKap, oldEscape); + if (DEBUG && oldEscape.action==escapeKap.action) { + Thread.dumpStack(); + } + replaceAction(im, am, KeyEvent.VK_UP, upKap, oldUp); + replaceAction(im, am, KeyEvent.VK_LEFT, leftKap, oldLeft); + replaceAction(im, am, KeyEvent.VK_DOWN, downKap, oldDown); + replaceAction(im, am, KeyEvent.VK_RIGHT, rightKap, oldRight); + replaceAction(im, am, KeyEvent.VK_ENTER, enterKap, oldEnter); + replaceAction(im, am, KeyEvent.VK_TAB, tabKap, oldTab); + replaceAction(im, am, KeyEvent.VK_HOME, homeKap, oldHome); + replaceAction(im, am, KeyEvent.VK_END, endKap, oldEnd); + replaceAction(im, am, KeyEvent.VK_PAGE_UP, pageUpKap, oldPageUp); + replaceAction(im, am, KeyEvent.VK_PAGE_DOWN, pageDownKap, oldPageDown); + + comp.addCaretListener(this); + + } + + public void mouseClicked(MouseEvent e) { if (e.getClickCount()==2) { insertSelectedCompletion(); @@ -255,64 +324,41 @@ lastLine = -1; /** - * Registers keyboard actions to listen for in the text component and - * intercept. + * "Puts back" the original kay/Action pair for a keystroke. This is used + * when this popup is hidden. * - * @see #unregisterActions() + * @param im The input map. + * @param am The action map. + * @param key The keystroke whose key/Action pair to change. + * @param kap The (original) key/Action pair. + * @see #replaceAction(InputMap, ActionMap, int, KeyActionPair, KeyActionPair) */ - private void registerActions() { - System.err.println("Registering actions"); - - if (escapeAction == null) { - createActions(); - } - - JTextComponent comp = ac.getTextComponent(); - Keymap km = comp.getKeymap(); - - KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); - oldEscapeAction = km.getAction(ks); - if (DEBUG && oldEscapeAction==escapeAction) { - Thread.dumpStack(); - return; - } - km.addActionForKeyStroke(ks, escapeAction); - - oldUpAction = replaceAction(km, KeyEvent.VK_UP, upAction); - oldDownAction = replaceAction(km, KeyEvent.VK_DOWN, downAction); - oldLeftAction = replaceAction(km, KeyEvent.VK_LEFT, leftAction); - oldRightAction = replaceAction(km, KeyEvent.VK_RIGHT, rightAction); - oldEnterAction = replaceAction(km, KeyEvent.VK_ENTER, enterAction); - oldTabAction = replaceAction(km, KeyEvent.VK_TAB, enterAction); - oldHomeAction = replaceAction(km, KeyEvent.VK_HOME, homeAction); - oldEndAction = replaceAction(km, KeyEvent.VK_END, endAction); - oldPageUpAction = replaceAction(km, KeyEvent.VK_PAGE_UP, pageUpAction); - oldPageDownAction = replaceAction(km, KeyEvent.VK_PAGE_DOWN, pageDownAction); - - comp.addCaretListener(this); - + private void putBackAction(InputMap im, ActionMap am, int key, + KeyActionPair kap) { + KeyStroke ks = KeyStroke.getKeyStroke(key, 0); + am.put(im.get(ks), kap.action); // Original action for the "new" key + im.put(ks, kap.key); // Original key for the keystroke. } /** - * Replaces the action binded to a keystroke. + * Replaces a key/Action pair in an InputMap and ActionMap with a new + * pair. * - * @param km The map in which to replace the action. - * @param key The keystroke whose action to replace. - * @param a The action to associate with <code>key</code>. If this is - * <code>null</code>, no keystroke will be associated with the key. - * @return The previous action associated with the key, or <code>null</code> - * if there was none. + * @param im The input map. + * @param am The action map. + * @param key The keystroke whose information to replace. + * @param kap The new key/Action pair for <code>key</code>. + * @param old A buffer in which to place the old key/Action pair. + * @see #putBackAction(InputMap, ActionMap, int, KeyActionPair) */ - private Action replaceAction(Keymap km, int key, Action a) { + private void replaceAction(InputMap im, ActionMap am, int key, + KeyActionPair kap, KeyActionPair old) { KeyStroke ks = KeyStroke.getKeyStroke(key, 0); - Action old = km.getAction(ks); - if (a!=null) { - km.addActionForKeyStroke(ks, a); - } else { - km.removeKeyStrokeBinding(ks); - } - return old; + old.key = im.get(ks); + im.put(ks, kap.key); + old.action = am.get(kap.key); + am.put(kap.key, kap.action); } @@ -442,7 +488,7 @@ lastLine = -1; public void setVisible(boolean visible) { if (visible!=isVisible()) { if (visible) { - registerActions(); + installKeyBindings(); lastLine = ac.getLineOfCaret(); selectFirstItem(); if (descWindow==null && ac.getShowDescWindow()) { @@ -456,7 +502,7 @@ lastLine = -1; } } else { - unregisterActions(); + uninstallKeyBindings(); } super.setVisible(visible); // Must set descWindow's visibility one way or the other each time, @@ -472,31 +518,35 @@ lastLine = -1; /** * Stops intercepting certain keystrokes from the text component. * - * @see #registerActions() + * @see #installKeyBindings() */ - public void unregisterActions() { + public void uninstallKeyBindings() { + + if (DEBUG) { + System.out.println("PopupWindow: Removing keybindings"); + } - System.err.println("Unregistering actions"); JTextComponent comp = ac.getTextComponent(); - Keymap km = comp.getKeymap(); - - replaceAction(km, KeyEvent.VK_ESCAPE, oldEscapeAction); - replaceAction(km, KeyEvent.VK_UP, oldUpAction); - replaceAction(km, KeyEvent.VK_DOWN, oldDownAction); - replaceAction(km, KeyEvent.VK_LEFT, oldLeftAction); - replaceAction(km, KeyEvent.VK_RIGHT, oldRightAction); - replaceAction(km, KeyEvent.VK_ENTER, oldEnterAction); - replaceAction(km, KeyEvent.VK_TAB, oldTabAction); - replaceAction(km, KeyEvent.VK_HOME, oldHomeAction); - replaceAction(km, KeyEvent.VK_END, oldEndAction); - replaceAction(km, KeyEvent.VK_PAGE_UP, oldPageUpAction); - replaceAction(km, KeyEvent.VK_PAGE_DOWN, oldPageDownAction); + InputMap im = comp.getInputMap(); + ActionMap am = comp.getActionMap(); + + putBackAction(im, am, KeyEvent.VK_ESCAPE, oldEscape); + putBackAction(im, am, KeyEvent.VK_ESCAPE, oldEscape); + putBackAction(im, am, KeyEvent.VK_UP, oldUp); + putBackAction(im, am, KeyEvent.VK_DOWN, oldDown); + putBackAction(im, am, KeyEvent.VK_LEFT, oldLeft); + putBackAction(im, am, KeyEvent.VK_RIGHT, oldRight); + putBackAction(im, am, KeyEvent.VK_ENTER, oldEnter); + putBackAction(im, am, KeyEvent.VK_TAB, oldTab); + putBackAction(im, am, KeyEvent.VK_HOME, oldHome); + putBackAction(im, am, KeyEvent.VK_END, oldEnd); + putBackAction(im, am, KeyEvent.VK_PAGE_UP, oldPageUp); + putBackAction(im, am, KeyEvent.VK_PAGE_DOWN, oldPageDown); comp.removeCaretListener(this); } - /** * Updates the <tt>LookAndFeel</tt> of this window and the description * window. @@ -504,7 +554,7 @@ lastLine = -1; public void updateUI() { SwingUtilities.updateComponentTreeUI(this); if (descWindow!=null) { - SwingUtilities.updateComponentTreeUI(descWindow); + descWindow.updateUI(); } } @@ -580,6 +630,28 @@ lastLine = -1; } + /** + * A mapping from a key (an Object) to an Action. + * + * @author Robert Futrell + * @version 1.0 + */ + private static class KeyActionPair { + + public Object key; + public Action action; + + public KeyActionPair() { + } + + public KeyActionPair(Object key, Action a) { + this.key = key; + this.action = a; + } + + } + + class LeftAction extends AbstractAction { public void actionPerformed(ActionEvent e) { diff --git a/src/org/fife/ui/autocomplete/DelegatingCellRenderer.java b/src/org/fife/ui/autocomplete/DelegatingCellRenderer.java index ff53978..5793d0b 100644 --- a/src/org/fife/ui/autocomplete/DelegatingCellRenderer.java +++ b/src/org/fife/ui/autocomplete/DelegatingCellRenderer.java @@ -25,6 +25,7 @@ package org.fife.ui.autocomplete; import java.awt.Component; import javax.swing.DefaultListCellRenderer; +import javax.swing.JComponent; import javax.swing.JList; import javax.swing.ListCellRenderer; @@ -91,4 +92,14 @@ class DelegatingCellRenderer extends DefaultListCellRenderer { } + /** + * {@inheritDoc} + */ + public void updateUI() { + if ((fallback instanceof JComponent) && fallback!=this) { + ((JComponent)fallback).updateUI(); + } + } + + } \ No newline at end of file diff --git a/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java b/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java index 881af58..df89cb2 100644 --- a/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java +++ b/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java @@ -122,15 +122,18 @@ class ParameterizedCompletionDescriptionToolTip { private Action oldTabAction; private Object oldShiftTabKey; private Action oldShiftTabAction; + private Object oldEnterKey; + private Action oldEnterAction; private Object oldEscapeKey; private Action oldEscapeAction; private Object oldClosingKey; private Action oldClosingAction; - private static final String IM_KEY_TAB = "ParamCompDescToolTip.Tab"; - private static final String IM_KEY_SHIFT_TAB = "ParamCompDescToolTip.ShiftTab"; - private static final String IM_KEY_ESCAPE = "ParamCompDescToolTip.Escape"; - private static final String IM_KEY_CLOSING = "ParamCompDescToolTip.Closing"; + private static final String IM_KEY_TAB = "ParamCompDescTip.Tab"; + private static final String IM_KEY_SHIFT_TAB = "ParamCompDescTip.ShiftTab"; + private static final String IM_KEY_ESCAPE = "ParamCompDescTip.Escape"; + private static final String IM_KEY_ENTER = "ParamCompDescTip.Enter"; + private static final String IM_KEY_CLOSING = "ParamCompDescTip.Closing"; /** @@ -222,6 +225,12 @@ class ParameterizedCompletionDescriptionToolTip { oldShiftTabAction = am.get(IM_KEY_SHIFT_TAB); am.put(IM_KEY_SHIFT_TAB, new PrevParamAction()); + ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); + oldEnterKey = im.get(ks); + im.put(ks, IM_KEY_ENTER); + oldEnterAction = am.get(IM_KEY_ENTER); + am.put(IM_KEY_ENTER, new GotoEndAction()); + ks = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); oldEscapeKey = im.get(ks); im.put(ks, IM_KEY_ESCAPE); @@ -413,6 +422,10 @@ class ParameterizedCompletionDescriptionToolTip { im.put(ks, oldShiftTabKey); am.put(IM_KEY_SHIFT_TAB, oldShiftTabAction); + ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); + im.put(ks, oldEnterKey); + am.put(IM_KEY_ENTER, oldEnterAction); + ks = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); im.put(ks, oldEscapeKey); am.put(IM_KEY_ESCAPE, oldEscapeAction); @@ -509,6 +522,23 @@ class ParameterizedCompletionDescriptionToolTip { /** + * Called when the user presses Enter while entering parameters. + * + * @author Robert Futrell + * @version 1.0 + */ + private class GotoEndAction extends AbstractAction { + + public void actionPerformed(ActionEvent e) { + JTextComponent tc = ac.getTextComponent(); + tc.setCaretPosition(maxPos.getOffset()); + setVisible(false, false); + } + + } + + + /** * Called when the user types the character marking the closing of the * parameter list, such as '<code>)</code>'. * -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/autocomplete.git _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

