/******************************************************************* Copyright (c) 2001-2007 Apprisant Technologies Inc. All rights reserved. Apprisant Technologies permits non-exclusive royalty free use, copying and modification of this demo program source code for the purposes of evaluating the Apprisant Toolkit or building applications that use it. This software and documentation is provided "AS IS". APPRISANT TECHNOLOGIES DISCLAIMS ANY REPRESENTATIONS AND WARRANTIES, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTY OF MERCHANTABILITY AND FITNESS OF THIS PRODUCT FOR ANY PARTICULAR PURPOSE. APPRISANT TECHNOLOGIES SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY ANY PARTY, INCLUDING LOST PROFITS, ARISING FROM THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ITS DERIVATIONS. ********************************************************************/ package schedule; import java.awt.*; import java.awt.geom.*; import java.io.*; import apprisant.diagram.*; /* The display element class for the Schedule demo. Calculates the rectangle and arrow representing the room booking in the diagram based on the day, start time and end time data attributes, and saves them as display attributes in the element. The element factory that instantiates the display elements is a nested class at the end of this file, and is registered with the element model in the Schedule class. */ public class ScheduleElement extends GeneralElement { // Display attributes to store the calculated figures static final String RECTANGLE = "rect"; static final String ARROW = "arrow"; // Geometry constants based on the background image static final float MIN_HOUR = 8; static final float DAY_WIDTH = 96; static final float HOUR_HEIGHT = 32; static final float X_OFFSET = 49; static final float Y_OFFSET = 30; static final float INSET = 1; static final float ARROWHEAD_HEIGHT = 16; static final float ARROW_TOP = 2; static final float ARROW_LEFT = 24; static final float ARROW_RIGHT = 72; static final float SCROLL_X = DAY_WIDTH / 2; static final float SCROLL_Y = HOUR_HEIGHT; // Precalculated rectangles and arrows for the sizes we will need, // shared by the elements. static Rectangle2D RECT_60 = new Rectangle2D.Float(INSET, INSET, DAY_WIDTH - 2 * INSET, HOUR_HEIGHT - 2 * INSET); static Rectangle2D RECT_90 = new Rectangle2D.Float(INSET, INSET, DAY_WIDTH - 2 * INSET, HOUR_HEIGHT * 1.5f - 2 * INSET); static Rectangle2D RECT_120 = new Rectangle2D.Float(INSET, INSET, DAY_WIDTH - 2 * INSET, HOUR_HEIGHT * 2f - 2 * INSET); static GeneralPath ARROW_60 = makeArrow(60); static GeneralPath ARROW_90 = makeArrow(90); static GeneralPath ARROW_120 = makeArrow(120); public ScheduleElement (Object key, Object dataObject) { super(key, dataObject); } /** Called by KeyModel when the element is added to the model or when the data object is updated. */ @Override public void update() { Booking booking = (Booking) getDataObject(); if (booking == null) return; // Get the day, start time and end time from the data object Booking.Day day = booking.getDay(); float start = booking.getStartTime(); int duration = booking.getDuration(); // Set the default point to the upper left corner of the rectangle, float x = X_OFFSET + day.ordinal() * DAY_WIDTH; float y = Y_OFFSET + (start - MIN_HOUR) * HOUR_HEIGHT; setPoint((double) x, (double) y); // Set attributes to the appropriate pre-calculated figures if (duration <= 60) { setAttribute(RECTANGLE, RECT_60); setAttribute(ARROW, ARROW_60); } else if (duration <= 90) { setAttribute(RECTANGLE, RECT_90); setAttribute(ARROW, ARROW_90); } else { setAttribute(RECTANGLE, RECT_120); setAttribute(ARROW, ARROW_120); } } /** Helper method to construct an arrow for the given duration in minutes. */ static GeneralPath makeArrow (int duration) { float height = (duration / 60f) * HOUR_HEIGHT; GeneralPath p = new GeneralPath(); p.moveTo(ARROW_LEFT, ARROW_TOP); p.lineTo(ARROW_RIGHT, ARROW_TOP); p.lineTo(ARROW_RIGHT, height - ARROWHEAD_HEIGHT); p.lineTo(DAY_WIDTH - INSET, height - ARROWHEAD_HEIGHT); p.lineTo(DAY_WIDTH / 2f, height - INSET); p.lineTo(INSET, height - ARROWHEAD_HEIGHT); p.lineTo(ARROW_LEFT, height - ARROWHEAD_HEIGHT); p.closePath(); return p; } /* Element factory class to instantiate ScheduleElements. */ public static class Factory implements ElementFactory, Serializable { public Factory() { } public ScheduleElement createElement (Object key, Object data) { return new ScheduleElement(key, data); } } }