001 /* 002 * $Id: JXFindBar.java 2948 2008-06-16 15:02:14Z kleopatra $ 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 import org.jdesktop.swingx.search.Searchable; 032 033 /** 034 * A simple low-intrusion default widget for incremental search. 035 * 036 * Actions registered (in addition to super): 037 * <ul> 038 * <li> {@link JXDialog#CLOSE_ACTION_COMMAND} - an action bound to this 039 * component's cancel method. The method itself is an empty implementation: 040 * Subclassing clients can override the method, all clients can register a 041 * custom action. 042 * </ul> 043 * 044 * Key bindings: 045 * <ul> 046 * <li> ESCAPE - calls action registered for 047 * {@link JXDialog#CLOSE_ACTION_COMMAND} 048 * </ul> 049 * 050 * This implementation uses textfield coloring as not-found visualization. 051 * 052 * <p> 053 * PENDING: the coloring needs to be read from the UIManager instead of 054 * hardcoding. 055 * 056 * <p> 057 * PENDING: the state transition of found/non-found coloring needs clean-up - 058 * there are spurious problems when re-using the same instance (as SearchFactory 059 * does). 060 * 061 * @author Jeanette Winzenburg 062 * 063 */ 064 public class JXFindBar extends JXFindPanel { 065 066 protected Color previousBackgroundColor; 067 068 protected Color previousForegroundColor; 069 070 // PENDING: need to read from UIManager 071 protected Color notFoundBackgroundColor = Color.decode("#FF6666"); 072 073 protected Color notFoundForegroundColor = Color.white; 074 075 protected JButton findNext; 076 077 protected JButton findPrevious; 078 079 public JXFindBar() { 080 this(null); 081 } 082 083 public JXFindBar(Searchable searchable) { 084 super(searchable); 085 getPatternModel().setIncremental(true); 086 getPatternModel().setWrapping(true); 087 } 088 089 @Override 090 public void setSearchable(Searchable searchable) { 091 super.setSearchable(searchable); 092 match(); 093 } 094 095 /** 096 * here: set textfield colors to not-found colors. 097 */ 098 @Override 099 protected void showNotFoundMessage() { 100 //JW: quick hack around #487-swingx - NPE in setSearchable 101 if (searchField == null) return; 102 searchField.setForeground(notFoundForegroundColor); 103 searchField.setBackground(notFoundBackgroundColor); 104 } 105 106 /** 107 * here: set textfield colors to normal. 108 */ 109 @Override 110 protected void showFoundMessage() { 111 //JW: quick hack around #487-swingx - NPE in setSearchable 112 if (searchField == null) return; 113 searchField.setBackground(previousBackgroundColor); 114 searchField.setForeground(previousForegroundColor); 115 } 116 117 @Override 118 public void addNotify() { 119 super.addNotify(); 120 if (previousBackgroundColor == null) { 121 previousBackgroundColor = searchField.getBackground(); 122 previousForegroundColor = searchField.getForeground(); 123 } else { 124 searchField.setBackground(previousBackgroundColor); 125 searchField.setForeground(previousForegroundColor); 126 } 127 } 128 129 // --------------------------- action call back 130 /** 131 * Action callback method for bound action JXDialog.CLOSE_ACTION_COMMAND. 132 * 133 * Here: does nothing. Subclasses can override to define custom "closing" 134 * behaviour. Alternatively, any client can register a custom action with 135 * the actionMap. 136 * 137 * 138 */ 139 public void cancel() { 140 } 141 142 // -------------------- init 143 144 @Override 145 protected void initExecutables() { 146 getActionMap().put(JXDialog.CLOSE_ACTION_COMMAND, 147 createBoundAction(JXDialog.CLOSE_ACTION_COMMAND, "cancel")); 148 super.initExecutables(); 149 } 150 151 @Override 152 protected void bind() { 153 super.bind(); 154 searchField 155 .addActionListener(getAction(JXDialog.EXECUTE_ACTION_COMMAND)); 156 findNext.setAction(getAction(FIND_NEXT_ACTION_COMMAND)); 157 findPrevious.setAction(getAction(FIND_PREVIOUS_ACTION_COMMAND)); 158 KeyStroke stroke = KeyStroke.getKeyStroke("ESCAPE"); 159 getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, 160 JXDialog.CLOSE_ACTION_COMMAND); 161 } 162 163 @Override 164 protected void build() { 165 setLayout(new FlowLayout(SwingConstants.LEADING)); 166 add(searchLabel); 167 add(new JLabel(":")); 168 add(new JLabel(" ")); 169 add(searchField); 170 add(findNext); 171 add(findPrevious); 172 } 173 174 @Override 175 protected void initComponents() { 176 super.initComponents(); 177 findNext = new JButton(); 178 findPrevious = new JButton(); 179 } 180 181 }