001: /*
002: * Sun Public License Notice
003: *
004: * The contents of this file are subject to the Sun Public License
005: * Version 1.0 (the "License"). You may not use this file except in
006: * compliance with the License. A copy of the License is available at
007: * http://www.sun.com/
008: *
009: * The Original Code is NetBeans. The Initial Developer of the Original
010: * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
011: * Microsystems, Inc. All Rights Reserved.
012: */
013:
014: package org.netbeans.editor.ext.java;
015:
016: import java.awt.Dialog;
017: import java.awt.Rectangle;
018: import java.awt.event.ActionEvent;
019: import java.awt.event.ActionListener;
020: import java.awt.event.MouseAdapter;
021: import java.awt.event.MouseEvent;
022: import java.awt.event.WindowAdapter;
023: import java.awt.event.WindowEvent;
024: import java.util.Collections;
025: import java.util.Iterator;
026: import java.util.List;
027:
028: import javax.swing.JButton;
029: import javax.swing.JDialog;
030: import javax.swing.JList;
031: import javax.swing.ListCellRenderer;
032: import javax.swing.SwingUtilities;
033:
034: import org.netbeans.editor.DialogSupport;
035: import org.netbeans.editor.LocaleSupport;
036: import org.netbeans.editor.ext.ListCompletionView;
037:
038: /**
039: *
040: * @author Miloslav Metelka
041: * @version 1.0
042: */
043:
044: public class JavaFastOpen implements ActionListener {
045:
046: private static final int TIMER_DELAY = 500;
047:
048: private JavaFastOpenPanel panel;
049:
050: private ListCellRenderer cellRenderer;
051:
052: private JList resultList;
053:
054: private Dialog dialog;
055:
056: private JButton[] buttons;
057:
058: private Evaluator evaluator;
059:
060: private static final int SET_EXP = 1;
061: private static final int POPULATE_LIST = 2;
062: private static final int OPEN = 3;
063:
064: /**
065: * Reference to instance of this class. Used for showing only one FastOpen
066: * dialog
067: */
068: protected static JavaFastOpen fastOpen = null;
069:
070: public JavaFastOpen() {
071: }
072:
073: public void setDialogVisible(boolean visible) {
074: if (dialog == null) {
075: dialog = createDialog();
076: }
077:
078: dialog.setVisible(visible);
079:
080: if (visible) {
081: requestFocus();
082:
083: } else {
084:
085: if (evaluator != null) {
086: evaluator.breakLoop();
087: }
088:
089: dialog.dispose();
090: fastOpen = null;
091: }
092: }
093:
094: protected void openSource(Object item) {
095: }
096:
097: /** Move focus to the opened window */
098: public void requestFocus() {
099: if (dialog == null)
100: return;
101: dialog.requestFocus();
102: getPanel().popupNotify();
103: }
104:
105: protected ListCellRenderer createCellRenderer() {
106: JCCellRenderer rr = new JCCellRenderer();
107: rr.setClassDisplayFullName(true);
108: return rr;
109: }
110:
111: protected JList createResultList() {
112: JList list = new ListCompletionView(getCellRenderer());
113: list.addMouseListener(new MouseAdapter() {
114: public void mouseClicked(MouseEvent e) {
115: if (e.getClickCount() == 2) {
116: actionPerformed(new ActionEvent(getButtons()[0], 0,
117: ""));
118: }
119: }
120: });
121:
122: return list;
123: }
124:
125: private JButton[] getButtons() {
126: if (buttons == null) {
127: buttons = new JButton[] {
128: new JButton(LocaleSupport.getString(
129: "JFO_openSourceButton", "Open Source")), // NOI18N
130: new JButton(LocaleSupport.getString(
131: "JFO_closeButton", "Close")) // NOI18N
132: };
133: buttons[0].setEnabled(false);
134:
135: String mnemonic = LocaleSupport.getString(
136: "JFO_openSourceButtonMnemonic", "O"); // NOI18N
137: if (mnemonic != null && mnemonic.length() > 0) {
138: buttons[0].setMnemonic(mnemonic.charAt(0));
139: }
140:
141: mnemonic = LocaleSupport.getString(
142: "JFO_closeButtonMnemonic", "C"); // NOI18N
143: if (mnemonic != null && mnemonic.length() > 0) {
144: buttons[1].setMnemonic(mnemonic.charAt(0));
145: }
146: buttons[0].getAccessibleContext().setAccessibleDescription(
147: LocaleSupport
148: .getString("ACSD_JFO_openSourceButton")); // NOI18N
149: buttons[1].getAccessibleContext().setAccessibleDescription(
150: LocaleSupport.getString("ACSD_JFO_closeButton")); // NOI18N
151: }
152:
153: return buttons;
154: }
155:
156: private Dialog createDialog() {
157: String title = LocaleSupport.getString("JFO_title",
158: "Open Java Source");
159:
160: Dialog dialog = DialogSupport.createDialog(title, getPanel(),
161: false, getButtons(), false, 0, 1, this );
162: dialog.addWindowListener(new WindowAdapter() {
163: public void windowClosing(WindowEvent e) {
164: JavaFastOpen.this .setDialogVisible(false);
165: }
166: });
167:
168: return dialog;
169: }
170:
171: private JavaFastOpenPanel getPanel() {
172: if (panel == null) {
173: panel = new JavaFastOpenPanel(this );
174: }
175: return panel;
176: }
177:
178: ListCellRenderer getCellRenderer() {
179: if (cellRenderer == null) {
180: cellRenderer = createCellRenderer();
181: }
182: return cellRenderer;
183: }
184:
185: JList getResultList() {
186: if (resultList == null) {
187: resultList = createResultList();
188: }
189: return resultList;
190: }
191:
192: private Evaluator getEvaluator() {
193: if (evaluator == null) {
194: evaluator = new Evaluator(0);
195: evaluator.start();
196: }
197: return evaluator;
198: }
199:
200: public void setSearchText(String text) {
201: getPanel().setSearchText(text);
202: postUpdate();
203: }
204:
205: void postUpdate() {
206: SwingUtilities.invokeLater(new Evaluator(SET_EXP));
207: }
208:
209: List evaluate(String exp) {
210: List ret = Collections.EMPTY_LIST;
211:
212: if (exp != null && exp.length() > 0) {
213: JCFinder finder = JavaCompletion.getFinder();
214: ret = finder.findClasses(null, exp, false);
215: // remove innerclasses
216: Iterator it = ret.iterator();
217: while (it.hasNext()) {
218: JCClass cls = (JCClass) it.next();
219: if (cls.getName().indexOf('.') >= 0) {
220: it.remove();
221: }
222: }
223: }
224:
225: return ret;
226: }
227:
228: void populate(List result) {
229: if (result != null) {
230: if (getResultList() instanceof ListCompletionView) {
231: SwingUtilities.invokeLater(new Evaluator(POPULATE_LIST,
232: result));
233: }
234: }
235: }
236:
237: void scrollDown() {
238: int currIndex = resultList.getSelectedIndex();
239: int maxIndex = resultList.getModel().getSize() - 1;
240: if (currIndex == -1 || currIndex == maxIndex)
241: return;
242: resultList.setSelectedIndex(currIndex + 1);
243: Rectangle r = resultList.getCellBounds(currIndex + 1,
244: currIndex + 1);
245: if (r != null) {
246: resultList.scrollRectToVisible(r);
247: }
248: }
249:
250: void scrollUp() {
251: int currIndex = resultList.getSelectedIndex();
252: if (currIndex == -1 || currIndex == 0)
253: return;
254: resultList.setSelectedIndex(currIndex - 1);
255: Rectangle r = resultList.getCellBounds(currIndex - 1,
256: currIndex - 1);
257: if (r != null) {
258: resultList.scrollRectToVisible(r);
259: }
260: }
261:
262: /**
263: * Invoked when an action occurs.
264: */
265: public void actionPerformed(ActionEvent evt) {
266: Object src = evt.getSource();
267:
268: if (src == buttons[0] || src == panel) { // Open button
269: getEvaluator().postOpen();
270: } else {
271: setDialogVisible(false);
272: }
273: }
274:
275: private void open() {
276: SwingUtilities.invokeLater(new Evaluator(OPEN));
277: }
278:
279: private class Evaluator extends Thread {
280:
281: private int opID;
282:
283: private List result;
284:
285: private String exp;
286:
287: private String lastExp;
288:
289: private boolean open;
290:
291: private boolean exit;
292:
293: Evaluator(int opID) {
294: this (opID, null);
295: }
296:
297: Evaluator(int opID, List result) {
298: this .opID = opID;
299: this .result = result;
300: }
301:
302: synchronized void setExp(String exp) {
303: this .exp = exp;
304: }
305:
306: synchronized void postOpen() {
307: this .open = true;
308: }
309:
310: void breakLoop() {
311: exit = true;
312: }
313:
314: public void run() {
315: switch (opID) {
316: case SET_EXP:
317: String text = getPanel().getSearchText();
318:
319: // We enable immediately after first typed character
320: if (getEvaluator().lastExp == null && text.length() > 0) {
321: getButtons()[0].setEnabled(true);
322: }
323:
324: getEvaluator().setExp(text);
325: return;
326:
327: case POPULATE_LIST:
328: ((ListCompletionView) getResultList())
329: .setResult(result);
330: getResultList().setSelectedIndex(0);
331: getButtons()[0].setEnabled(result.size() > 0);
332:
333: if (dialog instanceof JDialog) {
334: JDialog jd = (JDialog) dialog;
335: jd
336: .getRootPane()
337: .setDefaultButton(
338: getButtons()[0].isEnabled() ? getButtons()[0]
339: : null);
340: }
341: return;
342:
343: case OPEN:
344: int selIndex = getResultList().getSelectedIndex();
345: if (selIndex >= 0) {
346: openSource(getResultList().getModel().getElementAt(
347: selIndex));
348: setDialogVisible(false);
349: }
350: return;
351: }
352:
353: // regular evaluator behavior
354: try {
355: while (!exit) {
356: if (exp != null && !exp.equals(lastExp)) {
357: lastExp = exp;
358: if (lastExp != null) {
359: List result = evaluate(lastExp);
360:
361: if (lastExp == exp) {
362: populate(result);
363: }
364: }
365:
366: }
367:
368: synchronized (Evaluator.this ) {
369: if (exp != null && exp.equals(lastExp) && open) {
370: JavaFastOpen.this .open();
371: this .open = false;
372: }
373: }
374:
375: sleep(200);
376: }
377:
378: } catch (InterruptedException e) {
379: }
380: }
381:
382: }
383:
384: }
|