1 /*
2  * JaLingo, http://jalingo.sourceforge.net/
3  *
4  * Copyright (c) 2002-2006 Oleksandr Shyshko
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 package ja.lingo.application.gui.main.describer.find;
22 
23 import info.clearthought.layout.TableLayout;
24 import ja.centre.gui.actionbinder.ActionBinder;
25 import ja.centre.gui.actionbinder.config.NListener;
26 import ja.centre.gui.actionbinder.config.NListenerGroup;
27 import ja.centre.gui.mediator.EmptyFieldMediator;
28 import ja.centre.gui.resources.Resources;
29 import ja.centre.gui.util.IGui;
30 import ja.centre.gui.util.SelectAllOnEscapeListener;
31 import ja.lingo.application.model.Model;
32 import ja.lingo.application.model.ModelAdapter;
33 import ja.lingo.application.util.Buttons;
34 import ja.lingo.application.util.Components;
35 import ja.lingo.application.util.Gaps;
36 import ja.lingo.application.util.CheckBoxes;
37 
38 import javax.swing.*;
39 import javax.swing.event.DocumentListener;
40 import javax.swing.border.EtchedBorder;
41 import java.awt.event.ActionListener;
42 import java.awt.event.KeyEvent;
43 import java.awt.event.KeyListener;
44 import java.awt.*;
45 
46 public class FindGui implements IGui {
47     private Resources resources = Resources.forProperties( getClass() );
48 
49     @NListener(type = ActionListener.class, mappings = "actionPerformed > close")
50     private JButton closeButton;
51 
52     @NListenerGroup( {
53         @NListener( type = KeyListener.class, mappings = "keyPressed > onKeyPressed" ),
54         @NListener( property = "document", type = DocumentListener.class, mappings = {
55             "insertUpdate  > onDocumentChanged",
56             "removeUpdate  > onDocumentChanged",
57             "changedUpdate > onDocumentChanged"
58         } )
59     } )
60     private JTextField searchField;
61 
62     @NListener(type = ActionListener.class, mappings = "actionPerformed > next")
63     private JButton nextButton;
64 
65     @NListener(type = ActionListener.class, mappings = "actionPerformed > previous")
66     private JButton previousButton;
67 
68     private JCheckBox caseSensetiveCheckBox;
69 
70     private Model model;
71     private JToolBar gui;
72 
73     private Color foundFore;
74     private Color foundBack;
75 
76     private final Color notFoundFore = Color.WHITE;
77     private final Color notFoundBack = new Color( 0xff6666);
78 
FindGui( Model model )79     public FindGui( Model model ) {
80         this.model = model;
81 
82         this.model.addApplicationModelListener( new ModelAdapter() {
83             public void find_sendFeedback( boolean found ) {
84                 searchField.setForeground( found ? foundFore : notFoundFore );
85                 searchField.setBackground( found ? foundBack : notFoundBack );
86             }
87         } );
88 
89         closeButton = Buttons.closeCross();
90 
91         searchField = Components.textField();
92         searchField.setColumns( 10 );
93 
94         // NOTE: will not work with dynamic LF change
95         foundFore = searchField.getForeground();
96         foundBack = searchField.getBackground();
97 
98         nextButton = Buttons.next();
99         previousButton = Buttons.previous();
100 
101         caseSensetiveCheckBox = CheckBoxes.caseSensetive();
102 
103         gui = Components.toolBar();
104         gui.setLayout( new TableLayout( new double[][] { {
105                 TableLayout.PREFERRED,  // 0: X
106                 TableLayout.PREFERRED,  // 1: Find:
107                 Gaps.GAP3,
108                 TableLayout.FILL,       // 3: text field
109                 Gaps.GAP3,
110                 TableLayout.PREFERRED,  // 5: next
111                 TableLayout.PREFERRED,  // 6: previous
112                 TableLayout.PREFERRED   // 7: case sensetive
113         }, {
114                 TableLayout.PREFERRED
115         } } ) );
116 
117         gui.add( closeButton, "0, 0" );
118         gui.add( resources.label( "find" ), "1, 0" );
119         gui.add( searchField, "3, 0, full, center" );
120         gui.add( nextButton, "5, 0" );
121         gui.add( previousButton, "6, 0" );
122         gui.add( caseSensetiveCheckBox, "7, 0" );
123 
124         Gaps.compound( gui, new EtchedBorder(), Gaps.border2() );
125 
126         new EmptyFieldMediator( searchField, previousButton );
127         new EmptyFieldMediator( searchField, nextButton );
128 
129         SelectAllOnEscapeListener.register( searchField );
130 
131         ActionBinder.bind( this );
132 
133         close();
134     }
135 
show()136     public void show() {
137         searchField.selectAll();
138     }
139 
getGui()140     public JComponent getGui() {
141         return gui;
142     }
143 
close()144     public void close() {
145         gui.setVisible( false );
146     }
147 
next()148     public void next() {
149         find( true );
150     }
151 
previous()152     public void previous() {
153         find( false );
154     }
155 
find( boolean forwardDirection )156     private void find( boolean forwardDirection ) {
157         searchField.selectAll();
158         model.find( getSearchText(), false, forwardDirection,
159                 caseSensetiveCheckBox.isSelected(),
160                 false/*wholeWordsOnlyCheckBox.isSelected()*/ );
161         //searchField.requestFocus();
162     }
163 
onKeyPressed( KeyEvent e )164     public void onKeyPressed( KeyEvent e ) {
165         boolean shift = (e.getModifiers() & KeyEvent.SHIFT_MASK) > 0;
166         boolean enter = e.getKeyCode() == KeyEvent.VK_ENTER;
167 
168         boolean down = e.getKeyCode() == KeyEvent.VK_DOWN;
169         boolean up = e.getKeyCode() == KeyEvent.VK_UP;
170 
171         if ( down || (enter && !shift) ) {
172             next();
173         } else if ( up || (enter && shift) ) {
174             previous();
175         }
176     }
177 
onDocumentChanged()178     public void onDocumentChanged() {
179         model.find( getSearchText(), true, true,
180                 caseSensetiveCheckBox.isSelected(), false );
181     }
getSearchText()182     private String getSearchText() {
183         return searchField.getText().trim();
184     }
185 
showAndRequestFocus()186     public void showAndRequestFocus() {
187         gui.setVisible( true );
188         searchField.requestFocus();
189         searchField.selectAll();
190     }
191 }
192