/*
* $Id: Toolbox.java 52 2007-05-20 15:52:29Z chammer $
* Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* This class was originally published under the MPL by Bruno Lowagie
* and Carsten Hammer.
* It was a part of iText, a Java-PDF library. You can now use it under
* the MIT License; for backward compatibility you can also use it under
* the MPL version 1.1: http://www.mozilla.org/MPL/
* A copy of the MPL license is bundled with the source code FYI.
*/
package com.lowagie.tools;
import java.beans.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import bsh.Interpreter;
import bsh.BshClassManager;
/**
* This is a utility that allows you to use a number of iText tools.
*/
public class Toolbox extends JFrame implements ToolMenuItems, ActionListener {
/** A serial version ID */
private static final long serialVersionUID = -3766198389452935073L;
/** The DesktopPane of the toolbox. */
private JDesktopPane desktop;
/** The ConsolePane of the toolbox. */
private JScrollPane console;
/** The list of tools in the toolbox. */
private Properties toolmap = new Properties();
/** x-coordinate of the location of a new internal frame. */
private int locationX = 0;
/** y-coordinate of the location of a new internal frame. */
private int locationY = 0;
/**
* toolarray
*/
private ArrayList toolarray = new ArrayList();
Preferences preferences = null;
/**
* Constructs the Toolbox object.
*/
public Toolbox() {
super();
setSize(600, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(true);
setTitle("iText Toolbox");
desktop = new JDesktopPane();
setJMenuBar(getMenubar());
setIconImage(new ImageIcon(com.lowagie.tools.Toolbox.class.getResource(
"itextlogo.gif")).getImage());
Console c;
try {
c = new Console();
console = new JScrollPane(c.textArea);
} catch (IOException e) {
e.printStackTrace();
}
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
desktop,
console);
splitPane.setContinuousLayout(true);
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(300);
setContentPane(splitPane);
centerFrame(this);
setVisible(true);
}
/**
* Starts the Toolbox utility.
*
* use as first argument the name of the plugin,
* then the arguments of the plugin used.
*
* e.g.
*
* java -jar itext.jar Burst inputfile.pdf
*
* That way you can call plugins by name directly.
*
* @param args
* no arguments needed
*/
public static void main(String[] args) {
try {
Class.forName("com.lowagie.text.Document");
} catch (ClassNotFoundException e) {
JOptionPane.showMessageDialog(null,
"You need the iText.jar in your CLASSPATH!",
e.getClass().getName(),
JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
Toolbox toolbox = new Toolbox();
if (args.length > 0) {
try {
AbstractTool tool = toolbox.createFrame(args[0]);
String[] nargs = new String[args.length - 1];
System.arraycopy(args, 1, nargs, 0, args.length - 1);
tool.setMainArguments(nargs);
tool.execute();
} catch (PropertyVetoException ex) {
} catch (ClassNotFoundException ex) {
} catch (IllegalAccessException ex) {
} catch (InstantiationException ex) {
}
}
}
/**
* Gets the menubar.
*
* @return a menubar
*/
private JMenuBar getMenubar() {
Properties p = new Properties();
try {
p.load(Toolbox.class.getClassLoader().getResourceAsStream(
"com/lowagie/tools/tools.txt"));
String usertoolstxt = System.getProperty("user.home") +
System.getProperty("file.separator") +
"tools.txt";
File uttf = new File(usertoolstxt);
if (uttf.isFile() && uttf.exists()) {
p.load(new FileInputStream(usertoolstxt));
}
} catch (IOException e) {
e.printStackTrace();
}
toolmap = new Properties();
JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu(FILE);
JMenuItem open = new JMenuItem(OPEN);
open.addActionListener(this);
open.setAccelerator(KeyStroke.getKeyStroke('r', InputEvent.ALT_MASK));
file.add(open);
JMenuItem save = new JMenuItem(SAVE);
save.addActionListener(this);
save.setAccelerator(KeyStroke.getKeyStroke('s', InputEvent.ALT_MASK));
file.add(save);
preferences = new Preferences(PREFERENCES, desktop);
preferences.setAccelerator(KeyStroke.getKeyStroke('p',
InputEvent.ALT_MASK));
file.add(preferences);
JMenuItem close = new JMenuItem(CLOSE);
close.setMnemonic(KeyEvent.VK_C);
close.addActionListener(this);
file.add(close);
JMenu view = new JMenu(VIEW);
JMenuItem reset = new JMenuItem(RESET);
reset.addActionListener(this);
view.add(reset);
JMenu tools = new JMenu(TOOLS);
file.setMnemonic(KeyEvent.VK_T);
buildPluginMenuItems(new TreeMap(p), tools);
JMenu help = new JMenu(HELP);
JMenuItem about = new JMenuItem(ABOUT);
// about.setIcon(new ImageIcon(Toolbox.class.getResource(
// "Help24.gif")));
about.setMnemonic(KeyEvent.VK_A);
about.addActionListener(this);
help.add(about);
JMenuItem versions = new JMenuItem(VERSION);
// versions.setIcon(new ImageIcon(Toolbox.class.getResource(
// "About24.gif")));
versions.addActionListener(this);
help.add(versions);
menubar.add(file);
menubar.add(tools);
menubar.add(view);
menubar.add(Box.createGlue());
menubar.add(help);
return menubar;
}
/**
* BuildPluginMenuItems
*
* @param tmp Map
* @param tools JMenu
*/
private void buildPluginMenuItems(Map tmp, JMenu tools) {
String name, tool;
JMenu current = null;
JMenuItem item;
for (Iterator i = tmp.entrySet().iterator(); i.hasNext(); ) {
Map.Entry entry = (Map.Entry) i.next();
name = (String) entry.getKey();
if (current == null || !name.startsWith(current.getText())) {
current = new JMenu(name.substring(0, name.indexOf('.')));
tools.add(current);
}
item = new JMenuItem(name.substring(current.getText().length() + 1));
item.addActionListener(this);
tool = (String) entry.getValue();
try {
if(pulltool(tool)!=null){
toolmap.put(item.getText(), tool);
current.add(item);
}
} catch (ClassNotFoundException e) {
System.err.println("Plugin " + name
+ " was not found in your CLASSPATH.");
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
}
}
}
/**
* Creates an Internal Frame.
*
* @param name the name of the app
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
* @throws PropertyVetoException
* @return AbstractTool
*/
public AbstractTool createFrame(String name) throws InstantiationException,
IllegalAccessException, ClassNotFoundException,
PropertyVetoException {
AbstractTool ti = null;
String classname = (String) toolmap.get(name);
ti = (AbstractTool) pulltool(classname).newInstance();
toolarray.add(ti);
JInternalFrame f = ti.getInternalFrame();
f.setLocation(locationX, locationY);
int frameDistance = f.getHeight() - f.getContentPane().getHeight();
locationX += 25;
if (locationX > this.getWidth() + 50) {
locationX = 0;
}
locationY += 25;
if (locationY > this.getHeight() + 50) {
locationY = 0;
}
f.setVisible(true);
desktop.add(f);
f.setSelected(true);
return ti;
}
/**
* pulltool
*
* @param classname String
* @return Class
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
public Class pulltool(String classname) throws
InstantiationException,
IllegalAccessException, ClassNotFoundException {
Class ti = null;
if (classname.endsWith(".bsh")) {
if (preferences.isUseBeanshell()) {
try {
java.net.URL url = new java.net.URL(classname);
classname = url.getFile();
File file = new File(classname);
classname = file.getName();
classname = classname.substring(0, classname.length() - 4);
Interpreter i = new Interpreter(); // Construct an interpreter
BshClassManager bsh = i.getClassManager();
if (!bsh.classExists(classname)) {
i.source(url.getFile());
}
ti = bsh.classForName(classname);
} catch (IOException ex) {
System.err.println("File missing:" + ex);
return null;
} catch (Exception ex) {
System.err.println("Problem:" + ex);
return null;
}
} else {
System.err.println("Beanshell script " + classname + " found but beanshell support switched off. Switch Beanshell Support on in Preferences.");
return null;
}
} else {
ti = Class.forName(classname);
}
return ti;
}
/**
* Centers a JFrame.
*
* @param f JFrame
*/
public static void centerFrame(JFrame f) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = f.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
f.setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
}
/**
*
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
* @param evt ActionEvent
*/
public void actionPerformed(ActionEvent evt) {
if (CLOSE.equals(evt.getActionCommand())) {
System.out.println("The Toolbox is closed.");
System.exit(0);
} else if (ABOUT.equals(evt.getActionCommand())) {
System.out
.println("The iText Toolbox is part of iText, a Free Java-PDF Library.\nVisit http://itexttoolbox.sourceforge.net/ for more info.");
try {
Executable
.launchBrowser("http://itexttoolbox.sourceforge.net/");
} catch (IOException ioe) {
JOptionPane
.showMessageDialog(
this,
"The iText Toolbox is part of iText, a Free Java-PDF Library.\nVisit http://itexttoolbox.sourceforge.net/ for more info.");
}
} else if (RESET.equals(evt.getActionCommand())) {
JInternalFrame[] framearray = desktop.getAllFrames();
int xx = 0, yy = 0;
for (int i = 0; i < framearray.length; i++) {
if (!framearray[i].isIcon()) {
try {
int frameDistance = framearray[i].getHeight() -
framearray[i].getContentPane().
getHeight();
framearray[i].setMaximum(false);
int fwidth = framearray[i].getWidth();
int fheight = framearray[i].getHeight();
framearray[i].reshape(xx, yy, fwidth, fheight);
xx += frameDistance;
yy += frameDistance;
if (xx + fwidth > desktop.getWidth()) {
xx = 0;
}
if (yy + fheight > desktop.getHeight()) {
yy = 0;
}
} catch (PropertyVetoException e) {
}
}
}
} else if (VERSION.equals(evt.getActionCommand())) {
JFrame f = new Versions();
centerFrame(f);
f.setVisible(true);
} else if (OPEN.equals(evt.getActionCommand())) {
try {
System.out.println("start reading out.xml");
int result = JOptionPane.showInternalConfirmDialog(desktop,
"Import Frames discarding current configuration?");
if (result == 0) {
JInternalFrame[] frames = desktop.getAllFrames();
for (int i = 0; i < frames.length; i++) {
frames[i].dispose();
}
FileInputStream fis = new FileInputStream("out.xml");
XMLDecoder xmlde = new XMLDecoder(new BufferedInputStream(
fis));
toolarray = (ArrayList) xmlde.readObject();
for (int i = 0; i < toolarray.size(); i++) {
AbstractTool ti = (AbstractTool) toolarray.get(i);
JInternalFrame f = ti.getInternalFrame();
f.setLocation(locationX, locationY);
int frameDistance = f.getHeight() -
f.getContentPane().getHeight();
locationX += 25;
if (locationX > this.getWidth() + 50) {
locationX = 0;
}
locationY += 25;
if (locationY > this.getHeight() + 50) {
locationY = 0;
}
f.setVisible(true);
desktop.add(f);
f.setSelected(true);
}
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} catch (PropertyVetoException ex) {
ex.printStackTrace();
}
} else if (SAVE.equals(evt.getActionCommand())) {
try {
System.out.println("start writing out.xml");
FileOutputStream fos = new FileOutputStream("out.xml");
XMLEncoder xmlen = new XMLEncoder(new BufferedOutputStream(fos));
xmlen.writeObject(toolarray);
xmlen.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
} else {
try {
createFrame(evt.getActionCommand());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* A Class that redirects output to System.out and System.err.
*/
public class Console {
class ErrorContext extends StyleContext {
public static final String STDERROR = "Error";
public static final String STDOUT = "StdOut";
public ErrorContext() {
super();
Style root = getStyle(DEFAULT_STYLE);
Style s = addStyle(STDERROR, root);
StyleConstants.setForeground(s, Color.RED);
s = addStyle(STDOUT, root);
StyleConstants.setForeground(s, Color.BLACK);
}
}
PipedInputStream piOut;
PipedInputStream piErr;
PipedOutputStream poOut;
PipedOutputStream poErr;
ErrorContext errorcontext = new ErrorContext();
JTextPane textArea = new JTextPane(new DefaultStyledDocument(
errorcontext));
PrintStream oriout;
PrintStream orierr;
/**
* Creates a new Console object.
* @throws IOException
*/
public Console() throws IOException {
// Set up System.out
piOut = new PipedInputStream();
poOut = new PipedOutputStream(piOut);
oriout = System.out;
System.setOut(new PrintStream(poOut, true));
// Set up System.err
piErr = new PipedInputStream();
poErr = new PipedOutputStream(piErr);
orierr = System.err;
System.setErr(new PrintStream(poErr, true));
// Add a scrolling text area
textArea.setEditable(false);
// Create reader threads
new ReaderThread(piOut, ErrorContext.STDOUT).start();
new ReaderThread(piErr, ErrorContext.STDERROR).start();
}
class ReaderThread extends Thread {
PipedInputStream pi;
String type;
ReaderThread(PipedInputStream pi, String type) {
this.pi = pi;
this.type = type;
}
/**
* @see java.lang.Thread#run()
*/
public void run() {
final byte[] buf = new byte[1024];
while (true) {
try {
final int len = pi.read(buf);
if (len == -1) {
break;
}
javax.swing.text.Document doc = textArea.getDocument();
AttributeSet attset = errorcontext.getStyle(type);
String snippet = new String(buf, 0, len);
doc.insertString(doc.getLength(),
snippet, attset);
oriout.print(snippet);
textArea.setCaretPosition(textArea.getDocument().
getLength());
} catch (BadLocationException ex) {
} catch (IOException e) {
}
}
}
}
}
}