Package net.sf.rej.gui

Source Code of net.sf.rej.gui.MainWindow

/* Copyright (C) 2004-2007 Sami Koivu
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
package net.sf.rej.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ButtonGroup;
import javax.swing.DefaultButtonModel;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.sf.rej.files.ClassIndex;
import net.sf.rej.files.ClassLocator;
import net.sf.rej.files.Project;
import net.sf.rej.gui.debug.DebugControlPanel;
import net.sf.rej.gui.dialog.ClassChooseDialog;
import net.sf.rej.gui.dialog.NewClassDialog;
import net.sf.rej.gui.editor.LineIdentifierMode;
import net.sf.rej.gui.event.Event;
import net.sf.rej.gui.event.EventDispatcher;
import net.sf.rej.gui.event.EventObserver;
import net.sf.rej.gui.event.EventType;
import net.sf.rej.gui.preferences.Preferences;
import net.sf.rej.gui.preferences.Settings;
import net.sf.rej.gui.split.BytecodeToHexSync;
import net.sf.rej.gui.split.ConstantPoolToHexSync;
import net.sf.rej.gui.split.HexSplit;
import net.sf.rej.gui.split.SplitMode;
import net.sf.rej.gui.split.StructureToHexSync;
import net.sf.rej.gui.tab.CompareTab;
import net.sf.rej.gui.tab.ConstantPoolTab;
import net.sf.rej.gui.tab.DebugTab;
import net.sf.rej.gui.tab.EditorTab;
import net.sf.rej.gui.tab.FilesTab;
import net.sf.rej.gui.tab.HexEditorTab;
import net.sf.rej.gui.tab.InjectionTab;
import net.sf.rej.gui.tab.NoDebugTab;
import net.sf.rej.gui.tab.ObfuscationTab;
import net.sf.rej.gui.tab.SearchTab;
import net.sf.rej.gui.tab.StructureTab;
import net.sf.rej.gui.tab.Tab;
import net.sf.rej.gui.tab.Tabbable;
import net.sf.rej.java.ClassFile;

/**
* Java Application entry point for running the reJ GUI.
* In other words, the class with the main method. Also the
* primary window of the GUI Editor.
*
* @author Sami Koivu
*/
public class MainWindow extends JFrame implements EventObserver {
    private static final long serialVersionUID = 1L;
   
    private static final Logger logger = Logger.getLogger(MainWindow.class.getName());

    static MainWindow instance;

    BorderLayout borderLayout1 = new BorderLayout();
    JToolBar toolbar = new JToolBar();
    JTabbedPane tabbedPane = new JTabbedPane();
    DebugControlPanel debugPanel = null;

    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu = null;
    JMenu recentFilesMenu = null;
    JLabel status = new JLabel();

    JSplitPane splitPane = null;
    SplitMode split = SplitMode.NONE;
    HexSplit hexSplit = new HexSplit();
   
    EventDispatcher dispatcher = new EventDispatcher();

    JFileChooser fd = new JFileChooser();
    private Project project = null;

    // Tabs
    private FilesTab filesTab = new FilesTab();
    private StructureTab structureTab = new StructureTab();
    private ConstantPoolTab constantPoolTab = new ConstantPoolTab();
    private EditorTab editorTab = new EditorTab();
    private InjectionTab injectionTab = new InjectionTab();
    private ObfuscationTab obfuscationTab = new ObfuscationTab();
    private SearchTab searchTab = new SearchTab();
    private CompareTab compareTab = new CompareTab();
    private Tabbable debugTab = createDebugTab();
    private HexEditorTab hexTab = new HexEditorTab();

    /**
     * Maps menu checkboxes to tabs, for setting tab visibility.
     */
  Map<JCheckBoxMenuItem, Tab> viewCheckBoxes = new HashMap<JCheckBoxMenuItem, Tab>();
   
