001: /*
002: This library is free software; you can redistribute it and/or
003: modify it under the terms of the GNU General Public
004: License as published by the Free Software Foundation; either
005: version 2 of the license, or (at your option) any later version.
006: */
007:
008: package org.gjt.jclasslib.nbmodule;
009:
010: import org.gjt.jclasslib.browser.*;
011: import org.gjt.jclasslib.browser.config.window.BrowserPath;
012: import org.gjt.jclasslib.io.ClassFileReader;
013: import org.gjt.jclasslib.structures.ClassFile;
014: import org.openide.*;
015: import org.openide.filesystems.*;
016: import org.openide.filesystems.FileSystem;
017: import org.openide.nodes.Node;
018: import org.openide.text.CloneableEditorSupport;
019: import org.openide.windows.*;
020:
021: import javax.swing.*;
022: import java.awt.*;
023: import java.awt.event.ActionEvent;
024: import java.beans.BeanInfo;
025: import java.io.*;
026: import java.util.HashMap;
027:
028: /**
029: Parent component for a class file browser in Netbeans.
030:
031: @author <a href="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>
032: @version $Revision: 1.9 $ $Date: 2004/02/10 16:06:56 $
033: */
034: public class ClassFileViewer extends TopComponent implements
035: BrowserServices {
036:
037: private static HashMap fileObjectToClassFileViewer = new HashMap();
038:
039: private static final String VERSION = "1.2";
040:
041: private FileObject fo;
042: private ClassFileNode node;
043: private boolean initialized = false;
044: private ClassFile classFile;
045:
046: private Action actionBackward;
047: private Action actionForward;
048: private Action actionReload;
049:
050: private BrowserComponent browserComponent;
051:
052: /**
053: Retrieve an already opened <tt>ClassFileViewer</tt> or create
054: a new one if necessary.
055: @param fo the <tt>FileObject</tt> for which to create a
056: <tt>ClassFileViewer</tt>
057: @return the <tt>ClassFileViewer</tt>
058: */
059: public static ClassFileViewer getCachedClassFileViewer(FileObject fo) {
060:
061: if (fileObjectToClassFileViewer.containsKey(fo)) {
062: return (ClassFileViewer) fileObjectToClassFileViewer
063: .get(fo);
064: } else {
065: ClassFileViewer viewer = new ClassFileViewer(fo);
066: fileObjectToClassFileViewer.put(fo, viewer);
067: return viewer;
068: }
069: }
070:
071: /**
072: * Constructor.
073: */
074: public ClassFileViewer() {
075: setCloseOperation(CLOSE_EACH);
076: }
077:
078: private ClassFileViewer(FileObject fo) {
079:
080: this ();
081: this .fo = fo;
082: node = new ClassFileNode(fo);
083: setActivatedNodes(new Node[] { node });
084:
085: }
086:
087: public boolean canClose(Workspace workspace, boolean last) {
088:
089: fileObjectToClassFileViewer.remove(fo);
090: return true;
091: }
092:
093: public Image getIcon() {
094:
095: if (node != null) {
096: return node.getIcon(BeanInfo.ICON_COLOR_16x16);
097: } else {
098: return null;
099: }
100:
101: }
102:
103: public void open(Workspace ws) {
104:
105: init();
106: if (ws == null) {
107: ws = WindowManager.getDefault().getCurrentWorkspace();
108: }
109: Mode mode = ws.findMode(CloneableEditorSupport.EDITOR_MODE);
110: if (mode != null) {
111: mode.dockInto(this );
112: }
113: super .open(ws);
114: }
115:
116: public void writeExternal(ObjectOutput out) throws IOException {
117: if (out == null) {
118: return;
119: }
120: if (node == null) {
121: out.writeBoolean(false);
122: return;
123: }
124: out.writeBoolean(true);
125: out.writeUTF(VERSION);
126: out.writeObject(node.getHandle());
127:
128: super .writeExternal(out);
129: }
130:
131: public void readExternal(ObjectInput in) throws IOException,
132: ClassNotFoundException {
133: if (in == null) {
134: return;
135: }
136: boolean valid = in.readBoolean();
137: if (!valid) {
138: return;
139: }
140: in.readUTF(); // version string
141: Node.Handle handle = (Node.Handle) in.readObject();
142: super .readExternal(in);
143:
144: node = (ClassFileNode) handle.getNode();
145: fo = node.getFileObject();
146: setActivatedNodes(new Node[] { node });
147: }
148:
149: // Browser services
150:
151: public ClassFile getClassFile() {
152: return classFile;
153: }
154:
155: public BrowserComponent getBrowserComponent() {
156: return browserComponent;
157: }
158:
159: public Action getActionBackward() {
160: return actionBackward;
161: }
162:
163: public Action getActionForward() {
164: return actionForward;
165: }
166:
167: public void openClassFile(String className, BrowserPath browserPath) {
168:
169: FileSystem targetFs = OpenAction.getTargetFileSystem(fo);
170: String classFileName = className.replace('.', '/') + ".class";
171: FileObject targetFo = targetFs.findResource(classFileName);
172: if (targetFo == null) {
173: targetFo = Repository.getDefault().findResource(
174: classFileName);
175: }
176: if (targetFo != null) {
177: OpenAction.openFileObject(targetFo, browserPath);
178: } else {
179: NotifyDescriptor desc = new NotifyDescriptor.Message(
180: "The class " + className + " could not be found.",
181: NotifyDescriptor.INFORMATION_MESSAGE);
182: TopManager.getDefault().notify(desc);
183: }
184: }
185:
186: public boolean canOpenClassFiles() {
187: return true;
188: }
189:
190: public void activate() {
191: // not applicable
192: }
193:
194: private synchronized void init() {
195:
196: if (initialized) {
197: return;
198: }
199:
200: if (!SwingUtilities.isEventDispatchThread()) {
201: SwingUtilities.invokeLater(new Runnable() {
202: public void run() {
203: init();
204: }
205: });
206: return;
207: }
208:
209: if (fo != null) {
210: setName(fo.getName());
211: }
212:
213: if (fo != null && !readClassFile()) {
214: this .close();
215: return;
216: }
217:
218: setupActions();
219: setupComponent();
220:
221: initialized = true;
222: }
223:
224: private boolean readClassFile() {
225: try {
226: classFile = ClassFileReader.readFromInputStream(fo
227: .getInputStream());
228: } catch (Exception ex) {
229: ErrorManager.getDefault()
230: .notify(ErrorManager.EXCEPTION, ex);
231: return false;
232: }
233: return true;
234: }
235:
236: private void setupActions() {
237:
238: actionBackward = new DefaultAction("Backward", BrowserMDIFrame
239: .loadIcon("browser_backward_small.png"));
240: actionBackward.putValue(Action.SHORT_DESCRIPTION,
241: "Move backward in the navigation history");
242: actionBackward.setEnabled(false);
243:
244: actionForward = new DefaultAction("Forward", BrowserMDIFrame
245: .loadIcon("browser_forward_small.png"));
246: actionForward.putValue(Action.SHORT_DESCRIPTION,
247: "Move forward in the navigation history");
248: actionForward.setEnabled(false);
249:
250: actionReload = new DefaultAction("Reload", BrowserMDIFrame
251: .loadIcon("reload_small.png"));
252: actionReload.putValue(Action.SHORT_DESCRIPTION,
253: "Reload class file");
254: actionReload.setEnabled(true);
255:
256: }
257:
258: private void setupComponent() {
259:
260: setLayout(new BorderLayout());
261: browserComponent = new BrowserComponent(this );
262: add(buildToolbar(), BorderLayout.NORTH);
263: add(browserComponent, BorderLayout.CENTER);
264: }
265:
266: private JToolBar buildToolbar() {
267:
268: JToolBar toolBar = new JToolBar();
269: toolBar.add(actionBackward);
270: toolBar.add(actionForward);
271: toolBar.addSeparator();
272: toolBar.add(actionReload);
273:
274: toolBar.setFloatable(false);
275:
276: return toolBar;
277: }
278:
279: private class DefaultAction extends AbstractAction {
280:
281: private DefaultAction(String name, Icon icon) {
282: super (name, icon);
283: }
284:
285: public void actionPerformed(ActionEvent ev) {
286:
287: if (this == actionBackward) {
288: browserComponent.getHistory().historyBackward();
289: } else if (this == actionForward) {
290: browserComponent.getHistory().historyForward();
291: } else if (this == actionReload) {
292: readClassFile();
293: browserComponent.rebuild();
294: }
295: }
296: }
297:
298: }
|