From bde4f7f48c31570620e30b77df5c632a786ff3e2 Mon Sep 17 00:00:00 2001 From: hoenicke Date: Mon, 18 Sep 2000 11:53:50 +0000 Subject: [PATCH] Added a nice ClassPathDialog. Localized all strings. git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1262 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/swingui/ClassPathDialog.java | 274 ++++++++++++++++++++++ jode/jode/swingui/Main.java | 106 ++++----- jode/jode/swingui/Makefile.am | 3 +- jode/jode/swingui/Resources.properties | 27 +++ jode/jode/swingui/Resources_de.properties | 27 +++ 5 files changed, 382 insertions(+), 55 deletions(-) create mode 100644 jode/jode/swingui/ClassPathDialog.java create mode 100644 jode/jode/swingui/Resources.properties create mode 100644 jode/jode/swingui/Resources_de.properties diff --git a/jode/jode/swingui/ClassPathDialog.java b/jode/jode/swingui/ClassPathDialog.java new file mode 100644 index 0000000..24e6d24 --- /dev/null +++ b/jode/jode/swingui/ClassPathDialog.java @@ -0,0 +1,274 @@ +/* ClassPathDialog Copyright (C) 2000 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$ + */ + +package jode.swingui; +import jode.GlobalOptions; +import jode.bytecode.ClassPath; +import jode.decompiler.Decompiler; +import jode.decompiler.ProgressListener; + +///#def JAVAX_SWING javax.swing +import javax.swing.*; +import javax.swing.filechooser.*; +import javax.swing.event.*; +///#enddef + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.BorderLayout; +import java.awt.event.*; +import java.awt.AWTEventMulticaster; +import java.io.File; + +public class ClassPathDialog { + JDialog dialog; + + JTextField editField; + boolean editFieldChanged = false; + JList pathList; + DefaultListModel pathListModel; + + ClassPath currentClassPath; + ActionListener actionListener = null; + + public ClassPathDialog(JFrame frame, String[] classPath) { + dialog = new JDialog(frame, Main.bundle.getString("cpdialog.title"), + false); + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); + panel.add(BorderLayout.NORTH, createEditPane()); + panel.add(BorderLayout.CENTER, createListPane()); + panel.add(BorderLayout.SOUTH, createOkayCancelPane()); + + dialog.getContentPane().add(BorderLayout.CENTER, panel); + dialog.pack(); + dialog.addWindowListener(new WindowAdapter() { + public void windowClosing() { + dialog.setVisible(false); + } + }); + + for (int i = 0; i < classPath.length; i++) + pathListModel.addElement(classPath[i]); + createNewClassPath(); + } + + public void showDialog() { + dialog.setVisible(true); + } + + public ClassPath getClassPath() { + return currentClassPath; + } + + public void addActionListener(ActionListener l) { + actionListener = AWTEventMulticaster.add(actionListener, l); + } + public void removeActionListener(ActionListener l) { + actionListener = AWTEventMulticaster.remove(actionListener, l); + } + + ClassPath reflectClassPath = new ClassPath("reflection:"); + private void createNewClassPath() { + String[] paths = new String[pathListModel.getSize()]; + pathListModel.copyInto(paths); + currentClassPath = new ClassPath(paths, reflectClassPath); + if (actionListener != null) + actionListener.actionPerformed + (new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null)); + } + + void add() { + String entry = editField.getText(); + int index = pathListModel.getSize(); + if (pathList.isSelectionEmpty()) + pathListModel.addElement(entry); + else { + index = pathList.getLeadSelectionIndex() + 1; + pathListModel.add(index - 1, + editField.getText()); + } + pathList.setSelectedIndex(index); + editFieldChanged = false; + } + + static class JarFileFilter extends FileFilter { + public boolean accept(File f) { + if (f.isDirectory()) + return true; + String name = f.getName(); + int dot = name.lastIndexOf('.'); + if (dot >= 0) { + String ext = name.substring(dot+1); + if (ext.equals("jar") || ext.equals("zip")) + return true; + } + return false; + } + + public String getDescription() { + return Main.bundle.getString("browse.filter.description"); + } + } + + class BrowseListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + String fileName = editField.getText(); + if (fileName.length() == 0) + fileName = null; + JFileChooser fileChooser = new JFileChooser(fileName); + fileChooser.setFileSelectionMode + (JFileChooser.FILES_AND_DIRECTORIES); + fileChooser.setDialogType(JFileChooser.CUSTOM_DIALOG); + fileChooser.setDialogTitle(Main.bundle.getString("browse.title")); + fileChooser.setFileFilter(new JarFileFilter()); + fileChooser.setApproveButtonText + (Main.bundle.getString("button.select")); + fileChooser.setApproveButtonMnemonic('s'); + if (fileChooser.showDialog(dialog, null) + == JFileChooser.APPROVE_OPTION) { + editField.setText(fileChooser.getSelectedFile().getPath()); + add(); + } + } + } + + private JPanel createEditPane() { + editField = new JTextField(); + + JButton browseButton = new JButton + (Main.bundle.getString("button.browse")); + browseButton.setMnemonic('b'); + browseButton.addActionListener(new BrowseListener()); + + JButton addButton = new JButton + (Main.bundle.getString("button.add")); + addButton.setMnemonic('d'); + JButton removeButton = new JButton + (Main.bundle.getString("button.remove")); + removeButton.setMnemonic('r'); + + ActionListener addListener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + add(); + } + }; + addButton.addActionListener(addListener); + editField.addActionListener(addListener); + editField.getDocument().addDocumentListener(new DocumentListener() { + public void changedUpdate(DocumentEvent e) { + editFieldChanged = true; + } + public void insertUpdate(DocumentEvent e) { + editFieldChanged = true; + } + public void removeUpdate(DocumentEvent e) { + editFieldChanged = (editField.getText().length() > 0); + } + }); + + removeButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (!pathList.isSelectionEmpty()) { + int index = pathList.getLeadSelectionIndex(); + pathListModel.remove(index); + if (index < pathListModel.getSize()) + pathList.setSelectedIndex(index); + } + } + }); + + JPanel editPane = new JPanel(); + editPane.setLayout(new BorderLayout()); + editPane.add(BorderLayout.EAST, browseButton); + editPane.add(BorderLayout.SOUTH, + createButtonPane(new JButton[] { addButton, + removeButton })); + editPane.add(BorderLayout.CENTER, editField); + return editPane; + } + + private JComponent createListPane() { + pathListModel = new DefaultListModel(); + pathList = new JList(pathListModel); + pathList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + JScrollPane listScroller = new JScrollPane(pathList); + listScroller.setMinimumSize(new Dimension(250, 80)); + listScroller.setAlignmentX(JScrollPane.LEFT_ALIGNMENT); + + pathList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if (!pathList.isSelectionEmpty() + && !editFieldChanged) { + editField.setText((String) + pathList.getSelectedValue()); + editFieldChanged = false; + } + } + }); + return listScroller; + } + + private JPanel createOkayCancelPane() { + JButton okayButton = new JButton + (Main.bundle.getString("button.okay")); + okayButton.setMnemonic('o'); + okayButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + createNewClassPath(); + dialog.setVisible(false); + } + }); + JButton applyButton = new JButton + (Main.bundle.getString("button.apply")); + applyButton.setMnemonic('a'); + applyButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + createNewClassPath(); + } + }); + JButton cancelButton = new JButton + (Main.bundle.getString("button.cancel")); + cancelButton.setMnemonic('c'); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dialog.setVisible(false); + } + }); + return createButtonPane + (new JButton[] { okayButton, applyButton, cancelButton }); + } + + private JPanel createButtonPane(JButton[] buttons) { + JPanel buttonPane = new JPanel(); + buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS)); + buttonPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + buttonPane.add(Box.createHorizontalGlue()); + buttonPane.add(buttons[0]); + for (int i=1; i < buttons.length; i++) { + buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); + buttonPane.add(buttons[i]); + } + buttonPane.add(Box.createHorizontalGlue()); + return buttonPane; + } +} diff --git a/jode/jode/swingui/Main.java b/jode/jode/swingui/Main.java index 1cf6ac1..d3c0206 100644 --- a/jode/jode/swingui/Main.java +++ b/jode/jode/swingui/Main.java @@ -32,6 +32,8 @@ import javax.swing.tree.*; import java.awt.*; import java.awt.event.*; import java.io.*; +import java.util.StringTokenizer; +import java.util.ResourceBundle; public class Main implements ActionListener, Runnable, TreeSelectionListener { @@ -44,16 +46,35 @@ public class Main JTextArea sourcecodeArea, errorArea; Thread decompileThread; String currentClassPath, lastClassName; - ClassPath classPath; + ClassPathDialog classPathDialog; JProgressBar progressBar; boolean hierarchyTree; - public Main(String classpath) { + public static ResourceBundle bundle; + + public Main(String[] classpath) { decompiler = new Decompiler(); - setClassPath(classpath); frame = new JFrame(GlobalOptions.copyright); + classPathDialog = new ClassPathDialog(frame, classpath); + decompiler.setClassPath(classPathDialog.getClassPath()); + classPathDialog.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ClassPath classPath = classPathDialog.getClassPath(); + decompiler.setClassPath(classPath); + if (classTree != null) + classTree.clearSelection(); + if (packModel != null) + packModel.rebuild(); + if (hierModel != null && hierarchyTree) { + hierModel.rebuild(); + } else { + hierModel = null; + } + } + }); + fillContentPane(frame.getContentPane()); addMenu(frame); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); @@ -62,10 +83,10 @@ public class Main System.exit(0); } }); + frame.pack(); } public void show() { - frame.pack(); frame.show(); } @@ -137,7 +158,7 @@ public class Main progressBar.setMinimum(0); progressBar.setMaximum(1000); - progressBar.setString("decompiling"); + progressBar.setString(bundle.getString("main.decompiling")); progressBar.setStringPainted(true); decompileThread.start(); } @@ -189,7 +210,7 @@ public class Main decompiler.decompile(lastClassName, writer, progListener); } catch (Throwable t) { try { - writer.write("\nException while decompiling:"); + writer.write(bundle.getString("main.exception")); PrintWriter pw = new PrintWriter(writer); t.printStackTrace(pw); pw.flush(); @@ -220,8 +241,10 @@ public class Main JMenuBar bar = new JMenuBar(); JMenu menu; JMenuItem item; - menu = new JMenu("File"); - item = new JMenuItem("Garbage collect"); + menu = new JMenu(bundle.getString("menu.file")); + menu.setMnemonic('f'); + item = new JMenuItem(bundle.getString("menu.file.gc")); + item.setMnemonic('c'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { System.gc(); @@ -229,7 +252,8 @@ public class Main } }); menu.add(item); - item = new JMenuItem("Exit"); + item = new JMenuItem(bundle.getString("menu.file.exit")); + item.setMnemonic('x'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { System.exit(0); @@ -237,9 +261,12 @@ public class Main }); menu.add(item); bar.add(menu); - menu = new JMenu("Options"); + menu = new JMenu(bundle.getString("menu.opt")); + menu.setMnemonic('o'); final JCheckBoxMenuItem hierItem - = new JCheckBoxMenuItem("Class hierarchy", hierarchyTree); + = new JCheckBoxMenuItem(bundle.getString("menu.opt.hier"), + hierarchyTree); + hierItem.setMnemonic('h'); hierItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { hierarchyTree = hierItem.isSelected(); @@ -260,24 +287,11 @@ public class Main }); 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 = new JMenuItem(bundle.getString("menu.opt.cp")); + item.setMnemonic('c'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { - setClassPath(currentClassPath); + classPathDialog.showDialog(); } }); menu.add(item); @@ -286,25 +300,7 @@ public class Main } public ClassPath getClassPath() { - return classPath; - } - - ClassPath reflectClassPath = new ClassPath("reflection:"); - public void setClassPath(String classpath) { - if (classpath == null || classpath.length() == 0) - classpath = "."; - currentClassPath = classpath; - classPath = new ClassPath(classpath, reflectClassPath); - decompiler.setClassPath(classPath); - if (classTree != null) - classTree.clearSelection(); - if (packModel != null) - packModel.rebuild(); - if (hierModel != null && hierarchyTree) { - hierModel.rebuild(); - } else { - hierModel = null; - } + return classPathDialog.getClassPath(); } public void treeNodesChanged(TreeModelEvent e) { @@ -337,16 +333,13 @@ public class Main public static void usage() { PrintWriter err = GlobalOptions.err; - err.println("usage: jode.swingui.Main flags* script"); - err.println(" -h, --help "+ - "show this information."); - err.println(" -c, --cp , --classpath "+ - "search for classes in specified classpath."); - err.println(" "+ - "The directories should be separated by commas."); + int numUsage = Integer.parseInt(bundle.getString("usage.count")); + for (int i=0; i < numUsage ; i++) + err.println(bundle.getString("usage."+i)); } public static void main(String[] params) { + bundle = ResourceBundle.getBundle("jode.swingui.Resources"); String cp = System.getProperty("java.class.path", ""); cp = cp.replace(File.pathSeparatorChar, Decompiler.altPathSeparatorChar); @@ -360,7 +353,12 @@ public class Main return; } } - Main win = new Main(cp); + StringTokenizer st = new StringTokenizer + (cp, ""+Decompiler.altPathSeparatorChar); + String[] splitcp = new String[st.countTokens()]; + for (int i = 0; i< splitcp.length; i++) + splitcp[i] = st.nextToken(); + Main win = new Main(splitcp); win.show(); } } diff --git a/jode/jode/swingui/Makefile.am b/jode/jode/swingui/Makefile.am index b86f438..5883bd4 100644 --- a/jode/jode/swingui/Makefile.am +++ b/jode/jode/swingui/Makefile.am @@ -9,8 +9,9 @@ SUBSTCP = @SUBSTCP@ FULL_CLASSPATH := $(shell $(SUBSTCP) $(top_srcdir):$(top_builddir):$(CLASSPATH):$(CLASSLIB)) MY_JAVA_FILES = \ - Main.java \ + ClassPathDialog.java \ HierarchyTreeModel.java \ + Main.java \ PackagesTreeModel.java noinst_DATA = $(MY_JAVA_FILES:.java=.class) diff --git a/jode/jode/swingui/Resources.properties b/jode/jode/swingui/Resources.properties new file mode 100644 index 0000000..66b625d --- /dev/null +++ b/jode/jode/swingui/Resources.properties @@ -0,0 +1,27 @@ +usage.count=4 +usage.0 = usage: java jode.swingui.Main options* +usage.1 = \ -h, --help show this information. +usage.2 = \ -c, --cp , --classpath search for classes in specified classpath. +usage.3 = \ The directories must be separated by commas. + +browse.filter.description = *.jar, *.zip Archives +browse.title = Browse +cpdialog.title = Set Class Path + +button.okay=&Okay +button.apply=&Apply +button.cancel=&Cancel +button.select=&Select +button.browse=&Browse... +button.add=&Add +button.remove=&Remove + +main.decompiling=decompiling +main.exception = \nException while decompiling: + +menu.file = &File +menu.file.gc = &Collect Garbage +menu.file.exit = &Exit +menu.opt = &Options +menu.opt.hier = Class &Hierarchy +menu.opt.cp = Set &Class Path... diff --git a/jode/jode/swingui/Resources_de.properties b/jode/jode/swingui/Resources_de.properties new file mode 100644 index 0000000..95abb71 --- /dev/null +++ b/jode/jode/swingui/Resources_de.properties @@ -0,0 +1,27 @@ +usage.count=4 +usage.0 = Syntax: java jode.swingui.Main optionen* +usage.1 = \ -h, --help gib diese Hilfe aus +usage.2 = \ -c, --cp , --classpath Suche die Klassen im gegebenen Classpath +usage.3 = \ Die Verzeichnisse werden durch Kommas abgetrennt + +browse.filter.description = *.jar, *.zip Archive +browse.title = Durchsuchen +cpdialog.title = Setze Classpath + +button.okay = Ok +button.apply = Anwenden +button.cancel = Abbruch +button.select = Selektieren +button.browse = Durchsuchen... +button.add = Hinzufügen +button.remove = Entfernen + +main.decompiling = dekompiliere +main.exception = \nBeim Dekompilieren ist ein Fehler aufgetreten: + +menu.file = Datei +menu.file.gc = Speicher freiräumen +menu.file.exit = Beenden +menu.opt = Optionen +menu.opt.hier = Klassen-Hierarchie +menu.opt.cp = Setze Classpath...