Author: heuermh
Date: Fri May 15 12:44:06 2009
New Revision: 442
Added:
piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/PrintExample.java
Log:
Issue 66 ; adding PrintExample to examples to replicate issue
Added:
piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/PrintExample.java
==============================================================================
--- (empty file)
+++
piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/PrintExample.java
Fri May 15 12:44:06 2009
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2008-2009, Piccolo2D project, http://piccolo2d.org
+ * Copyright (c) 1998-2008, University of Maryland
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
this list of conditions
+ * and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
notice, this list of conditions
+ * and the following disclaimer in the documentation and/or other
materials provided with the
+ * distribution.
+ *
+ * None of the name of the University of Maryland, the name of the
Piccolo2D project, or the names of its
+ * contributors may be used to endorse or promote products derived from
this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package edu.umd.cs.piccolo.examples;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.util.Iterator;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+
+import edu.umd.cs.piccolo.PCanvas;
+import edu.umd.cs.piccolo.PLayer;
+import edu.umd.cs.piccolo.nodes.PPath;
+import edu.umd.cs.piccolo.util.PAffineTransform;
+import edu.umd.cs.piccolo.util.PBounds;
+import edu.umd.cs.piccolox.PFrame;
+import edu.umd.cs.piccolox.swing.PDefaultScrollDirector;
+import edu.umd.cs.piccolox.swing.PScrollDirector;
+import edu.umd.cs.piccolox.swing.PScrollPane;
+import edu.umd.cs.piccolox.swing.PViewport;
+
+/**
+ * Adding print action to scrolling example.
+ *
+ * @author Lance Good
+ * @author Ben Bederson
+ */
+public class PrintExample extends PFrame {
+
+ public PrintExample() {
+ this(null);
+ }
+
+ public PrintExample(PCanvas aCanvas) {
+ super("ScrollingExample", false, aCanvas);
+ }
+
+ public void initialize() {
+ final PCanvas canvas = getCanvas();
+ final PScrollPane scrollPane = new PScrollPane(canvas);
+ final PViewport viewport = (PViewport) scrollPane.getViewport();
+ final PScrollDirector windowSD = viewport.getScrollDirector();
+ final PScrollDirector documentSD = new DocumentScrollDirector();
+
+ // Make some rectangles on the surface so we can see where we are
+ for (int x = 0; x < 20; x++) {
+ for (int y = 0; y < 20; y++) {
+ if (((x + y) % 2) == 0) {
+ PPath path = PPath.createRectangle(50 * x, 50 * y, 40,
40);
+ path.setPaint(Color.blue);
+ path.setStrokePaint(Color.black);
+ canvas.getLayer().addChild(path);
+ }
+ else if (((x + y) % 2) == 1) {
+ PPath path = PPath.createEllipse(50 * x, 50 * y, 40,
40);
+ path.setPaint(Color.blue);
+ path.setStrokePaint(Color.black);
+ canvas.getLayer().addChild(path);
+ }
+ }
+ }
+
+ // Now, create the toolbar
+ JToolBar toolBar = new JToolBar();
+ JToggleButton window = new JToggleButton("Window Scrolling");
+ JToggleButton document = new JToggleButton("Document Scrolling");
+ JButton print = new JButton("Print");
+ ButtonGroup bg = new ButtonGroup();
+ bg.add(window);
+ bg.add(document);
+ toolBar.add(window);
+ toolBar.add(document);
+ toolBar.addSeparator();
+ toolBar.add(print);
+ toolBar.setFloatable(false);
+ window.setSelected(true);
+ window.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ viewport.setScrollDirector(windowSD);
+ viewport.fireStateChanged();
+ scrollPane.revalidate();
+ getContentPane().validate();
+ }
+ });
+ document.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ viewport.setScrollDirector(documentSD);
+ viewport.fireStateChanged();
+ scrollPane.revalidate();
+ getContentPane().validate();
+ }
+ });
+ print.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ print();
+ }
+ });
+ JPanel contentPane = new JPanel();
+ contentPane.setLayout(new BorderLayout());
+ contentPane.add("Center", scrollPane);
+ contentPane.add("North", toolBar);
+ setContentPane(contentPane);
+ validate();
+ }
+
+ /**
+ * A modified scroll director that performs document based scroling
rather
+ * than window based scrolling (ie. the scrollbars act in the inverse
+ * direction as normal)
+ */
+ public class DocumentScrollDirector extends PDefaultScrollDirector {
+
+ /**
+ * Get the View position given the specified camera bounds -
modified
+ * such that:
+ *
+ * Rather than finding the distance from the upper left corner of
the
+ * window to the upper left corner of the document - we instead
find the
+ * distance from the lower right corner of the window to the upper
left
+ * corner of the document THEN we subtract that value from total
+ * document width so that the position is inverted
+ *
+ * @param viewBounds The bounds for which the view position will be
+ * computed
+ * @return The view position
+ */
+ public Point getViewPosition(Rectangle2D viewBounds) {
+ Point pos = new Point();
+ if (camera != null) {
+ // First we compute the union of all the layers
+ PBounds layerBounds = new PBounds();
+ java.util.List layers = camera.getLayersReference();
+ for (Iterator i = layers.iterator(); i.hasNext();) {
+ PLayer layer = (PLayer) i.next();
+ layerBounds.add(layer.getFullBoundsReference());
+ }
+
+ // Then we put the bounds into camera coordinates and
+ // union the camera bounds
+ camera.viewToLocal(layerBounds);
+ layerBounds.add(viewBounds);
+
+ // Rather than finding the distance from the upper left
corner
+ // of the window to the upper left corner of the document -
+ // we instead find the distance from the lower right corner
+ // of the window to the upper left corner of the document
+ // THEN we measure the offset from the lower right corner
+ // of the document
+ pos.setLocation((int) (layerBounds.getWidth()
+ - (viewBounds.getX() + viewBounds.getWidth() -
layerBounds.getX()) + 0.5), (int) (layerBounds
+ .getHeight()
+ - (viewBounds.getY() + viewBounds.getHeight() -
layerBounds.getY()) + 0.5));
+ }
+
+ return pos;
+
+ }
+
+ /**
+ * We do the same thing we did in getViewPosition above to flip the
+ * document-window position relationship
+ *
+ * @param x The new x position
+ * @param y The new y position
+ */
+ public void setViewPosition(double x, double y) {
+ if (camera != null) {
+ // If a scroll is in progress - we ignore new scrolls -
+ // if we didn't, since the scrollbars depend on the camera
+ // location
+ // we can end up with an infinite loop
+ if (!scrollInProgress) {
+ scrollInProgress = true;
+
+ // Get the union of all the layers' bounds
+ PBounds layerBounds = new PBounds();
+ java.util.List layers = camera.getLayersReference();
+ for (Iterator i = layers.iterator(); i.hasNext();) {
+ PLayer layer = (PLayer) i.next();
+ layerBounds.add(layer.getFullBoundsReference());
+ }
+
+ PAffineTransform at = camera.getViewTransform();
+ at.transform(layerBounds, layerBounds);
+
+ // Union the camera view bounds
+ PBounds viewBounds = camera.getBoundsReference();
+ layerBounds.add(viewBounds);
+
+ // Now find the new view position in view coordinates -
+ // This is basically the distance from the lower right
+ // corner of the window to the upper left corner of the
+ // document
+ // We then measure the offset from the lower right
corner
+ // of the document
+ Point2D newPoint = new
Point2D.Double(layerBounds.getX() + layerBounds.getWidth()
+ - (x + viewBounds.getWidth()),
layerBounds.getY() + layerBounds.getHeight()
+ - (y + viewBounds.getHeight()));
+
+ // Now transform the new view position into global
coords
+ camera.localToView(newPoint);
+
+ // Compute the new matrix values to put the camera at
the
+ // correct location
+ double newX = -(at.getScaleX() * newPoint.getX() +
at.getShearX() * newPoint.getY());
+ double newY = -(at.getShearY() * newPoint.getX() +
at.getScaleY() * newPoint.getY());
+
+ at.setTransform(at.getScaleX(), at.getShearY(),
at.getShearX(), at.getScaleY(), newX, newY);
+
+ // Now actually set the camera's transform
+ camera.setViewTransform(at);
+ scrollInProgress = false;
+ }
+ }
+ }
+ }
+
+ /**
+ * Print the canvas.
+ */
+ private void print()
+ {
+ PrinterJob printJob = PrinterJob.getPrinterJob();
+ printJob.setPrintable(new Printable() {
+ public int print(Graphics graphics, PageFormat pageFormat, int
pageIndex) throws PrinterException {
+ if (pageIndex > 0) {
+ return (NO_SUCH_PAGE);
+ } else {
+ Graphics2D g2 = (Graphics2D) graphics;
+ g2.translate(pageFormat.getImageableX(),
pageFormat.getImageableY());
+ getCanvas().printAll(g2);
+ return (PAGE_EXISTS);
+ }
+ }
+ });
+ if (printJob.printDialog()) {
+ try {
+ printJob.print();
+ } catch (PrinterException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ new PrintExample();
+ }
+}
--~--~---------~--~----~------------~-------~--~----~
Piccolo2D Developers Group: http://groups.google.com/group/piccolo2d-dev?hl=en
-~----------~----~----~----~------~----~------~--~---