    private Action tabViewAction = new AbstractAction() {
      public void actionPerformed(ActionEvent e) {
        JCheckBoxMenuItem checkBox = (JCheckBoxMenuItem) e.getSource();
        Tab tab = viewCheckBoxes.get(checkBox);
        Tabbable tabComponent = getTab(tab);
        boolean tabVisible = isTabVisible(tabComponent);
        try {
          if (checkBox.isSelected() && !tabVisible) {
            // display tab
            ensureTabIsVisible(tabComponent);
            Preferences prefs = SystemFacade.getInstance().getPreferences();
            prefs.setTabVisibility(tab, true);
            prefs.save();
          } else if (!checkBox.isSelected() && tabVisible) {
            // hide tab
            hideTab(tabComponent);
            Preferences prefs = SystemFacade.getInstance().getPreferences();
            prefs.setTabVisibility(tab, false);
            prefs.save();
          }
        } catch (Exception ex) {
          SystemFacade.getInstance().handleException(ex);
        }
      }
    };

    private Action newProjectAction = new AbstractAction("Project..") {
        public void actionPerformed(ActionEvent e) {
          MainWindow.this.fd.setFileSelectionMode(JFileChooser.FILES_ONLY);
          MainWindow.this.fd.setDialogType(JFileChooser.SAVE_DIALOG);
          MainWindow.this.fd.setDialogTitle("Select Archive file to create");
          int i = MainWindow.this.fd.showDialog(instance, "Create");
          if (i == JFileChooser.APPROVE_OPTION) {
            SystemFacade.getInstance().createNewArchiveProject(MainWindow.this.fd.getSelectedFile());
          }
        }
    };

    private Action newClassAction = new AbstractAction("Class..") {
        public void actionPerformed(ActionEvent e) {
            if (project != null) {
                NewClassDialog dialog = new NewClassDialog(MainWindow.this);
                dialog.invoke();
                if( !dialog.userCancelled()) {
                    SystemFacade.getInstance().createNewClass(dialog.getFullClassName(), dialog.getSelectedFile());
                }
            }
        }
    };

    private Action openAction = new AbstractAction("Open..") {
        public void actionPerformed(ActionEvent e) {
            MainWindow.this.fd
                    .setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            MainWindow.this.fd.setDialogType(JFileChooser.OPEN_DIALOG);
            MainWindow.this.fd
                    .setDialogTitle("Select java .class file, an archive or a folder.");
            int i = MainWindow.this.fd.showDialog(instance, "Open");
            if (i == JFileChooser.APPROVE_OPTION) {
                SystemFacade.getInstance().openFile(
                        MainWindow.this.fd.getSelectedFile());
            }
        }
    };

    private Action saveAction = new AbstractAction("Save") {
        public void actionPerformed(ActionEvent e) {
            SystemFacade.getInstance().saveFile();
        }
    };

    private Action saveAsAction = new AbstractAction("Save as..") {
        public void actionPerformed(ActionEvent e) {
            MainWindow.this.fd
                    .setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            MainWindow.this.fd.setDialogType(JFileChooser.SAVE_DIALOG);
            MainWindow.this.fd.setDialogTitle("Save class or file set.");
            int i = MainWindow.this.fd.showDialog(instance, "Save");
            if (i == JFileChooser.APPROVE_OPTION) {
                SystemFacade.getInstance().saveFile(
                        MainWindow.this.fd.getSelectedFile());
            }
        }
    };

    private Action exitAction = new AbstractAction("Exit") {
        public void actionPerformed(ActionEvent e) {
            SystemFacade.getInstance().exit();
        }
    };

    private Action undoAction = new AbstractAction("Undo") {
        public void actionPerformed(ActionEvent e) {
          Tabbable tab = getSelectedTab();
          if (tab != null) {
            tab.undo();
          }
        }
    };

    private Action redoAction = new AbstractAction("Redo") {
        public void actionPerformed(ActionEvent e) {
          Tabbable tab = getSelectedTab();
          if (tab != null) {
            tab.redo();
          }
        }
    };

    private Action outlineAction = new AbstractAction("Quick Outline..") {
        public void actionPerformed(ActionEvent e) {
          Tabbable tab = getSelectedTab();
          if (tab != null) {
            tab.outline();
          }
        }
    };
   
