/* * AP(r) Computer Science GridWorld Case Study: * Copyright(c) 2002-2006 College Entrance Examination Board * (http://www.collegeboard.com). * * This code is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * This code 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 General Public License for more details. * * @author Alyce Brady * @author Jeff Raab, Northeastern University * @author Cay Horstmann */ package info.gridworld.gui; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.util.HashMap; import javax.swing.Icon; /** * <code>DisplayMap</code> is a collection that maps grid occupant * classes to objects that know how to display them. <br /> * This code is not tested on the AP CS A and AB exams. It contains GUI * implementation details that are not intended to be understood by AP CS * students. */ public class DisplayMap { private HashMap<Class, Display> map = new HashMap<Class, Display>(); private Display defaultDisplay = new DefaultDisplay(); /** * Associates a display object with a grid occupant class. * @param the occupant class * @return the ImageDisplay or (classname)Display object to display it, * or null if none was found */ private Display createDisplay(Class cl) { try { String className = cl.getName(); Class dcl = Class.forName(className + "Display"); if (Display.class.isAssignableFrom(dcl)) { Display display = (Display) dcl.newInstance(); map.put(cl, display); return display; } } catch (Exception e) { // oh well... } try { ImageDisplay display = new ImageDisplay(cl); map.put(cl, display); return display; } catch (Exception e) { // oh well... } return null; } /** * Finds a display class that knows how to display the given object. * @param obj the object to display */ public Display findDisplayFor(Class cl) { // Go up through the class hierarchy for obj and see // if there is a display for its class or superclasses. if (cl == Object.class) return defaultDisplay; Display display = map.get(cl); if (display != null) return display; display = createDisplay(cl); if (display != null) { map.put(cl, display); return display; } display = findDisplayFor(cl.getSuperclass()); map.put(cl, display); return display; } /** * Gets an icon to display a class in a menu * @param cl the class * @param w the icon width * @param h the icon height * @return the icon */ public Icon getIcon(Class cl, int w, int h) { return new DisplayIcon(cl, w, h); } private class DisplayIcon implements Icon { private Display displayObj; private int width, height; public DisplayIcon(Class cl, int w, int h) { displayObj = findDisplayFor(cl); width = w; height = h; } public int getIconWidth() { return width; } public int getIconHeight() { return height; } public void paintIcon(Component comp, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D) g; AffineTransform savedTransform = g2.getTransform(); // save current displayObj.draw(null, comp, g2, new Rectangle(x, y, getIconWidth(), getIconHeight())); g2.setTransform(savedTransform); // restore coordinate system } } }