/* * GraphSearchApp.java * * An applet to display a graph search algorithm. * * Copyright (c) Renaud Waldura, Thu Jun 15 03:48:14 1995 */ import awt.Graphics; import awt.Color; import graph.*; import geometry.Rect; /** * An applet to display a graph search algorithm */ class GraphSearchApp extends browser.Applet implements Runnable, GraphSearchDisplay { private Graph g; // the graph private Thread search; // the search thread private boolean suspended = false; // the search thread is suspended private String alg_name; // the search algorithm name private int sleep_time; // search speed private String error_message; // an error message used when initializing failed private Rect clip; // the painting "clipping region" /** * initialize the applet */ public void init () { java.io.InputStream is = null; try { String s = getAttribute("VERTICES"); if (s == null) throw new Exception("Applet attribute is mandatory: VERTICES"); int vertices = Integer.valueOf(s).intValue(); s = getAttribute("DIRECTED"); if (s == null) throw new Exception("Applet attribute is mandatory: DIRECTED"); boolean directed = s.equalsIgnoreCase("TRUE"); s = getAttribute("GRAPH"); if (s == null) throw new Exception("Applet attribute is mandatory: GRAPH"); is = new net.www.html.URL(documentURL, s).openStream(); g = new Graph(vertices, directed, is); s = getAttribute("ALGORITHM"); alg_name = "graph." + ((s == null) ? "DFS" : s.toUpperCase()) + "earch"; s = getAttribute("SPEED"); sleep_time = (s == null) ? 1000 : 5000 / Integer.valueOf(s).intValue(); error_message = null; } catch (Exception e) { g = null; alg_name = null; error_message = e.toString(); if (is != null) is.close(); } } /** * User clicked the applet: start/stop the search */ public synchronized void mouseUp (int x, int y) { if (search == null) { search = new Thread(this); search.start(); } else if (!suspended && search.isAlive()) { search.suspend(); suspended = true; // after suspend(), isAlive() returns true !! } else { search.resume(); suspended = false; } refresh(null); } /** * The run() method is executed by the ``search'' thread */ public void run () { if (g == null || alg_name == null) return; GraphSearch algorithm = (GraphSearch) new(alg_name); algorithm.init(this); algorithm.search(g); // here is the meat refresh(null); } /** * Stops the search by stopping the thread. */ public synchronized void stop () { if (search != null) { if (search.isAlive()) search.stop(); search = null; } } /** * This method is called to refresh the graph. */ public synchronized void refresh (Rect r) { clip = r; repaint(); if (!suspended && search.isAlive()) Thread.sleep(sleep_time); } /** * Clip the drawing region to a graph vertex. */ public void update (Graphics g) { if (clip != null) g.clipRect(clip.origin.x, clip.origin.y, clip.width, clip.height); else g.clearRect(0, 0, width, height); paint(g); } /** * Draws the graph at this time of the search. */ public void paint (Graphics g) { if (error_message == null) { this.g.draw(g); g.paint3DRect(0, 0, width - 1, height - 1, false, suspended || search == null || (search != null && !search.isAlive())); } else g.drawString("Error: " + error_message, 10, 10); } }