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 }