/* locator/ShirleyPictureLocator.java History: 23 Sep 05 R. Burkhardt Draw messages indicating image is loading for map and pictures. Consolidate map rendering into MapDisplayArea.drawBaseMap() and MapDisplayArea.drawArrow(). In imageUpdate, don't use ABORT flag to help determine return value. Extract LookupColorFailure and LookupColor to ColorUtility.java. Use safe version of ColorUtility.getColor(). 21 Sep 05 R. Burkhardt Fix it so PictureDialog window can be closed using "X" button. Redo PictureDialog resize computations. Replace deprecated API calls. 29 Jan 99 R. Burkhardt Added PictureDialog. 17 Nov 98 R. Burkhardt Created from ShirleyOpenSpace.java. */ import java.applet.Applet; import java.awt.*; import java.awt.event.*; // for WindowAdapter and WindowEvent import java.net.*; class Toggle extends Thread { MapDisplayArea m_client; long m_ms_delay; public Toggle(MapDisplayArea client, long ms_delay) { m_client = client; m_ms_delay = ms_delay; start(); } public void run() { for (;;) { try { sleep(m_ms_delay); } catch(Exception e) { } m_client.toggle(); } } } class PictureDisplayArea extends Canvas { PictureDialog m_client; Image m_picture; int m_w = 10, m_h = 10; boolean m_clear = false, m_resize = false; final public static String m_loading_message = "Please wait, image is loading ..."; PictureDisplayArea(PictureDialog client) { m_client = client; } public void setPicture(URL image_url) { int flags; m_picture = getToolkit().getImage(image_url); flags = checkImage(m_picture, this); if ((flags & ALLBITS) == 0) { m_clear = true; m_resize = true; prepareImage(m_picture, this); } else { m_w = m_picture.getWidth(this); m_h = m_picture.getHeight(this); int notapictureHeight = m_client.getHeight() - getHeight(); int notapictureWidth = m_client.getWidth() - getWidth(); m_client.setSize(m_w + notapictureWidth, m_h + notapictureHeight); m_client.validate(); } repaint(); } public Dimension preferredSize() { return new Dimension(m_w, m_h); } public boolean imageUpdate (Image img, int flags, int x, int y, int w, int h) { if (m_resize && (flags & WIDTH) != 0 && (flags & HEIGHT) != 0) { m_w = w; m_h = h; int notapictureHeight = m_client.getHeight() - getHeight(); int notapictureWidth = m_client.getWidth() - getWidth(); m_client.setSize(m_w + notapictureWidth, m_h + notapictureHeight); m_client.validate(); m_resize = false; } repaint(); return (flags & ALLBITS) == 0; } public void update(Graphics g) { if (m_clear) { g.clearRect(0, 0, getWidth(), getHeight()); m_clear = false; } StringUtility.drawCenteredString(m_loading_message, g, this); if (m_picture != null) g.drawImage(m_picture, 0, 0, this); } public void paint(Graphics g) { update(g); } } class PictureDialog extends Frame implements ActionListener { Label m_name; PictureDisplayArea m_picture; Panel m_panel; Button m_dismiss; PictureDialog() { super("Picture"); setLayout(new BorderLayout()); m_name = new Label(); m_name.setAlignment(Label.CENTER); m_picture = new PictureDisplayArea(this); m_dismiss = new Button("Dismiss"); m_dismiss.addActionListener(this); add("North", m_name); add("Center", m_picture); m_panel = new Panel(); m_panel.add(m_dismiss); add("South", m_panel); } public void setLabel(String label) { m_name.setText(label); } public void setPicture(URL image_url) { m_picture.setPicture(image_url); } public void actionPerformed(ActionEvent evt) { hide(); } } class MapDisplayArea extends Canvas implements MouseListener { boolean m_redraw_basemap = false; Image m_baseMap; int m_location; int[] m_arrowSpecs[]; final static double[][] m_arrowBaseCoords = { {0.5, 0.5}, {-5.5, 6.5}, {-2.5, 6.5}, {-2.5, 16.5}, {3.5, 16.5}, {3.5, 6.5}, {6.5, 6.5} }; Polygon m_arrow; Color m_arrowColor, m_arrowColor1, m_arrowColor2, m_dotColor; int m_dotDiameter; ShirleyPictureLocator m_client; Toggle m_toggle; public MapDisplayArea (URL image_url, int[][] arrowSpecs, ShirleyPictureLocator client) { m_arrowSpecs = arrowSpecs; m_client = client; m_arrowColor1 = ColorUtility.getColor(m_client.getParameter("arrowColor1"), Color.black); m_arrowColor2 = ColorUtility.getColor(m_client.getParameter("arrowColor2"), Color.green); m_dotColor = ColorUtility.getColor(m_client.getParameter("dotColor"), Color.blue); String dotDiameter = m_client.getParameter("dotDiameter"); if (dotDiameter != null) m_dotDiameter = Integer.valueOf(dotDiameter).intValue(); else m_dotDiameter = 4; m_arrow = new Polygon(new int[m_arrowBaseCoords.length], new int[m_arrowBaseCoords.length], m_arrowBaseCoords.length); m_baseMap = getToolkit().getImage(image_url); prepareImage(m_baseMap, this); m_toggle = new Toggle(this, 500); } private synchronized void computeArrow() { // arrow spec = x, y, arrow_angle (degrees) // arrow points straight up at zero degrees, degree setting moves // it counter clockwise double theta = (Math.PI/180.0)*(m_arrowSpecs[m_location][2] + 0.5); for (int i = 0; i < m_arrowBaseCoords.length; i++) { double cos = Math.cos(theta); double sin = Math.sin(theta); double nx = m_arrowBaseCoords[i][0]*cos + m_arrowBaseCoords[i][1]*sin; double ny = -m_arrowBaseCoords[i][0]*sin + m_arrowBaseCoords[i][1]*cos; m_arrow.xpoints[i] = (int)(m_arrowSpecs[m_location][0] + nx); m_arrow.ypoints[i] = (int)(m_arrowSpecs[m_location][1] + ny); } } synchronized void setLocation(int i) { m_location = i; computeArrow(); m_redraw_basemap = true; repaint(); } public boolean imageUpdate (Image img, int flags, int x, int y, int w, int h) { m_redraw_basemap = true; // let it get repainted when toggle is called return (flags & ALLBITS) == 0; } public void toggle() { m_arrowColor = (m_arrowColor == m_arrowColor1) ? m_arrowColor2 : m_arrowColor1; repaint(); } private void drawBaseMap(Graphics g) { StringUtility.drawCenteredString(PictureDisplayArea.m_loading_message, g, this); g.drawImage(m_baseMap, 0, 0, this); g.setColor(m_dotColor); for (int i = 0; i < m_arrowSpecs.length; i++) g.fillOval(m_arrowSpecs[i][0] - m_dotDiameter/2, m_arrowSpecs[i][1] - m_dotDiameter/2, m_dotDiameter, m_dotDiameter); } private void drawArrow(Graphics g) { g.setColor(m_arrowColor); g.fillPolygon(m_arrow); } public void update(Graphics g) { if (m_redraw_basemap) { paint(g); m_redraw_basemap = false; } else drawArrow(g); } public void paint(Graphics g) { drawBaseMap(g); drawArrow(g); } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { int x = e.getX(), y = e.getY(); for (int i = 0; i < m_arrowSpecs.length; i++) { int xloc = m_arrowSpecs[i][0]; int yloc = m_arrowSpecs[i][1]; int distance = (x < xloc) ? xloc - x : x - xloc; distance += (y < yloc) ? yloc - y: y - yloc; if (distance < m_dotDiameter) m_client.setLocation(i); } } public void mouseReleased(MouseEvent e) { } } public class ShirleyPictureLocator extends Applet implements ItemListener, ActionListener { Choice m_choice_n, m_choice_s; MapDisplayArea m_map_display_area; Button m_picture_n, m_picture_s; PictureDialog m_picture_dialog; public void init() { setLayout(new BorderLayout()); Panel p; m_choice_n = new Choice(); m_choice_s = new Choice(); for (int i = 0; i < pictureNames.length; i++) { m_choice_n.addItem(pictureNames[i][0]); m_choice_s.addItem(pictureNames[i][0]); } m_choice_n.addItemListener(this); m_choice_s.addItemListener(this); m_picture_dialog = new PictureDialog(); m_picture_dialog.setSize(500, 300); m_picture_dialog.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { e.getWindow().hide(); } }); p = new Panel(); p.add(m_choice_n); m_picture_n = new Button("Picture"); m_picture_n.addActionListener(this); p.add(m_picture_n); add("North", p); p = new Panel(); p.add(m_choice_s); m_picture_s = new Button("Picture"); m_picture_s.addActionListener(this); p.add(m_picture_s); add("South", p); try { m_map_display_area = new MapDisplayArea(new URL(getDocumentBase(), "shirley.jpg"), locationArrowSpecs, this); m_map_display_area.addMouseListener(m_map_display_area); add("Center", m_map_display_area); } catch(Exception e) { showStatus(e.toString()); } } public void start() { handleChoice(m_choice_n); } public void stop() { m_picture_dialog.hide(); } private void handleChoice(Choice choice) { setLocation(choice.getSelectedIndex()); } private void showPicture() { try { m_picture_dialog.setLabel (pictureNames[m_choice_n.getSelectedIndex()][0]); m_picture_dialog.setPicture (new URL(getDocumentBase(), "../artist/" + pictureNames[m_choice_n.getSelectedIndex()][1])); } catch(Exception e) { showStatus(e.toString()); } } synchronized void setLocation(int i) { m_choice_n.select(i); m_choice_s.select(i); m_map_display_area.setLocation(i); if (m_picture_dialog.isShowing()) showPicture(); } public void itemStateChanged(ItemEvent evt) { if (evt.getSource() == m_choice_n) handleChoice(m_choice_n); else handleChoice(m_choice_s); } public void actionPerformed(ActionEvent evt) { showPicture(); m_picture_dialog.hide(); m_picture_dialog.show(); m_picture_dialog.toFront(); } final static String pictureNames[][] = { { "Trestle over the Catecoonemaug", "trestle.jpg" }, { "Hazen Memorial Library", "library.jpg" }, { "Former Shirley Police Headquarters", "police.jpg" }, { "My Home", "home.jpg" }, { "Shirley Train Depot", "depot.jpg" }, { "View Out My Back Windows", "backyard.jpg" }, { "World War Memorial", "eagle.jpg" }, { "Civil War Memorial", "civilwar.jpg" }, { "First Parish Meetinghouse", "meeting.jpg" }, { "Maple and Vernal Pool", "vernpool.jpg" }, { "Center Town Hall", "townhall.jpg" }, { "Boynton Grave Marker", "robin.jpg" }, { "Samson Cordage", "samson.jpg" }, { "George Frost Building", "frost.jpg" }, { "Fredonian Park Gazebo", "fredonia.jpg" }, // "Administration Headquarters, Devens", { "Catecoonemaug River", "catecoon.jpg" }, { "Ice House Dam", "icedam.jpg" }, { "Waterfall at Rt 225 Bridge", "bridg225.jpg" }, { "Citgo Gas Station", "gas.jpg" }, { "Piccolino Club", "the_pic.jpg" }, { "Apartments by the Railroad Tracks", "aprtmnts.jpg" }, { "Leatherboard Pond", "lethrbrd.jpg" }, { "Garrison Road", "garrison.jpg" }, // "Dairy Barn in Groton", { "Trolley Powerhouse", "icehouse.jpg" }, { "Buildings at Shirley Airport", "airport.jpg" }, { "Burned-Out Hut", "broknhut.jpg" }, { "Hazen-Davis Barn", "circleb.jpg" }, }; final static int[] locationArrowSpecs[] = { { 118, 746, -170 }, { 150, 779, -100 }, { 154, 770, 70 }, { 156, 785, -65 }, { 208, 756, 170 }, { 160, 783, -65 }, { 210, 762, -170 }, { 193, 533, 45 }, { 191, 525, 45 }, { 241, 721, 45 }, { 187, 530, 70 }, { 171, 802, 30 }, { 209, 782, -80 }, { 142, 770, 20 }, { 165, 778, -120 }, { 109, 732, 20 }, { 385, 692, -170 }, { 327, 279, -90 }, { 178, 765, -40 }, { 199, 766, -80 }, { 176, 762, 70 }, { 103, 774, 65 }, { 193, 277, -8 }, { 385, 698, 20 }, { 95, 885, -115 }, { 74, 790, 170 }, { 144, 819, 180 }, }; }