/*
* $Id: PagePanel.java 3117 2008-01-31 05:53:22Z xlv $
*
* Copyright 2007 Bruno Lowagie.
* Inspired by a demo shipped with SUN's PDF Renderer (released under the LGPL)
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.lowagie.rups.view.renderer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.ImageObserver;
import javax.swing.JPanel;
import com.sun.pdfview.PDFPage;
/**
* The panel that will show a rendered PDF page.
*/
public class PagePanel extends JPanel
implements ImageObserver, MouseListener, MouseMotionListener {
/** A Serial Version UID. */
private static final long serialVersionUID = -130815955294007634L;
/** The current PDFPage that was rendered into currentImage */
protected PDFPage currentPage;
/** The image of the rendered PDF page being displayed */
protected Image currentImage;
/** The horizontal offset of the image from the left edge of the panel */
protected int offx;
/** The vertical offset of the image from the top of the panel */
protected int offy;
/** the size of the image */
Dimension prevSize;
/** the current clip, in device space */
Rectangle2D clip;
/** the clipping region used for the image */
Rectangle2D prevClip;
/** the zooming marquee */
protected Rectangle zoomRect;
/** the current transform from device space to page space */
AffineTransform deviceToPageSpaceTransformation;
/**
* Creates a new PagePanel
*/
public PagePanel() {
super();
setFocusable(true);
addMouseListener(this);
addMouseMotionListener(this);
}
/**
* Gets the current page number.
* @return the number of the currently shown page.
*/
public int getCurrentPageNumber() {
if (currentPage == null) return 0;
return currentPage.getPageNumber();
}
/**
* Draw the image.
*/
public void paint(Graphics g) {
Dimension sz= getSize();
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
if (currentImage == null) {
// No image -- draw an empty box
g.setColor(Color.black);
g.drawString("No page selected", getWidth()/2-30, getHeight()/2);
} else {
// draw the image
int imwid= currentImage.getWidth(null);
int imhgt= currentImage.getHeight(null);
// draw it centered within the panel
offx = (sz.width-imwid)/2;
offy = (sz.height-imhgt)/2;
if ((imwid == sz.width && imhgt <= sz.height) ||
(imhgt == sz.height && imwid <= sz.width)) {
g.drawImage(currentImage, offx, offy, this);
}
else {
if (currentPage!=null) {
showPage(currentPage);
}
}
}
// draw the zoomrect if there is one.
if (zoomRect!=null) {
g.setColor(Color.red);
g.drawRect(zoomRect.x, zoomRect.y,
zoomRect.width, zoomRect.height);
}
}
/**
* Stop the generation of any previous page, and draw the new one.
* @param page the PDFPage to draw.
*/
public synchronized void showPage(PDFPage page) {
// stop drawing the previous page
if (currentPage != null && prevSize != null) {
currentPage.stop(prevSize.width, prevSize.height, prevClip);
}
// set up the new page
currentPage= page;
if (page==null) {
// no page
currentImage= null;
clip= null;
deviceToPageSpaceTransformation = null;
repaint();
} else {
Dimension sz= getSize();
if (sz.width + sz.height == 0) {
// no image to draw.
return;
}
// calculate the clipping rectangle in page space from the
// desired clip in screen space.
Rectangle2D useClip = clip;
if (clip != null && deviceToPageSpaceTransformation != null) {
useClip = deviceToPageSpaceTransformation.createTransformedShape(clip).getBounds2D();
}
Dimension pageSize = page.getUnstretchedSize(sz.width, sz.height, useClip);
// get the new image
currentImage= page.getImage(pageSize.width, pageSize.height,
useClip, this);
// calculate the transform from screen to page space
deviceToPageSpaceTransformation = page.getInitialTransform(pageSize.width,
pageSize.height,
useClip);
try {
deviceToPageSpaceTransformation = deviceToPageSpaceTransformation.createInverse();
} catch (NoninvertibleTransformException nte) {
System.out.println("Error inverting page transform!");
nte.printStackTrace();
}
prevClip = useClip;
prevSize = pageSize;
repaint();
}
}
/**
* Handles notification of the fact that some part of the image
* changed. Repaints that portion.
* @return true if more updates are desired.
*/
public boolean imageUpdate(Image img, int infoflags, int x, int y,
int width, int height) {
if ((infoflags & (SOMEBITS|ALLBITS))!=0) {
repaint(x + offx, y + offy, width, height);
}
return true;
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}