KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > drjava > ui > predictive > PredictiveInputFrame


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32  *END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.drjava.ui.predictive;
35
36 import javax.swing.*;
37 import javax.swing.event.*;
38 import javax.swing.text.JTextComponent JavaDoc;
39 import javax.swing.text.Keymap JavaDoc;
40 import java.awt.*;
41 import java.awt.event.*;
42 import java.util.List JavaDoc;
43 import java.util.ArrayList JavaDoc;
44 import java.util.Arrays JavaDoc;
45 import java.util.StringTokenizer JavaDoc;
46 import java.util.NoSuchElementException JavaDoc;
47
48 import edu.rice.cs.util.Lambda;
49 import edu.rice.cs.util.swing.Utilities;
50
51 /** Frame with predictive string input based on a list of strings. */
52 public class PredictiveInputFrame<T extends Comparable JavaDoc<? super T>> extends JFrame {
53   
54   /** Interface that is used to generate additional information about an item. */
55   public static interface InfoSupplier<X> extends Lambda<String JavaDoc, X> {
56     public String JavaDoc apply(X param);
57   }
58
59 // /** General information supplier that just uses toString(). */
60
// public static final InfoSupplier<Object> TO_STRING_SUPPLIER = new InfoSupplier<Object>() {
61
// public String apply(Object param) { return param.toString(); }
62
// };
63

64   /** Interface for an action to be performed when the user closes the frame,
65    * either by using "OK" or "Cancel".
66    */

67   public static interface CloseAction<X extends Comparable JavaDoc<? super X>> extends Lambda<Object JavaDoc, PredictiveInputFrame<X>> {
68     public Object JavaDoc apply(PredictiveInputFrame<X> param);
69   }
70   
71   /** Class to save the frame state, i.e. location and dimensions.*/
72   public static class FrameState {
73     private volatile Dimension _dim;
74     private volatile Point _loc;
75     private volatile int _currentStrategyIndex;
76     public FrameState(Dimension d, Point l, int currentStrategyIndex) {
77       _dim = d;
78       _loc = l;
79       _currentStrategyIndex = currentStrategyIndex;
80     }
81     public FrameState(String JavaDoc s) {
82       StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(s);
83       try {
84         int x = Integer.valueOf(tok.nextToken());
85         int y = Integer.valueOf(tok.nextToken());
86         _dim = new Dimension(x, y);
87         x = Integer.valueOf(tok.nextToken());
88         y = Integer.valueOf(tok.nextToken());
89         _loc = new Point(x, y);
90         _currentStrategyIndex = Integer.valueOf(tok.nextToken());
91       }
92       catch(NoSuchElementException JavaDoc nsee) {
93         throw new IllegalArgumentException JavaDoc("Wrong FrameState string: " + nsee);
94       }
95       catch(NumberFormatException JavaDoc nfe) {
96         throw new IllegalArgumentException JavaDoc("Wrong FrameState string: " + nfe);
97       }
98     }
99     public FrameState(PredictiveInputFrame comp) {
100       _dim = comp.getSize();
101       _loc = comp.getLocation();
102       _currentStrategyIndex = comp._strategies.indexOf(comp._currentStrategy);
103     }
104     public String JavaDoc toString() {
105       final StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
106       sb.append((int)_dim.getWidth());
107       sb.append(' ');
108       sb.append((int)_dim.getHeight());
109       sb.append(' ');
110       sb.append(_loc.x);
111       sb.append(' ');
112       sb.append(_loc.y);
113       sb.append(' ');
114       sb.append(_currentStrategyIndex);
115       return sb.toString();
116     }
117     public Dimension getDimension() { return _dim; }
118     public Point getLocation() { return _loc; }
119     public int getCurrentStrategyIndex() { return _currentStrategyIndex; }
120   }
121
122   /** Predictive input model */
123   private volatile PredictiveInputModel<T> _pim;
124
125   /** Code for the last button that was pressed.*/
126   private volatile int _buttonPressed;
127
128   /** Ok button.*/
129   private final JButton _okButton = new JButton("OK");
130   
131   /** Text field for string input. */
132   private final JTextField _textField = new JTextField();
133   
134   /** Label with "Tab completes:" string. */
135   private final JLabel _tabCompletesLabel = new JLabel("Tab completes: ");
136
137   /** List with matches. */
138   private final JList _matchList;
139
140   /** True if the user is forced to select one of the items. */
141   private final boolean _force;
142   
143   /** Label with shared extension.*/
144   private final JLabel _sharedExtLabel = new JLabel("");
145
146   /** Listener for several events. */
147   private final PredictiveInputListener _listener = new PredictiveInputListener();
148
149   /** Info supplier. */
150   private final InfoSupplier<? super T> _info;
151
152   /** Text area for additional information. */
153   private final JLabel _infoLabel = new JLabel("");
154   
155   /** Owner frame. */
156   private final Frame _owner;
157   
158   /** Action to be performed when the user closes the frame using "OK". */
159   private final CloseAction<T> _okAction;
160   
161   /** Action to be performed when the user closes the frame using "Cancel". */
162   private final CloseAction<T> _cancelAction;
163   
164   /** Array of strategies. */
165   private final java.util.List JavaDoc<PredictiveInputModel.MatchingStrategy<T>> _strategies;
166   
167   /** Combo box. */
168   private final JComboBox _strategyBox;
169   
170   /** Last frame state. It can be stored and restored. */
171   private volatile FrameState _lastState;
172   
173   /** Currently used strategy. */
174   private volatile PredictiveInputModel.MatchingStrategy<T> _currentStrategy;
175
176   /** Create a new predictive string input frame.
177    * @param owner owner frame
178    * @param force true if the user is forced to select one of the items
179    * @param ignoreCase true if case should be ignored
180    * @param info information supplier to use for additional information display
181    * @param strategies array of matching strategies
182    * @param okAction action to be performed when the user closes the frame using "OK"
183    * @param cancelAction action to be performed when the user closes the frame using "Cancel"
184    * @param items list of items
185    */

186
187   public PredictiveInputFrame(Frame owner, String JavaDoc title, boolean force, boolean ignoreCase, InfoSupplier<? super T> info,
188                               java.util.List JavaDoc<PredictiveInputModel.MatchingStrategy<T>> strategies,
189                               CloseAction<T> okAction, CloseAction<T> cancelAction, java.util.List JavaDoc<T> items) {
190     super(title);
191     _strategies = strategies;
192     _strategyBox = new JComboBox(_strategies.toArray());
193     _currentStrategy = _strategies.get(0);
194     _pim = new PredictiveInputModel<T>(ignoreCase, _currentStrategy, items);
195     _matchList = new JList(_pim.getMatchingItems().toArray());
196     _force = force;
197     _info = info;
198     _lastState = null;
199     _owner = owner;
200     _okAction = okAction;
201     _cancelAction = cancelAction;
202     init(_info != null);
203   }
204
205   /** Create a new predictive string input frame.
206    * @param owner owner frame
207    * @param force true if the user is forced to select one of the items
208    * @param info information supplier to use for additional information display
209    * @param strategies array of matching strategies
210    * @param okAction action to be performed when the user closes the frame using "OK"
211    * @param cancelAction action to be performed when the user closes the frame using "Cancel"
212    * @param items varargs/array of items
213    */

214   public PredictiveInputFrame(Frame owner, String JavaDoc title, boolean force, boolean ignoreCase, InfoSupplier<? super T> info,
215                               List JavaDoc<PredictiveInputModel.MatchingStrategy<T>> strategies,
216                               CloseAction<T> okAction, CloseAction<T> cancelAction, T... items) {
217     this(owner, title, force, ignoreCase, info, strategies, okAction, cancelAction, Arrays.asList(items));
218 // super(title);
219
// _strategies = strategies;
220
// _strategyBox = new JComboBox(_strategies.toArray());
221
// _currentStrategy = _strategies.get(0);
222
// _pim = new PredictiveInputModel<T>(ignoreCase, _currentStrategy, items);
223
// _force = force;
224
// _info = info;
225
// _owner = owner;
226
// _okAction = okAction;
227
// _cancelAction = cancelAction;
228
// init(_info != null);
229
}
230   
231   /** Returns the last state of the frame, i.e. the location and dimension.
232    * @return frame state
233    */

234   public FrameState getFrameState() { return _lastState; }
235   
236   /** Sets state of the frame, i.e. the location and dimension of the frame for the next use.
237    * @param ds State to update to, or {@code null} to reset
238    */

239   public void setFrameState(FrameState ds) {
240     _lastState = ds;
241     if (_lastState!=null) {
242       setSize(_lastState.getDimension());
243       setLocation(_lastState.getLocation());
244       int index = _lastState.getCurrentStrategyIndex();
245       if ((index>=0) && (index<_strategies.size())) {
246         _currentStrategy = _strategies.get(index);
247         _strategyBox.setSelectedIndex(index);
248       }
249       selectStrategy();
250       validate();
251     }
252   }
253   
254   /** Sets state of the frame, i.e. the location and dimension of the frame for the next use.
255    * @param s State to update to, or {@code null} to reset
256    */

257   public void setFrameState(String JavaDoc s) {
258     try { _lastState = new FrameState(s); }
259     catch(IllegalArgumentException JavaDoc e) { _lastState = null; }
260     if (_lastState!=null) {
261       setSize(_lastState.getDimension());
262       setLocation(_lastState.getLocation());
263       int index = _lastState.getCurrentStrategyIndex();
264       if ((index>=0) && (index<_strategies.size())) {
265         _currentStrategy = _strategies.get(index);
266         _strategyBox.setSelectedIndex(index);
267       }
268       selectStrategy();
269       validate();
270     }
271     else {
272       Dimension parentDim = (_owner != null) ? _owner.getSize() : getToolkit().getScreenSize();
273       int xs = (int)parentDim.getWidth()/3;
274       int ys = (int)parentDim.getHeight()/4;
275       setSize(Math.max(xs,400), Math.max(ys, 300));
276       setLocationRelativeTo(_owner);
277       _currentStrategy = _strategies.get(0);
278       _strategyBox.setSelectedIndex(0);
279       selectStrategy();
280     }
281   }
282
283   /** Set the predictive input model.
284     * @param ignoreCase true if case should be ignored
285     * @param pim predictive input model
286     */

287   public void setModel(boolean ignoreCase, PredictiveInputModel<T> pim) {
288     _pim = new PredictiveInputModel<T>(ignoreCase, pim);
289     removeListener();
290     updateTextField();
291     updateExtensionLabel();
292     updateList();
293     addListener();
294   }
295
296   /** Set the items.
297     * @param ignoreCase true if case should be ignored
298     * @param items list of items
299     */

300   public void setItems(boolean ignoreCase, List JavaDoc<T> items) {
301     _pim = new PredictiveInputModel<T>(ignoreCase, _currentStrategy, items);
302     removeListener();
303     updateTextField();
304     updateExtensionLabel();
305     updateList();
306     addListener();
307   }
308   
309   /** Set the currently selected item.
310     * @param item item to select
311     */

312   public void setCurrentItem(T item) {
313     _pim.setCurrentItem(item);
314     removeListener();
315     updateTextField();
316     updateExtensionLabel();
317     updateList();
318     addListener();
319   }
320
321   /** Set the items.
322     * @param ignoreCase true if case should be ignored
323     * @param items varargs/array of items
324     */

325   public void setItems(boolean ignoreCase, T... items) {
326     _pim = new PredictiveInputModel<T>(ignoreCase, _currentStrategy, items);
327     removeListener();
328     updateTextField();
329     updateExtensionLabel();
330     updateList();
331     addListener();
332   }
333
334   /** Return the code for the last button that was pressed. This will be either JOptionPane.OK_OPTION or
335     * JOptionPane.CANCEL_OPTION.
336     * @return button code
337     */

338   public int getButtonPressed() {
339     return _buttonPressed;
340   }
341
342   /** Return the string that was entered in the text field.
343     * If the user is forced to select an item, then the text of the item will be returned.
344     * @return text in text field
345     */

346   public String JavaDoc getText() {
347     if (_force) {
348       @SuppressWarnings JavaDoc("unchecked")
349         T item = (T)_matchList.getSelectedValue();
350       return (item==null)?"":_currentStrategy.force(item,_textField.getText());
351     }
352     return _textField.getText();
353   }
354
355   /** Return the item that was selected or null the user entered a mask not in the list and force == false.
356     * @return item that was selected or null
357     */

358   public T getItem() {
359     if (!_force && _pim.getMatchingItems().size() == 0) return null;
360     @SuppressWarnings JavaDoc("unchecked")
361       T item = (T)_matchList.getSelectedValue();
362     return item;
363   }
364
365   /** Initialize the frame.
366    * @param info true if additional information is desired
367    */

368   private void init(boolean info) {
369     _buttonPressed = JOptionPane.CANCEL_OPTION;
370     addWindowListener(new java.awt.event.WindowAdapter JavaDoc() {
371       public void windowClosing(WindowEvent winEvt) {
372         cancelButtonPressed();
373       }
374     });
375     addComponentListener(new java.awt.event.ComponentAdapter JavaDoc() {
376       public void componentResized(ComponentEvent e) {
377         validate();
378         _matchList.ensureIndexIsVisible(_matchList.getSelectedIndex());
379       }
380     });
381
382     // buttons
383
_okButton.addActionListener(new ActionListener() {
384       public void actionPerformed(ActionEvent e) { okButtonPressed(); }
385     });
386
387     getRootPane().setDefaultButton(_okButton);
388
389     final JButton cancelButton = new JButton("Cancel");
390     cancelButton.addActionListener(new ActionListener() {
391       public void actionPerformed(ActionEvent e) {
392         cancelButtonPressed();
393       }
394     });
395     
396     _strategyBox.setEditable(false);
397     _strategyBox.addActionListener(new ActionListener() {
398       public void actionPerformed(ActionEvent e) {
399         // System.out.println("set strategy!");
400
selectStrategy();
401       }
402     });
403     _strategyBox.addFocusListener(new FocusListener() {
404       public void focusGained(FocusEvent e) { }
405
406       public void focusLost(FocusEvent e) {
407         if ((e.getOppositeComponent() != _textField) &&
408             (e.getOppositeComponent() != _okButton) &&
409             (e.getOppositeComponent() != cancelButton)) {
410           _textField.requestFocus();
411         }
412       }
413     });
414
415     // text field
416
_textField.setDragEnabled(false);
417     _textField.setFocusTraversalKeysEnabled(false);
418
419     addListener();
420
421     Keymap JavaDoc ourMap = JTextComponent.addKeymap("PredictiveInputFrame._textField", _textField.getKeymap());
422     ourMap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), new AbstractAction() {
423       public void actionPerformed(ActionEvent e) {
424 // System.out.println("esc!");
425
cancelButtonPressed();
426       }
427     });
428     ourMap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), new AbstractAction() {
429       public void actionPerformed(ActionEvent e) {
430 // System.out.println("enter!");
431
okButtonPressed();
432       }
433     });
434     ourMap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), new AbstractAction() {
435       public void actionPerformed(ActionEvent e) {
436 // System.out.println("tab!");
437
removeListener();
438         _pim.extendSharedMask();
439         updateTextField();
440         updateExtensionLabel();
441         updateList();
442         addListener();
443       }
444     });
445     ourMap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), new AbstractAction() {
446       public void actionPerformed(ActionEvent e) {
447 // System.out.println("up!");
448
if (_matchList.getModel().getSize() > 0) {
449           removeListener();
450           int i = _matchList.getSelectedIndex();
451           if (i > 0) {
452             _matchList.setSelectedIndex(i - 1);
453             _matchList.ensureIndexIsVisible(i - 1);
454             _pim.setCurrentItem(_pim.getMatchingItems().get(i - 1));
455             updateInfo();
456           }
457           addListener();
458         }
459       }
460     });
461     ourMap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), new AbstractAction() {
462       public void actionPerformed(ActionEvent e) {
463 // System.out.println("down!");
464
if (_matchList.getModel().getSize()>0) {
465           removeListener();
466           int i = _matchList.getSelectedIndex();
467           if (i < _matchList.getModel().getSize() - 1) {
468             _matchList.setSelectedIndex(i + 1);
469             _matchList.ensureIndexIsVisible(i + 1);
470             _pim.setCurrentItem(_pim.getMatchingItems().get(i + 1));
471             updateInfo();
472           }
473           addListener();
474         }
475       }
476     });
477     ourMap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0), new AbstractAction() {
478       public void actionPerformed(ActionEvent e) {
479 // System.out.println("page up!");
480
if (_matchList.getModel().getSize() > 0) {
481           removeListener();
482           int page = _matchList.getLastVisibleIndex() - _matchList.getFirstVisibleIndex() + 1;
483           int i = _matchList.getSelectedIndex() - page;
484           if (i < 0) i = 0;
485           _matchList.setSelectedIndex(i);
486           _matchList.ensureIndexIsVisible(i);
487           _pim.setCurrentItem(_pim.getMatchingItems().get(i));
488           updateInfo();
489           addListener();
490         }
491       }
492     });
493     ourMap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0), new AbstractAction() {
494       public void actionPerformed(ActionEvent e) {
495 // System.out.println("page down!");
496
if (_matchList.getModel().getSize()>0) {
497           removeListener();
498           int page = _matchList.getLastVisibleIndex() - _matchList.getFirstVisibleIndex() + 1;
499           int i = _matchList.getSelectedIndex() + page;
500           if (i >= _matchList.getModel().getSize()) {
501             i = _matchList.getModel().getSize() - 1;
502           }
503           _matchList.setSelectedIndex(i);
504           _matchList.ensureIndexIsVisible(i);
505           _pim.setCurrentItem(_pim.getMatchingItems().get(i));
506           updateInfo();
507           addListener();
508         }
509       }
510     });
511     _textField.setKeymap(ourMap);
512     
513 // _textField.addKeyListener(new KeyAdapter() {
514
// public void keyTyped(KeyEvent e) {
515
// char c = e.getKeyChar();
516
// if ((c != KeyEvent.VK_DELETE) && (c != KeyEvent.VK_BACK_SPACE) && (c >= 32)) {
517
// String oldMask = _pim.getMask();
518
// String newMask = oldMask.substring(0, _textField.getCaretPosition()) + c +
519
// oldMask.substring(_textField.getCaretPosition());
520
// _pim.setMask(newMask);
521
// if (_force && (_pim.getMatchingItems().size()==0)) {
522
// Toolkit.getDefaultToolkit().beep();
523
// e.consume();
524
// }
525
// _pim.setMask(oldMask);
526
// }
527
// }
528
// });
529

530     _textField.addFocusListener(new FocusListener() {
531       public void focusGained(FocusEvent e) { }
532
533       public void focusLost(FocusEvent e) {
534         if ((e.getOppositeComponent() != _strategyBox) &&
535             (e.getOppositeComponent() != _okButton) &&
536             (e.getOppositeComponent() != cancelButton)) {
537           _textField.requestFocus();
538         }
539       }
540     });
541
542     _matchList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
543     _matchList.addListSelectionListener(new ListSelectionListener() {
544       public void valueChanged(ListSelectionEvent e) {
545 // System.out.println("click!");
546
removeListener();
547         int i = _matchList.getSelectedIndex();
548         if (i >= 0) {
549           _pim.setCurrentItem(_pim.getMatchingItems().get(i));
550           _matchList.ensureIndexIsVisible(i);
551           updateInfo();
552         }
553         addListener();
554       }
555     });
556     
557     // put everything together
558
Container contentPane = getContentPane();
559     
560     GridBagLayout layout = new GridBagLayout();
561     contentPane.setLayout(layout);
562     
563     GridBagConstraints c = new GridBagConstraints();
564     c.anchor = GridBagConstraints.NORTHWEST;
565     c.weightx = 1.0;
566     c.weighty = 0.0;
567     c.gridwidth = GridBagConstraints.REMAINDER; // end row
568
c.insets.top = 2;
569     c.insets.left = 2;
570     c.insets.bottom = 2;
571     c.insets.right = 2;
572     
573     if (info) {
574       c.fill = GridBagConstraints.NONE;
575       contentPane.add(_infoLabel, c);
576     }
577
578     c.fill = GridBagConstraints.BOTH;
579     c.weighty = 1.0;
580     contentPane.add(new JScrollPane(_matchList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
581                                     JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
582                     c);
583     
584     c.anchor = GridBagConstraints.SOUTHWEST;
585     c.fill = GridBagConstraints.NONE;
586     c.weightx = 0.0;
587     c.weighty = 0.0;
588     c.gridwidth = 1;
589     contentPane.add(_tabCompletesLabel, c);
590     
591     c.fill = GridBagConstraints.HORIZONTAL;
592     c.weightx = 1.0;
593     c.gridwidth = GridBagConstraints.REMAINDER;
594     contentPane.add(_sharedExtLabel, c);
595     
596     contentPane.add(_textField, c);
597     
598     c.anchor = GridBagConstraints.SOUTH;
599     
600     JPanel buttonPanel = new JPanel(new GridBagLayout());
601     GridBagConstraints bc = new GridBagConstraints();
602     bc.insets.left = 2;
603     bc.insets.right = 2;
604     buttonPanel.add(new JLabel("Matching strategy:"), bc);
605     buttonPanel.add(_strategyBox, bc);
606     buttonPanel.add(_okButton, bc);
607     buttonPanel.add(cancelButton, bc);
608     
609     contentPane.add(buttonPanel, c);
610
611     Dimension parentDim = (_owner!=null)?(_owner.getSize()):getToolkit().getScreenSize();
612     int xs = (int)parentDim.getWidth()/3;
613     int ys = (int)parentDim.getHeight()/4;
614     setSize(Math.max(xs,400), Math.max(ys, 300));
615     setLocationRelativeTo(_owner);
616
617     removeListener();
618     updateTextField();
619     addListener();
620     updateList();
621   }
622   
623   /**
624    * Enable or disable owner. Can be overridden to toggle the hourglass, etc.
625    * @param b whether the owner should be enabled (true) or disabled
626    */

627   public void setOwnerEnabled(boolean b) {
628     // do nothing by default
629
}
630   
631   /** Validates before changing visibility,
632    * @param b true if frame should be shown, false if it should be hidden.
633    */

634   public void setVisible(boolean b) {
635     validate();
636     super.setVisible(b);
637     if (b) {
638       setOwnerEnabled(false);
639       _textField.requestFocus();
640     }
641     else {
642       setOwnerEnabled(true);
643       _owner.toFront();
644     }
645   }
646
647   /** Add the listener. */
648   private void addListener() {
649     _textField.getDocument().addDocumentListener(_listener);
650     _textField.addCaretListener(_listener);
651   }
652
653   /** Remove the listener. */
654   private void removeListener() {
655     _textField.getDocument().removeDocumentListener(_listener);
656     _textField.removeCaretListener(_listener);
657   }
658
659   /** Update the text field based on the model. */
660   private void updateTextField() {
661     _textField.setText(_pim.getMask());
662     _textField.setCaretPosition(_pim.getMask().length());
663   }
664
665   /** Update the extension label based on the model. */
666   private void updateExtensionLabel() {
667     _sharedExtLabel.setText(_pim.getSharedMaskExtension()+" ");
668     _tabCompletesLabel.setVisible(_pim.getSharedMaskExtension().length()>0);
669   }
670
671   /** Update the match list based on the model. */
672   private void updateList() {
673     _matchList.setListData(_pim.getMatchingItems().toArray());
674     _matchList.setSelectedValue(_pim.getCurrentItem(), true);
675     updateExtensionLabel();
676     updateInfo();
677     _okButton.setEnabled(_matchList.getModel().getSize()>0);
678   }
679
680   /** Update the information. */
681   private void updateInfo() {
682     if (_info == null) return;
683     if (_matchList.getModel().getSize()>0) {
684       @SuppressWarnings JavaDoc("unchecked") T item = (T)_matchList.getSelectedValue();
685       _infoLabel.setText("Path: " + _info.apply(item));
686     }
687     else _infoLabel.setText("No file selected");
688   }
689   
690   /** Handle OK button. */
691   private void okButtonPressed() {
692     if (_matchList.getModel().getSize()>0) {
693       _buttonPressed = JOptionPane.OK_OPTION;
694       _lastState = new FrameState(PredictiveInputFrame.this);
695       setVisible(false);
696       _okAction.apply(this);
697     }
698     else Toolkit.getDefaultToolkit().beep();
699   }
700   
701   /** Handle cancel button. */
702   private void cancelButtonPressed() {
703     _buttonPressed = JOptionPane.CANCEL_OPTION;
704     _lastState = new FrameState(PredictiveInputFrame.this);
705     setVisible(false);
706     _cancelAction.apply(this);
707   }
708   
709   /** Select the strategy for matching. */
710   public void selectStrategy() {
711     _currentStrategy = _strategies.get(_strategyBox.getSelectedIndex());
712     removeListener();
713     _pim.setStrategy(_currentStrategy);
714     updateTextField();
715     updateExtensionLabel();
716     updateList();
717     addListener();
718     _textField.requestFocus();
719   }
720
721   /** Listener for several events. */
722   private class PredictiveInputListener implements CaretListener, DocumentListener {
723     public void insertUpdate(DocumentEvent e) {
724 // System.out.println("insertUpdate fired!");
725
Utilities.invokeLater(new Runnable JavaDoc() {
726         public void run() {
727           removeListener();
728           _pim.setMask(_textField.getText());
729           updateExtensionLabel();
730           updateList();
731           addListener();
732         }
733       });
734     }
735
736     public void removeUpdate(DocumentEvent e) {
737 // System.out.println("removeUpdate fired!");
738
Utilities.invokeLater(new Runnable JavaDoc() {
739         public void run() {
740           removeListener();
741           _pim.setMask(_textField.getText());
742           updateExtensionLabel();
743           updateList();
744           addListener();
745         }
746       });
747     }
748
749     public void changedUpdate(DocumentEvent e) {
750 // System.out.println("changedUpdate fired!");
751
Utilities.invokeLater(new Runnable JavaDoc() {
752         public void run() {
753           removeListener();
754           _pim.setMask(_textField.getText());
755           updateExtensionLabel();
756           updateList();
757           addListener();
758         }
759       });
760     }
761
762     public void caretUpdate(CaretEvent e) { }
763   }
764 }
765
Popular Tags