001: /*
002: * WebSphinx web-crawling toolkit
003: *
004: * Copyright (c) 1998-2002 Carnegie Mellon University. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
020: * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
022: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
023: * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
024: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
025: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
026: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
027: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
028: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
029: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030: *
031: */
032:
033: package websphinx.workbench;
034:
035: import java.awt.*;
036: import java.io.*;
037: import java.net.URL;
038: import websphinx.*;
039: import rcm.awt.Constrain;
040: import rcm.awt.PopupDialog;
041: import rcm.awt.TabPanel;
042: import rcm.awt.BorderPanel;
043: import rcm.awt.ClosableFrame;
044:
045: public class Workbench extends Panel implements CrawlListener {
046:
047: Crawler crawler;
048:
049: String currentFilename = "";
050:
051: // panel wrappers
052: Panel workbenchPanel; // contains menuPanel, configPanel, buttonPanel
053: GridBagConstraints workbenchConstraints;
054: WorkbenchVizPanel vizPanel; // contains graph, outline, and statistics
055: GridBagConstraints vizConstraints;
056:
057: // GUI event listeners
058: WebGraph graph;
059: WebOutline outline;
060: Statistics statistics;
061: EventLog logger;
062:
063: // menu bar (for frame mode)
064: MenuBar menubar;
065: Menu fileMenu;
066: MenuItem newCrawlerItem;
067: MenuItem openCrawlerItem;
068: MenuItem saveCrawlerItem;
069: MenuItem createCrawlerItem;
070: MenuItem exitItem;
071:
072: // menu panel (for container mode)
073: Panel menuPanel;
074: Button newCrawlerButton;
075: Button openCrawlerButton;
076: Button saveCrawlerButton;
077: Button createCrawlerButton;
078:
079: WorkbenchTabPanel configPanel;
080: Panel simplePanel;
081: Panel crawlPanel;
082: Panel limitsPanel;
083: Panel classifiersPanel;
084: Panel linksPanel;
085: Panel actionPanel;
086:
087: CrawlerEditor crawlerEditor;
088: ClassifierListEditor classifierListEditor;
089: DownloadParametersEditor downloadParametersEditor;
090: LinkPredicateEditor linkPredicateEditor;
091: PagePredicateEditor pagePredicateEditor;
092: ActionEditor actionEditor;
093: SimpleCrawlerEditor simpleCrawlerEditor;
094:
095: boolean advancedMode = false;
096: boolean tornOff = false;
097:
098: Button startButton, pauseButton, stopButton, clearButton;
099:
100: boolean allowExit;
101:
102: // Frames
103: Frame workbenchFrame;
104: Frame vizFrame;
105:
106: static final int MARGIN = 8; // pixel border around configPanel
107:
108: public Workbench() {
109: this (makeDefaultCrawler());
110: return;
111: }
112:
113: private static Crawler makeDefaultCrawler() {
114: Crawler c = new Crawler();
115: c.setDomain(Crawler.SUBTREE);
116: return c;
117: }
118:
119: public Workbench(String filename) throws Exception {
120: //#ifdef JDK1.1
121: this (loadCrawler(new FileInputStream(filename)));
122: //#endif JDK1.1
123: /*#ifdef JDK1.0
124: throw new RuntimeException ("Crawler load/save not supported under Java 1.0");
125: #endif JDK1.0*/
126: }
127:
128: public Workbench(URL url) throws Exception {
129: //#ifdef JDK1.1
130: this (loadCrawler(url.openStream())); // FIX: Netscape 4 refuses to load off local disk
131: //#endif JDK1.1
132: /*#ifdef JDK1.0
133: throw new RuntimeException ("Crawler load/save not supported under Java 1.0");
134: #endif JDK1.0*/
135: }
136:
137: public Workbench(Crawler _crawler) {
138: Browser browser = Context.getBrowser();
139:
140: setLayout(new BorderLayout());
141: setBackground(Color.lightGray);
142:
143: setLayout(new GridLayout(2, 1));
144:
145: add(workbenchPanel = new Panel());
146: workbenchPanel.setLayout(new GridBagLayout());
147:
148: // menu buttons panel
149: makeMenus();
150: Constrain.add(workbenchPanel, menuPanel, Constrain.labelLike(0,
151: 0));
152:
153: // configuration panel
154: configPanel = new WorkbenchTabPanel();
155: Constrain.add(workbenchPanel, configPanel, Constrain.areaLike(
156: 0, 1));
157: simplePanel = makeSimplePanel();
158: crawlPanel = makeCrawlPanel();
159: linksPanel = makeLinksPanel();
160: actionPanel = makeActionPanel();
161: classifiersPanel = makeClassifiersPanel();
162: limitsPanel = makeLimitsPanel();
163:
164: // start/pause/stop button panel
165: Constrain.add(workbenchPanel, makeButtonPanel(), Constrain
166: .fieldLike(0, 2));
167:
168: // visualization panel
169: add(vizPanel = new WorkbenchVizPanel(this ));
170:
171: // graph visualization
172: graph = new WebGraph();
173: graph.setBackground(Color.white);
174: if (browser != null)
175: graph.addLinkViewListener(browser);
176: vizPanel.addTabPanel("Graph", true, graph);
177:
178: // outline visualization
179: outline = new WebOutline();
180: outline.setBackground(Color.white);
181: if (browser != null)
182: outline.addLinkViewListener(browser);
183: vizPanel.addTabPanel("Outline", true, outline);
184:
185: // statistics visualization
186: statistics = new Statistics();
187: Panel p = new Panel();
188: p.setLayout(new FlowLayout());
189: p.add(statistics);
190: vizPanel.addTabPanel("Statistics", true, p);
191:
192: // event logger (sends to System.err -- no GUI presence)
193: logger = new EventLog();
194:
195: // now that the GUI is set up, we can initialize it with the
196: // crawler
197: setCrawler(_crawler);
198: }
199:
200: public Frame makeFrame() {
201: if (workbenchFrame == null) {
202: Dimension screen = Toolkit.getDefaultToolkit()
203: .getScreenSize();
204: workbenchFrame = new WorkbenchFrame(this );
205: workbenchFrame.setForeground(getForeground());
206: workbenchFrame.setBackground(getBackground());
207: workbenchFrame.setFont(getFont());
208: workbenchFrame.setTitle("Crawler Workbench: "
209: + (crawler != null ? crawler.getName() : ""));
210: workbenchFrame.setLayout(new GridLayout(1, 1));
211: workbenchFrame.add(this );
212: workbenchPanel.remove(menuPanel);
213: workbenchFrame.setMenuBar(menubar);
214: workbenchFrame.reshape(0, 0, Math.min(550, screen.width),
215: screen.height - 50);
216: }
217: return workbenchFrame;
218: }
219:
220: public void setAllowExit(boolean yes) {
221: allowExit = yes;
222: }
223:
224: public boolean getAllowExit() {
225: return allowExit;
226: }
227:
228: public synchronized void setAdvancedMode(boolean adv) {
229: if (advancedMode == adv)
230: return;
231:
232: configureCrawler(); // write current mode's settings back to crawler
233: advancedMode = adv;
234: setCrawler(crawler); // read new mode's settings from crawler
235:
236: configPanel.advancedButton.setLabel(advancedMode ? "<< Simple"
237: : ">> Advanced");
238: validate();
239: }
240:
241: public boolean getAdvancedMode() {
242: return advancedMode;
243: }
244:
245: /* * * * * * * * * * * * * * * * * * * * * * *
246: * GUI Construction
247: * * * * * * * * * * * * * * * * * * * * * * */
248:
249: static void setVisible(Component comp, boolean visible) {
250: if (visible)
251: comp.show();
252: else
253: comp.hide();
254: }
255:
256: static void setEnabled(Component comp, boolean enabled) {
257: if (enabled)
258: comp.enable();
259: else
260: comp.disable();
261: }
262:
263: static void setEnabled(MenuItem item, boolean enabled) {
264: if (enabled)
265: item.enable();
266: else
267: item.disable();
268: }
269:
270: Panel makeMenus() {
271: // menubar
272: menubar = new MenuBar();
273: menuPanel = new Panel();
274: menuPanel.setLayout(new FlowLayout()); // for horizontal layout
275:
276: // FILE menu
277: menubar.add(fileMenu = new Menu("File"));
278:
279: // File/New Crawler
280: fileMenu.add(newCrawlerItem = new MenuItem("New Crawler"));
281: menuPanel.add(newCrawlerButton = new Button("New"));
282:
283: // File/Open Crawler
284: fileMenu.add(openCrawlerItem = new MenuItem("Open Crawler..."));
285: /*#ifdef JDK1.0
286: setEnabled (openCrawlerItem, false);
287: #endif JDK1.0*/
288: menuPanel.add(openCrawlerButton = new Button("Open..."));
289: /*#ifdef JDK1.0
290: setEnabled (openCrawlerButton, false);
291: #endif JDK1.0*/
292:
293: // File/Save Crawler
294: fileMenu.add(saveCrawlerItem = new MenuItem("Save Crawler..."));
295: /*#ifdef JDK1.0
296: setEnabled (saveCrawlerItem, false);
297: #endif JDK1.0*/
298: menuPanel.add(saveCrawlerButton = new Button("Save..."));
299: /*#ifdef JDK1.0
300: setEnabled (saveCrawlerButton, false);
301: #endif JDK1.0*/
302:
303: // File/Create Crawler
304: fileMenu.add(createCrawlerItem = new MenuItem(
305: "Create Crawler From Class..."));
306: menuPanel.add(createCrawlerButton = new Button("Create..."));
307:
308: // File/Exit
309: fileMenu.add(exitItem = new MenuItem("Exit"));
310:
311: return menuPanel;
312: }
313:
314: private Panel makeSimplePanel() {
315: return simpleCrawlerEditor = new SimpleCrawlerEditor();
316: }
317:
318: // FIX: add onlyHyperLinks, synchronous, ignoreVisitedLinks
319: private Panel makeCrawlPanel() {
320: return crawlerEditor = new CrawlerEditor();
321: }
322:
323: private Panel makeLinksPanel() {
324: Panel panel = new Panel();
325: panel.setLayout(new GridBagLayout());
326:
327: Constrain.add(panel, new Label("Follow:"), Constrain.labelLike(
328: 0, 0));
329: Constrain.add(panel,
330: linkPredicateEditor = new LinkPredicateEditor(),
331: Constrain.areaLike(1, 0));
332:
333: return panel;
334: }
335:
336: private Panel makeActionPanel() {
337: Panel panel = new Panel();
338: panel.setLayout(new GridBagLayout());
339:
340: Constrain.add(panel, new Label("Action:"), Constrain.labelLike(
341: 0, 0));
342: Constrain.add(panel, actionEditor = new ActionEditor(),
343: Constrain.areaLike(1, 0));
344:
345: Constrain.add(panel, new Label("on pages:"), Constrain
346: .labelLike(0, 1));
347: Constrain.add(panel,
348: pagePredicateEditor = new PagePredicateEditor(),
349: Constrain.areaLike(1, 1));
350: return panel;
351: }
352:
353: private Panel makeClassifiersPanel() {
354: classifierListEditor = new ClassifierListEditor();
355: return classifierListEditor;
356: }
357:
358: private Panel makeLimitsPanel() {
359: downloadParametersEditor = new DownloadParametersEditor();
360: return downloadParametersEditor;
361: }
362:
363: private Panel makeButtonPanel() {
364: Panel panel = new Panel();
365: panel.setLayout(new FlowLayout());
366:
367: panel.add(startButton = new Button("Start"));
368: panel.add(pauseButton = new Button("Pause"));
369: panel.add(stopButton = new Button("Stop"));
370: panel.add(clearButton = new Button("Clear"));
371: enableButtons(true, false, false, false);
372: return panel;
373: }
374:
375: String getCrawlerClassName(String label) {
376: String className = label;
377: if (className != null) {
378: if (className.equals("Crawler"))
379: className = "websphinx.Crawler";
380: else if (className.equals("Load Class..."))
381: className = null;
382: }
383: return className;
384: }
385:
386: public boolean handleEvent(Event event) {
387: if (doEvent(event))
388: return true;
389: else
390: return super .handleEvent(event);
391: }
392:
393: boolean doEvent(Event event) {
394: if (event.id == Event.ACTION_EVENT) {
395: if (event.target instanceof MenuItem) {
396: MenuItem item = (MenuItem) event.target;
397:
398: if (item == newCrawlerItem)
399: newCrawler();
400: //#ifdef JDK1.1
401: else if (item == openCrawlerItem)
402: openCrawler();
403: else if (item == saveCrawlerItem)
404: saveCrawler();
405: //#endif JDK1.1
406: else if (item == createCrawlerItem)
407: createCrawler(null);
408: else if (item == exitItem)
409: close();
410: else
411: return false;
412: } else if (event.target == newCrawlerButton)
413: newCrawler();
414: //#ifdef JDK1.1
415: else if (event.target == openCrawlerButton)
416: openCrawler();
417: else if (event.target == saveCrawlerButton)
418: saveCrawler();
419: //#endif JDK1.1
420: else if (event.target == createCrawlerButton)
421: createCrawler(null);
422: else if (event.target == configPanel.advancedButton)
423: setAdvancedMode(!advancedMode);
424: else if (event.target == vizPanel.optionsButton)
425: new WorkbenchControlPanel(graph, outline).show();
426: else if (event.target == vizPanel.tearoffButton)
427: if (tornOff)
428: dockVisualizations();
429: else
430: tearoffVisualizations();
431: else if (event.target == startButton)
432: start();
433: else if (event.target == pauseButton)
434: pause();
435: else if (event.target == stopButton)
436: stop();
437: else if (event.target == clearButton)
438: clear();
439: else
440: return false;
441: } else
442: return false;
443:
444: return true;
445: }
446:
447: /* * * * * * * * * * * * * * * * * * * * * * *
448: * Command handling
449: * * * * * * * * * * * * * * * * * * * * * * */
450:
451: protected void finalize() {
452: // FIX: dispose of frames
453: }
454:
455: void close() {
456: if (!allowExit)
457: return;
458:
459: // FIX: dispose of frames
460:
461: if (Context.isApplication()) {
462: //#ifdef JDK1.1
463: Runtime.runFinalizersOnExit(true);
464: //#endif JDK1.1
465: System.exit(0);
466: }
467: }
468:
469: public void refresh() {
470: graph.updateClosure(crawler.getCrawledRoots());
471: outline.updateClosure(crawler.getCrawledRoots());
472: }
473:
474: void connectVisualization(Crawler crawler, Object viz,
475: boolean linksToo) {
476: if (viz instanceof CrawlListener)
477: crawler.addCrawlListener((CrawlListener) viz);
478: if (linksToo && viz instanceof LinkListener)
479: crawler.addLinkListener((LinkListener) viz);
480: }
481:
482: void disconnectVisualization(Crawler crawler, Object viz,
483: boolean linksToo) {
484: if (viz instanceof CrawlListener)
485: crawler.removeCrawlListener((CrawlListener) viz);
486: if (linksToo && viz instanceof LinkListener)
487: crawler.removeLinkListener((LinkListener) viz);
488: }
489:
490: void showVisualization(Object viz) {
491: if (viz == graph)
492: graph.start();
493: }
494:
495: void hideVisualization(Object viz) {
496: if (viz == graph)
497: graph.stop();
498: }
499:
500: void tearoffVisualizations() {
501: if (tornOff)
502: return;
503:
504: if (vizFrame == null) {
505: Dimension screen = Toolkit.getDefaultToolkit()
506: .getScreenSize();
507: vizFrame = new WorkbenchVizFrame(this );
508: vizFrame.setForeground(getForeground());
509: vizFrame.setBackground(getBackground());
510: vizFrame.setFont(getFont());
511: vizFrame.setTitle("Visualization: "
512: + (crawler != null ? crawler.getName() : ""));
513: vizFrame.setLayout(new GridLayout(1, 1));
514: vizFrame.reshape(0, 0, Math.min(550, screen.width),
515: screen.height / 2);
516: }
517:
518: remove(vizPanel);
519: setLayout(new GridLayout(1, 1));
520: validate();
521:
522: vizFrame.add(vizPanel);
523: setVisible(vizFrame, true);
524:
525: vizPanel.tearoffButton.setLabel("Glue Back");
526:
527: tornOff = true;
528: }
529:
530: void dockVisualizations() {
531: if (!tornOff)
532: return;
533:
534: setVisible(vizFrame, false);
535: vizFrame.remove(vizPanel);
536:
537: setLayout(new GridLayout(2, 1));
538: add(vizPanel);
539: validate();
540:
541: vizPanel.tearoffButton.setLabel("Tear Off");
542:
543: tornOff = false;
544: }
545:
546: void newCrawler() {
547: setCrawler(makeDefaultCrawler());
548: currentFilename = "";
549: }
550:
551: void createCrawler(String className) {
552: if (className == null || className.length() == 0) {
553: className = PopupDialog.ask(workbenchPanel, "New Crawler",
554: "Create a Crawler of class:", crawler.getClass()
555: .getName());
556: if (className == null)
557: return;
558: }
559:
560: try {
561: Class crawlerClass = (Class) Class.forName(className);
562: Crawler newCrawler = (Crawler) crawlerClass.newInstance();
563:
564: setCrawler(newCrawler);
565: currentFilename = "";
566: } catch (Exception e) {
567: PopupDialog.warn(workbenchPanel, "Error", e.toString());
568: return;
569: }
570: }
571:
572: //#ifdef JDK1.1
573: void openCrawler() {
574: String fn = PopupDialog.askFilename(workbenchPanel,
575: "Open Crawler", "", true);
576: if (fn != null)
577: openCrawler(fn);
578: }
579:
580: void openCrawler(String filename) {
581: try {
582: setCrawler(loadCrawler(Access.getAccess().readFile(
583: new File(filename))));
584: currentFilename = filename;
585: } catch (Exception e) {
586: PopupDialog.warn(workbenchPanel, "Error", e.toString());
587: }
588: }
589:
590: void openCrawler(URL url) {
591: try {
592: setCrawler(loadCrawler(Access.getAccess().openConnection(
593: url).getInputStream()));
594: currentFilename = "";
595: } catch (Exception e) {
596: PopupDialog.warn(workbenchPanel, "Error", e.toString());
597: }
598: }
599:
600: static Crawler loadCrawler(InputStream stream) throws Exception {
601: ObjectInputStream in = new ObjectInputStream(stream);
602: Crawler loadedCrawler = (Crawler) in.readObject();
603: in.close();
604: return loadedCrawler;
605: }
606:
607: void saveCrawler() {
608: String fn = PopupDialog.askFilename(workbenchPanel,
609: "Save Crawler As", currentFilename, true);
610: if (fn != null)
611: saveCrawler(fn);
612: }
613:
614: void saveCrawler(String filename) {
615: configureCrawler();
616:
617: try {
618: ObjectOutputStream out = new ObjectOutputStream(Access
619: .getAccess().writeFile(new File(filename), false));
620: out.writeObject((Object) crawler);
621: out.close();
622:
623: currentFilename = filename;
624: } catch (Exception e) {
625: PopupDialog.warn(workbenchPanel, "Error", e.toString());
626: }
627: }
628:
629: //#endif JDK1.1
630:
631: void configureCrawler() {
632: if (advancedMode) {
633: crawlerEditor.getCrawler();
634: classifierListEditor.getCrawler();
635: crawler.setDownloadParameters(downloadParametersEditor
636: .getDownloadParameters());
637: if (advancedMode) {
638: crawler.setLinkPredicate(linkPredicateEditor
639: .getLinkPredicate());
640: crawler.setPagePredicate(pagePredicateEditor
641: .getPagePredicate());
642: crawler.setAction(actionEditor.getAction());
643: }
644: } else
645: simpleCrawlerEditor.getCrawler();
646: }
647:
648: void enableButtons(boolean fStart, boolean fPause, boolean fStop,
649: boolean fClear) {
650: setEnabled(startButton, fStart);
651: setEnabled(pauseButton, fPause);
652: setEnabled(stopButton, fStop);
653: setEnabled(clearButton, fClear);
654: }
655:
656: /* * * * * * * * * * * * * * * * * * * * * * *
657: * Changing the crawler
658: * * * * * * * * * * * * * * * * * * * * * * */
659:
660: public void setCrawler(Crawler _crawler) {
661: if (crawler != _crawler) {
662: if (crawler != null) {
663: clear();
664: disconnectVisualization(crawler, this , false);
665: disconnectVisualization(crawler, graph, true);
666: disconnectVisualization(crawler, outline, true);
667: disconnectVisualization(crawler, statistics, false);
668: disconnectVisualization(crawler, logger, true);
669: }
670:
671: connectVisualization(_crawler, this , false);
672: connectVisualization(_crawler, graph, true);
673: connectVisualization(_crawler, outline, true);
674: connectVisualization(_crawler, statistics, false);
675: connectVisualization(_crawler, logger, true);
676: }
677:
678: crawler = _crawler;
679:
680: // set all window titles
681: String name = crawler.getName();
682: if (workbenchFrame != null)
683: workbenchFrame.setTitle("Crawler Workbench: " + name);
684: if (vizFrame != null)
685: vizFrame.setTitle("Visualization: " + name);
686:
687: // set configuration
688:
689: if (advancedMode) {
690: crawlerEditor.setCrawler(crawler);
691: classifierListEditor.setCrawler(crawler);
692: downloadParametersEditor.setDownloadParameters(crawler
693: .getDownloadParameters());
694: if (advancedMode) {
695: linkPredicateEditor.setLinkPredicate(crawler
696: .getLinkPredicate());
697: pagePredicateEditor.setPagePredicate(crawler
698: .getPagePredicate());
699: actionEditor.setAction(crawler.getAction());
700: }
701: } else
702: simpleCrawlerEditor.setCrawler(crawler);
703:
704: if (advancedMode)
705: showAdvancedTabs();
706: else
707: showSimpleTabs();
708: }
709:
710: public Crawler getCrawler() {
711: return crawler;
712: }
713:
714: private void showAdvancedTabs() {
715: if (configPanel.countTabs() != 5) {
716: configPanel.removeAllTabPanels();
717: configPanel.addTabPanel("Crawl", true, crawlPanel);
718: configPanel.addTabPanel("Links", true, linksPanel);
719: configPanel.addTabPanel("Pages", true, actionPanel);
720: configPanel.addTabPanel("Classifiers", true,
721: classifiersPanel);
722: configPanel.addTabPanel("Limits", true, limitsPanel);
723: }
724: }
725:
726: private void showSimpleTabs() {
727: if (configPanel.countTabs() != 1) {
728: configPanel.removeAllTabPanels();
729: configPanel.addTabPanel("Crawl", true, simplePanel);
730: }
731: }
732:
733: /* * * * * * * * * * * * * * * * * * * * * * *
734: * Running the crawler
735: * * * * * * * * * * * * * * * * * * * * * * */
736:
737: public void start() {
738: configureCrawler();
739:
740: if (crawler.getState() == CrawlEvent.STOPPED)
741: crawler.clear();
742:
743: Thread thread = new Thread(crawler, crawler.getName());
744: thread.setDaemon(true);
745: thread.start();
746: }
747:
748: public void stop() {
749: crawler.stop();
750: }
751:
752: public void pause() {
753: crawler.pause();
754: }
755:
756: public void clear() {
757: crawler.clear();
758: }
759:
760: /**
761: * Notify that the crawler started
762: */
763: public void started(CrawlEvent event) {
764: enableButtons(false, true, true, false);
765: }
766:
767: /**
768: * Notify that the crawler ran out of links to crawl
769: */
770: public void stopped(CrawlEvent event) {
771: enableButtons(true, false, false, true);
772: }
773:
774: /**
775: * Notify that the crawler's state was cleared.
776: */
777: public void cleared(CrawlEvent event) {
778: enableButtons(true, false, false, false);
779: }
780:
781: /**
782: * Notify that the crawler timed out.
783: */
784: public void timedOut(CrawlEvent event) {
785: enableButtons(true, false, false, true);
786: }
787:
788: /**
789: * Notify that the crawler was paused.
790: */
791: public void paused(CrawlEvent event) {
792: enableButtons(true, false, true, true);
793: }
794:
795: public static void main(String[] args) throws Exception {
796: Workbench w = (args.length == 0) ? new Workbench()
797: : new Workbench(args[0]);
798: w.setAllowExit(true);
799:
800: Frame f = w.makeFrame();
801: f.show();
802: }
803: }
804:
805: class WorkbenchFrame extends ClosableFrame {
806: Workbench workbench;
807:
808: public WorkbenchFrame(Workbench workbench) {
809: super ();
810: this .workbench = workbench;
811: }
812:
813: public void close() {
814: workbench.close();
815: }
816:
817: public boolean handleEvent(Event event) {
818: if (workbench.doEvent(event))
819: return true;
820: else
821: return super .handleEvent(event);
822: }
823: }
824:
825: class WorkbenchVizFrame extends ClosableFrame {
826: Workbench workbench;
827:
828: public WorkbenchVizFrame(Workbench workbench) {
829: super (true);
830: this .workbench = workbench;
831: }
832:
833: public void close() {
834: workbench.dockVisualizations();
835: super .close();
836: }
837:
838: public boolean handleEvent(Event event) {
839: if (workbench.doEvent(event))
840: return true;
841: else
842: return super .handleEvent(event);
843: }
844: }
845:
846: class WorkbenchTabPanel extends TabPanel {
847: Button advancedButton;
848:
849: public WorkbenchTabPanel() {
850: super ();
851: add(advancedButton = new Button("Advanced >>"));
852: }
853: }
854:
855: class WorkbenchVizPanel extends TabPanel {
856: Workbench workbench;
857: Button optionsButton;
858: Button tearoffButton;
859:
860: public WorkbenchVizPanel(Workbench workbench) {
861: this .workbench = workbench;
862: add(optionsButton = new Button("Options..."));
863: add(tearoffButton = new Button("Tear Off"));
864: }
865:
866: public void select(int num) {
867: Component prior = getSelectedComponent();
868:
869: super .select(num);
870:
871: Component now = getSelectedComponent();
872:
873: if (prior == now)
874: return;
875:
876: if (prior != null)
877: workbench.hideVisualization(prior);
878:
879: if (now != null) {
880: workbench.showVisualization(now);
881: now.requestFocus();
882: }
883: }
884: }
|