/* * Copyright (C) 2002-@year@ by University of Maryland, College Park, MD 20742, USA * All rights reserved. * * Piccolo was written at the Human-Computer Interaction Laboratory * www.cs.umd.edu/hcil by Jesse Grosjean under the supervision of Ben Bederson. * The Piccolo website is www.cs.umd.edu/hcil/piccolo */ package edu.umd.cs.piccolox.swing; import java.awt.*; import java.awt.geom.*; import javax.swing.*; import edu.umd.cs.piccolo.PCanvas; import edu.umd.cs.piccolo.util.PBounds; /** * A subclass of JViewport that talks to the scroll director to negotiate * the view positions and sizes. * * @author Lance Good */ public class PViewport extends JViewport { /** * Controls what happens when scrolling occurs */ PScrollDirector scrollDirector; /** * Pass constructor info to super */ public PViewport() { super(); setScrollDirector(createScrollDirector()); } /** * Subclassers can override this to install a different * layout manager (or <code>null</code>) in the constructor. Returns * a new <code>ViewportLayout</code> object. * * @return a <code>LayoutManager</code> */ protected LayoutManager createLayoutManager() { return new PViewportLayout(); } /** * Subclassers can override this to install a different scroll director * in the constructor. Returns a new <code>PScrollDirector</code> object. * @return a <code>PScrollDirector */ protected PScrollDirector createScrollDirector() { return new PDefaultScrollDirector(); } /** * Set the scroll director on this viewport * @param scrollDirector The new scroll director */ public void setScrollDirector(PScrollDirector scrollDirector) { if (this.scrollDirector != null) { this.scrollDirector.unInstall(); } this.scrollDirector = scrollDirector; if (scrollDirector != null) { this.scrollDirector.install(this, (PCanvas) getView()); } } /** * @return The scroll director on this viewport */ public PScrollDirector getScrollDirector() { return scrollDirector; } /** * Overridden to throw an exception if the view is not a ZCanvas * @param view The new view - it better be a ZCanvas! */ public void setView(Component view) { if (!(view instanceof PCanvas)) { throw new UnsupportedOperationException("PViewport only supports ZCanvas"); } super.setView(view); if (scrollDirector != null) { scrollDirector.install(this, (PCanvas) view); } } /** * Sets the view coordinates that appear in the upper left * hand corner of the viewport, does nothing if there's no view. * * @param p a <code>Point</code> object giving the upper left coordinates */ public void setViewPosition(Point p) { if (getView() == null) { return; } double oldX = 0, oldY = 0, x = p.x, y = p.y; Point2D vp = getViewPosition(); if (vp != null) { oldX = vp.getX(); oldY = vp.getY(); } /** * Send the scroll director the exact view position and let it * interpret it as needed */ double newX = x; double newY = y; if ((oldX != newX) || (oldY != newY)) { scrollUnderway = true; scrollDirector.setViewPosition(newX, newY); fireStateChanged(); } } /** * Gets the view position from the scroll director based on the current * extent size * @return The new view position */ public Point getViewPosition() { if (scrollDirector != null) { Dimension extent = getExtentSize(); return scrollDirector.getViewPosition(new PBounds(0, 0, extent.getWidth(), extent.getHeight())); } else { return null; } } /** * Gets the view size from the scroll director based on the current * extent size * @return The new view size */ public Dimension getViewSize() { Dimension extent = getExtentSize(); return scrollDirector.getViewSize(new PBounds(0, 0, extent.getWidth(), extent.getHeight())); } /** * Gets the view size from the scroll director based on the specified * extent size * @param r The extent size from which the view is computed * @return The new view size */ public Dimension getViewSize(Rectangle2D r) { return scrollDirector.getViewSize(r); } /** * Notifies all <code>ChangeListeners</code> when the views * size, position, or the viewports extent size has changed. */ public void fireStateChanged() { super.fireStateChanged(); } /** * A simple layout manager to give the ZCanvas the same size as the * Viewport */ public static class PViewportLayout extends ViewportLayout { /** * Called when the specified container needs to be laid out. * * @param parent the container to lay out */ public void layoutContainer(Container parent) { JViewport vp = (JViewport) parent; Component view = vp.getView(); if (view == null) { return; } Dimension extentSize = vp.getSize(); vp.setViewSize(extentSize); } } }