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