/* * @(#)AbstractAttributedDecoratedFigure.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 org.jhotdraw.geom.Insets2D; import javax.annotation.Nullable; import java.awt.*; import java.awt.geom.*; import java.io.*; import static org.jhotdraw.draw.AttributeKeys.*; import org.jhotdraw.xml.*; /** * This abstract class can be extended to implement a {@link DecoratedFigure} * which has an attribute set. * * @author Werner Randelshofer * @version $Id$ */ public abstract class AbstractAttributedDecoratedFigure extends AbstractAttributedFigure implements DecoratedFigure, DOMStorable { private static final long serialVersionUID = 1L; @Nullable private Figure decorator; @Override public final void draw(Graphics2D g) { if (decorator != null) { drawDecorator(g); } drawFigure(g); } protected void drawFigure(Graphics2D g) { super.draw(g); } protected void drawDecorator(Graphics2D g) { updateDecoratorBounds(); decorator.draw(g); } @Override public final Rectangle2D.Double getDrawingArea() { Rectangle2D.Double r = getFigureDrawingArea(); if (decorator != null) { updateDecoratorBounds(); r.add(decorator.getDrawingArea()); } return r; } protected Rectangle2D.Double getFigureDrawingArea() { return super.getDrawingArea(); } @Override public void setDecorator(Figure newValue) { willChange(); decorator = newValue; if (decorator != null) { decorator.setBounds(getStartPoint(), getEndPoint()); } changed(); } @Override public Figure getDecorator() { return decorator; } protected void updateDecoratorBounds() { if (decorator != null) { Point2D.Double sp = getStartPoint(); Point2D.Double ep = getEndPoint(); Insets2D.Double decoratorInsets = get(DECORATOR_INSETS); sp.x -= decoratorInsets.left; sp.y -= decoratorInsets.top; ep.x += decoratorInsets.right; ep.y += decoratorInsets.bottom; decorator.setBounds(sp, ep); } } @Override public final boolean contains(Point2D.Double p) { if (decorator != null) { updateDecoratorBounds(); if (decorator.contains(p)) { return true; } } return figureContains(p); } protected abstract boolean figureContains(Point2D.Double p); @Override public void read(DOMInput in) throws IOException { super.read(in); readDecorator(in); } @Override public void write(DOMOutput out) throws IOException { super.write(out); writeDecorator(out); } protected void writeDecorator(DOMOutput out) throws IOException { if (decorator != null) { out.openElement("decorator"); out.writeObject(decorator); out.closeElement(); } } protected void readDecorator(DOMInput in) throws IOException { if (in.getElementCount("decorator") > 0) { in.openElement("decorator"); decorator = (Figure) in.readObject(); in.closeElement(); } else { decorator = null; } } @Override public AbstractAttributedDecoratedFigure clone() { AbstractAttributedDecoratedFigure that = (AbstractAttributedDecoratedFigure) super.clone(); if (this.decorator != null) { that.decorator = this.decorator.clone(); } return that; } }