pagepanel.java
来自「Java生成PDF Java生成PDF Java生成PDF」· Java 代码 · 共 595 行 · 第 1/2 页
JAVA
595 行
// $Id: PagePanel.java,v 1.24 2007/11/05 14:54:57 mike Exp $package org.faceless.pdf2.viewer2;import java.awt.*;import java.awt.image.*;import java.awt.event.*;import java.awt.geom.*;import java.io.*;import java.util.*;import java.util.List;import javax.swing.*;import org.faceless.pdf2.*;/** * The <code>PagePanel</code> class is the lowest-level class for rendering a {@link PDFPage} * as a {@link JPanel}. At it's most basic it will simply render the page via a {@link PagePainter}, * but when included inside a {@link DocumentViewport} as part of a {@link DocumentPanel} * this class may also create subcomponents representing {@link PDFAnnotation}s, as created by the * {@link AnnotationComponentFactory} class. * See the <a href="doc-files/tutorial.html">viewer tutorial</a> for more detail on how to use this class and the "viewer" package. * <p><i>This code is copyright the Big Faceless Organization. You're welcome to use, modify and distribute it in any form in your own projects, provided those projects continue to make use of the Big Faceless PDF library.</i></p> * @see DocumentViewport * @since 2.8 */public class PagePanel extends JPanel{ private DocumentViewport viewport; // The viewport this page is a member of private PDFPage page; // The page currently being displayed private PDFParser parser; // The PDFParser to create the pages private PagePainter pagepainter; // The PagePainter to paint the current page private PainterThread paintthread; // Thread that handles the page update private BufferedImage pageimage; // The image of the page created in paintthread private float dpi; // The DPI private float x1, y1, x2, y2; // Scope of the viewport private int orientation; // The Page orientation private RenderingHints hints; private final Collection listeners; // Collection of PagePanelListener objects private final Collection ilisteners; // Collection of PagePanelInteractionListener objects private Map annotcomponents; // Map of PDFAnnotation -> JComponent private Listener mouselistener; private boolean extract; private PageExtractor extractor; /** * Create a new PagePanel */ public PagePanel() { super(null, true); setOpaque(true); listeners = new LinkedHashSet(); ilisteners = new LinkedHashSet(); annotcomponents = new HashMap(); paintthread = new PainterThread(); paintthread.start(); mouselistener = new Listener(); } Map getAnnotationComponents() { return annotcomponents; } /** * Return the area of the page that is considered to be the "whole page" * as far as the viewer is concerned - the {@link PDFPage#getBox ViewBox} * @return the area of the page that's the full page, in points * @see PDFPage#getBox * @see PDF#getOption */ public static Rectangle2D getFullPageView(PDFPage page) { float[] box = page.getBox("ViewBox"); return new Rectangle2D.Float(box[0], box[1], box[2]-box[0], box[3]-box[1]); } /** * Add a {@link PagePanelListener} to this PagePanel */ public void addPagePanelListener(PagePanelListener listener) { if (listener!=null) listeners.add(listener); } /** * Remove a {@link PagePanelListener} from this PagePanel */ public void removePagePanelListener(PagePanelListener listener) { listeners.remove(listener); } /** * Add a {@link PagePanelInteractionListener} to this PagePanel */ public void addPagePanelInteractionListener(PagePanelInteractionListener listener) { if (listener!=null) { if (ilisteners.isEmpty()) { addMouseListener(mouselistener); addMouseMotionListener(mouselistener); } ilisteners.add(listener); } } /** * Remove a {@link PagePanelInteractionListener} from this PagePanel */ public void removePagePanelInteractionListener(PagePanelInteractionListener listener) { ilisteners.remove(listener); if (ilisteners.isEmpty()) { removeMouseListener(mouselistener); removeMouseMotionListener(mouselistener); } } /** * Set the {@link RenderingHints} to be used when rendering pages * in this PagePanel. * @param hints the RenderingHints to use - may be null */ public void setRenderingHints(RenderingHints hints) { this.hints = hints; } /** * Set the {@link PDFParser} object which should be used to render the pages. * @param parser the PDFParser */ public void setParser(PDFParser parser) { this.parser = parser; } /** * Set whether to extract text while rendering this page to a {@link PageExtractor} * @param extract true to extract the text, false otherwise */ public void setExtractText(boolean extract) { this.extract = extract; } /** * If the text was extracted on the last paint because of a call to * {@link #setExtractText}, return the {@link PageExtractor} it was * extracted to, otherwise return <code>null</code> */ public PageExtractor getPageExtractor() { return extractor; } /** * Redraw the page. The page will be rerendered in the background and when it's * complete this component will be resized and repainted. If annotations are being * created they will be repositioned and redrawn as well. * * @param page the page to draw * @param position the area of the page to draw, in points * @param dpi the resolution */ public void setPage(PDFPage page, Rectangle2D position, float dpi) { setPage(page, (float)position.getMinX(), (float)position.getMinY(), (float)position.getMaxX(), (float)position.getMaxY(), dpi); } /** * Redraw the page. The page will be rerendered in the background and when it's * complete this component will be resized and repainted. If annotations are being * created they will be repositioned and redrawn as well. * * @param page the page to draw * @param x1 the left-most X co-ordinate to draw, in points from the bottom-left * @param y1 the bottom-most Y co-ordinate to draw, in points from the bottom-left * @param x2 the right-most X co-ordinate to draw, in points from the bottom-left * @param y2 the top-most Y co-ordinate to draw, in points from the bottom-left * @param dpi the resolution */ public synchronized void setPage(PDFPage page, float x1, float y1, float x2, float y2, float dpi) { if (dpi<=0 || dpi!=dpi) throw new IllegalArgumentException("Invalid DPI "+dpi); if (page!=this.page) { removeAll(); if (page!=null) { pagepainter = parser.getPagePainter(page); if (hints!=null) pagepainter.setRenderingHints(hints); page.flush(); if (hasAnnotations()) { pagepainter.setPaintAnnotations(false); List annots = page.getAnnotations(); for (int i=0;i<annots.size();i++) { PDFAnnotation annot = (PDFAnnotation)annots.get(i); JComponent c = createComponentForAnnotation(annot); c.setVisible(false); annotcomponents.put(annot, c); add(c); } } } } paintthread.redraw(pagepainter, page, x1, y1, x2, y2, dpi); } /** * Get the {@link DocumentViewport} this PagePanel is contained inside, or * <code>null</code> if this PagePanel was not created as part of a * {@link DocumentPanel} */ public DocumentViewport getViewport() { return viewport; } /** * Get the {@link DocumentPanel} this PagePanel is contained inside, or * <code>null</code> if this PagePanel was not created as part of a * {@link DocumentPanel}. A shortcut for <code>getViewport().getDocumentPanel()</code> */ public DocumentPanel getDocumentPanel() { return viewport==null ? null : viewport.getDocumentPanel(); } /** * Return the {@link PDFPage} currently being displayed by this viewport. * Note this method returns the page being displayed, not the page currently * being rendered, so it's value will not immediately reflect the page passed * in to {@link #setPage setPage()}, and will be <code>null</code> if the * first page has not yet finished rendering. */ public PDFPage getPage() { return page; } /** * Returns the area of the page currently being displayed, in points with * (0,0) at the bottom-left. Like {@link #getPage} the return value of * this method will not immediately reflect the position passed in to * {@link #setPage setPage()}, and will be <code>null</code> if the fist * page has not yet finished rendering. */ public Rectangle2D getView() { Rectangle2D rect = null; if (page!=null) { int rot = (page.getPageOrientation()-orientation+360)%360; if (rot==0) { rect = new Rectangle2D.Float(x1, y1, x2-x1, y2-y1); } else { int w = page.getWidth(); int h = page.getHeight(); if (rot==90) { rect = new Rectangle2D.Float(y1, h-x2, y2-y1, x2-x1); } else if (rot==180) { rect = new Rectangle2D.Float(w-x2, h-y2, x2-x1, y2-y1); } else { rect = new Rectangle2D.Float(h-y2, x1, y2-y1, x2-x1); } } } return rect; } static boolean equalsRectangle2D(Rectangle2D r1, Rectangle2D r2) { // To catch rounding error double x1d = Math.abs(r1.getMinX()-r2.getMinX()); double x2d = Math.abs(r1.getMaxX()-r2.getMaxX()); double y1d = Math.abs(r1.getMinY()-r2.getMinY()); double y2d = Math.abs(r1.getMaxY()-r2.getMaxY()); return x1d<0.01 && x2d<0.01 && y1d<0.01 && y2d<0.01; } /** * Return the resolution of the page currently being displayed. * Like {@link #getPage} the return value of this method will not * immediately reflect the position passed in to {@link #setPage setPage()}, * and will be 0 if the fist page has not yet finished rendering. */ public float getDPI() { return page==null ? 0 : dpi; } /** * Given a location on this panel in pixels, return the equivalent * position on the current page in points. * @see #getAWTPoint */ public Point2D getPDFPoint(int x, int y) { return new Point2D.Float((x*72f/dpi) + x1, y2-(y*72f/dpi)); } /** * Given a location on the page in points, return the equivalent * position on this PagePanel in pixels. * @see #getPDFPoint */ public Point getAWTPoint(float x, float y) { return new Point((int)((x-x1)/72*dpi), (int)((y2-y)/72*dpi)); } void setViewport(DocumentViewport viewport) { this.viewport = viewport; } protected void addImpl(Component c, Object constraints, int index) { super.addImpl(c, constraints, index); if (c instanceof JComponent && ((JComponent)c).getClientProperty("pdf.rect")!=null) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?