KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > swingui > Main


1 /* Main Copyright (C) 1999-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; see the file COPYING. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: Main.java.in,v 1.6.2.4 2002/05/28 17:34:19 hoenicke Exp $
18  */

19
20 package jode.swingui;
21 import jode.GlobalOptions;
22 import jode.decompiler.Decompiler;
23 import jode.decompiler.ProgressListener;
24
25 import javax.swing.*;
26 import javax.swing.event.*;
27 import javax.swing.tree.*;
28
29 import java.awt.*;
30 import java.awt.event.*;
31 import java.io.*;
32
33 public class Main
34     implements ActionListener, Runnable JavaDoc, TreeSelectionListener {
35     Decompiler decompiler;
36     JFrame frame;
37     JTree classTree;
38     JPanel statusLine;
39     PackagesTreeModel packModel;
40     HierarchyTreeModel hierModel;
41     JTextArea sourcecodeArea, errorArea;
42     Thread JavaDoc decompileThread;
43     String JavaDoc currentClassPath, lastClassName;
44
45     JProgressBar progressBar;
46
47     boolean hierarchyTree;
48
49     public Main(String JavaDoc classpath) {
50         decompiler = new Decompiler();
51     setClassPath(classpath);
52     frame = new JFrame(GlobalOptions.copyright);
53     fillContentPane(frame.getContentPane());
54     addMenu(frame);
55     frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
56     frame.addWindowListener(new WindowAdapter() {
57         public void windowClosing(WindowEvent e) {
58         System.exit(0);
59         }
60     });
61     }
62
63     public void show() {
64     frame.pack();
65     frame.show();
66     }
67
68     public void fillContentPane(Container contentPane) {
69     statusLine = new JPanel();
70     hierarchyTree = false;
71     packModel = new PackagesTreeModel(this);
72     hierModel = null;
73     Font monospaced = new Font("monospaced", Font.PLAIN, 12);
74     classTree = new JTree(packModel);
75     classTree.setRootVisible(false);
76     DefaultTreeSelectionModel selModel = new DefaultTreeSelectionModel();
77     selModel.setSelectionMode(selModel.SINGLE_TREE_SELECTION);
78     classTree.setSelectionModel(selModel);
79     classTree.addTreeSelectionListener(this);
80         JScrollPane spClassTree = new JScrollPane(classTree);
81     sourcecodeArea = new JTextArea(20, 80);
82     sourcecodeArea.setEditable(false);
83     sourcecodeArea.setFont(monospaced);
84     JScrollPane spText = new JScrollPane(sourcecodeArea);
85     errorArea = new JTextArea(3, 80);
86     errorArea.setEditable(false);
87     errorArea.setFont(monospaced);
88     JScrollPane spError = new JScrollPane(errorArea);
89
90     JSplitPane rightPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
91                           spText, spError);
92     JSplitPane allPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
93                         spClassTree, rightPane);
94     contentPane.setLayout(new BorderLayout());
95     contentPane.add(allPane, BorderLayout.CENTER);
96     contentPane.add(statusLine, BorderLayout.SOUTH);
97     progressBar = new JProgressBar();
98     statusLine.add(progressBar);
99     rightPane.setDividerLocation(300);
100     rightPane.setDividerSize(4);
101     allPane.setDividerLocation(200);
102     allPane.setDividerSize(4);
103     decompiler.setErr(new PrintWriter
104         (new BufferedWriter(new AreaWriter(errorArea)), true));
105     }
106
107     public synchronized void valueChanged(TreeSelectionEvent e) {
108     if (decompileThread != null)
109         return;
110     TreePath path = e.getNewLeadSelectionPath();
111     if (path == null)
112         return;
113     Object JavaDoc node = path.getLastPathComponent();
114     if (node != null) {
115         if (hierarchyTree && hierModel.isValidClass(node))
116         lastClassName = hierModel.getFullName(node);
117         else if (!hierarchyTree && packModel.isValidClass(node))
118         lastClassName = packModel.getFullName(node);
119         else
120         return;
121         
122         startDecompiler();
123     }
124     }
125
126     public void actionPerformed(ActionEvent e) {
127     if (e.getSource() == classTree)
128         startDecompiler();
129     }
130
131     public synchronized void startDecompiler() {
132     if (decompileThread == null) {
133         decompileThread = new Thread JavaDoc(this);
134         decompileThread.setPriority(Thread.MIN_PRIORITY);
135         
136         progressBar.setMinimum(0);
137         progressBar.setMaximum(1000);
138         progressBar.setString("decompiling");
139         progressBar.setStringPainted(true);
140         decompileThread.start();
141     }
142     }
143
144     public class AreaWriter extends Writer {
145     boolean initialized = false;
146     boolean lastCR = false;
147     private JTextArea area;
148
149     public AreaWriter(JTextArea a) {
150         area = a;
151     }
152
153     public void write(char[] b, int off, int len) throws IOException {
154         /* Note that setText and append are thread safe! */
155         if (!initialized) {
156         area.setText("");
157         initialized = true;
158         }
159         String JavaDoc str = new String JavaDoc(b, off, len);
160         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(len);
161         while (str != null && str.length() > 0) {
162         if (lastCR && str.charAt(0) == '\n')
163             str = str.substring(1);
164         int crIndex = str.indexOf('\r');
165         if (crIndex >= 0) {
166             sb.append(str.substring(0, crIndex));
167             sb.append("\n");
168             str = str.substring(crIndex+1);
169             lastCR = true;
170         } else {
171             sb.append(str);
172             str = null;
173         }
174         }
175         area.append(sb.toString());
176     }
177
178     public void flush() {
179     }
180
181     public void close() {
182     }
183     }
184
185     public void run() {
186     errorArea.setText("");
187     Writer writer = new BufferedWriter
188         (new AreaWriter(sourcecodeArea), 1024);
189
190     ProgressListener progListener = new ProgressListener()
191         {
192         public void updateProgress(final double progress,
193                        final String JavaDoc detail) {
194             SwingUtilities.invokeLater(new Runnable JavaDoc()
195             {
196                 public void run() {
197                 progressBar.setValue((int)(1000 * progress));
198                 progressBar.setString(detail);
199                 }
200             });
201         }
202         };
203     try {
204         decompiler.decompile(lastClassName, writer, progListener);
205     } catch (Throwable JavaDoc t) {
206         try {
207         writer.write("\nException while decompiling:");
208         PrintWriter pw = new PrintWriter(writer);
209         t.printStackTrace(pw);
210         pw.flush();
211         } catch (IOException ex) {
212         /* Shouldn't happen, complain to stderr */
213         ex.printStackTrace();
214         }
215     } finally {
216         try {
217         writer.close();
218         } catch (IOException ex) {
219         /* ignore */
220         }
221         synchronized(this) {
222         decompileThread = null;
223         }
224     }
225     SwingUtilities.invokeLater(new Runnable JavaDoc()
226         {
227         public void run() {
228             progressBar.setValue(0);
229             progressBar.setString("");
230         }
231         });
232     }
233
234     public void addMenu(JFrame frame) {
235     JMenuBar bar = new JMenuBar();
236     JMenu menu;
237     JMenuItem item;
238     menu = new JMenu("File");
239     item = new JMenuItem("Garbage collect");
240     item.addActionListener(new ActionListener() {
241         public void actionPerformed(ActionEvent ev) {
242         System.gc();
243         System.runFinalization();
244         }
245     });
246     menu.add(item);
247     item = new JMenuItem("Exit");
248     item.addActionListener(new ActionListener() {
249         public void actionPerformed(ActionEvent ev) {
250         System.exit(0);
251         }
252     });
253     menu.add(item);
254     bar.add(menu);
255     menu = new JMenu("Options");
256     final JCheckBoxMenuItem hierItem
257         = new JCheckBoxMenuItem("Class hierarchy", hierarchyTree);
258     hierItem.addActionListener(new ActionListener() {
259         public void actionPerformed(ActionEvent ev) {
260         hierarchyTree = hierItem.isSelected();
261         if (hierarchyTree && hierModel == null) {
262             hierModel = new HierarchyTreeModel(Main.this, progressBar);
263             reselect();
264         }
265         classTree.setModel(hierarchyTree
266                    ? (TreeModel) hierModel : packModel);
267         if (lastClassName != null) {
268             TreePath lastPath = (hierarchyTree
269                      ? hierModel.getPath(lastClassName)
270                      : packModel.getPath(lastClassName));
271             classTree.setSelectionPath(lastPath);
272             classTree.scrollPathToVisible(lastPath);
273         }
274         }
275     });
276     menu.add(hierItem);
277     menu.add(new JSeparator());
278     item = new JMenuItem("Set classpath...");
279     item.addActionListener(new ActionListener() {
280         public void actionPerformed(ActionEvent ev) {
281         
282         String JavaDoc newClassPath = (String JavaDoc) JOptionPane.showInputDialog
283             (null, "New classpath:", null,
284              JOptionPane.QUESTION_MESSAGE, null,
285              null, currentClassPath);
286         if (newClassPath != null
287             && !newClassPath.equals(currentClassPath))
288             setClassPath(newClassPath);
289         }
290     });
291     menu.add(item);
292     item = new JMenuItem("Reload classpath");
293     item.addActionListener(new ActionListener() {
294         public void actionPerformed(ActionEvent ev) {
295         setClassPath(currentClassPath);
296         }
297     });
298     menu.add(item);
299     bar.add(menu);
300     frame.setJMenuBar(bar);
301     }
302
303     public void setClassPath(String JavaDoc classpath) {
304     if (classpath == null || classpath.length() == 0)
305         classpath = ".";
306     currentClassPath = classpath;
307     jode.bytecode.ClassInfo.setClassPath(classpath);
308     decompiler.setClassPath(classpath);
309     if (classTree != null)
310         classTree.clearSelection();
311     if (packModel != null)
312         packModel.rebuild();
313     if (hierModel != null && hierarchyTree) {
314         hierModel.rebuild();
315     } else {
316         hierModel = null;
317     }
318     }
319
320     public void treeNodesChanged(TreeModelEvent e) {
321     reselect();
322     }
323
324     public void treeNodesInserted(TreeModelEvent e) {
325     reselect();
326     }
327
328     public void treeNodesRemoved(TreeModelEvent e) {
329     reselect();
330     }
331
332     public void treeStructureChanged(TreeModelEvent e) {
333     reselect();
334     }
335
336     public void reselect() {
337     if (lastClassName != null) {
338         TreePath lastPath = (hierarchyTree
339                  ? hierModel.getPath(lastClassName)
340                  : packModel.getPath(lastClassName));
341         if (lastPath != null) {
342         classTree.setSelectionPath(lastPath);
343         classTree.scrollPathToVisible(lastPath);
344         }
345     }
346     }
347     
348     public static void usage() {
349     System.err.println("Usage: java jode.swingui.Main [CLASSPATH]");
350     System.err.println("The directories in CLASSPATH should be separated by ','.");
351     System.err.println("If no CLASSPATH is given the virtual machine classpath is used.");
352     }
353
354     public static void main(String JavaDoc[] params) {
355     String JavaDoc cp = System.getProperty("java.class.path", "");
356     cp = cp.replace(File.pathSeparatorChar,
357             Decompiler.altPathSeparatorChar);
358     String JavaDoc bootClassPath = System.getProperty("sun.boot.class.path");
359     if (bootClassPath != null)
360         cp += Decompiler.altPathSeparatorChar
361         + bootClassPath.replace(File.pathSeparatorChar,
362                     Decompiler.altPathSeparatorChar);
363     int i = 0;
364     if (i < params.length) {
365         if (params[i].equals("--classpath")
366         || params[i].equals("--cp")
367         || params[i].equals("-c"))
368         cp = params[++i];
369         else if (params[i].startsWith("-")) {
370         if (!params[i].equals("--help")
371             && !params[i].equals("-h"))
372         System.err.println("Unknown option: "+params[i]);
373         usage();
374         return;
375         } else
376         cp = params[i];
377         i++;
378     }
379     if (i < params.length) {
380         System.err.println("Too many arguments.");
381         usage();
382         return;
383     }
384     Main win = new Main(cp);
385     win.show();
386     }
387 }
388
Popular Tags