/* * Bibliothek - DockingFrames * Library built on Java/Swing, allows the user to "drag and drop" * panels containing any Swing-Component the developer likes to add. * * Copyright (C) 2007 Benjamin Sigg * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA * * Benjamin Sigg * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.paint.view; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import javax.swing.JPanel; import bibliothek.paint.model.Picture; import bibliothek.paint.model.PictureListener; import bibliothek.paint.model.Shape; import bibliothek.paint.model.ShapeFactory; /** * A page is a panel that paints a {@link Picture}. * @author Benjamin Sigg * */ public class Page extends JPanel implements PictureListener { /** the size a page has when its zoomfactor is set to 1.0 */ private static final Dimension ORIGINAL_SIZE = new Dimension( 800, 600 ); /** the picture which is painted on this panel */ private Picture picture; /** the factory which is used to create a new {@link Shape} when the user wants to insert a new one */ private ShapeFactory factory; /** the <code>Shape</code> the user is currently inserting */ private Shape current; /** the <code>Color</code> each new <code>Shape</code> will have */ private Color color = Color.BLACK; /** the zoomfactor, each coordinate will be multiplied with this factor */ private double zoom = 1.0; /** * Creates a new page. */ public Page(){ setFocusable( true ); addMouseListener( new MouseAdapter(){ @Override public void mousePressed( MouseEvent e ) { requestFocusInWindow(); if( current == null && factory != null ){ current = factory.create(); current.setColor( color ); current.setPointA( unstretch( e.getPoint() )); current.setPointB( unstretch( e.getPoint() )); repaint(); } } @Override public void mouseReleased( MouseEvent e ) { if( current != null ){ picture.add( current ); current = null; } } }); addMouseMotionListener( new MouseMotionAdapter(){ @Override public void mouseDragged( MouseEvent e ) { if( current != null ){ current.setPointB( unstretch( e.getPoint() )); repaint(); } } }); setZoom( 1.0 ); } /** * Sets the <code>Color</code> which is used to paint any new {@link Shape} * the user wants to insert. * @param color the new color */ public void setColor( Color color ){ this.color = color; } /** * Sets the zoom-factory. Each coordinate will be multiplied by this factor. * @param zoom a value greater than 0 */ public void setZoom( double zoom ){ this.zoom = zoom; setPreferredSize( new Dimension( (int)(ORIGINAL_SIZE.width * zoom), (int)(ORIGINAL_SIZE.height * zoom) ) ); revalidate(); repaint(); } /** * Gets the current zoom-factor. * @return the factor */ public double getZoom(){ return zoom; } /** * Divides each coordinate of <code>point</code> with the zoomfactor * of this <code>Page</code>. * @param point the point whose coordinates will be divided * @return a point with the divided coordinates */ private Point unstretch( Point point ){ return new Point( (int)(point.x / zoom), (int)(point.y / zoom) ); } /** * Gets the factory which is used to fetch new {@link Shape}s when the * user wants to insert a new <code>Shape</code>. * @return the factory */ public ShapeFactory getFactory() { return factory; } /** * Sets the factory which is used to fetch new {@link Shape}s when the * user wants to insert new ones. * @param factory the factory, should not be <code>null</code> */ public void setFactory( ShapeFactory factory ) { this.factory = factory; } /** * Gets the picture which is painted on this page. * @return the picture, can be <code>null</code> */ public Picture getPicture() { return picture; } /** * Sets the <code>Picture</code> which is painted on this page. * @param picture the picture to paint, can be <code>null</code> */ public void setPicture( Picture picture ) { if( this.picture != null ) this.picture.removeListener( this ); this.picture = picture; if( this.picture != null ){ this.picture.addListener( this ); } repaint(); } public void pictureChanged() { repaint(); } @Override protected void paintComponent( Graphics g ) { g.setColor( Color.WHITE ); g.fillRect( 0, 0, getWidth(), getHeight() ); if( picture != null ) picture.paint( g, zoom ); if( current != null ) current.paint( g, zoom ); } }