Main.java :  » Development » jode » jode » swingui » Java Open Source

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

package jode.swingui;
import jode.GlobalOptions;
import jode.decompiler.Decompiler;
import jode.decompiler.ProgressListener;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class Main 
    implements ActionListener, Runnable, TreeSelectionListener {
    Decompiler decompiler;
    JFrame frame;
    JTree classTree;
    JPanel statusLine;
    PackagesTreeModel packModel;
    HierarchyTreeModel hierModel;
    JTextArea  sourcecodeArea, errorArea;
    Thread decompileThread;
    String currentClassPath, lastClassName;

    JProgressBar progressBar;

    boolean hierarchyTree;

    public Main(String classpath) {
        decompiler = new Decompiler();
  setClassPath(classpath);
  frame = new JFrame(GlobalOptions.copyright);
  fillContentPane(frame.getContentPane());
  addMenu(frame);
  frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
  frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
    System.exit(0);
      }
  });
    }

    public void show() {
  frame.pack();
  frame.show();
    }

    public void fillContentPane(Container contentPane) {
  statusLine = new JPanel();
  hierarchyTree = false;
  packModel = new PackagesTreeModel(this);
  hierModel = null;
  Font monospaced = new Font("monospaced", Font.PLAIN, 12);
  classTree = new JTree(packModel);
  classTree.setRootVisible(false);
  DefaultTreeSelectionModel selModel = new DefaultTreeSelectionModel();
  selModel.setSelectionMode(selModel.SINGLE_TREE_SELECTION);
  classTree.setSelectionModel(selModel);
  classTree.addTreeSelectionListener(this);
        JScrollPane spClassTree = new JScrollPane(classTree);
  sourcecodeArea = new JTextArea(20, 80);
  sourcecodeArea.setEditable(false);
  sourcecodeArea.setFont(monospaced);
  JScrollPane spText = new JScrollPane(sourcecodeArea);
  errorArea = new JTextArea(3, 80);
  errorArea.setEditable(false);
  errorArea.setFont(monospaced);
  JScrollPane spError = new JScrollPane(errorArea);

  JSplitPane rightPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
                spText, spError);
  JSplitPane allPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
              spClassTree, rightPane);
  contentPane.setLayout(new BorderLayout());
  contentPane.add(allPane, BorderLayout.CENTER);
  contentPane.add(statusLine, BorderLayout.SOUTH);
  progressBar = new JProgressBar();
  statusLine.add(progressBar);
  rightPane.setDividerLocation(300);
  rightPane.setDividerSize(4);
  allPane.setDividerLocation(200);
  allPane.setDividerSize(4);
  decompiler.setErr(new PrintWriter
      (new BufferedWriter(new AreaWriter(errorArea)), true));
    }

    public synchronized void valueChanged(TreeSelectionEvent e) {
  if (decompileThread != null)
      return;
  TreePath path = e.getNewLeadSelectionPath();
  if (path == null)
      return;
  Object node = path.getLastPathComponent();
  if (node != null) {
      if (hierarchyTree && hierModel.isValidClass(node))
    lastClassName = hierModel.getFullName(node);
      else if (!hierarchyTree && packModel.isValidClass(node))
    lastClassName = packModel.getFullName(node);
      else
    return;
      
      startDecompiler();
  }
    }

    public void actionPerformed(ActionEvent e) {
  if (e.getSource() == classTree)
      startDecompiler();
    }

    public synchronized void startDecompiler() {
  if (decompileThread == null) {
      decompileThread = new Thread(this);
      decompileThread.setPriority(Thread.MIN_PRIORITY);
      
      progressBar.setMinimum(0);
      progressBar.setMaximum(1000);
      progressBar.setString("decompiling");
      progressBar.setStringPainted(true);
      decompileThread.start();
  }
    }

    public class AreaWriter extends Writer {
  boolean initialized = false;
  boolean lastCR = false;
  private JTextArea area;

  public AreaWriter(JTextArea a) {
      area = a;
  }

  public void write(char[] b, int off, int len) throws IOException {
      /* Note that setText and append are thread safe! */
      if (!initialized) {
    area.setText("");
    initialized = true;
      }
      String str = new String(b, off, len);
      StringBuffer sb = new StringBuffer(len);
      while (str != null && str.length() > 0) {
    if (lastCR && str.charAt(0) == '\n')
        str = str.substring(1);
    int crIndex = str.indexOf('\r');
    if (crIndex >= 0) {
        sb.append(str.substring(0, crIndex));
        sb.append("\n");
        str = str.substring(crIndex+1);
        lastCR = true;
    } else {
        sb.append(str);
        str = null;
    }
      }
      area.append(sb.toString());
  }

  public void flush() {
  }

  public void close() {
  }
    }

    public void run() {
  errorArea.setText("");
  Writer writer = new BufferedWriter
      (new AreaWriter(sourcecodeArea), 1024);

  ProgressListener progListener = new ProgressListener()
      {
    public void updateProgress(final double progress, 
             final String detail) {
        SwingUtilities.invokeLater(new Runnable() 
      {
          public void run() {
        progressBar.setValue((int)(1000 * progress));
        progressBar.setString(detail);
          }
      });
    }
      };
  try {
      decompiler.decompile(lastClassName, writer, progListener);
  } catch (Throwable t) {
      try {
    writer.write("\nException while decompiling:");
    PrintWriter pw = new PrintWriter(writer);
    t.printStackTrace(pw);
    pw.flush();
      } catch (IOException ex) {
    /* Shouldn't happen, complain to stderr */
    ex.printStackTrace();
      }
  } finally {
      try {
    writer.close();
      } catch (IOException ex) {
    /* ignore */
      }
      synchronized(this) {
    decompileThread = null;
      }
  }
  SwingUtilities.invokeLater(new Runnable()
      {
    public void run() {
        progressBar.setValue(0);
        progressBar.setString("");
    }
      });
    }

    public void addMenu(JFrame frame) {
  JMenuBar bar = new JMenuBar();
  JMenu menu;
  JMenuItem item;
  menu = new JMenu("File");
  item = new JMenuItem("Garbage collect");
  item.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
    System.gc();
    System.runFinalization();
      }
  });
  menu.add(item);
  item = new JMenuItem("Exit");
  item.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
    System.exit(0);
      }
  });
  menu.add(item);
  bar.add(menu);
  menu = new JMenu("Options");
  final JCheckBoxMenuItem hierItem
      = new JCheckBoxMenuItem("Class hierarchy", hierarchyTree);
  hierItem.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
    hierarchyTree = hierItem.isSelected();
    if (hierarchyTree && hierModel == null) {
        hierModel = new HierarchyTreeModel(Main.this, progressBar);
        reselect();
    }
    classTree.setModel(hierarchyTree
           ? (TreeModel) hierModel : packModel);
    if (lastClassName != null) {
        TreePath lastPath = (hierarchyTree
           ? hierModel.getPath(lastClassName)
           : packModel.getPath(lastClassName));
        classTree.setSelectionPath(lastPath);
        classTree.scrollPathToVisible(lastPath);
    }
      }
  });
  menu.add(hierItem);
  menu.add(new JSeparator());
  item = new JMenuItem("Set classpath...");
  item.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
    
    String newClassPath = (String) JOptionPane.showInputDialog
        (null, "New classpath:", null, 
         JOptionPane.QUESTION_MESSAGE, null,
         null, currentClassPath);
    if (newClassPath != null
        && !newClassPath.equals(currentClassPath))
        setClassPath(newClassPath);
      }
  });
  menu.add(item);
  item = new JMenuItem("Reload classpath");
  item.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
    setClassPath(currentClassPath);
      }
  });
  menu.add(item);
  bar.add(menu);
  frame.setJMenuBar(bar);
    }

    public void setClassPath(String classpath) {
  if (classpath == null || classpath.length() == 0)
      classpath = ".";
  currentClassPath = classpath;
  jode.bytecode.ClassInfo.setClassPath(classpath);
  decompiler.setClassPath(classpath);
  if (classTree != null)
      classTree.clearSelection();
  if (packModel != null)
      packModel.rebuild();
  if (hierModel != null && hierarchyTree) {
      hierModel.rebuild();
  } else {
      hierModel = null;
  }
    }

    public void treeNodesChanged(TreeModelEvent e) {
  reselect();
    }

    public void treeNodesInserted(TreeModelEvent e) {
  reselect();
    }

    public void treeNodesRemoved(TreeModelEvent e) {
  reselect();
    }

    public void treeStructureChanged(TreeModelEvent e) {
  reselect();
    }

    public void reselect() {
  if (lastClassName != null) {
      TreePath lastPath = (hierarchyTree
         ? hierModel.getPath(lastClassName)
         : packModel.getPath(lastClassName));
      if (lastPath != null) {
    classTree.setSelectionPath(lastPath);
    classTree.scrollPathToVisible(lastPath);
      }
  }
    }
    
    public static void usage() {
  System.err.println("Usage: java jode.swingui.Main [CLASSPATH]");
  System.err.println("The directories in CLASSPATH should be separated by ','.");
  System.err.println("If no CLASSPATH is given the virtual machine classpath is used.");
    }

    public static void main(String[] params) {
  String cp = System.getProperty("java.class.path", "");
  cp = cp.replace(File.pathSeparatorChar, 
      Decompiler.altPathSeparatorChar);
  String bootClassPath = System.getProperty("sun.boot.class.path");
  if (bootClassPath != null)
      cp += Decompiler.altPathSeparatorChar
    + bootClassPath.replace(File.pathSeparatorChar, 
          Decompiler.altPathSeparatorChar);
  int i = 0;
  if (i < params.length) {
      if (params[i].equals("--classpath")
    || params[i].equals("--cp")
    || params[i].equals("-c"))
    cp = params[++i];
      else if (params[i].startsWith("-")) {
    if (!params[i].equals("--help")
        && !params[i].equals("-h"))
    System.err.println("Unknown option: "+params[i]);
    usage();
    return;
      } else
    cp = params[i];
      i++;
  }
  if (i < params.length) {
      System.err.println("Too many arguments.");
      usage();
      return;
  }
  Main win = new Main(cp);
  win.show();
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.