    private Action openTypeAction = new AbstractAction("Open Type..") {
        public void actionPerformed(ActionEvent e) {
          if (MainWindow.this.project == null) {
            return; // early return
          }
         
          ClassIndex ci = SystemFacade.getInstance().getClassIndex();
          ClassChooseDialog ccd = new ClassChooseDialog(MainWindow.this, ci);
          ccd.setTitle("Open Type..");
          ccd.invoke();
          ClassLocator cl = ccd.getSelected();
          if (cl != null) {
            try {
          Event event = new Event(EventType.CLASS_OPEN);
              ClassFile cf = SystemFacade.getInstance().getClassFile(cl);
          event.setClassFile(cf);
          event.setFile(cl.getFile());
          MainWindow.this.dispatcher.notifyObservers(event);
          MainWindow.this.setTab(Tab.EDITOR);
            } catch(Exception ioe) {
              SystemFacade.getInstance().handleException(ioe);
            }
          }
        }
    };
   
    private Action goToAction = new AbstractAction("Go to..") {
        public void actionPerformed(ActionEvent e) {
            int selection = JOptionPane.showOptionDialog(MainWindow.this, "Go to..", "Go to..", JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, null, new String[] {"Source line number", "pc offset"}, "Source line number");
            Link link = null;
            switch (selection) {
              case 0: // source line #
                String positionStr = JOptionPane.showInputDialog(MainWindow.this, "Source line number to go to:");
                if (positionStr != null) {
                  int pos = Integer.parseInt(positionStr);
                  link = new Link();
                  link.setAnchor(Link.ANCHOR_SOURCE_LINE_NUMBER);
                  link.setTab(Tab.EDITOR);
                  link.setPosition(pos);
                }
                break;
              case 1: // code block pc
                positionStr = JOptionPane.showInputDialog(MainWindow.this, "Method pc offset to go to:");
                if (positionStr != null) {
                  int pos = Integer.parseInt(positionStr);
                  link = new Link();
                  link.setAnchor(Link.ANCHOR_PC_OFFSET);
                  link.setTab(Tab.EDITOR);
                  link.setPosition(pos);
                }
                break;
            }
           
            if (link != null) {
              SystemFacade.getInstance().goTo(link);
            }
        }
    };

    private Action insertAction = new AbstractAction("Insert..") {
        public void actionPerformed(ActionEvent e) {
          Tabbable tab = getSelectedTab();
          if (tab != null) {
            tab.insert();
          }
        }
    };

    private Action removeAction = new AbstractAction("Remove") {
        public void actionPerformed(ActionEvent e) {
          Tabbable tab = getSelectedTab();
          if (tab != null) {
            tab.remove();
          }
        }
    };

    private Action findAction = new AbstractAction("Find..") {
        public void actionPerformed(ActionEvent e) {
          Tabbable tab = getSelectedTab();
          if (tab != null) {
            tab.find();
          }
        }
    };

    private Action findNextAction = new AbstractAction("Find next") {
        public void actionPerformed(ActionEvent e) {
          Tabbable tab = getSelectedTab();
          if (tab != null) {
            tab.findNext();
          }
        }
    };

    private Action splitOffAction = new AbstractAction("None") {
        public void actionPerformed(ActionEvent e) {
          clearContentPane();
          hexSplit.setActive(false);
      getContentPane().add(tabbedPane, BorderLayout.CENTER);
      getContentPane().validate();
      split = SplitMode.NONE;
        }
    };

