/*
* $Id: PDFTest.java,v 1.2 2007/08/26 18:56:35 gil1 Exp $
*
* $Date: 2007/08/26 18:56:35 $
*
* Copyright (C) 2001 Eric Z. Beard, ericzbeard@hotmail.com
*
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package gnu.jpdf;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.JobAttributes;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.PrintJob;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.Scrollable;
/**
* <p>The purpose of this class is to test all functionality of the
* gnu.jpdf package and serve as a demonstration of how to use the
* library.</p>
*
* <p>This library produces pdf format files and can display and print
* them in a java Graphics context by extending java.awt.Graphics and
* java.awt.PrintJob. The pdf file itself is not viewed, but an
* identical copy made with the same methods that constructed the
* pdf file. See the code or the tutorial for an example</p>
*
* @author Eric Z. Beard
* <a href = "mailto:ericzbeard@hotmail.com">ericzbeard@hotmail.com</a>
* @version $Revision: 1.2 $
*/
public class PDFTest extends JFrame implements ActionListener
{
/** Entered on the command line after '-pdf' */
private static String outputPdfFile;
/** Entered on the command line after '-img' */
private static String sampleImageFile;
/** Not yet supported - test without a window */
private static boolean noWindow;
/** Main content pane */
private JPanel pane = new JPanel();
/** All sizes will be derived from the desired pdf document size */
private Dimension documentDimension;
private int currentPage;
private PDFJob job;
private boolean pdfDocumentAlreadyDone;
/**
* A JPanel used for drawing the document on the screen
*
* The source is included in this file at the bottom
*/
private TestPanel drawingArea;
/** The menu bar */
private TestMenuBar menuBar;
// TODO: Add the toolbar, use Action objects for action handling
public PDFTest(String outputPdfFile,
String sampleImageFile,
boolean noWindow) {
// First see if the file path is valid
File file = null;
FileOutputStream fileOutputStream = null;
try {
file = new File(outputPdfFile);
fileOutputStream = new FileOutputStream(file);
}
catch (Exception e) {
System.err.println("Error!! - Invalid output file path: " +
outputPdfFile);
usage();
System.exit(1);
}
// Handle window closing
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container contentPane = getContentPane();
pane.setLayout(new BorderLayout());
// Add the menubar
menuBar = new TestMenuBar(this);
setJMenuBar(menuBar);
// Get the Graphics object for pdf writing
Graphics pdfGraphics = null;
job = new PDFJob(fileOutputStream);
pdfGraphics = job.getGraphics();
Dimension d = job.getPageDimension();
documentDimension = d;
// Finish setting up the window and bring to front
int w = (int)d.getWidth();
int h = (int)d.getHeight();
drawingArea = new TestPanel();
// Put the drawing area in a scroll pane
JScrollPane scrollPane = new JScrollPane(drawingArea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
// Set the preferred size bigger than the scroll pane so the bars show up
drawingArea.setPreferredSize(new Dimension(1000, 1000));
pane.add(scrollPane, "Center");
contentPane.add(pane);
setTitle("PDF Test Application");
// Set the location and size of the window and show it
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
setLocation(50, 50);
setSize(w, h/2);
setVisible(true);
toFront();
doFirstPage(pdfGraphics);
currentPage = 1;
if (fileOutputStream != null) {
try {
fileOutputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
fileOutputStream = null;
}
drawingArea.repaint();
pane.revalidate();
} // end constructor
private void doFirstPage(Graphics pdfGraphics) {
Dimension d = documentDimension;
// Get the graphics object for screen drawing
Image img = drawingArea.createImage((int)d.getWidth(),
(int)d.getHeight());
if (img == null) {
System.out.println("Error!! - drawing image is null");
System.exit(1);
}
drawingArea.setImage(img);
Graphics javaGraphics = img.getGraphics();
// Now we have two Graphics objects - one for java Graphics to
// draw to the screen , another to write
// to the pdf file. We'll use the same methods to act on both
// objects, and (theoretically) the results should be identical.
// If 'Print' is selected from the menu, the same methods wi
// act on a Graphics object from the java.awt.PrintJob
doTest(javaGraphics, d);
javaGraphics.dispose();
// The whole pdf doc will be written when the program starts
if ((!pdfDocumentAlreadyDone) && (pdfGraphics != null)) {
doTest(pdfGraphics, d);
pdfGraphics.dispose();
pdfGraphics = job.getGraphics();
doSecondPageTest(pdfGraphics);
pdfGraphics.dispose();
job.end();
}
// The same methods (such as 'job.end()') are called on the pdf job
// as on a print job, so this could be abstracted further to use the
// same code on both jobs
currentPage = 1;
drawingArea.repaint();
drawingArea.revalidate();
}
/**
* <p>Very basic action handler - a more robust app would use
* Action objects</p>
*
* @param e an <code>ActionEvent</code> value
*/
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == menuBar.close) {
System.exit(0);
}
if (source == menuBar.printer) {
printPdf();
return;
}
if (source == menuBar.helpTopics) {
System.out.println("Help..");
showHelp();
return;
}
if (source == menuBar.aboutApp) {
System.out.println("About...");
showAboutBox();
return;
}
if (source == menuBar.viewFirstPage) {
if (currentPage != 1) {
doFirstPage(null);
return;
}
}
if (source == menuBar.viewSecondPage) {
if (currentPage != 2) {
doSecondPage();
return;
}
}
}
/**
* <p>Show the about dialog box</p>
*
*/
private void showAboutBox() {
JOptionPane.showMessageDialog(this, "gnujpdf test application, " +
"by Eric Z. Beard. " +
"http://gnujpdf.sourceforge.net");
}
/**
* <p>Show a help dialog - it would be good to use text from
* a tutorial that sits in the docs directory</p>
*
*/
private void showHelp() {
HelpFrame helpFrame = new HelpFrame();
}
/**
* <p>Gets a print job and uses the same drawing methods that
* were used on the other Graphics objects to print the document</p>
*
*/
private void printPdf() {
System.out.println("Printing..");
JobAttributes jobAttributes = new JobAttributes();
//jobAttributes.setDialog(JobAttributes.DialogType.NONE);
// CRAP!! - This doesn't work with jdk1.2.2 - fix it
Toolkit toolkit = Toolkit.getDefaultToolkit();
PrintJob pjob = toolkit.getPrintJob(this,
"PDF Test Print",
jobAttributes,
null);
if(pjob != null) {
Graphics printGraphics = pjob.getGraphics();
if (currentPage == 1) {
doTest(printGraphics, documentDimension);
printGraphics.dispose();
pjob.end();
}
else {
doSecondPageTest(printGraphics);
printGraphics.dispose();
pjob.end();
}
}
else {
System.err.println("Can't print: printjob null");
}
}
/**
* <p>This method accepts any Graphics object and draws to it. It
* can be a java Graphics object for drawing to the screen, a pdf
* graphics object for constructing a pdf object, or a print job
* graphics object. The goal is to make all three look exactly the
* same, along with how the document looks when opened in Acrobat
* Reader and printed from Acrobat Reader - so it's actually 5 things
* that should ultimately look exactly the same, all constructed with
* the same set of methods</p>
*
* <p>This method should provide programmers with a good basis
* for using the BoundingBox class, if they choose to do so. It is by
* no means necessary, as it only makes layout on a fixed dimension
* canvas easier. The point of the pdf graphics library is to use
* the same drawing methods used in applets and applications</p>
*
* @param g a <code>Graphics</code> object to draw to
* @param d a <code>Dimension</code> object, the size of the document
*/
private void doTest(Graphics g, Dimension d) {
g.setColor(Color.white);
g.fillRect(0,0,d.width, d.height);
g.setColor(Color.black);
Point boxUpperLeft = new Point(60, 60);
Dimension boxSize = new Dimension(200, 200);
Font f = new Font("TimesRoman", Font.PLAIN, 14);
g.setFont(f);
FontMetrics fm = g.getFontMetrics(f);
BoundingBox box = new BoundingBox(boxUpperLeft, boxSize);
String string = "Hello World! this is a really long string";
int padding = 10;
BoundingBox child = null;
try {
child = box.getStringBounds(string,
BoundingBox.HORIZ_ALIGN_CENTER,
BoundingBox.VERT_ALIGN_BOTTOM,
fm,
padding);
}
catch (StringTooLongException stle) {
// A more robust app might just cut off the end of the string or
// prevent the string from ever being too long or break it into
// pieces and create a new PDFPage (by getting a new graphics object)
// and continue the document
stle.printStackTrace();
return;
}
g.drawRect(60, 60, 200, 200);
g.drawRect((int)child.getLocation().getX() + 60,
(int)child.getLocation().getY() + 60,
(int)child.getSize().getWidth(),
(int)child.getSize().getHeight());
Point p = child.getDrawingPoint();
int x = (int)p.getX();
int y = (int)p.getY();
// Draw the baseline
g.drawLine(x, y, x + ((int)child.getSize().getWidth() - padding*2), y);
try {
child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_CENTER);
}
catch (StringTooLongException stle) {
stle.printStackTrace();
return;
}
//drawHeader(g, d);
//drawBody(g, d);
// Draw Hello world in a nested box
BoundingBox b1 = new BoundingBox(new Point(300, 60),
new Dimension(200, 200));
g.drawRect((int)b1.getAbsoluteLocation().getX(),
(int)b1.getAbsoluteLocation().getY(),
(int)b1.getSize().getWidth(),
(int)b1.getSize().getHeight());
BoundingBox b2 = new BoundingBox(new Point(10, 10),
new Dimension(100, 100));
b1.add(b2);
g.drawRect((int)b2.getAbsoluteLocation().getX(),
(int)b2.getAbsoluteLocation().getY(),
(int)b2.getSize().getWidth(),
(int)b2.getSize().getHeight());
try {
BoundingBox b3 = b2.getStringBounds(string,
BoundingBox.HORIZ_ALIGN_CENTER,
BoundingBox.VERT_ALIGN_BOTTOM,
fm,
padding);
g.drawRect((int)b3.getAbsoluteLocation().getX(),
(int)b3.getAbsoluteLocation().getY(),
(int)b3.getSize().getWidth(),
(int)b3.getSize().getHeight());
Point pt = b3.getDrawingPoint();
int px = (int)pt.getX();
int py = (int)pt.getY();
b3.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_CENTER);
}
catch (StringTooLongException stle) {
stle.printStackTrace();
}
drawStringsInBox(g);
drawSampleImage(g, d);
} // end doTest
/**
* Describe <code>drawStringsInBox</code> method here.
*
* @param g a <code>Graphics</code> value
*/
private void drawStringsInBox(Graphics g) {
g.setColor(Color.black);
BoundingBox box = new BoundingBox(new Point(20, 300),
new Dimension(250, 250));
g.drawRect((int)box.getAbsoluteLocation().getX(),
(int)box.getAbsoluteLocation().getY(),
(int)box.getSize().getWidth(),
(int)box.getSize().getHeight());
Font f = new Font("Helvetica", Font.PLAIN, 12);
g.setFont(f);
FontMetrics fm = g.getFontMetrics();
String line1 = "Line 1";
String line2 = "Line 2";
String line3 = "Line 3 realllllly loooooong .h gkjhg kjh gkjh gkjhg kjhg kjhg kjh gk jbhg";
int padding = 5;
BoundingBox child = null;
try {
child = box.getStringBounds(line1,
BoundingBox.HORIZ_ALIGN_LEFT,
BoundingBox.VERT_ALIGN_TOP,
fm,
padding);
child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_LEFT);
}
catch (StringTooLongException stle) {
stle.printStackTrace();
return;
}
box.subtract(child, BoundingBox.SUBTRACT_FROM_BOTTOM);
try {
child = box.getStringBounds(line2,
BoundingBox.HORIZ_ALIGN_LEFT,
BoundingBox.VERT_ALIGN_TOP,
fm,
padding);
child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_LEFT);
}
catch (StringTooLongException stle) {
stle.printStackTrace();
return;
}
box.subtract(child, BoundingBox.SUBTRACT_FROM_BOTTOM);
try {
child = box.getStringBounds(line3,
BoundingBox.HORIZ_ALIGN_LEFT,
BoundingBox.VERT_ALIGN_TOP,
fm,
padding);
child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_LEFT);
}
catch (StringTooLongException stle) {
stle.printStackTrace();
return;
}
box.subtract(child, BoundingBox.SUBTRACT_FROM_BOTTOM);
try {
child = box.getStringBounds(line1,
BoundingBox.HORIZ_ALIGN_RIGHT,
BoundingBox.VERT_ALIGN_BOTTOM,
fm,
padding);
child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_RIGHT);
box.subtract(child, BoundingBox.SUBTRACT_FROM_TOP);
child = box.getStringBounds(line2,
BoundingBox.HORIZ_ALIGN_RIGHT,
BoundingBox.VERT_ALIGN_BOTTOM,
fm,
padding);
child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_RIGHT);
box.subtract(child, BoundingBox.SUBTRACT_FROM_TOP);
child = box.getStringBounds(line3,
BoundingBox.HORIZ_ALIGN_RIGHT,
BoundingBox.VERT_ALIGN_BOTTOM,
fm,
padding);
child.drawWrappedString(g, fm, padding, BoundingBox.HORIZ_ALIGN_RIGHT);
box.subtract(child, BoundingBox.SUBTRACT_FROM_TOP);
}
catch (StringTooLongException stle) {
stle.printStackTrace();
return;
}
} // end drawStringsInBox
/**
* Describe <code>drawSampleImage</code> method here.
*
* @param g a <code>Graphics</code> value
* @param d a <code>Dimension</code> value
*/
private void drawSampleImage(Graphics g, Dimension d) {
try {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image img = toolkit.createImage(sampleImageFile);
MediaTracker tracker = new MediaTracker(drawingArea);
tracker.addImage(img, 0);
try {
tracker.waitForID(0);
}
catch (Exception e) {
e.printStackTrace();
}
/* bazsoft
g.drawImage(img, 300, 300,
img.getWidth(drawingArea),
img.getHeight(drawingArea),
Color.green,
drawingArea);
*/
g.drawImage(img, 10, 10,
img.getWidth(drawingArea),
img.getHeight(drawingArea),
Color.green,
drawingArea);
}
catch (Exception e) {
e.printStackTrace();
}
}
private void doSecondPage() {
Dimension d = documentDimension;
// Get the graphics object for screen drawing
Image img = drawingArea.createImage((int)d.getWidth(),
(int)d.getHeight());
if (img == null) {
System.out.println("Error!! - drawing image is null");
System.exit(1);
}
drawingArea.setImage(img);
Graphics javaGraphics = img.getGraphics();
doSecondPageTest(javaGraphics);
javaGraphics.dispose();
currentPage = 2;
drawingArea.repaint();
drawingArea.revalidate();
}
private void doSecondPageTest(Graphics g) {
g.setColor(Color.white);
g.fillRect(0,0,documentDimension.width, documentDimension.height);
g.setColor(Color.black);
// test drawLine()
g.drawLine(10,10,50,50);
// test drawRect()
g.drawRect(30,10,10,10);
// test fillRect()
g.fillRect(30,90,10,10);
// test drawPolygon()
int xp[] = new int[] {10,10,20,15,20};
int yp[] = new int[] {50,60,60,55,50};
int np = xp.length;
g.drawPolygon(xp,yp,np);
// test drawPolygon()
xp = new int[] {60,60,70,65,70};
yp = new int[] {80,90,90,85,80};
np = xp.length;
g.drawPolyline(xp,yp,np);
// test fillPolygon()
xp = new int[] {60,60,70,65,70};
yp = new int[] {50,60,60,55,50};
np = xp.length;
g.fillPolygon(xp,yp,np);
// Now some text
g.setFont(new Font("SansSerif",Font.PLAIN,12));
g.drawString("This is a simple string",10,120);
g.drawString("This is a (complex) string",10,130);
g.drawString("(complex) string (with ( (multiple brackets ))",10,140);
// Now some arcs - first test is with a square
g.drawRect(200, 60, 50, 50); // rectangle
g.drawLine(200, 60,250,110); // join both corners
g.drawLine(200,110,250, 60);
g.drawLine(200, 85,225, 60); // this should be a chord
g.drawArc( 200, 60, 50, 50, 45,180); // the arc
// June 20, 2001 ezb - Looks like ovals work as expected
g.drawArc(100, 400, 100, 200, 0, 360);
g.drawOval(200, 400, 100, 200);
g.fillOval(300, 400, 100, 200);
// These two tests act on a rectangular region (ie width != height)
// Now the interesting thing is that they don't fit the arc within
// the rectangle, but act on the width. This - by accident - matches the
// way the Linux JDK operates...
// Now the same test, but with a rectangle
g.drawRect(300,50,80,40);
g.drawLine(300,50,380,90);
g.drawLine(300,90,380,50);
g.drawArc(300,50,80,40, 135,180);
// Again the same test, but we will fill the arc
g.drawRect(400,50,40,80);
g.drawLine(400,50,440,130);
g.drawLine(400,130,440,50);
g.setColor(Color.blue);
g.fillArc(400,50,40,80, 135,180);
g.setColor(Color.black);
// Repeat again, but this time with different angles to the arc.
// We do this to compare how Java and PDF render the arcs
g.drawRect(400,150,40,80);
g.drawLine(400,150,440,230);
g.drawLine(400,230,440,150);
g.setColor(Color.blue);
g.fillArc(400,150,40,80, 135,225);
g.setColor(Color.black);
// Finally draw a small table of all the fonts and styles
String fonts[] = new String[] {"SansSerif",
"Monospaced",
"TimesRoman",
"Helvetica",
"Courier",
"Dialog",
"DialogInput"};
String modes[] = new String[] {"Plain",
"Bold",
"Italic",
"Bold+Italic"};
int imodes[] = new int[] {Font.PLAIN,
Font.BOLD,
Font.ITALIC,
Font.BOLD + Font.ITALIC};
int ty = 170;
for(int i=0;i<modes.length;i++)
g.drawString(modes[i],100+(50*i),ty-14);
FontMetrics fm = g.getFontMetrics();
for(int i=0;i<fonts.length;i++)
g.drawString(fonts[i],98-fm.stringWidth(fonts[i]),ty+(12*i));
Font cf = g.getFont();
for(int i=0;i<fonts.length;i++) {
for(int j=0;j<modes.length;j++) {
g.setFont(new Font(fonts[i],imodes[j],10));
g.drawString(modes[j],100+(50*j),ty);
}
ty+=12;
}
} // end doSecondPage
/**
* <p>The test is initiated through the main method. From the
* command line, two parameters are needed, -pdf [path-to-pdf], which
* is the path and filename of the pdf you would like to create using
* this test. It should end in ".pdf". The other param is
* -img [path-to-image]. It should be a pre-existing image, preferably
* a very small jpg. The command line arg -nw, for no window test, is
* not yet supported.</p>
*
* @param args a <code>String[]</code> value
*/
public static void main(String[] args) {
if ((args != null) && (args.length > 0)) {
int len = args.length;
for (int i = 0; i < len; i++) {
if (args[i].equals("-nw")) {
noWindow = true;
}
if (args[i].equals("-pdf")) {
if (len > (i + 1)) {
outputPdfFile = args[i + 1];
}
}
if (args[i].equals("-img")) {
if (len > (i + 1)) {
sampleImageFile = args[i + 1];
}
}
}
}
else {
usage();
System.exit(1);
}
if (outputPdfFile == null) {
System.err.println("No output file specified");
usage();
System.exit(1);
}
if (sampleImageFile == null) {
System.err.println("No sample image file specified");
usage();
System.exit(1);
}
// Params are ok, proceed with test
PDFTest window = new PDFTest(outputPdfFile, sampleImageFile, noWindow);
} // end main
private static void usage() {
System.out.println("PDFTest Usage:");
System.out.println();
System.out.print("java -classpath <$CLASSPATH> gnu.jpdf.PDFTest -pdf ");
System.out.print("<output-file-path> -img <path-to-image>");
System.out.println();
System.out.println();
System.out.println("This will produce the pdf file generated at ");
System.out.println("<output-file-path> (which should end in '.pdf') and ");
System.out.println("use the image at <path-to-image>. Use a small jpg ");
System.out.println("preferably since the compression is not so good ");
System.out.println("and a pdf file will typically be 10 times as big as ");
System.out.println("the image used as a sample.");
System.out.println();
}
} // end class PDFTest
// Non public classes used by PDFTest
class TestPanel extends JPanel implements Scrollable
{
// Scrollable methods
private Image image;
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize(); // Not sure if this is what I want
}
public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation,
int direction) {
return 20; // This is fine, no customization needed
}
public boolean getScrollableTracksViewportHeight() {
return false; // true disables scrolling
}
public boolean getScrollableTracksViewportWidth() {
return false; // true disables scrolling
}
public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation,
int direction) {
return 5; // This is fine, no customization needed
}
public void setImage(Image img) {
image = img;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.gray);
g.fillRect(0,0,getSize().width,getSize().height);
if (image != null) {
g.drawImage(image, 0, 0, this);
}
} // end paintComponent
} // end class TestPanel
/**
* Really basic toolbar - not an example of the finest GUI design
*
*/
class TestMenuBar extends JMenuBar
{
JMenu file, personnel, help, about, view;
JMenuItem printer;
JMenuItem close;
JMenuItem helpTopics;
JMenuItem aboutApp;
JMenuItem viewFirstPage;
JMenuItem viewSecondPage;
public TestMenuBar(ActionListener parent)
{
file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);
printer = new JMenuItem("Print");
printer.setMnemonic(KeyEvent.VK_R);
printer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
ActionEvent.CTRL_MASK));
printer.addActionListener(parent);
//printer.setEnabled(false);
file.add(printer);
close = new JMenuItem("Close");
close.setMnemonic(KeyEvent.VK_Q);
close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
ActionEvent.CTRL_MASK));
close.addActionListener(parent);
file.add(close);
view = new JMenu("View");
view.setMnemonic(KeyEvent.VK_V);
// This isn't very extensible
viewFirstPage = new JMenuItem("First Page");
viewFirstPage.addActionListener(parent);
view.add(viewFirstPage);
viewSecondPage = new JMenuItem("Second Page");
viewSecondPage.addActionListener(parent);
view.add(viewSecondPage);
help = new JMenu("Help");
help.setMnemonic(KeyEvent.VK_H);
helpTopics = new JMenuItem("Help Topics");
helpTopics.addActionListener(parent);
help.add(helpTopics);
about = new JMenu("About");
about.setMnemonic(KeyEvent.VK_A);
aboutApp = new JMenuItem("About");
aboutApp.addActionListener(parent);
about.add(aboutApp);
add(file);
add(view);
add(help);
add(about);
} // end constructor
} // end class TestMenuBar
/**
* A simple help frame. Nothing fancy.
*
*/
class HelpFrame extends JFrame
{
public HelpFrame() {
setTitle("gnupdf Help");
Container helpContent = getContentPane();
helpContent.setLayout(new BorderLayout());
JTextArea textArea = new JTextArea(20, 40);
textArea.setLineWrap(true);
textArea.append(getHelpText());
JScrollPane helpScroller = new JScrollPane(textArea);
helpContent.add(helpScroller);
setSize(helpScroller.getSize());
setLocation(new Point(200, 200));
pack();
toFront();
show();
//helpScroller.getViewport().setViewPosition(new Point(0, 0));
//textArea.scrollRectToVisible(new Rectangle(0, 0, 2, 2));
textArea.setCaretPosition(0);
textArea.setEditable(false);
}
private String getHelpText() {
StringBuffer out = new StringBuffer();
out.append("gnujpdf Help File and Tutorial\n");
out.append("\n");
out.append("This file contains some general help and a simple tutorial on the\n");
out.append("gnujpdf java package (gnu.jpdf.*). More information can be\n");
out.append("obtained from the website, http://gnujpdf.sourceforge.net.\n");
out.append("\n");
out.append("gnujpdf is a set of Java classes that allows a programmer to use\n");
out.append("extended versions of java.awt.Graphics and java.awt.PrintJob to\n");
out.append("generate and print pdf files. The idea is to use methods and\n");
out.append("classes that act on a Graphics object to produce the same output\n");
out.append("in a pdf file, on the screen, and on the printer.\n");
out.append("\n");
out.append("The best source of information for a programmer wishing to use\n");
out.append("this simple API is the source code in PDFTest.java. It\n");
out.append("demonstrates a simple application that displays various\n");
out.append("formatting and simultaneously writes a pdf file that will be an\n");
out.append("identical copy of what is seen on the screen.\n");
out.append("\n");
out.append("The starting point for creating any PDF document with this\n");
out.append("library is the PDFJob class.\n");
out.append("\n");
out.append("PDFJob job = new PDFJob(fileOutputStream);\n");
out.append("\n");
out.append("The fileOutputStream is normally a stream initialized with the\n");
out.append("name of the pdf you wish to generate, such as \"test.pdf\". A\n");
out.append("PDFGraphics object can be obtained from the job by calling:\n");
out.append("\n");
out.append("Graphics pdfGraphics = job.getGraphics();\n");
out.append("\n");
out.append("This Graphics object can be passed into the same methods used to\n");
out.append("draw to the screen. Most of the common methods in\n");
out.append("java.awt.Graphics have been implemented (with a few important\n");
out.append("exceptions - this is a beta product, so there is still plenty of\n");
out.append("work to be done - see the source code for more specifics). When\n");
out.append("calling methods such as drawString(..) or drawImage(..), what is\n");
out.append("actually happening is that the PDFGraphics object is writing the\n");
out.append("necessary markup to the output stream.\n");
out.append("\n");
out.append("A new pdf page is initialized by disposing of the exisiting\n");
out.append("Graphics object and getting a new one from the job.\n");
out.append("\n");
out.append("pdfGraphics.dispose(); \n");
out.append("pdfGraphics = job.getGraphics();\n");
out.append("\n");
out.append("Any Graphics operations will now be made on a new page in the pdf\n");
out.append("document. When the document is finished, the job must be closed\n");
out.append("out:\n");
out.append("\n");
out.append("pdfGraphics.dispose();\n");
out.append("job.end();\n");
out.append("\n");
out.append("And the fileOutputStream will need to be closed properly as well,\n");
out.append("as this is not guaranteed to be taken care of by the PDF classes.\n");
out.append("\n");
out.append("----------------\n");
out.append("End of Help File\n");
out.append("\n");
out.append("For more information, see http://gnujpdf.sourceforge.net\n");
out.append("\n");
return out.toString();
}
} // end class HelpFrame