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 websphinx.*;
036: import java.awt.*;
037: import java.util.Hashtable;
038: import java.util.Vector;
039: import java.applet.Applet;
040: import java.applet.AppletContext;
041: import java.net.URL;
042: import java.net.MalformedURLException;
043: import rcm.awt.Colors;
044: import rcm.awt.ClosableFrame;
045: import java.awt.image.MemoryImageSource;
046: import graph.Graph;
047: import rcm.awt.Constrain;
048: import rcm.awt.PopupDialog;
049:
050: // FIX: connect ALREADY_VISITED links to page
051:
052: public class WebGraph extends GraphLayout implements CrawlListener,
053: LinkListener {
054:
055: Hashtable links = new Hashtable();
056:
057: // maps Link -> WebNode (for root links) or WebEdge (for internal links)
058:
059: /**
060: * Make a WebGraph.
061: */
062: public WebGraph() {
063: setPageIcon(defaultPageIcon);
064: setLinkIcon(defaultLinkIcon);
065: setRetrievingIcon(defaultRetrievingIcon);
066: setErrorIcon(defaultErrorIcon);
067: }
068:
069: // Filtering of a node's outgoing links
070:
071: static final int NO_LINKS = 0;
072: // Show no outgoing links
073:
074: static final int RETRIEVED_LINKS = 1;
075: // Show only links that crawler started to retrieve
076:
077: static final int WALKED_LINKS = 2;
078: // Show RETRIEVED_LINKS, plus links queued for retrieval
079:
080: static final int TREE_LINKS = 3;
081: // Show WALKED_LINKS, plus links skipped by walk()
082:
083: static final int ALL_LINKS = 4;
084: // Show TREE_LINKS, plus links to already-visited pages
085:
086: int defaultFilter = RETRIEVED_LINKS;
087:
088: // Change the filter of a node
089: synchronized void setLinkFilter(WebNode node, int filter) {
090: if (filter == node.filter)
091: return;
092:
093: Page page = node.link.getPage();
094: if (page != null) {
095: Link[] linkarray = page.getLinks();
096:
097: if (filter < node.filter) {
098: // new mode is more restrictive; delete undesired edges
099: for (int j = 0; j < linkarray.length; ++j) {
100: if (!shouldDisplay(filter, linkarray[j].getStatus())) {
101: WebEdge edge = (WebEdge) links
102: .get(linkarray[j]);
103: if (edge != null) {
104: removeNode((WebNode) edge.to);
105: removeEdge(edge);
106: links.remove(linkarray[j]);
107: }
108: }
109: }
110: } else if (filter > node.filter) {
111: // new mode is less restrictive; add edges
112: for (int j = 0; j < linkarray.length; ++j) {
113: update(linkarray[j]); // update() will check shouldDisplay()
114: }
115: }
116: }
117:
118: node.filter = filter;
119: }
120:
121: // Change the filter of ALL nodes
122: synchronized void setLinkFilter(int filter) {
123: defaultFilter = filter;
124: Graph graph = getGraph();
125: for (int i = 0; i < graph.sizeNodes; ++i) {
126: WebNode n = (WebNode) graph.nodes[i];
127: setLinkFilter(n, filter);
128: }
129: }
130:
131: // Node rendering
132:
133: static final int ICON = 0;
134: // Show an icon
135:
136: static final int TITLE = 1;
137: // Show page title (or URL if not downloaded)
138:
139: static final int ABSOLUTE_URL = 2;
140: // Show absolute URL
141:
142: static final int RELATIVE_URL = 3;
143: // Show URL relative to parent
144:
145: int defaultRendering = ICON;
146:
147: // Change the rendering of a node
148: void setNodeRendering(WebNode n, int r) {
149: n.rendering = r;
150: update(n);
151:
152: repaint();
153: }
154:
155: // Change the rendering of ALL nodes
156: synchronized void setNodeRendering(int r) {
157: defaultRendering = r;
158:
159: Graph graph = getGraph();
160: for (int i = 0; i < graph.sizeNodes; ++i) {
161: WebNode n = (WebNode) graph.nodes[i];
162: n.rendering = r;
163: update(n);
164: }
165:
166: changedGraph();
167: }
168:
169: /**
170: * Show control panel for changing graph layout parameters.
171: */
172: public void showControlPanel() {
173: new WorkbenchControlPanel(this , null).show();
174: }
175:
176: /**
177: * Clear the graph display.
178: */
179: public synchronized void clear() {
180: links.clear();
181: super .clear();
182: }
183:
184: /**
185: * Notify that the crawler started.
186: */
187: public void started(CrawlEvent event) {
188: }
189:
190: /**
191: * Notify that the crawler has stopped.
192: */
193: public void stopped(CrawlEvent event) {
194: }
195:
196: /**
197: * Notify that the crawler's state was cleared.
198: */
199: public void cleared(CrawlEvent event) {
200: clear();
201: }
202:
203: /**
204: * Notify that the crawler has timed out
205: */
206: public void timedOut(CrawlEvent event) {
207: }
208:
209: /**
210: * Notify that the crawler is paused
211: */
212: public void paused(CrawlEvent event) {
213: }
214:
215: /**
216: * Notify that a crawling event has occured.
217: */
218: public void crawled(LinkEvent event) {
219: update(event.getLink());
220: }
221:
222: // check whether we want to display a link with this status
223: boolean shouldDisplay(int filter, int status) {
224: switch (status) {
225: case LinkEvent.QUEUED:
226: case LinkEvent.TOO_DEEP:
227: return (filter > RETRIEVED_LINKS);
228: case LinkEvent.SKIPPED:
229: return (filter > WALKED_LINKS);
230: case LinkEvent.ALREADY_VISITED:
231: return (filter > TREE_LINKS);
232: case LinkEvent.RETRIEVING:
233: case LinkEvent.DOWNLOADED:
234: case LinkEvent.VISITED:
235: case LinkEvent.ERROR:
236: return true;
237: default:
238: return false;
239: }
240: }
241:
242: /**
243: * Update all the links that the crawler reached from this link.
244: * Any reachable links not present in the graph are added.
245: */
246: public void updateClosure(Link[] links) {
247: if (links == null)
248: return;
249: for (int i = 0; i < links.length; ++i) {
250: Link link = links[i];
251: int status = link.getStatus();
252:
253: if (status == LinkEvent.NONE)
254: continue;
255:
256: update(link);
257:
258: if (status == LinkEvent.DOWNLOADED
259: || status == LinkEvent.VISITED) {
260: Page page = link.getPage();
261: if (page != null)
262: updateClosure(page.getLinks());
263: }
264: }
265: }
266:
267: /**
268: * Update the edge and node associated with a link.
269: * If the link is not present in the graph, it is added.
270: */
271: public synchronized void update(Link link) {
272: Object obj = links.get(link);
273:
274: if (obj == null) {
275: add(link);
276: } else if (obj instanceof WebEdge) {
277: WebEdge e = (WebEdge) obj;
278: update(e);
279: update((WebNode) e.to);
280: } else {
281: // obj instanceof WebNode
282: update((WebNode) obj);
283: }
284:
285: repaint();
286: }
287:
288: synchronized void add(Link link) {
289: WebNode n = new WebNode(link, defaultFilter, defaultRendering);
290: WebNode parent = findParent(link);
291:
292: if (parent == null) {
293: links.put(link, n);
294: update(n);
295: addNode(n);
296:
297: if (getGraph().sizeNodes == 1) {
298: // root node of first tree -- put it at the origin and fix it
299: n.fixed = true;
300: placeNodeOnGraph(n, 0, 0);
301: } else {
302: // root node of an additional tree -- drop it randomly
303: // within window
304:
305: Dimension d = size();
306:
307: int x = (int) (Math.random() * d.width);
308: int y = (int) (Math.random() * d.height);
309: placeNodeOnScreen(n, x, y);
310: }
311: } else {
312: // check if parent's filter allows this link to be displayed
313: if (!shouldDisplay(parent.filter, link.getStatus()))
314: return;
315:
316: // hang the node off its parent in a random direction
317: double len = getRestLength();
318: double angle = Math.random() * 2 * Math.PI;
319: double x = parent.x + len * Math.cos(angle);
320: double y = parent.y + len * Math.sin(angle);
321:
322: update(n);
323: addNode(n);
324: placeNodeOnGraph(n, x, y);
325:
326: WebEdge e = new WebEdge(link, parent, n);
327: links.put(link, e);
328: update(e);
329: addEdge(e);
330: }
331: }
332:
333: void update(WebEdge e) {
334: e.color = Colors.parseColor(e.link.getLabel("Workbench.color"));
335: e.thick = e.link.hasLabel("Workbench.thick");
336: }
337:
338: void update(WebNode n) {
339: Page page = n.link.getPage();
340: int status = n.link.getStatus();
341:
342: if (page == null) {
343: // not downloaded yet
344: switch (n.rendering) {
345: case ICON:
346: n.name = null;
347: n.icon = getIcon(LinkEvent.eventName[status]);
348: break;
349: case TITLE:
350: case ABSOLUTE_URL:
351: n.name = n.link.getURL().toString();
352: n.icon = null;
353: break;
354: case RELATIVE_URL: {
355: Link origin = n.link.getSource().getOrigin();
356: if (origin != null)
357: n.name = Link.relativeTo(origin.getURL(), n.link
358: .getURL());
359: else
360: n.name = n.link.getURL().toString();
361: n.icon = null;
362: break;
363: }
364: }
365: } else {
366: switch (n.rendering) {
367: case ICON:
368: n.name = null;
369: n.icon = getIcon(page.getLabel("Workbench.icon",
370: LinkEvent.eventName[status]));
371: break;
372: case TITLE:
373: n.name = page.getTitle();
374: if (n.name == null)
375: n.name = "[" + n.link.getURL().toString() + "]";
376: n.icon = null;
377: break;
378: case ABSOLUTE_URL:
379: n.name = n.link.getURL().toString();
380: n.icon = null;
381: break;
382: case RELATIVE_URL: {
383: Link origin = n.link.getSource().getOrigin();
384: if (origin != null)
385: n.name = Link.relativeTo(origin.getURL(), n.link
386: .getURL());
387: else
388: n.name = n.link.getURL().toString();
389: n.icon = null;
390: break;
391: }
392: }
393: n.color = Colors.parseColor(page
394: .getLabel("Workbench.color"));
395: n.scale = page.getNumericLabel("Workbench.size",
396: new Integer(1)).doubleValue();
397: }
398:
399: if (n.icon == null) {
400: FontMetrics fm = getFontMetrics();
401: n.width = fm.stringWidth(n.name) + 10;
402: n.height = fm.getHeight() + 4;
403: } else {
404: n.width = (int) (n.icon.getWidth(this ) * n.scale);
405: n.height = (int) (n.icon.getHeight(this ) * n.scale);
406: }
407: }
408:
409: WebEdge findEdge(Link l) {
410: if (l == null)
411: return null;
412: Object obj = links.get(l);
413: if (obj instanceof WebEdge)
414: return (WebEdge) obj;
415: else
416: return null;
417: }
418:
419: WebNode findNode(Link l) {
420: if (l == null)
421: return null;
422: Object obj = links.get(l);
423: if (obj instanceof WebEdge)
424: return (WebNode) ((WebEdge) obj).to;
425: else
426: return (WebNode) obj;
427: }
428:
429: WebNode findParent(Link l) {
430: if (l == null)
431: return null;
432: Page source = l.getSource();
433: Link origin = source.getOrigin();
434: return findNode(origin);
435: }
436:
437: /*
438: * LinkView listeners
439: */
440:
441: private Vector listeners = new Vector();
442:
443: /**
444: * Add a listener for LinkViewEvents. A LinkViewEvent is sent every time a
445: * node or edge in the graph is double-clicked.
446: * @param listener Object that wants to receive LinkViewEvents
447: */
448: public void addLinkViewListener(LinkViewListener listener) {
449: if (!listeners.contains(listener))
450: listeners.addElement(listener);
451: }
452:
453: /**
454: * Removes a listener from the set of LinkViewEvent listeners. If it is not found in the set,
455: * does nothing.
456: *
457: * @param listen a listener
458: */
459: public void removeLinkViewListener(CrawlListener listener) {
460: listeners.removeElement(listener);
461: }
462:
463: void fireEvent(Link link) {
464: LinkViewEvent event = new LinkViewEvent(this , link);
465:
466: for (int j = 0, len = listeners.size(); j < len; ++j) {
467: LinkViewListener listen = (LinkViewListener) listeners
468: .elementAt(j);
469: listen.viewLink(event);
470: }
471: }
472:
473: void doubleClick(int x, int y) {
474: Object over = pick(x, y);
475: if (over != null) {
476: Link link;
477: if (over instanceof WebNode)
478: link = ((WebNode) over).link;
479: else
480: link = ((WebEdge) over).link;
481: fireEvent(link);
482: }
483: }
484:
485: public boolean handleEvent(Event event) {
486: if (event.id == Event.MOUSE_DOWN && event.clickCount == 2) {
487: doubleClick(event.x, event.y);
488: } else
489: return super .handleEvent(event);
490: return true;
491: }
492:
493: public Link getSelectedLink() {
494: WebNode n = (WebNode) getSelectedNode();
495: if (n != null)
496: return n.link;
497:
498: WebEdge e = (WebEdge) getSelectedEdge();
499: if (e != null)
500: return e.link;
501:
502: return null;
503: }
504:
505: /**
506: * Create a new Frame containing a WebGraph connected to a crawler.
507: */
508: public static Frame monitor(Crawler crawler) {
509: Frame win = new ClosableFrame("Graph: " + crawler.getName());
510:
511: WebGraph g = new WebGraph();
512: crawler.addCrawlListener(g);
513: crawler.addLinkListener(g);
514: g.setNodeCharge(1000);
515: g.setRestLength(50);
516:
517: win.add("Center", g);
518: win.pack();
519: win.show();
520:
521: return win;
522: }
523:
524: static String[] getTip(Link link) {
525: Vector result = new Vector();
526:
527: String exception = link.getLabel("exception");
528: if (exception != null && exception.length() > 0)
529: result.addElement("*** " + exception);
530:
531: String anchor = link.toText();
532: if (anchor != null && anchor.length() > 0)
533: result.addElement(anchor);
534:
535: String url = link.getURL().toString();
536: if (url != null && url.length() > 0)
537: result.addElement(url);
538:
539: String labels = link.getObjectLabels();
540: if (labels != null && labels.length() > 0)
541: result.addElement(labels);
542:
543: String[] tip = new String[result.size()];
544: result.copyInto(tip);
545: return tip;
546: }
547:
548: static String[] getTip(Page page) {
549: Vector result = new Vector();
550:
551: String title = page.getTitle();
552: if (title != null && title.length() > 0)
553: result.addElement(title);
554:
555: String url = page.getURL().toString();
556: if (url != null && url.length() > 0)
557: result.addElement(url);
558:
559: String labels = page.getObjectLabels();
560: if (labels != null && labels.length() > 0)
561: result.addElement(labels);
562:
563: String[] tip = new String[result.size()];
564: result.copyInto(tip);
565: return tip;
566: }
567:
568: Hashtable icons = new Hashtable();
569: // maps String (CrawlEvent name or user-defined icon name) to Image
570:
571: Image pageIcon;
572: Image linkIcon;
573: Image retrievingIcon;
574: Image errorIcon;
575:
576: /**
577: * Get a named icon.
578: * @param name Name of icon.
579: * @return icon associated with the name, or null if name unknown.
580: */
581: public synchronized Image getIcon(String name) {
582: return (Image) icons.get(name);
583: }
584:
585: /**
586: * Map a name to an icon.
587: * @param name Name of icon.
588: * @param icon Icon image. If null, mapping is deleted.
589: */
590: public synchronized void setIcon(String name, Image icon) {
591: if (icon != null)
592: icons.put(name, icon);
593: else
594: icons.remove(name);
595: }
596:
597: /**
598: * Set the default icon used for pages.
599: * @param icon Icon image. If null, mapping is deleted.
600: */
601: public synchronized void setPageIcon(Image icon) {
602: pageIcon = icon;
603: setIcon(LinkEvent.eventName[LinkEvent.VISITED], icon);
604: }
605:
606: /**
607: * Set the default icon used for links.
608: * @param icon Icon image. If null, mapping is deleted.
609: */
610: public synchronized void setLinkIcon(Image icon) {
611: linkIcon = icon;
612: setIcon(LinkEvent.eventName[LinkEvent.QUEUED], icon);
613: setIcon(LinkEvent.eventName[LinkEvent.TOO_DEEP], icon);
614: setIcon(LinkEvent.eventName[LinkEvent.ALREADY_VISITED], icon);
615: setIcon(LinkEvent.eventName[LinkEvent.SKIPPED], icon);
616: }
617:
618: /**
619: * Set the default icon used for requests in progress.
620: * @param icon Icon image. If null, mapping is deleted.
621: */
622: public synchronized void setRetrievingIcon(Image icon) {
623: retrievingIcon = icon;
624: setIcon(LinkEvent.eventName[LinkEvent.RETRIEVING], icon);
625: setIcon(LinkEvent.eventName[LinkEvent.DOWNLOADED], icon);
626: }
627:
628: /**
629: * Set the default icon used for failed requests.
630: * @param icon Icon image. If null, mapping is deleted.
631: */
632: public synchronized void setErrorIcon(Image icon) {
633: errorIcon = icon;
634: setIcon(LinkEvent.eventName[LinkEvent.ERROR], icon);
635: }
636:
637: public static Image defaultPageIcon;
638: public static Image defaultLinkIcon;
639: public static Image defaultRetrievingIcon;
640: public static Image defaultErrorIcon;
641:
642: static int linkWidth = 17;
643: static int linkHeight = 17;
644: static int[] linkData = { 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
645: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
646: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
647: 0xff343464, 0xff343464, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
648: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
649: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
650: 0xff343464, 0xff343464, 0xffd4d4fc, 0xffc4c4c4, 0xff343464,
651: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
652: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343464, 0xff343464,
653: 0xff343464, 0xff343464, 0xffd4d4fc, 0xffd4d4fc, 0xffc4c4c4,
654: 0xff6464cc, 0xff343464, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
655: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343464,
656: 0xffccccfc, 0xff848484, 0xff343464, 0xffd4d4fc, 0xff848484,
657: 0xff848484, 0xff6464cc, 0xff343464, 0xfffcfcfc, 0xfffcfcfc,
658: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343464,
659: 0xff343464, 0xffd4d4fc, 0xffc4c4c4, 0xff343464, 0xffd4d4fc,
660: 0xffc4c4c4, 0xff6464cc, 0xff6464cc, 0xff343464, 0xfffcfcfc,
661: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
662: 0xfffcfcfc, 0xff343464, 0xff343464, 0xffd4d4fc, 0xffc4c4c4,
663: 0xff343464, 0xffd4d4fc, 0xffc4c4c4, 0xff6464cc, 0xff6464cc,
664: 0xff343464, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
665: 0xfffcfcfc, 0xfffcfcfc, 0xff343464, 0xffccccfc, 0xffd4d4fc,
666: 0xffc4c4c4, 0xff343464, 0xff343464, 0xff6464cc, 0xff6464cc,
667: 0xff343464, 0xff343464, 0xff343464, 0xfffcfcfc, 0xfffcfcfc,
668: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343464, 0xffd4d4fc,
669: 0xffc4c4c4, 0xffc4c4c4, 0xff343464, 0xfffcfcfc, 0xfffcfcfc,
670: 0xff343464, 0xff343464, 0xffd4d4fc, 0xffccccfc, 0xff343464,
671: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343464,
672: 0xffccccfc, 0xffc4c4c4, 0xff343464, 0xff343464, 0xfffcfcfc,
673: 0xfffcfcfc, 0xff040404, 0xff343464, 0xffccccfc, 0xffc4c4c4,
674: 0xffc4c4c4, 0xff343464, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
675: 0xfffcfcfc, 0xff343464, 0xff040404, 0xff343464, 0xff343464,
676: 0xff343464, 0xfffcfcfc, 0xff040404, 0xff343464, 0xffccccfc,
677: 0xffc4c4c4, 0xff343464, 0xff343464, 0xfffcfcfc, 0xfffcfcfc,
678: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343464, 0xff343464,
679: 0xffd4d4fc, 0xffc4c4c4, 0xffc4c4c4, 0xff343464, 0xff343464,
680: 0xffccccfc, 0xffc4c4c4, 0xff343464, 0xfffcfcfc, 0xfffcfcfc,
681: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
682: 0xff343464, 0xffccccfc, 0xff040404, 0xff6464cc, 0xff6464cc,
683: 0xff343464, 0xffccccfc, 0xff040404, 0xff343464, 0xfffcfcfc,
684: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
685: 0xfffcfcfc, 0xfffcfcfc, 0xff343464, 0xffccccfc, 0xff040404,
686: 0xff6464cc, 0xff6464cc, 0xff343464, 0xffccccfc, 0xff040404,
687: 0xff343464, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
688: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343464, 0xffccccfc,
689: 0xffc4c4c4, 0xff6464cc, 0xff343464, 0xff343464, 0xffccccfc,
690: 0xffc4c4c4, 0xff343464, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
691: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
692: 0xff343464, 0xff040404, 0xff6464cc, 0xff343464, 0xff343464,
693: 0xff343464, 0xff343464, 0xff343464, 0xfffcfcfc, 0xfffcfcfc,
694: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
695: 0xfffcfcfc, 0xfffcfcfc, 0xff343464, 0xff343464, 0xff343464,
696: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
697: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
698: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
699: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
700: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
701: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
702: 0xfffcfcfc };
703:
704: static int pageWidth = 22;
705: static int pageHeight = 26;
706: static int[] pageData = { 0xffffff, 0xffffff, 0xffffff, 0xffffff,
707: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
708: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
709: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
710: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
711: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
712: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
713: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
714: 0xff343434, 0xff343434, 0xff343434, 0xff343434, 0xff343434,
715: 0xff343434, 0xff343434, 0xff343434, 0xff343434, 0xff343434,
716: 0xff343434, 0xff343434, 0xff343434, 0xffffff, 0xffffff,
717: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
718: 0xffffff, 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
719: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
720: 0xfffcfcfc, 0xfffcfcfc, 0xff343434, 0xfffcfcfc, 0xff343434,
721: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
722: 0xffffff, 0xffffff, 0xff343434, 0xfffcfcfc, 0xfffcfcfc,
723: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
724: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343434, 0xfffcfcfc,
725: 0xfffcfcfc, 0xff343434, 0xffffff, 0xffffff, 0xffffff,
726: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xff343434,
727: 0xfffcfcfc, 0xfffcfcfc, 0xff343434, 0xff343434, 0xff343434,
728: 0xff343434, 0xff343434, 0xff343434, 0xfffcfcfc, 0xfffcfcfc,
729: 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff343434,
730: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
731: 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xff343434, 0xfffccc34,
732: 0xfffccc34, 0xff64ccfc, 0xff64ccfc, 0xff64ccfc, 0xfffcfcfc,
733: 0xfffcfcfc, 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
734: 0xfffcfcfc, 0xff343434, 0xffffff, 0xffffff, 0xffffff,
735: 0xffffff, 0xffffff, 0xff343434, 0xfffcfcfc, 0xfffcfcfc,
736: 0xff343434, 0xfffccc34, 0xff64ccfc, 0xff64ccfc, 0xff64ccfc,
737: 0xff64ccfc, 0xfffcfcfc, 0xfffcfcfc, 0xff040404, 0xff343434,
738: 0xff040404, 0xff343434, 0xff040404, 0xff343434, 0xff040404,
739: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xff343434,
740: 0xfffcfcfc, 0xfffcfcfc, 0xff343434, 0xff64ccfc, 0xff64ccfc,
741: 0xff64ccfc, 0xff64ccfc, 0xff64ccfc, 0xfffcfcfc, 0xfffcfcfc,
742: 0xff040404, 0xff040404, 0xff040404, 0xff040404, 0xff040404,
743: 0xff040404, 0xff040404, 0xffffff, 0xffffff, 0xffffff,
744: 0xffffff, 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xff343434,
745: 0xff9c6434, 0xff9c6434, 0xff9c6434, 0xff9c6434, 0xff9c6434,
746: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff9c9c9c,
747: 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c, 0xff040404, 0xffffff,
748: 0xffffff, 0xffffff, 0xffffff, 0xff343434, 0xfffcfcfc,
749: 0xfffcfcfc, 0xff343434, 0xff9c6434, 0xff9c6434, 0xff9c6434,
750: 0xff9c6434, 0xff9c6434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
751: 0xfffcfcfc, 0xfffcfcfc, 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c,
752: 0xff040404, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
753: 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
754: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
755: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
756: 0xfffcfcfc, 0xff9c9c9c, 0xff040404, 0xffffff, 0xffffff,
757: 0xffffff, 0xffffff, 0xff343434, 0xfffcfcfc, 0xfffcfcfc,
758: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
759: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
760: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff9c9c9c, 0xff040404,
761: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xff343434,
762: 0xfffcfcfc, 0xfffcfcfc, 0xff040404, 0xff040404, 0xff040404,
763: 0xff040404, 0xff040404, 0xff040404, 0xff040404, 0xff040404,
764: 0xff040404, 0xff040404, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
765: 0xff9c9c9c, 0xff040404, 0xffffff, 0xffffff, 0xffffff,
766: 0xffffff, 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
767: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
768: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
769: 0xfffcfcfc, 0xfffcfcfc, 0xff9c9c9c, 0xff040404, 0xffffff,
770: 0xffffff, 0xffffff, 0xffffff, 0xff343434, 0xfffcfcfc,
771: 0xfffcfcfc, 0xff040404, 0xff040404, 0xff040404, 0xff040404,
772: 0xff040404, 0xff040404, 0xff040404, 0xff040404, 0xff040404,
773: 0xff040404, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff9c9c9c,
774: 0xff040404, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
775: 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
776: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
777: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
778: 0xfffcfcfc, 0xff9c9c9c, 0xff040404, 0xffffff, 0xffffff,
779: 0xffffff, 0xffffff, 0xff343434, 0xfffcfcfc, 0xfffcfcfc,
780: 0xfffcfcfc, 0xfffcfcfc, 0xfffc3434, 0xfffcfcfc, 0xff040404,
781: 0xff040404, 0xff040404, 0xff040404, 0xff040404, 0xff040404,
782: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff9c9c9c, 0xff040404,
783: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xff343434,
784: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
785: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
786: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
787: 0xff9c9c9c, 0xff040404, 0xffffff, 0xffffff, 0xffffff,
788: 0xffffff, 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
789: 0xfffcfcfc, 0xfffc3434, 0xfffcfcfc, 0xff040404, 0xff040404,
790: 0xff040404, 0xff040404, 0xff040404, 0xff040404, 0xfffcfcfc,
791: 0xfffcfcfc, 0xfffcfcfc, 0xff9c9c9c, 0xff040404, 0xffffff,
792: 0xffffff, 0xffffff, 0xffffff, 0xff343434, 0xfffcfcfc,
793: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
794: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
795: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xff9c9c9c,
796: 0xff040404, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
797: 0xff343434, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
798: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
799: 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc, 0xfffcfcfc,
800: 0xfffcfcfc, 0xff9c9c9c, 0xff040404, 0xffffff, 0xffffff,
801: 0xffffff, 0xffffff, 0xff343434, 0xff343434, 0xff9c9c9c,
802: 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c,
803: 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c,
804: 0xff9c9c9c, 0xff9c9c9c, 0xff9c9c9c, 0xff343434, 0xff040404,
805: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
806: 0xff040404, 0xff040404, 0xff040404, 0xff040404, 0xff040404,
807: 0xff040404, 0xff040404, 0xff040404, 0xff040404, 0xff040404,
808: 0xff040404, 0xff040404, 0xff040404, 0xff040404, 0xff040404,
809: 0xff040404, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
810: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
811: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
812: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
813: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
814: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
815: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
816: 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff };
817:
818: static int retrieveWidth = 8;
819: static int retrieveHeight = 8;
820: static int[] retrieveData = { 0xffffff, 0xffffff, 0xff008000,
821: 0xff008000, 0xff008000, 0xff008000, 0xffffff, 0xffffff,
822: 0xffffff, 0xff008000, 0xff008000, 0xff008000, 0xff008000,
823: 0xff008000, 0xff008000, 0xffffff, 0xff008000, 0xff008000,
824: 0xff008000, 0xff008000, 0xff008000, 0xff008000, 0xff008000,
825: 0xff008000, 0xff008000, 0xff008000, 0xff008000, 0xff008000,
826: 0xff008000, 0xff008000, 0xff008000, 0xff008000, 0xff008000,
827: 0xff008000, 0xff008000, 0xff008000, 0xff008000, 0xff008000,
828: 0xff008000, 0xff008000, 0xff008000, 0xff008000, 0xff008000,
829: 0xff008000, 0xff008000, 0xff008000, 0xff008000, 0xff008000,
830: 0xffffff, 0xff008000, 0xff008000, 0xff008000, 0xff008000,
831: 0xff008000, 0xff008000, 0xffffff, 0xffffff, 0xffffff,
832: 0xff008000, 0xff008000, 0xff008000, 0xff008000, 0xffffff,
833: 0xffffff };
834:
835: static int errorWidth = 8;
836: static int errorHeight = 8;
837: static int[] errorData = { 0xfffc0404, 0xfffc0404, 0xfcfcfc,
838: 0xfcfcfc, 0xfcfcfc, 0xfcfcfc, 0xfffc0404, 0xfffc0404,
839: 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfcfcfc, 0xfcfcfc,
840: 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfcfcfc, 0xfffc0404,
841: 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfffc0404,
842: 0xfcfcfc, 0xfcfcfc, 0xfcfcfc, 0xfffc0404, 0xfffc0404,
843: 0xfffc0404, 0xfffc0404, 0xfcfcfc, 0xfcfcfc, 0xfcfcfc,
844: 0xfcfcfc, 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfffc0404,
845: 0xfcfcfc, 0xfcfcfc, 0xfcfcfc, 0xfffc0404, 0xfffc0404,
846: 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfcfcfc,
847: 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfcfcfc, 0xfcfcfc,
848: 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfffc0404, 0xfffc0404,
849: 0xfcfcfc, 0xfcfcfc, 0xfcfcfc, 0xfcfcfc, 0xfffc0404,
850: 0xfffc0404 };
851:
852: static {
853: Toolkit tkit = Toolkit.getDefaultToolkit();
854: defaultPageIcon = tkit.createImage(new MemoryImageSource(
855: pageWidth, pageHeight, pageData, 0, pageWidth));
856: defaultLinkIcon = tkit.createImage(new MemoryImageSource(
857: linkWidth, linkHeight, linkData, 0, linkWidth));
858: defaultRetrievingIcon = tkit.createImage(new MemoryImageSource(
859: retrieveWidth, retrieveHeight, retrieveData, 0,
860: retrieveWidth));
861: defaultErrorIcon = tkit.createImage(new MemoryImageSource(
862: errorWidth, errorHeight, errorData, 0, errorWidth));
863:
864: }
865: }
|