    private Action splitHexAction = new AbstractAction("Hex View") {
        public void actionPerformed(ActionEvent e) {
      splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, hexSplit, tabbedPane);
      hexSplit.setActive(true);
      clearContentPane();
      getContentPane().add(splitPane, BorderLayout.CENTER);
      getContentPane().validate();
      split = SplitMode.HEX;
      editorTab.setSplitSynchronizer(new BytecodeToHexSync(hexSplit));
      structureTab.setSplitSynchronizer(new StructureToHexSync(hexSplit));
      constantPoolTab.setSplitSynchronizer(new ConstantPoolToHexSync(hexSplit));
        }
    };

    private Action splitSourceAction = new AbstractAction("Java Source View") {
        public void actionPerformed(ActionEvent e) {
          // TODO: implement source view
      splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JPanel(), tabbedPane);
      clearContentPane();
      getContentPane().add(splitPane, BorderLayout.CENTER);
      getContentPane().validate();
      split = SplitMode.SOURCE;
        }
    };
   
    private Action cpTranslationOff = new AbstractAction("No translation") {
        public void actionPerformed(ActionEvent e) {
            EditorFacade.getInstance().setConstantPoolTranslationMode(ConstantPoolTranslationMode.OFF);
        }
    };

    private Action cpTranslationNormal = new AbstractAction("Translation") {
        public void actionPerformed(ActionEvent e) {
            EditorFacade.getInstance().setConstantPoolTranslationMode(ConstantPoolTranslationMode.TRANSLATION);
        }
    };

    private Action cpTranslationHybrid = new AbstractAction("Hybrid") {
        public void actionPerformed(ActionEvent e) {
            EditorFacade.getInstance().setConstantPoolTranslationMode(ConstantPoolTranslationMode.HYBRID);
        }
    };

    private Action lineIdOff = new AbstractAction("Off") {
        public void actionPerformed(ActionEvent e) {
            EditorFacade.getInstance().setLineMode(LineIdentifierMode.MODE_OFF);
        }
    };

    private Action lineIdPC = new AbstractAction("PC") {
        public void actionPerformed(ActionEvent e) {
            EditorFacade.getInstance().setLineMode(LineIdentifierMode.MODE_PC);
        }
    };

    private Action lineIdSrc = new AbstractAction("Sourcecode line") {
        public void actionPerformed(ActionEvent e) {
            EditorFacade.getInstance().setLineMode(
                    LineIdentifierMode.MODE_SOURCELINE);
        }
    };

    private Action preferencesAction = new AbstractAction("Preferences..") {
        public void actionPerformed(ActionEvent e) {
            SystemFacade.getInstance().showPreferencesDialog();
        }
    };

    private Action compareAction = new AbstractAction("Compare..") {
        public void actionPerformed(ActionEvent e) {
          setTab(Tab.COMPARE);
        }
    };

    private Action extendsObjectAction = new AbstractAction("Display \"extends Object\"") {
        public void actionPerformed(ActionEvent e) {
          try {
            Preferences prefs = SystemFacade.getInstance().getPreferences();
            prefs.invertSetting(Settings.DISPLAY_EXTENDS_OBJECT);
            prefs.save();
            dispatcher.notifyObservers(new Event(EventType.DISPLAY_PARAMETER_UPDATE));   
          } catch(Exception ex) {
            SystemFacade.getInstance().handleException(ex);
          }
        }
    };
   
    private Action showGenericsAction = new AbstractAction("Display Generics") {
        public void actionPerformed(ActionEvent e) {
          try {
            Preferences prefs = SystemFacade.getInstance().getPreferences();
            prefs.invertSetting(Settings.DISPLAY_GENERICS);
            prefs.save();
            dispatcher.notifyObservers(new Event(EventType.DISPLAY_PARAMETER_UPDATE));
          } catch(Exception ex) {
            SystemFacade.getInstance().handleException(ex);
          }
        }
    };

    private Action showVarargsAction = new AbstractAction("Display Varargs") {
        public void actionPerformed(ActionEvent e) {
          try {
            Preferences prefs = SystemFacade.getInstance().getPreferences();
            prefs.invertSetting(Settings.DISPLAY_VARARGS);
            prefs.save();
            dispatcher.notifyObservers(new Event(EventType.DISPLAY_PARAMETER_UPDATE));
          } catch(Exception ex) {
            SystemFacade.getInstance().handleException(ex);
          }
        }
    };

    JPanel progressAndStatusPanel = new JPanel();
    JProgressBar progress = new JProgressBar();
    GridLayout gridLayout1 = new GridLayout();

    public MainWindow() {
        super("reJ");
        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
       
        this.tabbedPane.addChangeListener(new ChangeListener() {
          Tabbable lastTab = null;
      public void stateChanged(ChangeEvent e) {
        if (lastTab != null) {
          lastTab.leavingTab();
        }
        lastTab = (Tabbable) tabbedPane.getSelectedComponent();
        if (lastTab != null) {
          lastTab.enteringTab();
        }
      }
        });
       
        this.fd.setFileHidingEnabled(false);
        try {
            this.addWindowListener(new WindowAdapter() {
                @Override
        public void windowClosing(WindowEvent we) {
                    SystemFacade.getInstance().exit();
                }
            });
           
            this.setJMenuBar(this.menuBar);

            this.setState(Frame.NORMAL);
            this.getContentPane().setLayout(this.borderLayout1);
            this.status.setText("Situation under control.");
            clearContentPane();
            this.getContentPane().add(this.tabbedPane, BorderLayout.CENTER);
            this.progressAndStatusPanel.setLayout(this.gridLayout1);
            this.gridLayout1.setRows(2);
            this.progressAndStatusPanel.add(this.progress, null);
            this.progressAndStatusPanel.add(this.status, null);

            // toolbar
            populateToolbar();

            createMenu();

            setVisible(true);
            pack();
            setExtendedState(Frame.MAXIMIZED_BOTH);
           
            // register components to receive messages
            this.dispatcher.registerObserver(this);
            this.dispatcher.registerObserver(this.compareTab);
            this.dispatcher.registerObserver(this.constantPoolTab);
            if (this.debugTab instanceof EventObserver) {
              this.dispatcher.registerObserver((EventObserver) this.debugTab);
            }
            this.dispatcher.registerObserver(EditorFacade.getInstance());
            this.dispatcher.registerObserver(this.editorTab);
            this.dispatcher.registerObserver(this.hexTab);
            this.dispatcher.registerObserver(this.filesTab);
            this.dispatcher.registerObserver(this.obfuscationTab);
            this.dispatcher.registerObserver(this.structureTab);
            this.dispatcher.registerObserver(SystemFacade.getInstance());
            this.dispatcher.registerObserver(this.hexSplit);
           
        conditionalSetVisible(Tab.COMPARE);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

  public void clearContentPane() {
    this.getContentPane().removeAll();
    this.getContentPane().add(this.toolbar, BorderLayout.NORTH);
    this.getContentPane().add(this.progressAndStatusPanel, BorderLayout.SOUTH);
  }

  private void createMenu() {
    // File
    this.fileMenu = new JMenu("File");
    this.menuBar.add(this.fileMenu);
        JMenu newMenu = new JMenu("New");
        newMenu.add(this.newProjectAction);
        newMenu.add(this.newClassAction);
        this.fileMenu.add(newMenu);
        this.fileMenu.add(new JMenuItem(this.openAction));
        JMenuItem item = new JMenuItem(this.saveAction);
        this.fileMenu.add(item);
        item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
                InputEvent.CTRL_MASK));
        this.fileMenu.add(new JMenuItem(this.saveAsAction));
        this.fileMenu.add(new JSeparator());

        this.recentFilesMenu = new JMenu("Recent Files");
        updateRecentFilesMenu();
        this.fileMenu.add(this.recentFilesMenu);
        this.fileMenu.add(new JSeparator());
        this.fileMenu.add(new JMenuItem(this.exitAction));
    updateRecentFilesMenu();

    // Edit
    JMenu editMenu = new JMenu("Edit");
    this.menuBar.add(editMenu);
    item = new JMenuItem(this.undoAction);
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z,
            InputEvent.CTRL_MASK));
    editMenu.add(item);
    item = new JMenuItem(this.redoAction);
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y,
            InputEvent.CTRL_MASK));
    editMenu.add(item);
    editMenu.add(new JSeparator());
    editMenu.add(new JMenuItem(this.insertAction));
    item = new JMenuItem(this.removeAction);
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
    editMenu.add(item);
    editMenu.add(new JSeparator());
    item = new JMenuItem(this.findAction);
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F,
            InputEvent.CTRL_DOWN_MASK));
    editMenu.add(item);
    item = new JMenuItem(this.findNextAction);
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0));
    editMenu.add(item);

    // Navigate
    JMenu navigate = new JMenu("Navigate");
    this.menuBar.add(navigate);
    item = new JMenuItem(this.openTypeAction);
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
    navigate.add(item);           
    item = new JMenuItem(this.outlineAction);
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK));
    navigate.add(item);
    item = new JMenuItem(this.goToAction);
    item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_DOWN_MASK));
    navigate.add(item);
   
    // View
    JMenu view = new JMenu("View");
    this.menuBar.add(view);
    // View / Line identifier
    {
      JMenu sub = new JMenu("Line identifier");
      ButtonGroup bg = new ButtonGroup();
      JRadioButtonMenuItem btn = new JRadioButtonMenuItem(this.lineIdOff);
      bg.add(btn);
      sub.add(btn);
      btn = new JRadioButtonMenuItem(this.lineIdPC);
      btn.setSelected(true);
      bg.add(btn);
      sub.add(btn);
      btn = new JRadioButtonMenuItem(this.lineIdSrc);
      bg.add(btn);
      sub.add(btn);
      view.add(sub);
    }
    // View / Reference Translation
    {
      JMenu translation = new JMenu("Reference Translation");
      ButtonGroup bg = new ButtonGroup();
      JRadioButtonMenuItem btn = new JRadioButtonMenuItem(this.cpTranslationOff);
      bg.add(btn);
      translation.add(btn);
      btn = new JRadioButtonMenuItem(this.cpTranslationNormal);
      btn.setSelected(true);
      bg.add(btn);
      translation.add(btn);
      btn = new JRadioButtonMenuItem(this.cpTranslationHybrid);
      bg.add(btn);
      translation.add(btn);
      view.add(translation);
    }
    // View / Editor Split Mode
    {
      JMenu split = new JMenu("Split Mode");
      ButtonGroup bg = new ButtonGroup();
      JRadioButtonMenuItem btn = new JRadioButtonMenuItem(this.splitOffAction);
      btn.setSelected(true);
      bg.add(btn);
      split.add(btn);
      btn = new JRadioButtonMenuItem(this.splitHexAction);
      bg.add(btn);
      split.add(btn);
      btn = new JRadioButtonMenuItem(this.splitSourceAction);
      bg.add(btn);
      split.add(btn);
      view.add(split);
    }
    view.add(new JSeparator());
    // View / Display extends Object
    JCheckBoxMenuItem extendsObject = new JCheckBoxMenuItem(extendsObjectAction);
    extendsObject.setModel(new DefaultButtonModel() {
      @Override
      public boolean isSelected() {
        Preferences prefs = SystemFacade.getInstance().getPreferences();
        return prefs.getSetting(Settings.DISPLAY_EXTENDS_OBJECT, Boolean.class).booleanValue();
      }
    });
    view.add(extendsObject);
    // View / Show generics
    JCheckBoxMenuItem showGenerics = new JCheckBoxMenuItem(showGenericsAction);
    showGenerics.setModel(new DefaultButtonModel() {
      @Override
      public boolean isSelected() {
        Preferences prefs = SystemFacade.getInstance().getPreferences();
        return prefs.getSetting(Settings.DISPLAY_GENERICS, Boolean.class).booleanValue();
      }     
    });
    view.add(showGenerics);
    // View / Show varargs
    JCheckBoxMenuItem showVarargs = new JCheckBoxMenuItem(showVarargsAction);
    showVarargs.setModel(new DefaultButtonModel() {
      @Override
      public boolean isSelected() {
        Preferences prefs = SystemFacade.getInstance().getPreferences();
        return prefs.getSetting(Settings.DISPLAY_VARARGS, Boolean.class).booleanValue();
      }     
    });
    view.add(showVarargs);

   
    view.add(new JSeparator());

    // View / Tabs   
    JCheckBoxMenuItem box = new JCheckBoxMenuItem(tabViewAction);
    box.setText(this.structureTab.getTabTitle());
    view.add(box);
    this.viewCheckBoxes.put(box, Tab.STRUCTURE);
   
    box = new JCheckBoxMenuItem(tabViewAction);
    box.setText(this.hexTab.getTabTitle());
    view.add(box);
    this.viewCheckBoxes.put(box, Tab.HEX);

    box = new JCheckBoxMenuItem(tabViewAction);
    box.setText(this.constantPoolTab.getTabTitle());
    view.add(box);
    this.viewCheckBoxes.put(box, Tab.CONSTANTPOOL);

    box = new JCheckBoxMenuItem(tabViewAction);
    box.setText(this.editorTab.getTabTitle());
    view.add(box);
    this.viewCheckBoxes.put(box, Tab.EDITOR);

    box = new JCheckBoxMenuItem(tabViewAction);
    box.setText(this.obfuscationTab.getTabTitle());
    view.add(box);
    this.viewCheckBoxes.put(box, Tab.OBFUSCATION);

    box = new JCheckBoxMenuItem(tabViewAction);
    box.setText(this.searchTab.getTabTitle());
    view.add(box);
    this.viewCheckBoxes.put(box, Tab.SEARCH);

    box = new JCheckBoxMenuItem(tabViewAction);
    box.setText(this.debugTab.getTabTitle());
    view.add(box);
    this.viewCheckBoxes.put(box, Tab.DEBUG);

    box = new JCheckBoxMenuItem(tabViewAction);
    box.setText(this.compareTab.getTabTitle());
    view.add(box);
    this.viewCheckBoxes.put(box, Tab.COMPARE);
   
    for (JCheckBoxMenuItem chkBox : this.viewCheckBoxes.keySet()) {
      chkBox.setSelected(false);
    }

   
    // Tools
    JMenu tools = new JMenu("Tools");
    this.menuBar.add(tools);
    item = new JMenuItem(this.preferencesAction);
    tools.add(item);
    item = new JMenuItem(this.compareAction);
    tools.add(item);
  }

    public void updateRecentFilesMenu() {
      this.recentFilesMenu.removeAll();
        List list = SystemFacade.getInstance().getRecentFiles();
        for (int i = 0; i < list.size(); i++) {
            File file = new File((String) list.get(i));
            this.recentFilesMenu.add(new JMenuItem(new OpenRecentFileAction(file)));
        }
    }

    public static void main(String args[]) throws Exception {
        if (args.length > 0 && args[0].equalsIgnoreCase("-debug")) {
            Handler fh = new FileHandler("reJ.log");
            Logger.getLogger("net.sf.rej").addHandler(fh);
          Logger.getLogger("net.sf.rej").setLevel(Level.FINEST);         
        } else if (args.length > 0 && args[0].equalsIgnoreCase("-nolog")) {
          // no logging
        } else {
            Handler fh = new FileHandler("reJ.log");
            Logger.getLogger("net.sf.rej").addHandler(fh);
          Logger.getLogger("net.sf.rej").setLevel(Level.WARNING);
        }

        SwingUtilities.invokeLater(new Runnable() {
        public void run() {
              instance = new MainWindow();
        }
      });
    }

    public static MainWindow getInstance() {
        return instance;
    }

  public void processEvent(Event event) {
        // get currect project and update all tabs and all that
    if (event.getType() == EventType.PROJECT_UPDATE) {
      this.project = event.getProject();
      if (this.project != null) {
        insertControlTabs();
      } else {
        this.tabbedPane.removeAll();
        for (JCheckBoxMenuItem item : this.viewCheckBoxes.keySet()) {
          item.setSelected(true);
        }
        ensureTabIsVisible(this.filesTab);
      }
    } else if (event.getType() == EventType.CLASS_OPEN && event.getFile() != null) {
      insertConditionalTabs();
      selectFileRelatedTab();
    } else if (event.getType() == EventType.DEBUG_STACK_FRAME_CHANGED) {
      insertConditionalTabs();
      setTab(Tab.EDITOR);
      } else if (event.getType() == EventType.DEBUG_ATTACH) {
      this.splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, getDebugPanel(), this.tabbedPane);
      this.getContentPane().remove(this.tabbedPane);
      this.getContentPane().add(this.splitPane, BorderLayout.CENTER);
      this.getContentPane().validate();
      } else if (event.getType() == EventType.DEBUG_DETACH) {
      this.getContentPane().remove(this.splitPane);
      this.getContentPane().add(this.tabbedPane, BorderLayout.CENTER);
      this.getContentPane().validate();
      }
    }
 
  private void insertControlTabs() {
    ensureTabIsVisible(this.filesTab);
    conditionalSetVisible(Tab.SEARCH);
    conditionalSetVisible(Tab.DEBUG);
  }
 
  private void insertConditionalTabs() {
    conditionalSetVisible(Tab.STRUCTURE);
    conditionalSetVisible(Tab.CONSTANTPOOL);
    conditionalSetVisible(Tab.EDITOR);
    conditionalSetVisible(Tab.HEX);
    conditionalSetVisible(Tab.OBFUSCATION);
  }
 
  private void selectFileRelatedTab() {
    if (this.tabbedPane.indexOfComponent(this.editorTab) != -1) {
      setTab(Tab.EDITOR);
    } else if (this.tabbedPane.indexOfComponent(this.structureTab) != -1) {
      setTab(Tab.STRUCTURE);
    } else if (this.tabbedPane.indexOfComponent(this.hexTab) != -1) {
      setTab(Tab.HEX);
    } else if (this.tabbedPane.indexOfComponent(this.constantPoolTab) != -1) {
      setTab(Tab.CONSTANTPOOL);
    } else {
      // none of the file related tabs are open, open and select Bytecode editor
      setTab(Tab.EDITOR);
    }
  }

  private void conditionalSetVisible(Tab tab) {
    Preferences prefs = SystemFacade.getInstance().getPreferences();
    if (prefs.isTabVisible(tab)) {
      ensureTabIsVisible(getTab(tab));
    }
  }

  private void ensureTabIsVisible(Tabbable tab) {
    if (!isTabVisible(tab)) {
      this.tabbedPane.addTab(tab.getTabTitle(), (Component)tab);
      for (Entry<JCheckBoxMenuItem, Tab> set : this.viewCheckBoxes.entrySet()) {
        if (this.getTab(set.getValue()) == tab) {
          set.getKey().setSelected(true);
        }
      }
    }   
  }
 
    public Tabbable getSelectedTab() {
        return (Tabbable) this.tabbedPane.getSelectedComponent();
    }

    public void setProgress(final int i) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainWindow.this.progress.setValue(i);
            }
        });
    }

    public void setProgressScope(final int min, final int max) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainWindow.this.progress.setMinimum(min);
                MainWindow.this.progress.setMaximum(max);
                MainWindow.this.progress.setValue(min);
            }
        });
    }

    public void setStatus(String status) {
        this.status.setText(status);
    }

    public void showErrorMessage(String message) {
        JOptionPane.showMessageDialog(this, message, "Error",
                JOptionPane.ERROR_MESSAGE);
    }

    public void setTab(Tab tab) {
      Tabbable tabbable = getTab(tab);
      ensureTabIsVisible(tabbable);
        this.tabbedPane.setSelectedComponent((Component)tabbable);   
    }
   
    public void hideTab(Tabbable tab) {
      tabbedPane.remove((Component)tab);
    }
   
    public boolean isTabVisible(Tab tab) {
      return isTabVisible(getTab(tab));
    }
   
    public boolean isTabVisible(Tabbable tab) {
      return this.tabbedPane.indexOfComponent((Component)tab) != -1;
    }

    public Tabbable getTab(Tab tab) {
        switch (tab) {
        case FILES:
          return this.filesTab;
        case STRUCTURE:
          return this.structureTab;
        case CONSTANTPOOL:
          return this.constantPoolTab;
        case EDITOR:
          return this.editorTab;
        case HEX:
          return this.hexTab;
        case INJECTION:
          return this.injectionTab;
        case SEARCH:
          return this.searchTab;
        case OBFUSCATION:
          return this.obfuscationTab;
        case COMPARE:
          return this.compareTab;
        case DEBUG:
           return this.debugTab;
        }
       
        return null;
    }

    public SearchTab getSearchTab() {
        return this.searchTab;
    }
   
    public HexEditorTab getHexTab() {
        return this.hexTab;
    }
   
    public void populateToolbar() {
      this.toolbar.removeAll();
        this.toolbar.add(this.openAction);
        this.toolbar.add(this.saveAction);
        this.toolbar.add(this.saveAsAction);
        this.toolbar.add(new JSeparator());
        this.toolbar.add(this.insertAction);
        this.toolbar.add(this.removeAction);
        this.toolbar.add(new JSeparator());
        this.toolbar.add(this.findAction);
        this.toolbar.add(new JSeparator());
        this.toolbar.add(this.exitAction);
    }

  private Tabbable createDebugTab() {
    try {
      @SuppressWarnings("unused")
      Class c = Class.forName("com.sun.jdi.Bootstrap");
      // JDI classes found on path, go ahead and create
      // the debug tab.
      return new DebugTab();
    } catch(ClassNotFoundException ncdfe) {
      logger.warning("Class com.sun.jdi.Bootstrap not found. Probably due to the fact that JDI library (tools.jar) is not on classpath. In order to have debugging support, please correct this and restart reJ.");
      return new NoDebugTab();
    }
  }

  public Tabbable getDebugTab() {
    return this.debugTab;
  }
 
  public EditorTab getEditorTab() {
    return this.editorTab;   
  }

  private JPanel getDebugPanel() {
    if (this.debugPanel == null) {
      this.debugPanel = new DebugControlPanel();
      this.dispatcher.registerObserver(this.debugPanel);
    }
   
    return this.debugPanel;
  }

}
TOP

Related Classes of net.sf.rej.gui.MainWindow

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.