KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > htmlparser > parserapplications > filterbuilder > FilterBuilder


1 // HTMLParser Library $Name: v1_5_20050313 $ - A java-based parser for HTML
2
// http://sourceforge.org/projects/htmlparser
3
// Copyright (C) 2005 Derrick Oswald
4
//
5
// Revision Control Information
6
//
7
// $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/parserapplications/filterbuilder/FilterBuilder.java,v $
8
// $Author: derrickoswald $
9
// $Date: 2005/03/04 15:57:25 $
10
// $Revision: 1.3 $
11
//
12
// This library is free software; you can redistribute it and/or
13
// modify it under the terms of the GNU Lesser General Public
14
// License as published by the Free Software Foundation; either
15
// version 2.1 of the License, or (at your option) any later version.
16
//
17
// This library is distributed in the hope that it will be useful,
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
// Lesser General Public License for more details.
21
//
22
// You should have received a copy of the GNU Lesser General Public
23
// License along with this library; if not, write to the Free Software
24
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
//
26

27 package org.htmlparser.parserapplications.filterbuilder;
28
29 import java.awt.BorderLayout JavaDoc;
30 import java.awt.Component JavaDoc;
31 import java.awt.Container JavaDoc;
32 import java.awt.Dimension JavaDoc;
33 import java.awt.Event JavaDoc;
34 import java.awt.FileDialog JavaDoc;
35 import java.awt.FlowLayout JavaDoc;
36 import java.awt.Insets JavaDoc;
37 import java.awt.Point JavaDoc;
38 import java.awt.Toolkit JavaDoc;
39 import java.awt.datatransfer.Clipboard JavaDoc;
40 import java.awt.datatransfer.ClipboardOwner JavaDoc;
41 import java.awt.datatransfer.DataFlavor JavaDoc;
42 import java.awt.datatransfer.StringSelection JavaDoc;
43 import java.awt.datatransfer.Transferable JavaDoc;
44 import java.awt.datatransfer.UnsupportedFlavorException JavaDoc;
45 import java.awt.dnd.DnDConstants JavaDoc;
46 import java.awt.dnd.DragGestureEvent JavaDoc;
47 import java.awt.dnd.DragGestureListener JavaDoc;
48 import java.awt.dnd.DragSource JavaDoc;
49 import java.awt.dnd.DragSourceDragEvent JavaDoc;
50 import java.awt.dnd.DragSourceDropEvent JavaDoc;
51 import java.awt.dnd.DragSourceEvent JavaDoc;
52 import java.awt.dnd.DragSourceListener JavaDoc;
53 import java.awt.dnd.DropTarget JavaDoc;
54 import java.awt.dnd.DropTargetContext JavaDoc;
55 import java.awt.dnd.DropTargetDragEvent JavaDoc;
56 import java.awt.dnd.DropTargetDropEvent JavaDoc;
57 import java.awt.dnd.DropTargetEvent JavaDoc;
58 import java.awt.dnd.DropTargetListener JavaDoc;
59 import java.awt.event.ActionEvent JavaDoc;
60 import java.awt.event.ActionListener JavaDoc;
61 import java.awt.event.InputEvent JavaDoc;
62 import java.awt.event.KeyEvent JavaDoc;
63 import java.awt.event.MouseEvent JavaDoc;
64 import java.awt.event.MouseListener JavaDoc;
65 import java.awt.event.MouseMotionListener JavaDoc;
66 import java.awt.event.WindowEvent JavaDoc;
67 import java.awt.event.WindowListener JavaDoc;
68 import java.beans.PropertyVetoException JavaDoc;
69 import java.io.File JavaDoc;
70 import java.io.FileReader JavaDoc;
71 import java.io.FileWriter JavaDoc;
72 import java.io.IOException JavaDoc;
73 import java.io.LineNumberReader JavaDoc;
74 import java.io.PrintWriter JavaDoc;
75 import java.io.StringWriter JavaDoc;
76 import java.lang.reflect.Method JavaDoc;
77 import java.net.MalformedURLException JavaDoc;
78 import java.net.URL JavaDoc;
79 import java.util.Vector JavaDoc;
80
81 import javax.swing.Icon JavaDoc;
82 import javax.swing.ImageIcon JavaDoc;
83 import javax.swing.JButton JavaDoc;
84 import javax.swing.JDesktopPane JavaDoc;
85 import javax.swing.JFrame JavaDoc;
86 import javax.swing.JInternalFrame JavaDoc;
87 import javax.swing.JMenu JavaDoc;
88 import javax.swing.JMenuBar JavaDoc;
89 import javax.swing.JMenuItem JavaDoc;
90 import javax.swing.JOptionPane JavaDoc;
91 import javax.swing.JPanel JavaDoc;
92 import javax.swing.JPopupMenu JavaDoc;
93 import javax.swing.JScrollPane JavaDoc;
94 import javax.swing.JSeparator JavaDoc;
95 import javax.swing.JSplitPane JavaDoc;
96 import javax.swing.JTextField JavaDoc;
97 //import javax.swing.JTextPane;
98
import javax.swing.JToolBar JavaDoc;
99 import javax.swing.JTree JavaDoc;
100 import javax.swing.KeyStroke JavaDoc;
101 import javax.swing.ScrollPaneConstants JavaDoc;
102 import javax.swing.WindowConstants JavaDoc;
103
104 import org.htmlparser.Parser;
105 import org.htmlparser.beans.FilterBean;
106 import org.htmlparser.parserapplications.filterbuilder.layouts.NullLayoutManager;
107 import org.htmlparser.util.EncodingChangeException;
108 import org.htmlparser.util.NodeIterator;
109 import org.htmlparser.util.NodeList;
110 import org.htmlparser.util.ParserException;
111
112 /**
113  * The main program for the FilterBuilder programming system.
114  * <p>ToDo:
115  * <ul>
116  * <li>thread the attribute fetching</li>
117  * <li>CSS selector filter</li>
118  * <li>table row filter</li>
119  * <li>table column filter</li>
120  * <li>trigger filter</li>
121  * <li>undo</li>
122  * <li>handle bad URLs</li>
123  * <li>StringBean type secondary text output</li>
124  * <li>context sensitive menus</li>
125  * </ul>
126  */

