Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jpicedt/widgets/HistoryTextField.java


1   /*
2    * HistoryTextField.java - Text field with a history
3    * Copyright (C) 1999, 2000, 2001 Slava Pestov
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18   */
19  
20  package jpicedt.widgets;
21  
22  import javax.swing.*;
23  import java.awt.*;
24  import java.awt.event.*;
25  
26  /**
27   * Text field with an arrow-key accessable history.
28   * @author Slava Pestov
29   * @version $Id: HistoryTextField.java,v 1.1.1.1 2002/04/18 16:23:02 reynal Exp $
30   */
31  public class HistoryTextField extends JTextField
32  {
33    /**
34     * Creates a new history text field.
35     * @param name The history model name
36     */
37    public HistoryTextField(String name)
38    {
39      this(name,false,true);
40    }
41  
42    /**
43     * Creates a new history text field.
44     * @param name The history model name
45     * @param instantPopup If true, selecting a value from the history
46     * popup will immediately fire an ActionEvent. If false, the user
47     * will have to press 'Enter' first
48     *
49     * @since jEdit 2.2pre5
50     */
51    public HistoryTextField(String name, boolean instantPopups)
52    {
53      this(name,instantPopups,true);
54    }
55  
56    /**
57     * Creates a new history text field.
58     * @param name The history model name
59     * @param instantPopup If true, selecting a value from the history
60     * popup will immediately fire an ActionEvent. If false, the user
61     * will have to press 'Enter' first
62     * @param enterAddsToHistory If true, pressing the Enter key will
63     * automatically add the currently entered text to the history.
64     *
65     * @since jEdit 2.6pre5
66     */
67    public HistoryTextField(String name, boolean instantPopups,
68      boolean enterAddsToHistory)
69    {
70      if(name != null)
71        historyModel = HistoryModel.getModel(name);
72      addMouseListener(new MouseHandler());
73  
74      this.instantPopups = instantPopups;
75      this.enterAddsToHistory = enterAddsToHistory;
76  
77      index = -1;
78    }
79  
80    /**
81     * Sets the history list model.
82     * @param name The model name
83     * @since jEdit 2.3pre3
84     */
85    public void setModel(String name)
86    {
87      if(name == null)
88        historyModel = null;
89      else
90        historyModel = HistoryModel.getModel(name);
91      index = -1;
92    }
93  
94    /**
95     * Adds the currently entered item to the history.
96     */
97    public void addCurrentToHistory()
98    {
99      if(historyModel != null)
100       historyModel.addItem(getText());
101     index = 0;
102   }
103 
104   /**
105    * Sets the displayed text.
106    */
107   public void setText(String text)
108   {
109     super.setText(text);
110     index = -1;
111   }
112 
113   /**
114    * Returns the underlying history model.
115    */
116   public HistoryModel getModel()
117   {
118     return historyModel;
119   }
120 
121   /**
122    * Fires an action event to all listeners. This is public so
123    * that inner classes can access it.
124    */
125   public void fireActionPerformed()
126   {
127     super.fireActionPerformed();
128   }
129 
130   // protected members
131   protected void processKeyEvent(KeyEvent evt)
132   {
133     evt = KeyEventWorkaround.processKeyEvent(evt);
134     if(evt == null)
135       return;
136 
137     if(evt.getID() == KeyEvent.KEY_PRESSED)
138     {
139       if(evt.getKeyCode() == KeyEvent.VK_ENTER)
140       {
141         if(enterAddsToHistory)
142           addCurrentToHistory();
143 
144         if(evt.getModifiers() == 0)
145         {
146           fireActionPerformed();
147           evt.consume();
148         }
149       }
150       else if(evt.getKeyCode() == KeyEvent.VK_UP)
151       {
152         if((evt.getModifiers() & InputEvent.CTRL_MASK) != 0)
153           doBackwardSearch();
154         else
155           historyPrevious();
156         evt.consume();
157       }
158       else if(evt.getKeyCode() == KeyEvent.VK_DOWN)
159       {
160         if((evt.getModifiers() & InputEvent.CTRL_MASK) != 0)
161           doForwardSearch();
162         else
163           historyNext();
164         evt.consume();
165       }
166       else if(evt.getKeyCode() == KeyEvent.VK_TAB
167         && (evt.getModifiers() & InputEvent.CTRL_MASK) != 0)
168       {
169         doBackwardSearch();
170         evt.consume();
171       }
172     }
173 
174     if(!evt.isConsumed())
175       super.processKeyEvent(evt);
176   }
177 
178   // private members
179   private HistoryModel historyModel;
180   private JPopupMenu popup;
181   private boolean instantPopups;
182   private boolean enterAddsToHistory;
183   private String current;
184   private int index;
185 
186   private void doBackwardSearch()
187   {
188     if(historyModel == null)
189       return;
190 
191     if(getSelectionEnd() != getDocument().getLength())
192     {
193       setCaretPosition(getDocument().getLength());
194     }
195 
196     String text = getText().substring(0,getSelectionStart());
197     if(text == null)
198     {
199       historyPrevious();
200       return;
201     }
202 
203     for(int i = index + 1; i < historyModel.getSize(); i++)
204     {
205       String item = historyModel.getItem(i);
206       if(item.startsWith(text))
207       {
208         replaceSelection(item.substring(text.length()));
209         select(text.length(),getDocument().getLength());
210         index = i;
211         return;
212       }
213     }
214 
215     getToolkit().beep();
216   }
217 
218   private void doForwardSearch()
219   {
220     if(historyModel == null)
221       return;
222 
223     if(getSelectionEnd() != getDocument().getLength())
224     {
225       setCaretPosition(getDocument().getLength());
226     }
227 
228     String text = getText().substring(0,getSelectionStart());
229     if(text == null)
230     {
231       historyNext();
232       return;
233     }
234 
235     for(int i = index - 1; i >= 0; i--)
236     {
237       String item = historyModel.getItem(i);
238       if(item.startsWith(text))
239       {
240         replaceSelection(item.substring(text.length()));
241         select(text.length(),getDocument().getLength());
242         index = i;
243         return;
244       }
245     }
246 
247     getToolkit().beep();
248   }
249 
250   private void historyPrevious()
251   {
252     if(historyModel == null)
253       return;
254 
255     if(index == historyModel.getSize() - 1)
256       getToolkit().beep();
257     else if(index == -1)
258     {
259       current = getText();
260       setText(historyModel.getItem(0));
261       index = 0;
262     }
263     else
264     {
265       // have to do this because setText() sets index to -1
266       int newIndex = index + 1;
267       setText(historyModel.getItem(newIndex));
268       index = newIndex;
269     }
270   }
271 
272   private void historyNext()
273   {
274     if(historyModel == null)
275       return;
276 
277     if(index == -1)
278       getToolkit().beep();
279     else if(index == 0)
280       setText(current);
281     else
282     {
283       // have to do this because setText() sets index to -1
284       int newIndex = index - 1;
285       setText(historyModel.getItem(newIndex));
286       index = newIndex;
287     }
288   }
289 
290   private void showPopupMenu(String text, int x, int y)
291   {
292     if(historyModel == null)
293       return;
294 
295     requestFocus();
296 
297     if(popup != null && popup.isVisible())
298     {
299       popup.setVisible(false);
300       return;
301     }
302 
303     ActionHandler actionListener = new ActionHandler();
304 
305     popup = new JPopupMenu();
306     JMenuItem caption = new JMenuItem(historyModel.getName()
307       + (text.length() == 0 ? "" : "/" + text));
308     caption.getModel().setEnabled(false);
309     popup.add(caption);
310     popup.addSeparator();
311 
312     for(int i = 0; i < historyModel.getSize(); i++)
313     {
314       String item = historyModel.getItem(i);
315       if(item.startsWith(text))
316       {
317         JMenuItem menuItem = new JMenuItem(item);
318         menuItem.setActionCommand(String.valueOf(i));
319         menuItem.addActionListener(actionListener);
320         popup.add(menuItem);
321       }
322     }
323 
324     popup.show(this,x,y);
325   }
326 
327   class ActionHandler implements ActionListener
328   {
329     public void actionPerformed(ActionEvent evt)
330     {
331       int ind = Integer.parseInt(evt.getActionCommand());
332       if(ind == -1)
333       {
334         if(index != -1)
335           setText(current);
336       }
337       else
338       {
339         setText(historyModel.getItem(ind));
340         index = ind;
341       }
342       if(instantPopups)
343       {
344         addCurrentToHistory();
345         fireActionPerformed();
346       }
347     }
348   }
349 
350   class MouseHandler extends MouseAdapter
351   {
352     public void mousePressed(MouseEvent evt)
353     {
354       if((evt.getModifiers() & InputEvent.CTRL_MASK) != 0)
355       {
356         showPopupMenu(getText().substring(0,getSelectionStart()),
357           0,getHeight());
358       }
359       else if((evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0)
360         showPopupMenu("",0,getHeight());
361     }
362   }
363 }