001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.languages.features;
043:
044: import java.awt.Component;
045: import java.awt.Image;
046: import java.awt.event.KeyEvent;
047: import java.awt.event.KeyListener;
048: import java.util.Iterator;
049: import javax.swing.JComponent;
050: import javax.swing.event.CaretEvent;
051: import javax.swing.event.CaretListener;
052: import javax.swing.tree.DefaultMutableTreeNode;
053: import javax.swing.tree.DefaultTreeCellRenderer;
054: import java.awt.event.MouseEvent;
055: import java.awt.event.MouseListener;
056: import java.io.IOException;
057: import java.util.HashMap;
058: import java.util.Map;
059: import javax.swing.Icon;
060: import javax.swing.ImageIcon;
061: import javax.swing.JEditorPane;
062: import javax.swing.JLabel;
063: import javax.swing.JScrollPane;
064: import javax.swing.JTree;
065: import javax.swing.SwingUtilities;
066: import javax.swing.ToolTipManager;
067: import javax.swing.tree.TreePath;
068:
069: import org.netbeans.spi.navigator.NavigatorPanel;
070: import org.netbeans.modules.editor.NbEditorDocument;
071: import org.netbeans.modules.languages.LanguagesManager;
072: import org.openide.cookies.EditorCookie;
073: import org.openide.cookies.LineCookie;
074: import org.openide.loaders.DataObject;
075: import org.openide.util.Lookup;
076: import org.openide.util.Lookup.Result;
077: import org.openide.util.LookupEvent;
078: import org.openide.util.LookupListener;
079: import org.openide.util.Utilities;
080: import org.openide.loaders.DataObject;
081:
082: /**
083: *
084: * @author Jan Jancura
085: */
086: public class LanguagesNavigator implements NavigatorPanel {
087:
088: /** holds UI of this panel */
089: private JComponent panelUI;
090: private JTree tree;
091: private MyLookupListener lookupListener;
092:
093: public String getDisplayHint() {
094: return "This is Navigator";
095: }
096:
097: public String getDisplayName() {
098: return "Navigator";
099: }
100:
101: public JComponent getComponent() {
102: if (panelUI == null) {
103: tree = new JTree() {
104: public String getToolTipText(MouseEvent ev) {
105: TreePath path = tree.getPathForLocation(ev.getX(),
106: ev.getY());
107: if (path == null)
108: return null;
109: Object node = path.getLastPathComponent();
110: LanguagesNavigatorModel model = (LanguagesNavigatorModel) tree
111: .getModel();
112: return model.getTooltip(node);
113: }
114: };
115: ToolTipManager.sharedInstance().registerComponent(tree);
116: tree.setRootVisible(false);
117: tree.setShowsRootHandles(true);
118: Listener listener = new Listener();
119: tree.addMouseListener(listener);
120: tree.addKeyListener(listener);
121: tree.setToggleClickCount(Integer.MAX_VALUE); // [PENDING]
122: tree.setModel(new LanguagesNavigatorModel());
123: tree.setCellRenderer(new Renderer());
124: /*
125: tree.addTreeSelectionListener (new TreeSelectionListener () {
126: public void valueChanged (TreeSelectionEvent e) {
127: selectionChanged ();
128: }
129: });
130: tree.addFocusListener (new FocusListener () {
131: public void focusGained (FocusEvent e) {
132: selectionChanged ();
133: }
134: public void focusLost (FocusEvent e) {
135: selectionChanged ();
136: }
137: });
138: */
139: panelUI = new JScrollPane(tree);
140: }
141: return panelUI;
142: }
143:
144: public void panelActivated(Lookup context) {
145: getComponent();
146: Result<DataObject> result = context
147: .<DataObject> lookupResult(DataObject.class);
148: DataObject dataObject = result.allInstances().iterator().next();
149:
150: if (lookupListener != null)
151: lookupListener.remove();
152: lookupListener = new MyLookupListener(result);
153:
154: setDataObject(dataObject);
155: }
156:
157: public void panelDeactivated() {
158: if (lastEditor != null)
159: lastEditor.removeCaretListener(caretListener);
160: lastEditor = null;
161: }
162:
163: public Lookup getLookup() {
164: return null;
165: }
166:
167: // other methods ...........................................................
168:
169: private DataObject dataObject;
170:
171: private void setDataObject(DataObject dataObject) {
172: if (this .dataObject == dataObject)
173: return;
174: final EditorCookie ec = dataObject
175: .getCookie(EditorCookie.class);
176: if (ec == null)
177: return;
178: LanguagesNavigatorModel model = (LanguagesNavigatorModel) tree
179: .getModel();
180: try {
181: NbEditorDocument document = (NbEditorDocument) ec
182: .openDocument();
183: String mimeType = (String) document.getProperty("mimeType");
184: if (mimeType == null)
185: return;
186: if (!LanguagesManager.getDefault().isSupported(mimeType))
187: return;
188: model.setContext(document);
189: } catch (IOException ex) {
190: model.setContext(null);
191: }
192: SwingUtilities.invokeLater(new Runnable() {
193: public void run() {
194: if (ec.getOpenedPanes() != null
195: && ec.getOpenedPanes().length > 0)
196: setCurrentEditor(ec.getOpenedPanes()[0]);
197: else
198: setCurrentEditor(null);
199: }
200: });
201: }
202:
203: private JEditorPane lastEditor;
204: private MyCaretListener caretListener;
205:
206: private void setCurrentEditor(JEditorPane editor) {
207: if (caretListener == null)
208: caretListener = new MyCaretListener();
209: if (lastEditor != null)
210: lastEditor.removeCaretListener(caretListener);
211: lastEditor = editor;
212: if (lastEditor != null)
213: lastEditor.addCaretListener(caretListener);
214: }
215:
216: // highlight selected node in editor ...
217:
218: // private Document highlightedDocument = null;
219: // private Object highlighted = null;
220: // private JEditorPane highlightedEditor = null;
221: //
222: // private void selectionChanged () {
223: // removeHighlight ();
224: // if (!tree.hasFocus ()) return;
225: // TreePath selPath = tree.getSelectionPath ();
226: // if (selPath == null) return;
227: // Object selObj = selPath.getLastPathComponent ();
228: // if (selObj == null || !(selObj instanceof NavigatorNode))
229: // return;
230: // NavigatorNode node = (NavigatorNode)selObj;
231: // if (node.line == null) return;
232: // node.line.show (Line.SHOW_SHOW, node.column);
233: // //S ystem.out.println ("highlight " + lastDocument + " : " + lastEditor);
234: // highlighted = node.item;
235: // Highlighting.getHighlighting (highlightedDocument = lastDocument).
236: // highlight (node.item, getHighlightAS ());
237: // DataObject dataObject = (DataObject) node.line.getLookup ().
238: // lookup (DataObject.class);
239: // EditorCookie ec = (EditorCookie) dataObject.getCookie
240: // (EditorCookie.class);
241: // highlightedEditor = ec.getOpenedPanes () [0];
242: // highlightedEditor.repaint ();
243: // }
244: //
245: // private void removeHighlight () {
246: // if (highlighted == null) return;
247: // if (highlighted instanceof ASTToken)
248: // Highlighting.getHighlighting (highlightedDocument).removeHighlight
249: // ((ASTToken) highlighted);
250: // else
251: // Highlighting.getHighlighting (highlightedDocument).removeHighlight
252: // ((ASTNode) highlighted);
253: // highlightedEditor.repaint ();
254: // highlighted = null;
255: // highlightedDocument = null;
256: // highlightedEditor = null;
257: // }
258: //
259: // private static AttributeSet highlightAS = null;
260: //
261: // private static AttributeSet getHighlightAS () {
262: // if (highlightAS == null) {
263: // SimpleAttributeSet as = new SimpleAttributeSet ();
264: // as.addAttribute (StyleConstants.Background, Color.yellow); //new Color (230, 230, 230));
265: // highlightAS = as;
266: // }
267: // return highlightAS;
268: // }
269:
270: // innerclasses ............................................................
271:
272: static class Renderer extends DefaultTreeCellRenderer {
273:
274: public Component getTreeCellRendererComponent(JTree tree,
275: Object value, boolean sel, boolean expanded,
276: boolean leaf, int row, boolean hasFocus) {
277: JLabel l = (JLabel) super .getTreeCellRendererComponent(
278: tree, value, sel, expanded, leaf, row, hasFocus);
279:
280: if (value instanceof DefaultMutableTreeNode) {
281: l.setIcon(null);
282: l.setText((String) ((DefaultMutableTreeNode) value)
283: .getUserObject());
284: return l;
285: }
286: LanguagesNavigatorModel model = (LanguagesNavigatorModel) tree
287: .getModel();
288: l.setIcon(getCIcon(model.getIcon(value)));
289: l.setText(model.getDisplayName(value));
290: return l;
291: }
292:
293: private static Map<String, Icon> icons = new HashMap<String, Icon>();
294:
295: private static Icon getCIcon(String resourceName) {
296: if (resourceName == null)
297: return null;
298: if (!icons.containsKey(resourceName)) {
299: Image image = Utilities.loadImage(resourceName);
300: if (image == null)
301: image = Utilities
302: .loadImage("org/netbeans/modules/languages/resources/node.gif");
303: icons.put(resourceName, new ImageIcon(image));
304: }
305: return icons.get(resourceName);
306: }
307: }
308:
309: class Listener implements MouseListener, KeyListener {
310:
311: public void mouseClicked(MouseEvent ev) {
312: if (ev.getClickCount() != 2)
313: return;
314: TreePath path = tree.getPathForLocation(ev.getX(), ev
315: .getY());
316: if (path == null)
317: return;
318: Object node = path.getLastPathComponent();
319: LanguagesNavigatorModel model = (LanguagesNavigatorModel) tree
320: .getModel();
321: model.show(node);
322: }
323:
324: public void mouseEntered(MouseEvent e) {
325: }
326:
327: public void mouseExited(MouseEvent e) {
328: }
329:
330: public void mousePressed(MouseEvent e) {
331: }
332:
333: public void mouseReleased(MouseEvent e) {
334: }
335:
336: public void keyTyped(KeyEvent e) {
337: }
338:
339: public void keyPressed(KeyEvent e) {
340: if (e.getKeyCode() != 10)
341: return; // ENTER pressed?
342: TreePath path = tree.getSelectionPath();
343: if (path == null)
344: return;
345: Object node = path.getLastPathComponent();
346: LanguagesNavigatorModel model = (LanguagesNavigatorModel) tree
347: .getModel();
348: model.show(node);
349: }
350:
351: public void keyReleased(KeyEvent e) {
352: }
353: }
354:
355: class MyCaretListener implements CaretListener {
356:
357: public void caretUpdate(CaretEvent e) {
358: LanguagesNavigatorModel model = (LanguagesNavigatorModel) tree
359: .getModel();
360: TreePath treePath = model.getTreePath(e.getDot());
361: if (treePath == null)
362: return;
363: tree.setSelectionPath(treePath);
364: tree.scrollPathToVisible(treePath);
365: }
366: }
367:
368: class MyLookupListener implements LookupListener {
369:
370: private Result<DataObject> result;
371:
372: MyLookupListener(Result<DataObject> result) {
373: this .result = result;
374: result.addLookupListener(this );
375: }
376:
377: void remove() {
378: result.removeLookupListener(this );
379: }
380:
381: public void resultChanged(LookupEvent ev) {
382: Iterator<? extends DataObject> it = result.allInstances()
383: .iterator();
384: if (!it.hasNext())
385: setDataObject(null);
386: else
387: setDataObject(it.next());
388: }
389: }
390: }
|