All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.swingx.autocomplete.AutoComplete Maven / Gradle / Ivy

There is a newer version: 1.7.2
Show newest version
/*
 * $Id: AutoComplete.java 4051 2011-07-19 20:17:05Z kschaefe $
 *
 * Copyright 2010 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package org.jdesktop.swingx.autocomplete;

import javax.swing.Action;
import javax.swing.JComboBox;
import javax.swing.text.JTextComponent;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeEvent;

import static org.jdesktop.swingx.autocomplete.AutoCompleteDecorator.createAutoCompleteDocument;
import static org.jdesktop.swingx.autocomplete.AutoCompleteDecorator.decorate;
import static org.jdesktop.swingx.autocomplete.AutoCompleteDecorator.undecorate;

/**
 * @author kschaefer
 */
final class AutoComplete {

    static class InputMap extends javax.swing.InputMap {

        private static final long serialVersionUID = 1L;
    }

    static class FocusAdapter extends java.awt.event.FocusAdapter {

        private final AbstractAutoCompleteAdaptor adaptor;

        FocusAdapter(AbstractAutoCompleteAdaptor adaptor) {
            this.adaptor = adaptor;
        }

        @Override
        public void focusGained(FocusEvent e) {
            adaptor.markEntireText();
        }
    }

    static class KeyAdapter extends java.awt.event.KeyAdapter {

        private final JComboBox comboBox;

        KeyAdapter(JComboBox comboBox) {
            this.comboBox = comboBox;
        }

        @Override
        public void keyPressed(KeyEvent keyEvent) {
            // don't popup on action keys (cursor movements, etc...)
            if (keyEvent.isActionKey()) {
                return;
            }

            // don't popup if the combobox isn't visible or empty anyway
            if (comboBox.isDisplayable() && !comboBox.isPopupVisible() && comboBox.getModel().getSize() != 0) {
                int keyCode = keyEvent.getKeyCode();
                // don't popup when the user hits shift,ctrl or alt
                if (keyCode == KeyEvent.VK_SHIFT || keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_ALT)
                    return;
                // don't popup when the user hits escape (see issue #311)
                if (keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_ESCAPE)
                    return;
                comboBox.setPopupVisible(true);
            }
        }
    }

    static class PropertyChangeListener implements java.beans.PropertyChangeListener {

        private final JComboBox comboBox;

        PropertyChangeListener(JComboBox comboBox) {
            this.comboBox = comboBox;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        @SuppressWarnings("nls")
        public void propertyChange(PropertyChangeEvent evt) {
            if ("editor".equals(evt.getPropertyName())) {
                handleEditor(evt);
            } else if ("enabled".equals(evt.getPropertyName())) {
                handleEnabled(evt);
            }
        }

        private void handleEnabled(PropertyChangeEvent evt) {
            if (Boolean.TRUE.equals(evt.getNewValue())) {
                comboBox.setEditable(true);
            } else {
                JTextComponent textComponent = (JTextComponent) comboBox.getEditor().getEditorComponent();
                boolean strictMatching = ((AutoCompleteDocument) textComponent.getDocument()).strictMatching;

                comboBox.setEditable(!strictMatching);
            }
        }

        private void handleEditor(PropertyChangeEvent evt) {
            if (evt.getNewValue() instanceof AutoCompleteComboBoxEditor) {
                return;
            }

            AutoCompleteComboBoxEditor acEditor = (AutoCompleteComboBoxEditor) evt.getOldValue();
            boolean strictMatching = false;

            if (acEditor.getEditorComponent() != null) {
                JTextComponent textComponent = (JTextComponent) acEditor.getEditorComponent();
                strictMatching = ((AutoCompleteDocument) textComponent.getDocument()).strictMatching;

                undecorate(textComponent);

                for (KeyListener l : textComponent.getKeyListeners()) {
                    if (l instanceof KeyAdapter) {
                        textComponent.removeKeyListener(l);
                        break;
                    }
                }
            }

            JTextComponent editorComponent = (JTextComponent) comboBox.getEditor().getEditorComponent();
            AbstractAutoCompleteAdaptor adaptor = new ComboBoxAdaptor(comboBox);
            AutoCompleteDocument document = createAutoCompleteDocument(
                adaptor, strictMatching, acEditor.stringConverter, editorComponent.getDocument()
            );
            decorate(editorComponent, document, adaptor);

            editorComponent.addKeyListener(new KeyAdapter(comboBox));

            //set before adding the listener for the editor
            comboBox.setEditor(new AutoCompleteComboBoxEditor(comboBox.getEditor(), document.stringConverter));
        }
    }

    static class SelectionAction implements Action {

        private final Action delegate;

        SelectionAction(Action delegate) {
            this.delegate = delegate;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void actionPerformed(ActionEvent e) {
            JComboBox comboBox = (JComboBox) e.getSource();
            JTextComponent textComponent = (JTextComponent) comboBox.getEditor().getEditorComponent();
            AutoCompleteDocument doc = (AutoCompleteDocument) textComponent.getDocument();

            // doing this prevents the updating of the selected item to "" during the remove prior
            // to the insert in JTextComponent.setText
            doc.strictMatching = true;
            try {
                delegate.actionPerformed(e);
            } finally {
                doc.strictMatching = false;
            }
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) {
            delegate.addPropertyChangeListener(listener);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) {
            delegate.removePropertyChangeListener(listener);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public Object getValue(String key) {
            return delegate.getValue(key);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void putValue(String key, Object value) {
            delegate.putValue(key, value);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isEnabled() {
            return delegate.isEnabled();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void setEnabled(boolean b) {
            delegate.setEnabled(b);
        }
    }

    private AutoComplete() {
        // prevent instantiation
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy