KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > gui > ActionBar


1 /*
2  * ActionBar.java - For invoking actions directly
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2003 Slava Pestov
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22
23 package org.gjt.sp.jedit.gui;
24
25 //{{{ Imports
26
import bsh.NameSpace;
27 import java.awt.event.*;
28 import java.awt.*;
29 import java.util.ArrayList JavaDoc;
30 import javax.swing.event.*;
31 import javax.swing.*;
32 import org.gjt.sp.jedit.*;
33 //}}}
34

35 /**
36  * Action invocation bar.
37  */

38 public class ActionBar extends JPanel
39 {
40     //{{{ ActionBar constructor
41
public ActionBar(View view, boolean temp)
42     {
43         setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
44
45         this.view = view;
46         this.temp = temp;
47
48         add(Box.createHorizontalStrut(2));
49
50         JLabel label = new JLabel(jEdit.getProperty("view.action.prompt"));
51         add(label);
52         add(Box.createHorizontalStrut(12));
53         add(action = new ActionTextField());
54         action.setEnterAddsToHistory(false);
55         Dimension max = action.getPreferredSize();
56         max.width = Integer.MAX_VALUE;
57         action.setMaximumSize(max);
58         action.addActionListener(new ActionHandler());
59         action.getDocument().addDocumentListener(new DocumentHandler());
60
61         if(temp)
62         {
63             close = new RolloverButton(GUIUtilities.loadIcon("closebox.gif"));
64             close.addActionListener(new ActionHandler());
65             close.setToolTipText(jEdit.getProperty(
66                 "view.action.close-tooltip"));
67             add(close);
68         }
69
70         // if 'temp' is true, hide search bar after user is done with it
71
this.temp = temp;
72     } //}}}
73

74     //{{{ getField() method
75
public HistoryTextField getField()
76     {
77         return action;
78     } //}}}
79

80     //{{{ goToActionBar() method
81
public void goToActionBar()
82     {
83         repeatCount = view.getInputHandler().getRepeatCount();
84         action.setText(null);
85         action.requestFocus();
86     } //}}}
87

88     //{{{ Private members
89

90     private static NameSpace namespace = new NameSpace(
91         BeanShell.getNameSpace(),"action bar namespace");
92
93     //{{{ Instance variables
94
private View view;
95     private boolean temp;
96     private int repeatCount;
97     private HistoryTextField action;
98     private CompletionPopup popup;
99     private RolloverButton close;
100     //}}}
101

102     //{{{ invoke() method
103
private void invoke()
104     {
105         String JavaDoc cmd;
106         if(popup != null)
107             cmd = popup.list.getSelectedValue().toString();
108         else
109         {
110             cmd = action.getText().trim();
111             int index = cmd.indexOf('=');
112             if(index != -1)
113             {
114                 action.addCurrentToHistory();
115                 String JavaDoc propName = cmd.substring(0,index).trim();
116                 String JavaDoc propValue = cmd.substring(index + 1).trim();
117                 String JavaDoc code;
118                 /* construct a BeanShell snippet instead of
119                  * invoking directly so that user can record
120                  * property changes in macros. */

121                 if(propName.startsWith("buffer."))
122                 {
123                     if(propName.equals("buffer.mode"))
124                     {
125                         code = "buffer.setMode(\""
126                             + MiscUtilities.charsToEscapes(
127                             propValue) + "\");";
128                     }
129                     else
130                     {
131                         code = "buffer.setStringProperty(\""
132                             + MiscUtilities.charsToEscapes(
133                             propName.substring("buffer.".length())
134                             ) + "\",\""
135                             + MiscUtilities.charsToEscapes(
136                             propValue) + "\");";
137                     }
138
139                     code += "\nbuffer.propertiesChanged();";
140                 }
141                 else if(propName.startsWith("!buffer."))
142                 {
143                     code = "jEdit.setProperty(\""
144                         + MiscUtilities.charsToEscapes(
145                         propName.substring(1)) + "\",\""
146                         + MiscUtilities.charsToEscapes(
147                         propValue) + "\");\n"
148                         + "jEdit.propertiesChanged();";
149                 }
150                 else
151                 {
152                     code = "jEdit.setProperty(\""
153                         + MiscUtilities.charsToEscapes(
154                         propName) + "\",\""
155                         + MiscUtilities.charsToEscapes(
156                         propValue) + "\");\n"
157                         + "jEdit.propertiesChanged();";
158                 }
159
160                 Macros.Recorder recorder = view.getMacroRecorder();
161                 if(recorder != null)
162                     recorder.record(code);
163                 BeanShell.eval(view,namespace,code);
164                 cmd = null;
165             }
166             else if(cmd.length() != 0)
167             {
168                 String JavaDoc[] completions = getCompletions(cmd);
169                 if(completions.length != 0)
170                 {
171                     cmd = completions[0];
172                 }
173             }
174             else
175                 cmd = null;
176         }
177
178         if(popup != null)
179         {
180             popup.dispose();
181             popup = null;
182         }
183
184         final String JavaDoc finalCmd = cmd;
185         final EditAction act = (finalCmd == null ? null : jEdit.getAction(finalCmd));
186         if(temp)
187             view.removeToolBar(this);
188
189         SwingUtilities.invokeLater(new Runnable JavaDoc()
190         {
191             public void run()
192             {
193                 view.getTextArea().requestFocus();
194                 if(act == null)
195                 {
196                     if(finalCmd != null)
197                     {
198                         view.getStatus().setMessageAndClear(
199                             jEdit.getProperty(
200                             "view.action.no-completions"));
201                     }
202                 }
203                 else
204                 {
205                     view.getInputHandler().setRepeatCount(repeatCount);
206                     view.getInputHandler().invokeAction(act);
207                 }
208             }
209         });
210     } //}}}
211

212     //{{{ getCompletions() method
213
private String JavaDoc[] getCompletions(String JavaDoc str)
214     {
215         str = str.toLowerCase();
216         String JavaDoc[] actions = jEdit.getActionNames();
217         ArrayList JavaDoc<String JavaDoc> returnValue = new ArrayList JavaDoc<String JavaDoc>(actions.length);
218         for(int i = 0; i < actions.length; i++)
219         {
220             if(actions[i].toLowerCase().contains(str))
221                 returnValue.add(actions[i]);
222         }
223
224         return returnValue.toArray(new String JavaDoc[returnValue.size()]);
225     } //}}}
226

227     //{{{ complete() method
228
private void complete(boolean insertLongestPrefix)
229     {
230         String JavaDoc text = action.getText().trim();
231         String JavaDoc[] completions = getCompletions(text);
232         if(completions.length == 1)
233         {
234             if(insertLongestPrefix)
235                 action.setText(completions[0]);
236         }
237         else if(completions.length != 0)
238         {
239             if(insertLongestPrefix)
240             {
241                 String JavaDoc prefix = MiscUtilities.getLongestPrefix(
242                     completions,true);
243                 if(prefix.contains(text))
244                     action.setText(prefix);
245             }
246
247             if(popup != null)
248                 popup.setModel(completions);
249             else
250                 popup = new CompletionPopup(completions);
251             return;
252         }
253
254         if(popup != null)
255         {
256             popup.dispose();
257             popup = null;
258         }
259     } //}}}
260

261     //}}}
262

263     //{{{ Inner classes
264

265     //{{{ ActionHandler class
266
class ActionHandler implements ActionListener
267     {
268         public void actionPerformed(ActionEvent evt)
269         {
270             if(evt.getSource() == close)
271                 view.removeToolBar(ActionBar.this);
272             else
273                 invoke();
274         }
275     } //}}}
276

277     //{{{ DocumentHandler class
278
class DocumentHandler implements DocumentListener
279     {
280         //{{{ insertUpdate() method
281
public void insertUpdate(DocumentEvent evt)
282         {
283             if(popup != null)
284                 complete(false);
285         } //}}}
286

287         //{{{ removeUpdate() method
288
public void removeUpdate(DocumentEvent evt)
289         {
290             if(popup != null)
291                 complete(false);
292         } //}}}
293

294         //{{{ changedUpdate() method
295
public void changedUpdate(DocumentEvent evt) {}
296         //}}}
297
} //}}}
298

299     //{{{ ActionTextField class
300
class ActionTextField extends HistoryTextField
301     {
302         boolean repeat;
303         boolean nonDigit;
304
305         ActionTextField()
306         {
307             super("action");
308             setSelectAllOnFocus(true);
309         }
310
311         public boolean isManagingFocus()
312         {
313             return false;
314         }
315
316         public boolean getFocusTraversalKeysEnabled()
317         {
318             return false;
319         }
320
321         public void processKeyEvent(KeyEvent evt)
322         {
323             evt = KeyEventWorkaround.processKeyEvent(evt);
324             if(evt == null)
325                 return;
326
327             switch(evt.getID())
328             {
329             case KeyEvent.KEY_TYPED:
330                 char ch = evt.getKeyChar();
331                 if(!nonDigit && Character.isDigit(ch))
332                 {
333                     super.processKeyEvent(evt);
334                     repeat = true;
335                     repeatCount = Integer.parseInt(action.getText());
336                 }
337                 else
338                 {
339                     nonDigit = true;
340                     if(repeat)
341                     {
342                         passToView(evt);
343                     }
344                     else
345                         super.processKeyEvent(evt);
346                 }
347                 break;
348             case KeyEvent.KEY_PRESSED:
349                 int keyCode = evt.getKeyCode();
350                 if(evt.isActionKey()
351                     || evt.isControlDown()
352                     || evt.isAltDown()
353                     || evt.isMetaDown()
354                     || keyCode == KeyEvent.VK_BACK_SPACE
355                     || keyCode == KeyEvent.VK_DELETE
356                     || keyCode == KeyEvent.VK_ENTER
357                     || keyCode == KeyEvent.VK_TAB
358                     || keyCode == KeyEvent.VK_ESCAPE)
359                 {
360                     nonDigit = true;
361                     if(repeat)
362                     {
363                         passToView(evt);
364                         break;
365                     }
366                     else if(keyCode == KeyEvent.VK_TAB)
367                     {
368                         complete(true);
369                         evt.consume();
370                     }
371                     else if(keyCode == KeyEvent.VK_ESCAPE)
372                     {
373                         evt.consume();
374                         if(popup != null)
375                         {
376                             popup.dispose();
377                             popup = null;
378                             action.requestFocus();
379                         }
380                         else
381                         {
382                             if(temp)
383                                 view.removeToolBar(ActionBar.this);
384                             view.getEditPane().focusOnTextArea();
385                         }
386                         break;
387                     }
388                     else if((keyCode == KeyEvent.VK_UP
389                         || keyCode == KeyEvent.VK_DOWN)
390                         && popup != null)
391                     {
392                         popup.list.processKeyEvent(evt);
393                         break;
394                     }
395                 }
396                 super.processKeyEvent(evt);
397                 break;
398             }
399         }
400
401         private void passToView(final KeyEvent evt)
402         {
403             if(temp)
404                 view.removeToolBar(ActionBar.this);
405             view.getTextArea().requestFocus();
406             SwingUtilities.invokeLater(new Runnable JavaDoc()
407             {
408                 public void run()
409                 {
410                     view.getTextArea().requestFocus();
411                     view.getInputHandler().setRepeatCount(repeatCount);
412                     view.getInputHandler().processKeyEvent(evt,
413                         View.ACTION_BAR, false);
414                 }
415             });
416         }
417
418         public void addNotify()
419         {
420             super.addNotify();
421             repeat = nonDigit = false;
422         }
423     } //}}}
424

425     //{{{ CompletionPopup class
426
class CompletionPopup extends JWindow
427     {
428         CompletionList list;
429
430         //{{{ CompletionPopup constructor
431
CompletionPopup(String JavaDoc[] actions)
432         {
433             super(view);
434
435             setContentPane(new JPanel(new BorderLayout())
436             {
437                 /**
438                  * Returns if this component can be traversed by pressing the
439                  * Tab key. This returns false.
440                  */

441                 public boolean isManagingFocus()
442                 {
443                     return false;
444                 }
445
446                 /**
447                  * Makes the tab key work in Java 1.4.
448                  */

449                 public boolean getFocusTraversalKeysEnabled()
450                 {
451                     return false;
452                 }
453             });
454
455             list = new CompletionList(actions);
456             list.setVisibleRowCount(8);
457             list.addMouseListener(new MouseHandler());
458             list.setSelectedIndex(0);
459             list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
460
461             // stupid scrollbar policy is an attempt to work around
462
// bugs people have been seeing with IBM's JDK -- 7 Sep 2000
463
JScrollPane scroller = new JScrollPane(list,
464                 ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
465                 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
466
467             getContentPane().add(scroller, BorderLayout.CENTER);
468
469             GUIUtilities.requestFocus(this,list);
470
471             pack();
472             Point p = new Point(0,-getHeight());
473             SwingUtilities.convertPointToScreen(p,action);
474             setLocation(p);
475             setVisible(true);
476
477             KeyHandler keyHandler = new KeyHandler();
478             addKeyListener(keyHandler);
479             list.addKeyListener(keyHandler);
480         } //}}}
481

482         //{{{ setModel() method
483
void setModel(String JavaDoc[] actions)
484         {
485             list.setListData(actions);
486             list.setSelectedIndex(0);
487         } //}}}
488

489         //{{{ MouseHandler class
490
class MouseHandler extends MouseAdapter
491         {
492             public void mouseClicked(MouseEvent evt)
493             {
494                 invoke();
495             }
496         } //}}}
497

498         //{{{ CompletionList class
499
class CompletionList extends JList
500         {
501             CompletionList(Object JavaDoc[] data)
502             {
503                 super(data);
504             }
505
506             // we need this public not protected
507
public void processKeyEvent(KeyEvent evt)
508             {
509                 super.processKeyEvent(evt);
510             }
511         } //}}}
512

513         //{{{ KeyHandler class
514
class KeyHandler extends KeyAdapter
515         {
516             public void keyTyped(KeyEvent evt)
517             {
518                 action.processKeyEvent(evt);
519             }
520
521             public void keyPressed(KeyEvent evt)
522             {
523                 int keyCode = evt.getKeyCode();
524                 if(keyCode == KeyEvent.VK_ESCAPE)
525                     action.processKeyEvent(evt);
526                 else if(keyCode == KeyEvent.VK_ENTER)
527                     invoke();
528                 else if(keyCode == KeyEvent.VK_UP)
529                 {
530                     int selected = list.getSelectedIndex();
531                     if(selected == 0)
532                     {
533                         list.setSelectedIndex(
534                             list.getModel().getSize()
535                             - 1);
536                         evt.consume();
537                     }
538                 }
539                 else if(keyCode == KeyEvent.VK_DOWN)
540                 {
541                     int selected = list.getSelectedIndex();
542                     if(selected == list.getModel().getSize() - 1)
543                     {
544                         list.setSelectedIndex(0);
545                         evt.consume();
546                     }
547                 }
548             }
549         } //}}}
550
} //}}}
551

552     //}}}
553
}
554
Popular Tags