/* * @(#)DrawingView.java * * Copyright (c) 1996-2010 The authors and contributors of JHotDraw. * You may not use, copy or modify this file, except in compliance with the * accompanying license terms. */ package org.jhotdraw.draw; import java.awt.Cursor; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.KeyListener; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelListener; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.beans.PropertyChangeListener; import java.util.Collection; import java.util.Set; import javax.annotation.Nullable; import javax.swing.JComponent; import org.jhotdraw.draw.event.FigureSelectionListener; import org.jhotdraw.draw.handle.Handle; /** * A <em>drawing view</em> paints a {@link Drawing} on a {@code JComponent}. * <p> * A drawing view can hold only one drawing at a time, but a drawing can be in * multiple drawing views at the same time. * <p> * {@code DrawingView} can paint the drawing with a scale factor. It supports * conversion between view coordinates and drawing coordinates. * <p> * {@code DrawingView} maintains a selection of the {@link Figure}s contained in * the drawing. When a figure is selected, the drawing view request {@link Handle}s * from the figure and draws them on top of the drawing. * <p> * To support editing, a drawing view needs to be added to a {@link DrawingEditor}. * The current {@link org.jhotdraw.draw.tool.Tool} of the drawing editor * receives mouse and key events from all drawing views of the drawing editor. * When added to an editor, the drawing view paints the current {@link org.jhotdraw.draw.tool.Tool} on * top of the drawing. The selected figures and handles can be the targets of * the current tool of the drawing editor. * <p> * Editing operations can be constrained, for example by a grid. The constraints * are defined by a {@link Constrainer} object. Handles and tools should take * the constrainer of the drawing view into account when editing a figure. * <p> * The painting process of {@code DrawingView} view involves the following steps: * <ol> * <li>Paint the background of the drawing view.</li> * <li>Invoke {@link Drawing#drawCanvas}.</li> * <li>Invoke {@link Constrainer#draw} if a constrainer is set.</li> * <li>Invoke {@link Drawing#draw}.</li> * <li>Invoke {@link org.jhotdraw.draw.handle.Handle#draw} on the handles * of selected figures.</li> * <li>Invoke {@link org.jhotdraw.draw.tool.Tool#draw} if the drawing view * is the active view of the {@code DrawingEditor}.</li> * </ol> * * <hr> * <b>Design Patterns</b> * * <p><em>Framework</em><br> * The following interfaces define the contracts of a framework for structured * drawing editors:<br> * Contract: {@link Drawing}, {@link Figure}, {@link DrawingView}, * {@link DrawingEditor}, {@link org.jhotdraw.draw.handle.Handle} and * {@link org.jhotdraw.draw.tool.Tool}. * * <p><em>Chain of responsibility</em><br> * Mouse and keyboard events of the user occur on the drawing view, and are * preprocessed by the {@code DragTracker} of a {@code SelectionTool}. In * turn {@code org.jhotdraw.draw.selectiontool.DragTracker} invokes "track" methods on a {@code Handle} which in * turn changes an aspect of a figure.<br> * Client: {@link org.jhotdraw.draw.tool.SelectionTool}; * Handler: {@link org.jhotdraw.draw.tool.DragTracker}, * {@link org.jhotdraw.draw.handle.Handle}. * * <p><em>Mediator</em><br> * {@code DrawingEditor} acts as a mediator for coordinating drawing tools * and drawing views:<br> * Mediator: {@link DrawingEditor}; * Colleagues: {@link DrawingView}, {@link org.jhotdraw.draw.tool.Tool}. * * <p><em>Model-View-Controller</em><br> * The following classes implement together the Model-View-Controller design * pattern:<br> * Model: {@link Drawing}; View: {@link DrawingView}; Controller: * {@link DrawingEditor}. * * <p><em>Observer</em><br> * Selection changes of {@code DrawingView} are observed by user interface * components which act on selected figures.<br> * Subject: {@link org.jhotdraw.draw.DrawingView}; * Observer: {@link org.jhotdraw.draw.event.FigureSelectionListener}; * Event: {@link org.jhotdraw.draw.event.FigureSelectionEvent}. * * <p><em>Observer</em><br> * State changes of figures can be observed by other objects. Specifically * {@code CompositeFigure} observes area invalidations and remove requests * of its child figures. {@code DrawingView} also observes area invalidations * of its drawing object. * Subject: {@link Figure}; Observer: * {@link org.jhotdraw.draw.event.FigureListener}; * Event: {@link org.jhotdraw.draw.event.FigureEvent}; * Concrete Observer: {@link CompositeFigure}, {@link DrawingView}. * * <p><em>Observer</em><br> * State changes of handles can be observed by other objects. Specifically * {@code DrawingView} observes area invalidations and remove requests of * handles.<br> * Subject: {@link Handle}; * Observer: {@link org.jhotdraw.draw.event.HandleListener}; * Event: {@link org.jhotdraw.draw.event.HandleEvent}; * Concrete Observer: {@link DrawingView}. * * <p><em>Strategy</em><br> * Editing can be constrained by a constrainer which is associated to a * drawing view.<br> * Context: {@link DrawingView}; Strategy: {@link Constrainer}. * <hr> * * @author Werner Randelshofer * @version $Id$ */ public interface DrawingView { /** * This constant is used to identify the drawing property of the DrawingView. */ public static final String DRAWING_PROPERTY = "drawing"; /** * This constant is used to identify the cursor property of the DrawingView. */ public static final String CURSOR_PROPERTY = "cursor"; /** * This constant is used to identify the constrainer property of the DrawingView. */ public static final String CONSTRAINER_PROPERTY = "constrainer"; /** * This constant is used to identify the visible constrainer property of the DrawingView. */ public static final String VISIBLE_CONSTRAINER_PROPERTY = "visibleConstrainer"; /** * This constant is used to identify the invisible constrainer property of the DrawingView. */ public static final String INVISIBLE_CONSTRAINER_PROPERTY = "invisibleConstrainer"; /** * This constant is used to identify the constrainer visible property of the DrawingView. */ public static final String CONSTRAINER_VISIBLE_PROPERTY = "constrainerVisible"; /** * This constant is used to identify the scale factor property of the DrawingView. */ public static final String SCALE_FACTOR_PROPERTY = "scaleFactor"; /** * This constant is used to identify the handle detail level property of the DrawingView. */ public static final String HANDLE_DETAIL_LEVEL_PROPERTY = "handleDetailLevel"; /** * This constant is used to identify the enabled property of the DrawingView. */ public static final String ENABLED_PROPERTY = "enabled"; /** * This constant is used to identify the activeHandle property of the DrawingView. */ public static final String ACTIVE_HANDLE_PROPERTY = "activeHandle"; /** * Gets the drawing. * This is a bound property. */ @Nullable public Drawing getDrawing(); /** * Sets and installs another drawing in the view. * This is a bound property. */ public void setDrawing(@Nullable Drawing d); /** * Sets the cursor of the DrawingView. * This is a bound property. */ public void setCursor(@Nullable Cursor c); /** * Test whether a given figure is selected. */ public boolean isFigureSelected(Figure checkFigure); /** * Adds a figure to the current selection. */ public void addToSelection(Figure figure); /** * Adds a collection of figures to the current selection. */ public void addToSelection(Collection<Figure> figures); /** * Removes a figure from the selection. */ public void removeFromSelection(Figure figure); /** * If a figure isn't selected it is added to the selection. * Otherwise it is removed from the selection. */ public void toggleSelection(Figure figure); /** * Clears the current selection. */ public void clearSelection(); /** * Selects all figures. */ public void selectAll(); /** * Gets the selected figures. Returns an empty set, if no figures are selected. */ public Set<Figure> getSelectedFigures(); /** * Gets the number of selected figures. */ public int getSelectionCount(); /** * Finds a handle at the given coordinates. * @return A handle, null if no handle is found. */ @Nullable public Handle findHandle(Point p); /** * Gets compatible handles. * @return A collection containing the handle and all compatible handles. */ public Collection<Handle> getCompatibleHandles(Handle handle); /** * Sets the active handle. */ public void setActiveHandle(@Nullable Handle newValue); /** * Gets the active handle. */ @Nullable public Handle getActiveHandle(); /** * Finds a figure at the given point. * @return A figure, null if no figure is found. */ @Nullable public Figure findFigure(Point p); /** * Returns all figures that lie within or intersect the specified * bounds. The figures are returned in Z-order from back to front. */ public Collection<Figure> findFigures(Rectangle r); /** * Returns all figures that lie within the specified * bounds. The figures are returned in Z-order from back to front. */ public Collection<Figure> findFiguresWithin(Rectangle r); /** * Informs the view that it has been added to the specified editor. * The view must draw the tool of the editor, if getActiveView() of the * editor returns the view. */ public void addNotify(DrawingEditor editor); /** * Informs the view that it has been removed from the specified editor. * The view must not draw the tool from the editor anymore. */ public void removeNotify(DrawingEditor editor); /** * Gets the drawing editor associated to the DrawingView. * This is a bound property. */ @Nullable public DrawingEditor getEditor(); /** * Add a listener for selection changes in this DrawingView. * @param fsl jhotdraw.framework.FigureSelectionListener */ public void addFigureSelectionListener(FigureSelectionListener fsl); /** * Remove a listener for selection changes in this DrawingView. * @param fsl jhotdraw.framework.FigureSelectionListener */ public void removeFigureSelectionListener(FigureSelectionListener fsl); /** This is a convenience method for invoking * {@code getComponent().requestFocus()}. */ public void requestFocus(); /** * Converts drawing coordinates to view coordinates. */ public Point drawingToView(Point2D.Double p); /** * Converts view coordinates to drawing coordinates. */ public Point2D.Double viewToDrawing(Point p); /** * Converts drawing coordinates to view coordinates. */ public Rectangle drawingToView(Rectangle2D.Double p); /** * Converts view coordinates to drawing coordinates. */ public Rectangle2D.Double viewToDrawing(Rectangle p); /** * Gets the current constrainer of this view. * If isConstrainerVisible is true, this method returns getVisibleConstrainer, * otherwise it returns getInvisibleConstrainer. * This is a bound property. */ @Nullable public Constrainer getConstrainer(); /** * Sets the editor's constrainer for this view, for use, when the * visible constrainer is turned on. * This is a bound property. */ public void setVisibleConstrainer(@Nullable Constrainer constrainer); /** * Gets the editor's constrainer for this view, for use, when the * visible constrainer is turned on. * This is a bound property. */ @Nullable public Constrainer getVisibleConstrainer(); /** * Sets the editor's constrainer for this view, for use, when the * visible constrainer is turned off. * This is a bound property. */ public void setInvisibleConstrainer(Constrainer constrainer); /** * Gets the editor's constrainer for this view, for use, when the * visible constrainer is turned off. * This is a bound property. */ public Constrainer getInvisibleConstrainer(); /** * Changes between a visible Constrainer and an invisible Constrainer. * This is a bound property. */ public void setConstrainerVisible(boolean newValue); /** * Returns true, if the visible Constrainer is in use, returns false, * if the invisible Constrainer is in use. * This is a bound property. */ public boolean isConstrainerVisible(); /** * Returns the JComponent of the drawing view. * <p> * The drawing framework supports only two use cases, where this * component may be accessed: * <ul> * <li>The component can be used to add the drawing view to a parent Swing * component.</li> * <li>The currently active {@link org.jhotdraw.draw.tool.Tool} may add * child components to the drawing view. The tool <b>must</b> remove these * components when it becomes inactive.</li> * </ul> */ public JComponent getComponent(); /** * Gets an transform which can be used to convert * drawing coordinates to view coordinates. */ public AffineTransform getDrawingToViewTransform(); /** * Gets the scale factor of the drawing view. * This is a bound property. */ public double getScaleFactor(); /** * Sets the scale factor of the drawing view. * This is a bound property. */ public void setScaleFactor(double newValue); /** * The detail level of the handles. * This is a bound property. */ public void setHandleDetailLevel(int newValue); /** * Returns the detail level of the handles. * This is a bound property. */ public int getHandleDetailLevel(); /** * Sets the enabled state of the drawing view. * This is a bound property. */ public void setEnabled(boolean newValue); /** * Gets the enabled state of the drawing view. * This is a bound property. */ public boolean isEnabled(); /** Repaints the handles of the view. */ public void repaintHandles(); /** * Adds a property change listener to the drawing view. * * @param listener */ public void addPropertyChangeListener(PropertyChangeListener listener); /** * Removes a property change listener to the drawing view. * * @param listener */ public void removePropertyChangeListener(PropertyChangeListener listener); /** * Adds a mouse listener to the drawing view. * * @param l the listener. */ public void addMouseListener(MouseListener l); /** * Removes a mouse listener to the drawing view. * * @param l the listener. */ public void removeMouseListener(MouseListener l); /** * Adds a key listener to the drawing view. * * @param l the listener. */ public void addKeyListener(KeyListener l); /** * Removes a key listener to the drawing view. * * @param l the listener. */ public void removeKeyListener(KeyListener l); /** * Adds a mouse motion listener to the drawing view. * * @param l the listener. */ public void addMouseMotionListener(MouseMotionListener l); /** * Removes a mouse motion listener to the drawing view. * * @param l the listener. */ public void removeMouseMotionListener(MouseMotionListener l); public void addMouseWheelListener(MouseWheelListener l); public void removeMouseWheelListener(MouseWheelListener l); }