//******************************************************************************
//
// File:    DisplayablePanel.java
// Package: edu.rit.swing
// Unit:    Class edu.rit.swing.DisplayablePanel
//
// This Java source file is copyright (C) 2006 by Alan Kaminsky. All rights
// reserved. For further information, contact the author, Alan Kaminsky, at
// ark@cs.rit.edu.
//
// This Java source file is part of the Parallel Java Library ("PJ"). PJ is free
// software; you can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// PJ 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 General Public License for more details.
//
// A copy of the GNU General Public License is provided in the file gpl.txt. You
// may also obtain a copy of the GNU General Public License on the World Wide
// Web at http://www.gnu.org/licenses/gpl.html.
//
//******************************************************************************

package edu.rit.swing;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;

import javax.swing.JPanel;

/**
 * Class DisplayablePanel is a Swing {@link javax.swing.JPanel
 * JPanel} that displays a {@link Displayable
 * Displayable} object. The displayable panel can then be made part
 * of a Swing GUI.
 * 

* The displayable object is specified when the displayable panel is * constructed. A different displayable object can be specified later using the * display() method. The displayable panel's preferred size and the * displayable panel's bounds are set to the size of the displayable object when * the displayable panel is constructed and when the display() method * is called. If the same displayable panel will be displaying different * displayable objects, consider embedding the displayable panel in a * JScrollPane so the whole displayable object can be scrolled into view if the * displayable object becomes larger. *

* The displayable panel supports zooming (scaling) the displayable object. The * zoom factor is set when the displayable panel is constructed and when the * zoom() method is called. The displayable panel's preferred size and * bounds are actually those of the displayable object multiplied by the zoom * factor. *

* If the autofitting flag is true (see setAutofitting()), the * displayable panel will display a scaled version of the displayable object, * such that the displayable object is completely visible within the displayable * panel's current size. * * @author Alan Kaminsky * @version 10-Jul-2006 */ public class DisplayablePanel extends JPanel { // Hidden data members. private Displayable myDisplayable; private double myZoom = 1.0; private Dimension mySize; private boolean iamAutofitting; // Exported constructors. /** * Construct a new displayable panel. The displayable panel's preferred size * and bounds are set to the size of theDisplayable. * * @param theDisplayable Displayable object. * * @exception NullPointerException * (unchecked exception) Thrown if theDisplayable is null. */ public DisplayablePanel (Displayable theDisplayable) { super(); display (theDisplayable); } /** * Construct a new displayable panel with the given zoom factor. The * displayable panel's preferred size and bounds are set to the size of * theDisplayable multiplied by theZoom. * * @param theDisplayable Displayable object. * @param theZoom Zoom factor. * * @exception NullPointerException * (unchecked exception) Thrown if theDisplayable is null. * @exception IllegalArgumentException * (unchecked exception) Thrown if theZoom <= 0. */ public DisplayablePanel (Displayable theDisplayable, double theZoom) { super(); zoom (theZoom); display (theDisplayable); } // Exported operations. /** * Obtain this displayable panel's displayable object. * * @return Displayable object this displayable panel is displaying. */ public Displayable display() { return myDisplayable; } /** * Tell this displayable panel to display the given displayable object. * * @param theDisplayable Displayable object. * * @exception NullPointerException * (unchecked exception) Thrown if theDisplayable is null. */ public void display (Displayable theDisplayable) { if (theDisplayable == null) { throw new NullPointerException(); } myDisplayable = theDisplayable; if (! iamAutofitting) { Rectangle2D box = theDisplayable.getBoundingBox(); double w = box.getWidth() * myZoom; double h = box.getHeight() * myZoom; Dimension size = new Dimension(); size.setSize (w, h); setPreferredSize (size); Rectangle bounds = getBounds(); setBounds (bounds.x, bounds.y, (int) w, (int) h); } repaint(); } /** * Obtain this displayable panel's zoom factor. * * @return Zoom factor. */ public double zoom() { return myZoom; } /** * Specify this displayable panel's zoom factor. * * @param theZoom Zoom factor. * * @exception IllegalArgumentException * (unchecked exception) Thrown if theZoom <= 0. */ public void zoom (double theZoom) { if (theZoom <= 0.0) throw new IllegalArgumentException(); myZoom = theZoom; if (myDisplayable != null) display (myDisplayable); } /** * Determine whether this displayable panel is autofitting. * * @return True if this displayable panel is autofitting, false otherwise. */ public boolean isAutofitting() { return iamAutofitting; } /** * Set this displayable panel's autofitting flag to the given value. If the * autofitting flag is true, the displayable panel will display a scaled * version of the displayable object, such that the displayable object is * completely visible within the displayable panel's current size. * * @param autofit True to autofit, false otherwise. */ public void setAutofitting (boolean autofit) { iamAutofitting = autofit; repaint(); } /** * Paint this displayable panel into the given graphics context. * * @param g Graphics context. */ protected void paintComponent (Graphics g) { super.paintComponent (g); Graphics2D g2d = (Graphics2D) g; // Save graphics context. Paint oldPaint = g2d.getPaint(); RenderingHints oldHints = g2d.getRenderingHints(); AffineTransform oldTransform = g2d.getTransform(); // Turn on antialiasing. g2d.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint (RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // Paint one way if autofitting is turned on. if (iamAutofitting) { // Paint background. Rectangle panelsize = getBounds (null); g2d.setPaint (myDisplayable.getBackgroundPaint()); g2d.fill (panelsize); // Determine X and Y scale factors. double pw = panelsize.getWidth(); double ph = panelsize.getHeight(); Rectangle2D objectsize = myDisplayable.getBoundingBox(); double ow = objectsize.getWidth(); double oh = objectsize.getHeight(); double scalex = pw / ow; double scaley = ph / oh; // Set transform if X scale factor is smaller. if (scalex < scaley) { g2d.translate (0.0, (ph - oh * scalex) * 0.5); g2d.scale (scalex, scalex); } // Set transform if Y scale factor is smaller. else { g2d.translate ((pw - ow * scaley) * 0.5, 0.0); g2d.scale (scaley, scaley); } // Draw displayable object. myDisplayable.draw (g2d); } // Paint another way if autofitting is turned off. else { // Set zoom factor. g2d.scale (myZoom, myZoom); // Paint background. g2d.setPaint (myDisplayable.getBackgroundPaint()); g2d.fill (myDisplayable.getBoundingBox()); // Draw displayable object. myDisplayable.draw (g2d); } // Restore graphics context. g2d.setPaint (oldPaint); g2d.setRenderingHints (oldHints); g2d.setTransform (oldTransform); } }

Ads help maintain this website.