001    /*
002     * $Id: JXFindBar.java,v 1.10 2005/10/24 10:27:44 kleopatra Exp $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     * 
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     * 
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    package org.jdesktop.swingx;
022    
023    import java.awt.Color;
024    import java.awt.FlowLayout;
025    
026    import javax.swing.JButton;
027    import javax.swing.JLabel;
028    import javax.swing.KeyStroke;
029    import javax.swing.SwingConstants;
030    
031    /**
032     * A simple low-intrusion default widget for incremental search.
033     * 
034     * Actions registered (in addition to super):
035     * <ul>
036     * <li> {@link JXDialog#CLOSE_ACTION_COMMAND} - an action bound to this
037     * component's cancel method. The method itself is an empty implementation:
038     * Subclassing clients can override the method, all clients can register a
039     * custom action.
040     * </ul>
041     * 
042     * Key bindings:
043     * <ul>
044     * <li> ESCAPE - calls action registered for
045     * {@link JXDialog#CLOSE_ACTION_COMMAND}
046     * </ul>
047     * 
048     * This implementation uses textfield coloring as not-found visualization.
049     * 
050     * <p>
051     * PENDING: the coloring needs to be read from the UIManager instead of
052     * hardcoding.
053     * 
054     * <p>
055     * PENDING: the state transition of found/non-found coloring needs clean-up -
056     * there are spurious problems when re-using the same instance (as SearchFactory
057     * does).
058     * 
059     * @author Jeanette Winzenburg
060     * 
061     */
062    public class JXFindBar extends JXFindPanel {
063    
064        protected Color previousBackgroundColor;
065    
066        protected Color previousForegroundColor;
067    
068        // PENDING: need to read from UIManager
069        protected Color notFoundBackgroundColor = Color.decode("#FF6666");
070    
071        protected Color notFoundForegroundColor = Color.white;
072    
073        protected JButton findNext;
074    
075        protected JButton findPrevious;
076    
077        public JXFindBar() {
078            this(null);
079        }
080    
081        public JXFindBar(Searchable searchable) {
082            super(searchable);
083            getPatternModel().setIncremental(true);
084            getPatternModel().setWrapping(true);
085        }
086    
087        @Override
088        public void setSearchable(Searchable searchable) {
089            super.setSearchable(searchable);
090            match();
091        }
092    
093        /**
094         * here: set textfield colors to not-found colors.
095         */
096        @Override
097        protected void showNotFoundMessage() {
098            searchField.setForeground(notFoundForegroundColor);
099            searchField.setBackground(notFoundBackgroundColor);
100        }
101    
102        /**
103         * here: set textfield colors to normal.
104         */
105        @Override
106        protected void showFoundMessage() {
107            searchField.setBackground(previousBackgroundColor);
108            searchField.setForeground(previousForegroundColor);
109        }
110    
111        @Override
112        public void addNotify() {
113            super.addNotify();
114            if (previousBackgroundColor == null) {
115                previousBackgroundColor = searchField.getBackground();
116                previousForegroundColor = searchField.getForeground();
117            } else {
118                searchField.setBackground(previousBackgroundColor);
119                searchField.setForeground(previousForegroundColor);
120            }
121        }
122    
123        // --------------------------- action call back
124        /**
125         * Action callback method for bound action JXDialog.CLOSE_ACTION_COMMAND.
126         * 
127         * Here: does nothing. Subclasses can override to define custom "closing"
128         * behaviour. Alternatively, any client can register a custom action with
129         * the actionMap.
130         * 
131         * 
132         */
133        public void cancel() {
134        }
135    
136        // -------------------- init
137    
138        @Override
139        protected void initExecutables() {
140            getActionMap().put(JXDialog.CLOSE_ACTION_COMMAND,
141                    createBoundAction(JXDialog.CLOSE_ACTION_COMMAND, "cancel"));
142            super.initExecutables();
143        }
144    
145        @Override
146        protected void bind() {
147            super.bind();
148            searchField
149                    .addActionListener(getAction(JXDialog.EXECUTE_ACTION_COMMAND));
150            findNext.setAction(getAction(FIND_NEXT_ACTION_COMMAND));
151            findPrevious.setAction(getAction(FIND_PREVIOUS_ACTION_COMMAND));
152            KeyStroke stroke = KeyStroke.getKeyStroke("ESCAPE");
153            getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke,
154                    JXDialog.CLOSE_ACTION_COMMAND);
155        }
156    
157        @Override
158        protected void build() {
159            setLayout(new FlowLayout(SwingConstants.LEADING));
160            add(searchLabel);
161            add(new JLabel(":"));
162            add(new JLabel("  "));
163            add(searchField);
164            add(findNext);
165            add(findPrevious);
166        }
167    
168        @Override
169        protected void initComponents() {
170            super.initComponents();
171            findNext = new JButton();
172            findPrevious = new JButton();
173        }
174    
175    }