127 public class FilterBuilder
128     extends
129         JFrame JavaDoc
130     implements
131         WindowListener JavaDoc,
132         ActionListener JavaDoc,
133         MouseListener JavaDoc,
134         MouseMotionListener JavaDoc,
135         DragGestureListener JavaDoc,
136         DragSourceListener JavaDoc,
137         DropTargetListener JavaDoc,
138         ClipboardOwner JavaDoc
139 {
140     static final String JavaDoc TITLE = "HTML Parser FilterBuilder";
141
142     static final URL JavaDoc mDocumentBase;
143     
144     static
145     {
146         
147         String JavaDoc p;
148         char ps;
149         URL JavaDoc base;
150
151         p = System.getProperty ("user.dir");
152         // if the system file separator isn't the URL file separator convert it.
153
try
154         {
155             ps = (System.getProperty ("file.separator")).charAt(0);
156             if ('/' != ps)
157                 p.replace (ps, '/');
158         }
159         catch (StringIndexOutOfBoundsException JavaDoc e)
160         {
161         }
162
163         try
164         {
165             base = new URL JavaDoc ("file:///" + p + "/");
166         }
167         catch (MalformedURLException JavaDoc murle)
168         {
169             base = null;
170         }
171         mDocumentBase = base;
172     }
173
174     static String JavaDoc mHomeDir;
175     
176     static
177     {
178         String JavaDoc dir;
179         File JavaDoc file;
180
181         dir = System.getProperty ("user.home")
182             + System.getProperty ("file.separator")
183             + ".htmlparser";
184         file = new File JavaDoc (dir);
185         if (!file.exists ())
186             if (!file.mkdirs ()) // make the directory if it doesn't exist
187
throw new RuntimeException JavaDoc (
188                     "cannot create directory "
189                     + file.getAbsolutePath ());
190         mHomeDir = file.getAbsolutePath ();
191     }
192     
193     /**
194      * The relative position of the mouse while dragging.
195      */

196     protected Point JavaDoc mBasePoint;
197
198     /**
199      * Selected commands.
200      */

201     protected Vector JavaDoc mSelection;
202
203     /**
204      * If true selection moved.
205      */

206     protected boolean mMoved;
207
208     /**
209      * This component is a drop target.
210      */

211     protected DropTarget JavaDoc mDropTarget;
212     
213     /**
214      * Enables this component to be a Drag Source.
215      */

216     protected DragSource JavaDoc mDragSource;
217
218     /**
219      * Kludge: Used by actionPerformed/filterAction to remember the filter menu item.
220      */

221     protected Component JavaDoc mCurrentComponent;
222
223     protected JPanel JavaDoc mMainPanel;
224     protected JScrollPane JavaDoc mMainScroller;
225     protected JTextField JavaDoc mURLField;
226     protected JDesktopPane JavaDoc mOutput;
227
228     /**
229      * Create an FilterBuilder programming environment.
230      */

231     public FilterBuilder ()
232     {
233         JMenuBar JavaDoc menubar;
234         JToolBar JavaDoc toolbar;
235         JMenu JavaDoc menu;
236         JPanel JavaDoc panel;
237         JScrollPane JavaDoc pane;
238         JSplitPane JavaDoc split;
239         JMenuItem JavaDoc item;
240
241         // drag and drop support
242
mMainPanel = new JPanel JavaDoc ();
243         mDropTarget = new DropTarget JavaDoc (mMainPanel, this);
244         mDragSource = new DragSource JavaDoc ();
245
246         // menu and toolbar
247
menubar = new JMenuBar JavaDoc();
248         toolbar = new JToolBar JavaDoc ();
249         toolbar.setAlignmentY (0.222222F);
250
251         // file menu
252
menu = new JMenu JavaDoc ();
253         menu.setText ("File");
254         menu.setActionCommand ("File");
255         menu.setMnemonic ((int)'F');
256         makeMenuButton ("New", "Create a new document", "New", 'N', KeyStroke.getKeyStroke (KeyEvent.VK_N, Event.CTRL_MASK), toolbar, menu);
257         makeMenuButton ("Open", "Open an existing document", "Open...", 'O', KeyStroke.getKeyStroke (KeyEvent.VK_O, Event.CTRL_MASK), toolbar, menu);
258         makeMenuButton ("Save", "Save the active document", "Save...", 'S', KeyStroke.getKeyStroke (KeyEvent.VK_S, Event.CTRL_MASK), toolbar, menu);
259         makeMenuButton ("SaveAs", "Save the active document", "Save As...", 'A', KeyStroke.getKeyStroke (KeyEvent.VK_A, Event.CTRL_MASK), null, menu);
260         menu.add (new JSeparator JavaDoc ());
261         makeMenuButton ("Exit", "Exit the program", "Exit", 'E', KeyStroke.getKeyStroke (KeyEvent.VK_E, Event.CTRL_MASK), null, menu);
262         menubar.add (menu);
263         
264         toolbar.add(new JToolBar.Separator JavaDoc());
265
266         // edit menu
267
menu = new JMenu JavaDoc ();
268         menu.setText ("Edit");
269         menu.setActionCommand ("Edit");
270         menu.setMnemonic ((int)'E');
271         makeMenuButton ("Cut", "Cut the selection and put it on the Clipboard", "Cut", 'T', KeyStroke.getKeyStroke (KeyEvent.VK_X, Event.CTRL_MASK), toolbar, menu);
272         makeMenuButton ("Copy", "Copy the selection and put it on the Clipboard", "Copy", 'C', KeyStroke.getKeyStroke (KeyEvent.VK_C, Event.CTRL_MASK), toolbar, menu);
273         makeMenuButton ("Paste", "Insert Clipboard contents", "Paste", 'P', KeyStroke.getKeyStroke (KeyEvent.VK_V, Event.CTRL_MASK), toolbar, menu);
274         makeMenuButton ("Delete", "Delete the selection", "Delete", 'D', KeyStroke.getKeyStroke (KeyEvent.VK_DELETE, 0), toolbar, menu);
275         menubar.add (menu);
276
277         // filter menu
278
menu = new JMenu JavaDoc ();
279         menu.setText ("Filter");
280         menu.setActionCommand ("Filter");
281         menu.setMnemonic ((int)'F');
282         menubar.add (menu);
283
284         toolbar.add (new JToolBar.Separator JavaDoc());
285
286         // filters menu and filters toolbar
287
addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.AndFilterWrapper");
288         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.OrFilterWrapper");
289         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.NotFilterWrapper");
290         menu.addSeparator ();
291         toolbar.add (new JToolBar.Separator JavaDoc ());
292
293         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.StringFilterWrapper");
294         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.RegexFilterWrapper");
295         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.TagNameFilterWrapper");
296         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.NodeClassFilterWrapper");
297         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.HasAttributeFilterWrapper");
298         menu.addSeparator ();
299         toolbar.add (new JToolBar.Separator JavaDoc ());
300
301         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.HasParentFilterWrapper");
302         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.HasChildFilterWrapper");
303         addFilter (menu, toolbar, "org.htmlparser.parserapplications.filterbuilder.wrappers.HasSiblingFilterWrapper");
304         menu.addSeparator ();
305         toolbar.add (new JToolBar.Separator JavaDoc ());
306
307         // operation menu
308
menu = new JMenu JavaDoc ();
309         menu.setText ("Operation");
310         menu.setActionCommand ("Operation");
311         menu.setMnemonic ((int)'r');
312         item = new JMenuItem JavaDoc ();
313         item.setText ("Expand");
314         item.setActionCommand ("expandAction");
315         item.addActionListener (this);
316         menu.add (item);
317         item = new JMenuItem JavaDoc ();
318         item.setText ("Collapse");
319         item.setActionCommand ("collapseAction");
320         item.addActionListener (this);
321         menu.add (item);
322         menu.addSeparator ();
323         item = new JMenuItem JavaDoc ();
324         item.setText ("Expand All");
325         item.setActionCommand ("expandAllAction");
326         item.addActionListener (this);
327         menu.add (item);
328         item = new JMenuItem JavaDoc ();
329         item.setText ("Collapse All");
330         item.setActionCommand ("collapseAllAction");
331         item.addActionListener (this);
332         menu.add (item);
333         menu.addSeparator ();
334         item = new JMenuItem JavaDoc ("Fetch Page");
335         item.setActionCommand ("fetchAction");
336         item.addActionListener (this);
337         menu.add (item);
338         item = new JMenuItem JavaDoc ("Execute Filter");
339         item.setActionCommand ("executeAction");
340         item.addActionListener (this);
341         menu.add (item);
342         menubar.add (menu);
343
344         // help menu
345
menu = new JMenu JavaDoc ();
346         menu.setText ("Help");
347         menu.setActionCommand ("Help");
348         menu.setMnemonic ((int)'H');
349         item = new JMenuItem JavaDoc ("Filtering");
350         item.setActionCommand ("filteringAction");
351         item.addActionListener (this);
352         menu.add (item);
353         item = new JMenuItem JavaDoc ("Instructions");
354         item.setActionCommand ("instructionsAction");
355         item.addActionListener (this);
356         menu.add (item);
357         item = new JMenuItem JavaDoc ("Tutorial");
358         item.setActionCommand ("tutorialAction");
359         item.addActionListener (this);
360         menu.add (item);
361         item = new JMenuItem JavaDoc ("Hints");
362         item.setActionCommand ("hintsAction");
363         item.addActionListener (this);
364         menu.add (item);
365         makeMenuButton ("About", "Display program information, version number and copyright", "About", 'B', KeyStroke.getKeyStroke (KeyEvent.VK_H, Event.CTRL_MASK), toolbar, menu);
366         menubar.add (menu);
367
368         setJMenuBar (menubar);
369
370         // toolbar panel
371
panel = new JPanel JavaDoc ();
372         panel.setLayout (new FlowLayout JavaDoc (FlowLayout.LEFT,0,0));
373         panel.add (toolbar);
374         getContentPane().setLayout (new BorderLayout JavaDoc (0,0));
375         getContentPane ().add (BorderLayout.NORTH, panel);
376
377         // URL entry
378
mURLField = new JTextField JavaDoc ();
379         mURLField.setToolTipText ("Enter the URL to view");
380 // mTextField.addActionListener (this);
381
mURLField.setText ("http://sourceforge.org/projects/htmlparser");
382         getContentPane().add (BorderLayout.SOUTH, mURLField);
383
384         // application setup
385
setTitle (TITLE);
386         setDefaultCloseOperation (WindowConstants.DO_NOTHING_ON_CLOSE);
387         setSize (640, 480);
388         setVisible (false);
389
390         // main panel
391
mMainPanel.setLayout (new NullLayoutManager ());
392         mMainScroller = new JScrollPane JavaDoc (
393                 mMainPanel,
394                 ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
395                 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
396
397         split = new JSplitPane JavaDoc ();
398         pane = new JScrollPane JavaDoc ();
399         pane.setViewportView (mMainScroller);
400         split.setLeftComponent (pane);
401
402         mOutput = new JDesktopPane JavaDoc ();
403         split.setRightComponent (mOutput);
404
405         getContentPane().add (BorderLayout.CENTER, split);
406
407         // shenanigans to get the splitter bar at the midpoint
408
setVisible (true);
409         split.setDividerLocation (0.5);
410         setVisible (false);
411
412         // listeners
413
addWindowListener (this);
414         setIconImage (Toolkit.getDefaultToolkit ().getImage ("images/program16.gif"));
415         addMouseListener (this);
416         addMouseMotionListener (this);
417
418         // clipboard buffer
419
mSelection = new Vector JavaDoc ();
420     }
421
422     /**
423      * Creates a new instance of an FilterBuilder environment with the given title.
424      * @param title the title for the new frame.
425      * @see #FilterBuilder()
426      */

427     public FilterBuilder (String JavaDoc title)
428     {
429         this ();
430         setTitle (title);
431     }
432
433     /**
434      * Makes menu and toolbar items for commands.
435      * @param name The name of the command.
436      * @param description A description for the tooltip.
437      * @param text The text for the menu.
438      * @param mnemonic The navigation mnemonic.
439      * @param key Accelerator key.
440      * @param toolbar The toolbar to add the button to.
441      * @param menu The menu to add the menu item to.
442      */

443     protected void makeMenuButton (
444             String JavaDoc name,
445             String JavaDoc description,
446             String JavaDoc text,
447             int mnemonic,
448             KeyStroke JavaDoc key,
449             JToolBar JavaDoc toolbar,
450             JMenu JavaDoc menu)
451     {
452         JButton JavaDoc button;
453         JMenuItem JavaDoc item;
454         ImageIcon JavaDoc icon;
455         String JavaDoc command;
456
457         command = name.toLowerCase ();
458         try
459         {
460             icon = new ImageIcon JavaDoc (getURL ("images/" + command + ".gif"));
461         }
462         catch (java.net.MalformedURLException JavaDoc error)
463         {
464             icon = null;
465         }
466
467         item = new JMenuItem JavaDoc ();
468         item.setText (text);
469         item.setActionCommand (command + "Action");
470         item.setAccelerator (key);
471         item.setMnemonic (mnemonic);
472         item.setIcon (icon);
473         item.addActionListener (this);
474         menu.add (item);
475
476         if (null != toolbar)
477         {
478             button = new JButton JavaDoc ();
479             button.setDefaultCapable (false);
480             button.setToolTipText (description);
481             button.setMnemonic (mnemonic);
482             button.setActionCommand (command + "Action");
483             button.setMargin (new Insets JavaDoc (0, 0, 0, 0));
484             button.setIcon (icon);
485             button.addActionListener (this);
486             toolbar.add (button);
487         }
488     }
489
490     /**
491      * Get a url for the given resource specification.
492      * @param spec The name of the resource.
493      */

494     protected URL JavaDoc getURL (String JavaDoc spec)
495         throws MalformedURLException JavaDoc
496     {
497         URL JavaDoc ret;
498
499         if (null == (ret = getClass ().getResource (spec)))
500             if ((null != mDocumentBase) && (-1 == spec.indexOf ("//")))
501                 ret = new URL JavaDoc (mDocumentBase, spec);
502             else
503                 ret = new URL JavaDoc (spec);
504
505         return ret;
506     }
507
508     /**
509      * Creates a new button for the given class.
510      * @param class_name The name of the Filter class.
511      * @return A fully functional button with name, tool tip,
512      * icon and drag recognizer.
513      */

514     public JButton JavaDoc makeFilterButton (String JavaDoc class_name)
515     {
516         Filter filter;
517         JButton JavaDoc ret;
518
519         ret = new JButton JavaDoc ();
520         filter = Filter.instantiate (class_name);
521         if (null != filter)
522         {
523             ret.setName (class_name); // filter.getNodeFilter ().getClass ().getName ());
524
ret.setToolTipText (filter.getDescription ());
525             ret.setMargin (new Insets JavaDoc (0, 0, 0, 0));
526             ret.setIcon (filter.getIcon ());
527             mDragSource.createDefaultDragGestureRecognizer (
528                 ret,
529                 DnDConstants.ACTION_MOVE,
530                 this);
531             ret.setActionCommand ("filterAction");
532             ret.addActionListener (this);
533         }
534         
535         return (ret);
536     }
537
538     public void addFilter (JMenu JavaDoc menu, JToolBar JavaDoc toolbar, String JavaDoc class_name)
539     {
540         Filter filter;
541
542         filter = Filter.instantiate (class_name);
543         if (null != filter)
544         {
545             String JavaDoc name;
546             String JavaDoc description;
547             Icon JavaDoc icon;
548             String JavaDoc text;
549             JMenuItem JavaDoc item;
550
551             name = filter.getNodeFilter ().getClass ().getName ();
552             description = filter.getDescription ();
553             icon = filter.getIcon ();
554             text = name.substring (name.lastIndexOf ('.') + 1);
555
556             item = new JMenuItem JavaDoc ();
557             item.setName (class_name);
558             item.setText (text);
559             item.setActionCommand ("filterAction");
560 // item.setAccelerator (key);
561
// item.setMnemonic (mnemonic);
562
item.setToolTipText (description);
563             item.setIcon (icon);
564             item.addActionListener (this);
565             menu.add (item);
566             
567             toolbar.add (makeFilterButton (class_name));
568         }
569     }
570
571     protected void insertFilters (Filter[] filters, Point JavaDoc point, SubFilterList list)
572     {
573         Dimension JavaDoc dimension;
574
575         if (null == list)
576         {
577             for (int i = 0; i < filters.length; i++)
578             {
579                 filters[i].setLocation (point);
580                 mMainPanel.add (filters[i]);
581                 dimension = filters[i].getPreferredSize ();
582                 point.y += dimension.height;
583             }
584         }
585         else
586             for (int i = 0; i < filters.length; i++)
587                 list.addFilter (filters[i]);
588         setupDropTargets (filters);
589         setupMouseListeners (filters);
590         relayout ();
591     }
592
593     /**
594      * Sets the position of the mouse in the component.
595      *
596      * @param point The point where the mouse position is.
597      */

598     protected void setBasePoint (Point JavaDoc point)
599     {
600         mBasePoint = point;
601     }
602     
603     /**
604      * Gets the current base point of the mouse pointer.
605      * This value is used to offset the drag position
606      * to maintain the mouse position at the same
607      * relative position within the card while dragging.
608      *
609      * @return The current base point of the mouse pointer.
610      */

611     protected Point JavaDoc getBasePoint ()
612     {
613         return (mBasePoint);
614     }
615
616     /**
617      * Get the enclosing sub filter list if any.
618      * @param component The component that's supposedly enclosed.
619      * @return The enclosing component or <code>null</code> otherwise.
620      */

621     protected SubFilterList getEnclosing (Component JavaDoc component)
622     {
623         do
624             component = component.getParent ();
625         while ( (null != component)
626                 && !(component instanceof SubFilterList));
627
628         return ((SubFilterList)component);
629     }
630
631     /**
632      * Get the enclosed sub filter list if any.
633      * @param component The component that's supposedly enclosing the list.
634      * @return The enclosed component or <code>null</code> otherwise.
635      */

636     protected SubFilterList getEnclosed (Component JavaDoc component)
637     {
638         Component JavaDoc[] list;
639
640         if (component instanceof Container JavaDoc)
641         {
642             list = ((Container JavaDoc)component).getComponents ();
643             for (int i = 0; i < list.length; i++)
644                 if (list[i] instanceof SubFilterList)
645                     return ((SubFilterList)list[i]);
646         }
647
648         return (null);
649     }
650
651     /* makes a program like:
652         // Generated by FilterBuilder. http://htmlparser.org
653         // [aced0005737200206f72672e68746d6c7061727365722e66696c746572732e416e6446696c74657224c30516b2b7b2120200015b000b6d5072656469636174657374001c5b4c6f72672f68746d6c7061727365722f4e6f646546696c7465723b78707572001c5b4c6f72672e68746d6c7061727365722e4e6f646546696c7465723b8f17479b1d5f7992020000787000000002737200246f72672e68746d6c7061727365722e66696c746572732e5461674e616d6546696c746572b28b2601a614890f0200014c00056d4e616d657400124c6a6176612f6c616e672f537472696e673b78707400044d455441737200296f72672e68746d6c7061727365722e66696c746572732e48617341747472696275746546696c74657296abdfb3b0714cda0200024c000a6d41747472696275746571007e00064c00066d56616c756571007e000678707400046e616d6570]
654                                                                                                                                                                 
655         import org.htmlparser.*;
656         import org.htmlparser.filters.*;
657         import org.htmlparser.beans.*;
658         import org.htmlparser.util.*;
659                                                                                                                                                                 
660         public class Test
661         {
662             public static void main (String args[])
663             {
664                 TagNameFilter filter0 = new TagNameFilter ();
665                 filter0.setName ("META");
666                 HasAttributeFilter filter1 = new HasAttributeFilter ();
667                 filter1.setAttributeName ("name");
668                 NodeFilter[] array0 = new NodeFilter[2];
669                 array0[0] = filter0;
670                 array0[1] = filter1;
671                 AndFilter filter2 = new AndFilter ();
672                 filter2.setPredicates (array0);
673                 NodeFilter[] array1 = new NodeFilter[1];
674                 array1[0] = filter2;
675                 FilterBean bean = new FilterBean ();
676                 bean.setFilters (array1);
677                 if (0 != args.length)
678                 {
679                     bean.setURL (args[0]);
680                     System.out.println (bean.getNodes ().toHtml ());
681                 }
682                 else
683                     System.out.println ("Usage: java -classpath .:htmlparser.jar Test <url>");
684             }
685         }
686      */

687     protected void makeProgram (String JavaDoc name, StringBuffer JavaDoc out, FilterBean bean)
688     {
689         // so we need to keep track of filters and arrays of filters to give them unique numbers
690
// each Filter is responsible for outputting it's code and returning it's variable name
691
int[] context; // 0 - indent, 1 - next filter variable #, 2 - next array of filters variable #
692
String JavaDoc[] names;
693         Filter[] filters;
694         String JavaDoc array;
695
696         filters = (Filter[])bean.getFilters ();
697
698         context = new int[3];
699         context[0] = 0;
700
701         Filter.spaces (out, context[0]);
702         out.append ("// Generated by FilterBuilder. http://htmlparser.org");
703         Filter.newline (out);
704         Filter.spaces (out, context[0]);
705         out.append ("// ");
706         try
707         {
708             out.append (Filter.deconstitute (filters));
709         }
710         catch (IOException JavaDoc ioe)
711         {
712             ioe.printStackTrace ();
713         }
714         Filter.newline (out);
715         Filter.newline (out);
716
717         Filter.spaces (out, context[0]);
718         out.append ("import org.htmlparser.*;");
719         Filter.newline (out);
720         Filter.spaces (out, context[0]);
721         out.append ("import org.htmlparser.filters.*;");
722         Filter.newline (out);
723         Filter.spaces (out, context[0]);
724         out.append ("import org.htmlparser.beans.*;");
725         Filter.newline (out);
726         Filter.spaces (out, context[0]);
727         out.append ("import org.htmlparser.util.*;");
728         Filter.newline (out);
729         Filter.newline (out);
730
731         Filter.spaces (out, context[0]);
732         out.append ("public class ");
733         out.append (name);
734         Filter.newline (out);
735         Filter.spaces (out, context[0]);
736         out.append ("{");
737
738         context[0] = 4;
739         Filter.newline (out);
740         Filter.spaces (out, context[0]);
741         out.append ("public static void main (String args[])");
742         Filter.newline (out);
743         Filter.spaces (out, context[0]);
744         out.append ("{");
745         Filter.newline (out);
746         
747         context[0] = 8;
748         names = new String JavaDoc [filters.length];
749         for (int i = 0; i < names.length; i++)
750             names[i] = filters[i].toJavaCode (out, context);
751
752         array = "array" + context[2]++;
753         Filter.spaces (out, context[0]);
754         out.append ("NodeFilter[] ");
755         out.append (array);
756         out.append (" = new NodeFilter[");
757         out.append (filters.length);
758         out.append ("];");
759         Filter.newline (out);
760         for (int i = 0; i < filters.length; i++)
761         {
762             Filter.spaces (out, context[0]);
763             out.append (array);
764             out.append ("[");
765             out.append (i);
766             out.append ("] = ");
767             out.append (names[i]);
768             out.append (";");
769             Filter.newline (out);
770         }
771
772         Filter.spaces (out, context[0]);
773         out.append ("FilterBean bean = new FilterBean ();");
774         Filter.newline (out);
775         Filter.spaces (out, context[0]);
776         out.append ("bean.setFilters (");
777         out.append (array);
778         out.append (");");
779         Filter.newline (out);
780         Filter.spaces (out, context[0]);
781         out.append ("if (0 != args.length)");
782         Filter.newline (out);
783         Filter.spaces (out, context[0]);
784         out.append ("{");
785         Filter.newline (out);
786         context[0] = 12;
787         Filter.spaces (out, context[0]);
788         out.append ("bean.setURL (args[0]);");
789         Filter.newline (out);
790         Filter.spaces (out, context[0]);
791         out.append ("System.out.println (bean.getNodes ().toHtml ());");
792         Filter.newline (out);
793         context[0] = 8;
794         Filter.spaces (out, context[0]);
795         out.append ("}");
796         Filter.newline (out);
797         Filter.spaces (out, context[0]);
798         out.append ("else");
799         Filter.newline (out);
800         context[0] = 12;
801         Filter.spaces (out, context[0]);
802         out.append ("System.out.println (\"Usage: java -classpath .:htmlparser.jar ");
803         out.append (name);
804         out.append (" <url>\");");
805         Filter.newline (out);
806         
807         context[0] = 4;
808         Filter.spaces (out, context[0]);
809         out.append ("}");
810         Filter.newline (out);
811
812         context[0] = 0;
813         Filter.spaces (out, context[0]);
814         out.append ("}");
815         Filter.newline (out);
816     }
817
818     /**
819      * Extracts a java class name from a file name.
820      * ToDo: make this package-smart somehow.
821      * @param file The name of the file.
822      * @return The name of the class.
823      */

824     protected String JavaDoc classFromFile (String JavaDoc file)
825     {
826         String JavaDoc filesep;
827         int index;
828
829         // remove any path
830
filesep = System.getProperty ("file.separator");
831         index = file.lastIndexOf (filesep);
832         if (-1 != index)
833             file = file.substring (index + filesep.length ());
834         // remove the extension
835
index = file.indexOf ('.');
836         if (-1 != index)
837             file = file.substring (0, index);
838
839         return (file);
840     }
841
842     /**
843      * Save the workspace contents to file.
844      * @param name The name of the file to save it under.
845      */

846     public void save (String JavaDoc name)
847     {
848         Filter[] selections;
849         FilterBean bean;
850         StringBuffer JavaDoc buffer;
851         PrintWriter JavaDoc out;
852         String JavaDoc ok = "OK";
853
854         selections = getFilters ();
855         if (0 != selections.length)
856         {
857             bean = new FilterBean ();
858             bean.setURL (mURLField.getText ());
859             bean.setFilters (selections);
860             buffer = new StringBuffer JavaDoc ();
861             makeProgram (classFromFile (name), buffer, bean);
862             try
863             {
864                 out = new PrintWriter JavaDoc (new FileWriter JavaDoc (name), true);
865                 try
866                 {
867                     out.write (buffer.toString ());
868                     out.flush ();
869                 }
870                 finally
871                 {
872                     out.close ();
873                 }
874             }
875             catch (IOException JavaDoc ioe)
876             {
877                 ioe.printStackTrace ();
878             }
879         }
880         else // ToDo: grey out save option if nothing to save...
881
JOptionPane.showOptionDialog (
882                 mMainPanel,
883                 "No filters to save.",
884                 "Oops",
885                 JOptionPane.DEFAULT_OPTION,
886                 JOptionPane.ERROR_MESSAGE,
887                 null,
888                 new String JavaDoc[] { ok },
889                 ok);
890     }
891
892     /**
893      * The action to take when "New" menu or button pressed.
894      */

895     protected void newAction ()
896     {
897         mMainPanel.removeAll ();
898         mSelection.clear ();
899         relayout ();
900     }
901
902     /**
903      * The action to take when "Open" menu or button pressed.
904      */

905     protected void openAction ()
906     {
907         FileDialog JavaDoc dialog;
908         File JavaDoc file;
909
910         dialog = new FileDialog JavaDoc (this);
911         dialog.setMode (FileDialog.LOAD);
912         dialog.setTitle ("Open");
913         dialog.setDirectory (mHomeDir);
914         dialog.setVisible (true);
915         if (null != dialog.getFile ())
916         {
917             mHomeDir = dialog.getDirectory ();
918             file = new File JavaDoc (mHomeDir + dialog.getFile ());
919             open (file.getAbsolutePath ());
920             setTitle (TITLE + " - " + file.getAbsolutePath ());
921         }
922     }
923
924     /**
925      * The action to take when "Save" menu or button pressed.
926      */

927     protected void saveAction ()
928     {
929         String JavaDoc title;
930         int index;
931         File JavaDoc file;
932         FileDialog JavaDoc dialog;
933
934         title = getTitle ();
935         index = title.indexOf (" - ");
936         if (-1 != index)
937             file = new File JavaDoc (title.substring (index + 3));
938         else
939         {
940             dialog = new FileDialog JavaDoc (this);
941             dialog.setMode (FileDialog.SAVE);
942             dialog.setTitle ("Save");
943             dialog.setDirectory (mHomeDir);
944             dialog.setVisible (true);
945             if (null != dialog.getFile ())
946             {
947                 mHomeDir = dialog.getDirectory ();
948                 file = new File JavaDoc (mHomeDir + dialog.getFile ());
949                 setTitle (TITLE + " - " + file.getAbsolutePath ());
950             }
951             else
952                 file = null;
953         }
954         if (null != file)
955             save (file.getAbsolutePath ());
956     }
957
958     /**
959      * The action to take when "Save As" menu or button pressed.
960      */

961     protected void saveasAction ()
962     {
963         setTitle (TITLE);
964         saveAction ();
965     }
966
967     /**
968      * The action to take when "Exit" menu or button pressed.
969      */

970     protected void exitAction ()
971     {
972         exitApplication ();
973     }
974
975     /**
976      * The action to take when "Cut" menu or button pressed.
977      */

978     protected void cutAction ()
979     {
980         String JavaDoc string;
981         StringSelection JavaDoc contents;
982         Clipboard JavaDoc cb;
983             
984         // get the selection
985
string = serializeSelection ();
986         // copy to clipboard
987
contents = new StringSelection JavaDoc (string);
988         cb = Toolkit.getDefaultToolkit ().getSystemClipboard ();
989         cb.setContents (contents, this);
990         // delete the selection
991
deleteSelection ();
992         relayout ();
993     }
994
995     /**
996      * The action to take when "Copy" menu or button pressed.
997      */

998     protected void copyAction ()
999     {
1000        String JavaDoc string;
1001        StringSelection JavaDoc contents;
1002        Clipboard JavaDoc cb;
1003            
1004        // get the selection
1005
string = serializeSelection ();
1006        // copy to clipboard
1007
contents = new StringSelection JavaDoc (string);
1008        cb = Toolkit.getDefaultToolkit ().getSystemClipboard ();
1009        cb.setContents (contents, this);
1010    }
1011
1012    /**
1013     * The action to take when "Paste" menu or button pressed.
1014     */

1015    protected void pasteAction ()
1016    {
1017        Clipboard JavaDoc cb;
1018        Transferable JavaDoc content;
1019        String JavaDoc string;
1020        Filter[] filters;
1021        Point JavaDoc point;
1022        SubFilterList list;
1023            
1024        // get the text
1025
cb = Toolkit.getDefaultToolkit ().getSystemClipboard ();
1026        content = cb.getContents (this);
1027        if (content.isDataFlavorSupported (DataFlavor.stringFlavor))
1028        {
1029            try
1030            {
1031                string = (String JavaDoc)content.getTransferData (DataFlavor.stringFlavor);
1032                // deserialize it and add into the selection
1033
filters = Filter.reconstitute (string, new Parser (mURLField.getText ()));
1034                // add it to the (single) selected object or main panel
1035
if (isSingleSelection ()
1036                        && (null != (list = getEnclosed (getSelection ()[0]))))
1037                {
1038                    for (int i = 0; i < filters.length; i++)
1039                        list.addFilter (filters[i]);
1040                }
1041                else
1042                {
1043                    point = new Point JavaDoc (0,0);
1044                    for (int i = 0; i < filters.length; i++)
1045                    {
1046                        filters[i].setLocation (point);
1047                        mMainPanel.add (filters[i]);
1048                        point.y += filters[i].getPreferredSize ().height;
1049                    }
1050                }
1051                setupMouseListeners (filters);
1052                setupDropTargets (filters);
1053                relayout ();
1054            }
1055            catch (Exception JavaDoc e)
1056            {
1057                e.printStackTrace ();
1058            }
1059        }
1060    }
1061
1062    /**
1063     * The action to take when "Delete" menu or button pressed.
1064     */

1065    protected void deleteAction ()
1066    {
1067        // delete the selection
1068
deleteSelection ();
1069        relayout ();
1070    }
1071
1072    /**
1073     * The action to take when a filter menu or button pressed.
1074     */

1075    protected void filterAction ()
1076    {
1077        String JavaDoc cls;
1078        Filter filter;
1079        SubFilterList list;
1080        Point JavaDoc point;
1081        
1082        // retrieve the source component placed there by actionPerformed
1083
cls = mCurrentComponent.getName ();
1084        filter = Filter.instantiate (cls);
1085        // need this to get the underlying filter prepped?
1086
try
1087        {
1088            filter = Filter.wrap (filter.getNodeFilter (), new Parser (mURLField.getText ()));
1089        }
1090        catch (ParserException pe)
1091        {
1092            pe.printStackTrace ();
1093        }
1094        // add it to the (single) selected object or main panel
1095
if (isSingleSelection ()
1096                && (null != (list = getEnclosed (getSelection ()[0]))))
1097        {
1098            insertFilters (new Filter[] {filter}, null, list);
1099        }
1100        else
1101        {
1102            point = new Point JavaDoc (50,50); // find where and who to stick it into
1103
insertFilters (new Filter[] {filter}, point, null);
1104        }
1105    }
1106    
1107    /**
1108     * The action to take when "Fetch" menu pressed.
1109     */

1110    protected void fetchAction ()
1111    {
1112        JInternalFrame JavaDoc frame;
1113        Dimension JavaDoc dimension;
1114        Parser parser;
1115        NodeList list;
1116
1117        // set up an internal frame for the results
1118
frame = new JInternalFrame JavaDoc (mURLField.getText ());
1119        frame.setClosable (true);
1120        frame.setResizable (true);
1121        dimension = mOutput.getSize ();
1122        frame.setBounds (0, 0, dimension.width, dimension.height);
1123        list = new NodeList ();
1124        try
1125        {
1126            parser = new Parser (mURLField.getText ());
1127            try
1128            {
1129                for (NodeIterator iterator = parser.elements (); iterator.hasMoreNodes (); )
1130                    list.add (iterator.nextNode ());
1131            }
1132            catch (EncodingChangeException ece)
1133            {
1134                list.removeAll ();
1135                parser.reset ();
1136                for (NodeIterator iterator = parser.elements (); iterator.hasMoreNodes (); )
1137                    list.add (iterator.nextNode ());
1138            }
1139        }
1140        catch (ParserException pe)
1141        {
1142            pe.printStackTrace ();
1143        }
1144        JTree JavaDoc tree = new JTree JavaDoc (new HtmlTreeModel (list));
1145        tree.setRootVisible (false);
1146        tree.setCellRenderer (new HtmlTreeCellRenderer ());
1147        JScrollPane JavaDoc treeView = new JScrollPane JavaDoc (tree);
1148        frame.setContentPane (new JScrollPane JavaDoc (
1149            treeView,
1150            ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
1151            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED));
1152        mOutput.add (frame, new Integer JavaDoc (1));
1153        try
1154        {
1155            frame.setSelected (true);
1156        }
1157        catch (PropertyVetoException JavaDoc pve)
1158        {
1159            pve.printStackTrace ();
1160        }
1161        frame.show ();
1162    }
1163
1164    /**
1165     * The action to take when "Execute" menu or button pressed.
1166     */

1167    protected void executeAction ()
1168    {
1169        Filter[] selections;
1170        FilterBean bean;
1171        JInternalFrame JavaDoc frame;
1172        Dimension JavaDoc dimension;
1173// JTextPane text;
1174

1175        selections = getSelection ();
1176        if (0 == selections.length)
1177            selections = getFilters ();
1178        if (0 != selections.length)
1179        {
1180            bean = new FilterBean ();
1181            bean.setURL (mURLField.getText ());
1182            bean.setFilters (selections);
1183            
1184            // set up an internal frame for the results
1185
frame = new JInternalFrame JavaDoc (bean.getURL ());
1186            frame.setClosable (true);
1187            frame.setResizable (true);
1188            dimension = mOutput.getSize ();
1189            frame.setBounds (0, 0, dimension.width, dimension.height / 2);
1190            JTree JavaDoc tree = new JTree JavaDoc (new HtmlTreeModel (bean.getNodes ()));
1191            tree.setRootVisible (false);
1192            tree.setCellRenderer (new HtmlTreeCellRenderer ());
1193            JScrollPane JavaDoc treeView = new JScrollPane JavaDoc (tree);
1194            frame.setContentPane (new JScrollPane JavaDoc (
1195                treeView,
1196                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
1197                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED));
1198// text = new JTextPane ();
1199
// text.setText (bean.getNodes ().toHtml ());
1200
// frame.setContentPane (new JScrollPane (
1201
// text,
1202
// ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
1203
// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED));
1204
mOutput.add (frame, new Integer JavaDoc(2)); // layer 2?
1205
try
1206            {
1207                frame.setSelected (true);
1208            }
1209            catch (PropertyVetoException JavaDoc pve)
1210            {
1211                pve.printStackTrace ();
1212            }
1213            frame.show ();
1214        }
1215    }
1216
1217    /**
1218     * The action to take when "Instructions" menu pressed.
1219     */

1220    protected void instructionsAction ()
1221    {
1222        String JavaDoc instructions =
1223            "<html>" +
1224            "Enter the target URL in the text box at the bottom of the window.<br>" +
1225            "Choose 'Fetch Page' from the Operations menu to see the whole page.<br>" +
1226            "Pick filters from the Filter menu or drag them from the toolbar.<br>" +
1227            "Filters such as And, Or, Not, HasParent, HasChild and HasSibling contain other filters:<br>" +
1228            "<ul><li>drag new filters into their blank areas at the bottom</li>" +
1229            "<li>cut an existing filter and paste into a selected filter</li></ul>" +
1230            "Build the filter incrementally, choosing 'Execute Filter' to test the selected filter.<br>" +
1231            "Save creates a .java file that runs the top level filter.<br>" +
1232            "Right click on a filter displays a pop-up menu.<br>" +
1233            "Double click on a blue item in the result pane expands the tree." +
1234            "</html>";
1235        String JavaDoc close = "Close";
1236        JOptionPane.showOptionDialog (
1237        // not .showMessageDialog(
1238
mMainPanel,
1239            instructions,
1240            "FilterBuilder Instructons",
1241            // remove this:
1242
JOptionPane.DEFAULT_OPTION,
1243            JOptionPane.INFORMATION_MESSAGE,
1244            // and remove rest of these:
1245
null,
1246            new String JavaDoc[] { close },
1247            close);
1248    }
1249
1250    /**
1251     * The action to take when "Filtering" menu pressed.
1252     */

1253    protected void filteringAction ()
1254    {
1255        String JavaDoc instructions =
1256            "<html>" +
1257            "The HTML Parser filter subsystem extracts items from a web page,<br>" +
1258            "corresponding to the use-case 'I want this little piece of information from http://yadda'.<br>" +
1259            "The web page is considered a heirarchical tree of nodes. Usually the root node is &lt;html&gt;,<br>" +
1260            "intermediate level nodes are &lt;div&gt; and &lt;table&gt; for example,<br>" +
1261            "and leaf nodes are things like text or &lt;img&gt;.<br>" +
1262            "Any node that isn't the root node has a 'parent' node.<br>" +
1263            "Leaf nodes, by definition, have no 'children'.<br>" +
1264            "A filter is a Java class that answers the simple question:<br>" +
1265            "<pre>Is this node acceptable? True or false.</pre><br>" +
1266            "Some filters know the answer just by looking at the node,<br>" +
1267            "while others must ask other filters, sometimes looking up or down the node heirarchy.<br>" +
1268            "<b>The FilterBuilder is a program for making other programs that use filters.</b><br>" +
1269            "By combining different types of filters, specific nodes can be isolated from the<br>" +
1270            "target web page.<br>" +
1271            "The results are usually passed on to another part of the users program<br>" +
1272            "that does something useful with them.<br>" +
1273            "The filters available include:<br>" +
1274            "<ul>" +
1275            "<li>AndFilter - The main 'combining' filter, answers <code>true</code> only if<br>" +
1276            "all it's subfilters (predicates) are <code>true</code>.</li>" +
1277            "<li>OrFilter - A 'combining' filter that answers <code>true</code> if<br>" +
1278            "any of it's subfilters (predicates) are <code>true</code>.</li>" +
1279            "<li>NotFilter - A 'reversing' filter that answers <code>true</code> if<br>" +
1280            "it's subfilter (predicate) is <code>false</code>.</li>" +
1281            "<li>StringFilter - A 'leaf' filter that answers <code>true</code> if<br>" +
1282            "the node is text and it contains a certain sequence of characters.<br>" +
1283            "It can be made case insensitive, but in this case a 'locale' must be<br>" +
1284            "supplied as a context for upper-case conversion.</li>" +
1285            "<li>RegexFilter - A 'leaf' filter that answers <code>true</code> if<br>" +
1286            "the node is text and it contains a certain pattern (regular expression).<br>" +
1287            "Regular expressions are descibed in the java.util.regex.Pattern class documentation.</li>" +
1288            "<li>TagNameFilter - A filter that answers <code>true</code> if<br>" +
1289            "the node is a tag and it has a certain name," +
1290            "i.e. &lt;div&gt; would match the name <code>DIV</code>.</li>" +
1291            "<li>NodeClassFilter - A filter that answers <code>true</code> if<br>" +
1292            "the node is a certain tag class. Not recommended, use TagNameFilter instead.</li>" +
1293            "<li>HasAttributeFilter - A filter that answers <code>true</code> if<br>" +
1294            "the node is a tag and it has a certain attribute,<br>" +
1295            "i.e. &lt;script language=javascript&gt; would match the attribute <code>LANGUAGE</code>.<br>" +
1296            "It can be further restricted to have a certain attribute value as well,<br>" +
1297            "i.e. 'javascript' in this example.</li>" +
1298            "<li>HasParentFilter - A filter that answers <code>true</code> if<br>" +
1299            "the node is a child of a node that is acceptable to a certain filter.<br>" +
1300            "This can be made recursive, which means the acceptable parent can be<br>" +
1301            "further up the heirarchy than just the immediate parent node.</li>" +
1302            "<li>HasChildFilter - A filter that answers <code>true</code> if<br>" +
1303            "the node is a parent of a node that is acceptable to a certain filter.<br>" +
1304            "This can be made recursive, which means the acceptable child can be<br>" +
1305            "further down the heirarchy than just the immediate children nodes.</li>" +
1306            "<li>HasSiblingFilter - A filter that answers <code>true</code> if<br>" +
1307            "the node is a sibling (they have a common parent) of a node that is<br>" +
1308            "acceptable to a certain filter.</li>" +
1309            "</ul>" +
1310            "</html>";
1311        String JavaDoc close = "Close";
1312        JOptionPane.showOptionDialog (
1313        // not .showMessageDialog(
1314
mMainPanel,
1315            instructions,
1316            "FilterBuilder Instructons",
1317            // remove this:
1318
JOptionPane.DEFAULT_OPTION,
1319            JOptionPane.INFORMATION_MESSAGE,
1320            // and remove rest of these:
1321
null,
1322            new String JavaDoc[] { close },
1323            close);
1324    }
1325
1326    /**
1327     * The action to take when "Tutorial" menu pressed.
1328     */

1329    protected void tutorialAction ()
1330    {
1331        String JavaDoc instructions =
1332            "<html>" +
1333            "To get the title text from a page:<br>" +
1334            "<ul><li>Choose 'New' from the File menu.</li>" +
1335            "<li>Choose 'AndFilter' from the Filter menu.</li>" +
1336            "<li>Select the And filter so it is highlighted.</li>" +
1337            "<li>Choose 'HasParent' from the Filter menu.</li>" +
1338            "<li>Toggle the 'Recursive' checkbox on in the HasParent filter.</li>" +
1339            "<li>Select the HasParent filter so it is highlighted.</li>" +
1340            "<li>Choose 'TagName' from the Filter menu.<br>" +
1341            "<i>Alternatively, you can drag the TagName filter (icon Hello-BOB)<br>" +
1342            "from the toolbar and drop inside the HasParent filter</i></li>" +
1343            "<li>Choose 'TITLE' from the TagName combo-box.</li>" +
1344            "<li>Select the And filter and choose 'Execute Filter' from the<br>" +
1345            "Operations menu to test it.</li>" +
1346            "<li>If there is unwanted non-text nodes in the result<br>" +
1347            "select the And filter and choose 'RegexFilter' from the Filter menu.</li>" +
1348            "<li>Test it again, as above.</li>" +
1349            "<li>Choose 'Save' from the File menu and enter a filename like GetTitle.java</li>" +
1350            "<li>Compile the java file and run it.</li></ul>" +
1351            "</html>";
1352        String JavaDoc close = "Close";
1353        JOptionPane.showOptionDialog (
1354        // not .showMessageDialog(
1355
mMainPanel,
1356            instructions,
1357            "FilterBuilder Tutorial",
1358            // remove this:
1359
JOptionPane.DEFAULT_OPTION,
1360            JOptionPane.INFORMATION_MESSAGE,
1361            // and remove rest of these:
1362
null,
1363            new String JavaDoc[] { close },
1364            close);
1365    }
1366
1367    /**
1368     * The action to take when "Hints" menu pressed.
1369     */

1370    protected void hintsAction ()
1371    {
1372        String JavaDoc instructions =
1373            "<html>" +
1374            "Hints:<br>" +
1375            "<ul><li>There is no undo yet, so save often.</li>" +
1376            "<li>Recursive HasParent and HasChild filters can be costly.</li>" +
1377            "<li>RegexFilter is more expensive than StringFilter.</li>" +
1378            "<li>The order of predicates in And and Or filters matters for performance,<br>" +
1379            "put cheap tests first.</li>" +
1380            "<li>The same node may show up more than once in the results,<br>" +
1381            "and at more than one nesting depth, depending on the filter used.</li>" +
1382            "<li>Typing in a tag name in the TagName filter is not recommended,<br>" +
1383            "since extraneous characters can be added. Use an item from the list instead.</li></ul>" +
1384            "</html>";
1385        String JavaDoc close = "Close";
1386        JOptionPane.showOptionDialog (
1387        // not .showMessageDialog(
1388
mMainPanel,
1389            instructions,
1390            "FilterBuilder Hints",
1391            // remove this:
1392
JOptionPane.DEFAULT_OPTION,
1393            JOptionPane.INFORMATION_MESSAGE,
1394            // and remove rest of these:
1395
null,
1396            new String JavaDoc[] { close },
1397            close);
1398    }
1399
1400    /**
1401     * The action to take when "About" menu or button pressed.
1402     */

1403    protected void aboutAction ()
1404    {
1405        String JavaDoc close = "Close";
1406        JOptionPane.showOptionDialog (
1407        // not .showMessageDialog(
1408
mMainPanel,
1409            "<html><center><font color=black>The HTML Parser <font color=blue><b>FilterBuilder</b></font><br><i>by Derrick Oswald</i>&nbsp;&nbsp;<b>DerrickOswald@users.sourceforge.net</b><br>http://htmlparser.org<br><br><font size=-2>Copyright &copy; 2005</font></center></html>",
1410            "About FilterBuilder",
1411            // remove this:
1412
JOptionPane.DEFAULT_OPTION,
1413            JOptionPane.INFORMATION_MESSAGE,
1414            // and remove rest of these:
1415
null,
1416            new String JavaDoc[] { close },
1417            close);
1418    }
1419
1420    /**
1421     * The action to take when "Expand" menu chosen.
1422     */

1423    public void expandAction ()
1424    {
1425        setExpanded (getSelection (), true, false);
1426    }
1427
1428    /**
1429     * The action to take when "Collapse" menu chosen.
1430     */

1431    public void collapseAction ()
1432    {
1433        setExpanded (getSelection (), false, false);
1434    }
1435
1436    /**
1437     * The action to take when "Expand All" menu chosen.
1438     */

1439    public void expandAllAction ()
1440    {
1441        setExpanded (getSelection (), true, true);
1442    }
1443
1444    /**
1445     * The action to take when "Collapse" menu chosen.
1446     */

1447    public void collapseAllAction ()
1448    {
1449        setExpanded (getSelection (), false, true);
1450    }
1451
1452    /**
1453     * Set up mouse listeners.
1454     * Sets <code>this</code> up to listen to each command
1455     * in the list as a MouseListener.
1456     * Recursively descends the tree adding to all contained elements also.
1457     * @param filters The container with commands in it.
1458     */

1459    public void setupMouseListeners (Filter[] filters)
1460    {
1461        SubFilterList list;
1462
1463        for (int i = 0; i < filters.length; i++)
1464        {
1465            // set us up as a mouse listener on it
1466
((Component JavaDoc)filters[i]).addMouseListener (this);
1467            ((Component JavaDoc)filters[i]).addMouseMotionListener (this);
1468            list = getEnclosed (filters[i]);
1469            if (null != list)
1470                setupMouseListeners (list.getFilters ());
1471        }
1472    }
1473
1474    /**
1475     * Set up drop targets.
1476     * Recursively descends the filter tree and sets up
1477     * the filter lists as drop targets.
1478     * @param filters The container with filters in it.
1479     */

1480    public void setupDropTargets (Filter[] filters)
1481    {
1482        SubFilterList list;
1483        Component JavaDoc[] components;
1484
1485        for (int i = 0; i < filters.length; i++)
1486        {
1487            list = getEnclosed (filters[i]);
1488            if (null != list)
1489            {
1490                components = list.getDropTargets ();
1491                for (int j = 0; j < components.length; j++)
1492                    new DropTarget JavaDoc (components[j], this);
1493                setupDropTargets (list.getFilters ());
1494            }
1495        }
1496    }
1497
1498    /**
1499     * Expand or collapse filters, possibly recursively.
1500     * @param filters The list of filters to expand or collapse.
1501     * @param expanded If <code>true</code> the filters are expanded,
1502     * otherwise they are collapsed.
1503     * @param recursive If <code>true</code> the filters are processed
1504     * recursively.
1505     */

1506    public void setExpanded (
1507        Filter[] filters,
1508        boolean expanded,
1509        boolean recursive)
1510    {
1511        SubFilterList list;
1512
1513        for (int i = 0; i < filters.length; i++)
1514        {
1515            if (recursive && (null != (list = getEnclosed (filters[i]))))
1516                setExpanded (list.getFilters (), expanded, recursive);
1517            filters[i].setExpanded (expanded);
1518        }
1519    }
1520
1521    /**
1522     * Retrieve the top level filters in the main window.
1523     * @return The top level filters.
1524     */

1525    public Filter[] getFilters ()
1526    {
1527        Component JavaDoc[] components;
1528        Filter[] ret;
1529
1530        components = mMainPanel.getComponents ();
1531        ret = new Filter[components.length];
1532        System.arraycopy (components, 0, ret, 0, components.length);
1533        
1534        return (ret);
1535    }
1536
1537    /**
1538     * Redo the layout.
1539     */

1540    public void relayout ()
1541    {
1542        mMainPanel.invalidate ();
1543        mMainScroller.invalidate ();
1544        mMainScroller.validate ();
1545        mMainScroller.repaint ();
1546    }
1547
1548    /**
1549     * Read a workspace from file.
1550     * The current contents are erased.
1551     * @param name The name of the file to open.
1552     */

1553    public void open (String JavaDoc name)
1554    {
1555        LineNumberReader JavaDoc reader;
1556        String JavaDoc line;
1557        Filter[] filters;
1558        Point JavaDoc point;
1559        Dimension JavaDoc dimension;
1560
1561        try
1562        {
1563            reader = new LineNumberReader JavaDoc (new FileReader JavaDoc (name));
1564            while (null != (line = reader.readLine ()))
1565                if (line.startsWith ("// ["))
1566                {
1567                    line = line.substring (3);
1568                    try
1569                    {
1570                        filters = Filter.reconstitute (line, new Parser (mURLField.getText ()));
1571                        mMainPanel.removeAll ();
1572                        point = new Point JavaDoc ();
1573                        for (int i = 0; i < filters.length; i++)
1574                        {
1575                            dimension = filters[i].getPreferredSize ();
1576                            mMainPanel.add (filters[i]);
1577                            filters[i].setLocation (point);
1578                            point.y += dimension.height;
1579                        }
1580                        setupMouseListeners (filters);
1581                        setupDropTargets (filters);
1582                        relayout ();
1583                    }
1584                    catch (ParserException pe)
1585                    {
1586                        pe.printStackTrace ();
1587                    }
1588                    break;
1589                }
1590            reader.close ();
1591        }
1592        catch (IOException JavaDoc ioe)
1593        {
1594            ioe.printStackTrace ();
1595        }
1596    }
1597
1598    /**
1599     * Exit back to the operating system.
1600     */

1601    void exitApplication ()
1602    {
1603        this.setVisible (false); // hide the Frame
1604
this.dispose (); // free the system resources
1605
System.exit (0); // close the application
1606
}
1607
1608    /**
1609     * Show a pop up context menu.
1610     * Shows a context sensitive popup menu at the location of the
1611     * mouse event.
1612     * @param event The mouse event that initiates the popup.
1613     */

1614    public void showContextMenu (MouseEvent JavaDoc event)
1615    {
1616        JPopupMenu JavaDoc menu;
1617        JMenuItem JavaDoc item;
1618
1619        menu = new JPopupMenu JavaDoc ();
1620        menu.setName ("Popup");
1621
1622        item = new JMenuItem JavaDoc ("Expand");
1623        item.setActionCommand ("expandAction");
1624        item.addActionListener (this);
1625        menu.add (item);
1626
1627        item = new JMenuItem JavaDoc ("Collapse");
1628        item.setActionCommand ("collapseAction");
1629        item.addActionListener (this);
1630        menu.add (item);
1631
1632        menu.addSeparator ();
1633
1634        item = new JMenuItem JavaDoc ("Expand All");
1635        item.setActionCommand ("expandAllAction");
1636        item.addActionListener (this);
1637        menu.add (item);
1638
1639        item = new JMenuItem JavaDoc ("CollapseAll");
1640        item.setActionCommand ("collapseAllAction");
1641        item.addActionListener (this);
1642        menu.add (item);
1643
1644        menu.addSeparator ();
1645
1646        item = new JMenuItem JavaDoc ("Cut");
1647        item.setActionCommand ("cutAction");
1648        item.addActionListener (this);
1649        menu.add (item);
1650
1651        item = new JMenuItem JavaDoc ("Copy");
1652        item.setActionCommand ("copyAction");
1653        item.addActionListener (this);
1654        menu.add (item);
1655
1656        item = new JMenuItem JavaDoc ("Paste");
1657        item.setActionCommand ("pasteAction");
1658        item.addActionListener (this);
1659        menu.add (item);
1660
1661        item = new JMenuItem JavaDoc ("Delete");
1662        item.setActionCommand ("deleteAction");
1663        item.addActionListener (this);
1664        menu.add (item);
1665
1666        menu.addSeparator ();
1667
1668        item = new JMenuItem JavaDoc ("Execute Filter");
1669        item.setActionCommand ("executeAction");
1670        item.addActionListener (this);
1671        menu.add (item);
1672
1673        menu.show (event.getComponent (), event.getX (), event.getY ());
1674    }
1675
1676    //
1677
// selection manipulation
1678
//
1679

1680    protected void addSelection (Filter filter)
1681    {
1682        if (!selectionContains (filter))
1683            mSelection.addElement (filter);
1684        filter.setSelected (true);
1685        mMoved = false;
1686    }
1687
1688    protected void removeSelection (Filter filter)
1689    {
1690        mSelection.removeElement (filter); // no harm if not contained
1691
filter.setSelected (false);
1692    }
1693
1694    protected void selectSelection (boolean select)
1695    {
1696        int count;
1697        Filter filter;
1698        
1699        count = mSelection.size ();
1700        for (int i = 0; i < count; i++)
1701        {
1702            filter = (Filter)mSelection.elementAt (i);
1703            filter.setSelected (select);
1704        }
1705    }
1706
1707    protected void clearSelection ()
1708    {
1709        selectSelection (false);
1710        mSelection.removeAllElements ();
1711    }
1712
1713    protected void moveSelection (Point JavaDoc translation)
1714    {
1715        int count;
1716        Filter filter;
1717        Point JavaDoc point;
1718        
1719        count = mSelection.size ();
1720        for (int i = 0; i < count; i++)
1721        {
1722            filter = (Filter)mSelection.elementAt (i);
1723            point = filter.getLocation ();
1724            point.translate (translation.x, translation.y);
1725            synchronized (filter.getTreeLock ())
1726            {
1727                filter.setLocation (point.x, point.y);
1728            }
1729        }
1730        mMoved = true;
1731    }
1732
1733    protected boolean selectionContains (Filter filter)
1734    {
1735        return (mSelection.contains (filter));
1736    }
1737
1738    protected Filter lastSelected ()
1739    {
1740        Filter ret;
1741        
1742        ret = null;
1743
1744        if (0 < mSelection.size ())
1745            ret = (Filter)mSelection.lastElement ();
1746            
1747        return (ret);
1748    }
1749
1750    protected Filter[] getSelection ()
1751    {
1752        Filter[] ret;
1753
1754        ret = new Filter[mSelection.size ()];
1755        mSelection.copyInto (ret);
1756
1757        return (ret);
1758    }
1759
1760    public String JavaDoc serializeSelection ()
1761    {
1762        Filter[] filters;
1763        StringWriter JavaDoc writer;
1764        PrintWriter JavaDoc out;
1765
1766        filters = getSelection ();
1767        // serialize the selection
1768
writer = new StringWriter JavaDoc (200);
1769        out = new PrintWriter JavaDoc (writer, false);
1770        try
1771        {
1772            out.println (Filter.deconstitute (filters));
1773        }
1774        catch (IOException JavaDoc ioe)
1775        {
1776            ioe.printStackTrace ();
1777        }
1778        finally
1779        {
1780            out.close ();
1781        }
1782        
1783        return (writer.getBuffer ().toString ());
1784    }
1785
1786    public void deleteSelection ()
1787    {
1788        Filter[] filters;
1789        SubFilterList list;
1790
1791        filters = getSelection ();
1792        for (int i = 0; i < filters.length; i++)
1793        {
1794            list = getEnclosing (filters[i]);
1795            if (null != list)
1796                list.removeFilter (filters[i]);
1797            else
1798                mMainPanel.remove (filters[i]);
1799        }
1800        mSelection.clear ();
1801    }
1802    
1803    public boolean isSingleSelection ()
1804    {
1805        return (1 == mSelection.size());
1806    }
1807
1808    //
1809
// MouseListener interface
1810
//
1811

1812    /**
1813     * Invoked when the mouse has been clicked on a component.
1814     * @param event The mouse clicked event.
1815     */

1816    public void mouseClicked (MouseEvent JavaDoc event)
1817    {
1818        Object JavaDoc component;
1819        Filter filter;
1820        SubFilterList list;
1821        int modifiers;
1822        boolean contained;
1823        Filter[] filters;
1824        
1825        component = event.getSource ();
1826        if (component instanceof Filter)
1827        {
1828            filter = (Filter)component;
1829            modifiers = event.getModifiers ();
1830            contained = selectionContains (filter);
1831            
1832            if (0 != (modifiers & InputEvent.SHIFT_MASK))
1833            {
1834                // add everything from last selected to this command
1835
list = getEnclosed (filter);
1836                if (null != list)
1837                    filters = list.getFilters ();
1838                else
1839                    filters = getFilters ();
1840                Filter last = lastSelected ();
1841                if (null == last)
1842                    addSelection (filter);
1843                else
1844                {
1845                    int current = -1;
1846                    int recent = -1;
1847                    for (int i = 0; i < filters.length; i++)
1848                    {
1849                        if (filters[i] == filter)
1850                            current = i;
1851                        if (filters[i] == last)
1852                            recent = i;
1853                    }
1854                    if ((current != -1) && (recent != -1))
1855                        for (int i = Math.min (current, recent);
1856                            i <= Math.max (current, recent); i++)
1857                        addSelection (filters[i]);
1858                }
1859            }
1860            else if (0 != (modifiers & InputEvent.CTRL_MASK))
1861            {
1862                // add just the new command
1863
if (contained)
1864                    removeSelection (filter);
1865                else
1866                    addSelection (filter);
1867            }
1868            else if (0 != (modifiers & InputEvent.BUTTON3_MASK))
1869            {
1870                if (!selectionContains (filter))
1871                {
1872                    clearSelection ();
1873                    addSelection (filter);
1874                }
1875                showContextMenu (event);
1876            }
1877            else
1878            {
1879                clearSelection ();
1880                addSelection (filter);
1881            }
1882        }
1883        else
1884            clearSelection ();
1885    }
1886
1887    /**
1888     * Invoked when a mouse button has been released on a component.
1889     * @param event The mouse released event.
1890     */

1891    public void mouseReleased (MouseEvent JavaDoc event)
1892    {
1893    }
1894
1895    /**
1896     * Invoked when the mouse enters a component.
1897     * @param event The mouse entered event.
1898     */

1899    public void mouseEntered (MouseEvent JavaDoc event)
1900    {
1901    }
1902
1903    /**
1904     * Invoked when the mouse exits a component.
1905     * @param event The mouse exited event.
1906     */

1907    public void mouseExited (MouseEvent JavaDoc event)
1908    {
1909    }
1910
1911    /**
1912     * Invoked when a mouse button has been pressed on a component.
1913     * @param event The mouse pressed event.
1914     */

1915    public void mousePressed (MouseEvent JavaDoc event)
1916    {
1917        Object JavaDoc component;
1918        Point JavaDoc newpoint;
1919        Point JavaDoc upperleft;
1920        
1921        component = event.getSource ();
1922        if (component instanceof Filter)
1923        {
1924            // translate the point relative to the enclosing container
1925
newpoint = event.getPoint ();
1926            upperleft = ((Component JavaDoc)component).getLocation ();
1927            newpoint.translate (upperleft.x, upperleft.y);
1928            setBasePoint (newpoint);
1929        }
1930        else
1931            setBasePoint (null);
1932    }
1933
1934    //
1935
// MouseMotionListener interface
1936
//
1937

1938    /**
1939     * Mouse drag notification.
1940     * Invoked when a mouse button is pressed on a component and
1941     * then dragged. Mouse drag events will continue to be
1942     * delivered to the component where the first originated
1943     * until the mouse button is released (regardless of whether
1944     * the mouse position is within the bounds of the component).
1945     * @param event The mouse drag event.
1946     */

1947    public synchronized void mouseDragged (MouseEvent JavaDoc event)
1948    {
1949        Object JavaDoc component;
1950        Filter filter;
1951        Point JavaDoc base;
1952        Point JavaDoc newpoint;
1953        Point JavaDoc upperleft;
1954        Point JavaDoc translation;
1955        
1956        component = event.getSource ();
1957        if (component instanceof Filter)
1958        {
1959            filter = (Filter)component;
1960            if (selectionContains (filter)) // drag on a selected item
1961
{
1962                if (null == getEnclosing (filter)) // not contained
1963
try
1964                    {
1965                        base = getBasePoint ();
1966                        if (null != base)
1967                        {
1968                            newpoint = event.getPoint ();
1969                            // translate the point relative to the enclosing container
1970
upperleft = filter.getLocation ();
1971                            newpoint.translate (upperleft.x, upperleft.y);
1972                            // get the difference between this point and the old base
1973
translation = new Point JavaDoc (
1974                                newpoint.x - base.x,
1975                                newpoint.y - base.y);
1976                            // update the base point
1977
setBasePoint (newpoint);
1978                            // apply this difference to the selection
1979
moveSelection (translation);
1980                        }
1981                    }
1982                    catch (Exception JavaDoc e)
1983                    {
1984                    }
1985            }
1986            else
1987                mouseClicked (event); // a small slip shouldn't stop a click
1988
}
1989    }
1990
1991    /**
1992     * Mouse move notification.
1993     * Invoked when the mouse button has been moved on a component
1994     * (with no buttons no down).
1995     * @param event The mouse moved event.
1996     */

1997    public void mouseMoved (MouseEvent JavaDoc event)
1998    {
1999    }
2000
2001    //
2002
// WindowListener interface
2003
//
2004

2005    /**
2006     * Invoked the first time a window is made visible.
2007     * <i>Not used.</i>
2008     * @param event The window event.
2009     */

2010    public void windowOpened (WindowEvent JavaDoc event) {}
2011
2012    /**
2013     * Handles window closing event.
2014     * Performs function <code>exitApplication()</code>.
2015     * @param event The window event.
2016     */

2017    public void windowClosing (WindowEvent JavaDoc event)
2018    {
2019        if (event.getSource () == this)
2020            exitApplication ();
2021    }
2022
2023    /**
2024     * Invoked when a window has been closed as the result
2025     * of calling dispose on the window.
2026     * <i>Not used.</i>
2027     * @param event The window event.
2028     */

2029    public void windowClosed (WindowEvent JavaDoc event) {}
2030
2031    /**
2032     * Invoked when a window is changed from a normal to a
2033     * minimized state. For many platforms, a minimized window
2034     * is displayed as the icon specified in the window's
2035     * iconImage property.
2036     * <i>Not used.</i>
2037     * @param event The window event.
2038     */

2039    public void windowIconified (WindowEvent JavaDoc event) {}
2040
2041    /**
2042     * Invoked when a window is changed from a minimized
2043     * to a normal state.
2044     * <i>Not used.</i>
2045     * @param event The window event.
2046     */

2047    public void windowDeiconified (WindowEvent JavaDoc event) {}
2048
2049    /**
2050     * Invoked when the window is set to be the user's
2051     * active window, which means the window (or one of its
2052     * subcomponents) will receive keyboard events.
2053     * <i>Not used.</i>
2054     * @param event The window event.
2055     */

2056    public void windowActivated (WindowEvent JavaDoc event) {}
2057
2058    /**
2059     * Invoked when a window is no longer the user's active
2060     * window, which means that keyboard events will no longer
2061     * be delivered to the window or its subcomponents.
2062     * <i>Not used.</i>
2063     * @param event The window event.
2064     */

2065    public void windowDeactivated (WindowEvent JavaDoc event) {}
2066
2067    //
2068
// ActionListener interface
2069
//
2070

2071    /**
2072     * Handles menu and toolbar item choices.
2073     * @param event The action even that triggers this function.
2074     */

2075    public void actionPerformed (ActionEvent JavaDoc event)
2076    {
2077        Object JavaDoc object;
2078        String JavaDoc action;
2079        
2080        object = event.getSource();
2081// if (object instanceof JButton)
2082
// {
2083
// String url;
2084
// url = mURLField.getText ();
2085
// mURLField.selectAll ();
2086
// //setURL (url);
2087
// }
2088
if (object instanceof JButton JavaDoc)
2089            action = ((JButton JavaDoc)object).getActionCommand ();
2090        else if (object instanceof JMenuItem JavaDoc)
2091            action = ((JMenuItem JavaDoc)object).getActionCommand ();
2092        else
2093            action = null;
2094
2095        if (object instanceof Component JavaDoc)
2096            mCurrentComponent = (Component JavaDoc)object;
2097
2098        if (null != action)
2099            try
2100            {
2101                Method JavaDoc method = this.getClass ().getDeclaredMethod (action, new Class JavaDoc[0]);
2102                method.invoke (this, new Object JavaDoc[0]);
2103            }
2104            catch (NoSuchMethodException JavaDoc nsme)
2105            {
2106                System.out.println ("no " + action + " method found");
2107            }
2108            catch (Exception JavaDoc e)
2109            {
2110                e.printStackTrace ();
2111            }
2112    }
2113
2114    //
2115
// ClipboardOwner interface
2116
//
2117

2118    /**
2119     * Notifies this object that it is no longer the owner
2120     * of the contents of the clipboard.
2121     * @param clipboard The clipboard that is no longer owned.
2122     * @param contents The contents which this owner had placed on the clipboard.
2123     */

2124    public void lostOwnership (Clipboard JavaDoc clipboard, Transferable JavaDoc contents)
2125    {
2126        System.out.println ("lost clipboard ownership");
2127    }
2128
2129    //
2130
// DragGestureListener interface
2131
//
2132

2133    /**
2134     * A DragGestureRecognizer has detected a platform-dependent drag initiating gesture.
2135     * It is notifying this listener in order for it to initiate the action for the user.
2136     * @param event The DragGestureEvent describing the gesture that has just occurred.
2137     */

2138    public void dragGestureRecognized (DragGestureEvent JavaDoc event)
2139    {
2140        Component JavaDoc component;
2141        String JavaDoc cls;
2142        Filter filter;
2143        StringSelection JavaDoc text;
2144        
2145        
2146        component = event.getComponent ();
2147        try
2148        {
2149            cls = component.getName (); // (String)Filter.mWrappers.get (component.getName ());
2150
if (null != cls)
2151            {
2152                filter = Filter.instantiate (cls);
2153                text = new StringSelection JavaDoc (Filter.deconstitute (new Filter[] { filter }));
2154                mDragSource.startDrag (event, DragSource.DefaultMoveDrop, text, this);
2155            }
2156        }
2157        catch (Exception JavaDoc e)
2158        {
2159            e.printStackTrace ();
2160        }
2161    }
2162
2163    //
2164
// DragSourceListener interface
2165
//
2166

2167    /**
2168     * This message goes to DragSourceListener,
2169     * informing it that the dragging has ended
2170     *
2171     */

2172    public void dragDropEnd (DragSourceDropEvent JavaDoc event)
2173    {
2174        if (event.getDropSuccess ())
2175        {
2176            // System.out.println ("added new class");
2177
}
2178    }
2179
2180    /**
2181     * This message goes to DragSourceListener,
2182     * informing it that the dragging has entered the DropSite
2183     *
2184     */

2185    public void dragEnter (DragSourceDragEvent JavaDoc event)
2186    {
2187        // System.out.println ("dragEnter");
2188
}
2189
2190    /**
2191     * this message goes to DragSourceListener, informing it that the dragging
2192     * has exited the DropSite
2193     *
2194     */

2195    public void dragExit (DragSourceEvent JavaDoc event)
2196    {
2197        // System.out.println( "dragExit");
2198
}
2199
2200    /**
2201     * this message goes to DragSourceListener, informing it that the dragging is currently
2202     * ocurring over the DropSite
2203     *
2204     */

2205    public void dragOver (DragSourceDragEvent JavaDoc event)
2206    {
2207        // System.out.println( "dragExit");
2208
}
2209
2210    /**
2211     * is invoked when the user changes the dropAction
2212     *
2213     */

2214    public void dropActionChanged (DragSourceDragEvent JavaDoc event)
2215    {
2216        // System.out.println( "dropActionChanged");
2217
}
2218
2219    //
2220
// DropTargetListener interface
2221
//
2222

2223    /**
2224     * is invoked when you are dragging over the DropSite
2225     *
2226     */

2227    public void dragEnter (DropTargetDragEvent JavaDoc event)
2228    {
2229        // debug messages for diagnostics
2230
// event.acceptDrag (DnDConstants.ACTION_MOVE);
2231
// System.out.println ("dragEnter");
2232
DropTargetContext JavaDoc context;
2233        Component JavaDoc component;
2234        SubFilterList list;
2235
2236        // find the enclosing filter
2237
context = event.getDropTargetContext ();
2238        component = context.getComponent ();
2239        while ( (null != component)
2240                && !(component instanceof SubFilterList)
2241                && !(component == mMainPanel))
2242            component = component.getParent ();
2243        if (component instanceof SubFilterList)
2244            list = (SubFilterList)component;
2245        else
2246            list = null;
2247        // so either list is the enclosing list,
2248
// or list is null and the target component is the main panel
2249

2250        if (null != list)
2251            if (!list.canAccept ())
2252                event.rejectDrag ();
2253            else
2254                list.setSelected (true);
2255    }
2256
2257    /**
2258     * is invoked when you are exit the DropSite without dropping
2259     *
2260     */

2261    public void dragExit (DropTargetEvent JavaDoc event)
2262    {
2263        // debug messages for diagnostics
2264
// event.acceptDrag (DnDConstants.ACTION_MOVE);
2265
// System.out.println ("dragEnter");
2266
DropTargetContext JavaDoc context;
2267        Component JavaDoc component;
2268        SubFilterList list;
2269
2270        // find the enclosing filter
2271
context = event.getDropTargetContext ();
2272        component = context.getComponent ();
2273        while ( (null != component)
2274                && !(component instanceof SubFilterList)
2275                && !(component == mMainPanel))
2276            component = component.getParent ();
2277        if (component instanceof SubFilterList)
2278            list = (SubFilterList)component;
2279        else
2280            list = null;
2281        // so either list is the enclosing list,
2282
// or list is null and the target component is the main panel
2283

2284        if (null != list)
2285            list.setSelected (false);
2286    }
2287
2288    /**
2289     * is invoked when a drag operation is going on
2290     *
2291     */

2292    public void dragOver (DropTargetDragEvent JavaDoc event)
2293    {
2294        // System.out.println( "dragOver");
2295
}
2296
2297    /**
2298     * a drop has occurred
2299     * @param event The drop event.
2300     */

2301    public void drop (DropTargetDropEvent JavaDoc event)
2302    {
2303        DropTargetContext JavaDoc context;
2304        Component JavaDoc component;
2305        SubFilterList list;
2306        String JavaDoc s;
2307        Point JavaDoc point;
2308        Filter[] filters;
2309        boolean accept;
2310
2311        // find the enclosing filter
2312
context = event.getDropTargetContext ();
2313        component = context.getComponent ();
2314        while ( (null != component)
2315                && !(component instanceof SubFilterList)
2316                && !(component == mMainPanel))
2317            component = component.getParent ();
2318        if (component instanceof SubFilterList)
2319            list = (SubFilterList)component;
2320        else
2321            list = null;
2322        // so either list is the enclosing list,
2323
// or list is null and the target component is the main panel
2324

2325        try
2326        {
2327            accept = false;
2328            Transferable JavaDoc transferable = event.getTransferable();
2329                                   
2330            // we accept only Strings
2331
if (transferable.isDataFlavorSupported (DataFlavor.stringFlavor))
2332            {
2333                accept = true;
2334                event.acceptDrop (DnDConstants.ACTION_MOVE);
2335                s = (String JavaDoc)transferable.getTransferData (DataFlavor.stringFlavor);
2336                point = event.getLocation ();
2337                try
2338                {
2339                    // get the filter and add into the target
2340
filters = Filter.reconstitute (s, new Parser (mURLField.getText ()));
2341                    if (0 < filters.length)
2342                        insertFilters (filters, point, list);
2343                    if (null != list)
2344                        list.setSelected (false);
2345                }
2346                catch (Exception JavaDoc e)
2347                {
2348                    e.printStackTrace ();
2349                }
2350                // signal the drop was successful
2351
context.dropComplete (accept);
2352            }
2353            else
2354                event.rejectDrop();
2355        }
2356        catch (IOException JavaDoc exception)
2357        {
2358            exception.printStackTrace();
2359            System.err.println( "Exception" + exception.getMessage());
2360            event.rejectDrop();
2361        }
2362        catch (UnsupportedFlavorException JavaDoc ufException)
2363        {
2364            ufException.printStackTrace();
2365            System.err.println( "Exception" + ufException.getMessage());
2366            event.rejectDrop();
2367        }
2368    }
2369
2370    /**
2371     * is invoked if the use modifies the current drop gesture
2372     *
2373     */

2374    public void dropActionChanged ( DropTargetDragEvent JavaDoc event )
2375    {
2376        System.out.println( "dropActionChanged");
2377    }
2378
2379    /**
2380     * The entry point for this application.
2381     * Creates a new FilterBuilder and makes it visible.
2382     */

2383    public static void main (String JavaDoc args[])
2384    {
2385        try
2386        {
2387            // set the Look and Feel to the the native system
2388
// try
2389
// {
2390
// javax.swing.UIManager.setLookAndFeel (javax.swing.UIManager.getSystemLookAndFeelClassName ());
2391
// }
2392
// catch (Exception e)
2393
// {
2394
// }
2395

2396            // create a new instance of our application's frame, and make it visible
2397
FilterBuilder builder = new FilterBuilder ();
2398            builder.setVisible (true);
2399        }
2400        catch (Throwable JavaDoc t)
2401        {
2402            t.printStackTrace ();
2403            // ensure the application exits with an error condition
2404
System.exit (1);
2405        }
2406    }
2407
2408}
2409
Popular Tags