KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > htmlparser > lexerapplications > thumbelina > ThumbelinaFrame


1 // HTMLParser Library $Name: v1_5_20050313 $ - A java-based parser for HTML
2
// http://sourceforge.org/projects/htmlparser
3
// Copyright (C) 2003 Derrick Oswald
4
//
5
// Revision Control Information
6
//
7
// $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/lexerapplications/thumbelina/ThumbelinaFrame.java,v $
8
// $Author: derrickoswald $
9
// $Date: 2004/09/02 02:28:14 $
10
// $Revision: 1.4 $
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.lexerapplications.thumbelina;
28
29 import java.awt.BorderLayout JavaDoc;
30 import java.awt.Component JavaDoc;
31 import java.awt.Dimension JavaDoc;
32 import java.awt.Rectangle JavaDoc;
33 import java.awt.Toolkit JavaDoc;
34 import java.awt.event.ActionEvent JavaDoc;
35 import java.awt.event.ActionListener JavaDoc;
36 import java.awt.event.ItemEvent JavaDoc;
37 import java.awt.event.ItemListener JavaDoc;
38 import java.awt.event.WindowEvent JavaDoc;
39 import java.awt.event.WindowListener JavaDoc;
40 import java.beans.PropertyChangeEvent JavaDoc;
41 import java.beans.PropertyChangeListener JavaDoc;
42 import java.net.HttpURLConnection JavaDoc;
43 import java.net.MalformedURLException JavaDoc;
44 import java.net.URL JavaDoc;
45 import java.util.ArrayList JavaDoc;
46 import java.util.prefs.BackingStoreException JavaDoc;
47 import java.util.prefs.Preferences JavaDoc;
48 import javax.swing.ImageIcon JavaDoc;
49 import javax.swing.JCheckBoxMenuItem JavaDoc;
50
51 import javax.swing.JFrame JavaDoc;
52 import javax.swing.JMenu JavaDoc;
53 import javax.swing.JMenuBar JavaDoc;
54 import javax.swing.JMenuItem JavaDoc;
55 import javax.swing.JOptionPane JavaDoc;
56 import javax.swing.JSeparator JavaDoc;
57 import org.htmlparser.lexer.Lexer;
58
59 /**
60  * Encapsulate a Thumbelina bean and add menu and preferences support.
61  * Provides a JFrame base in which to place a Thumbelina bean, and
62  * adds a menu system with MRU (Most Recently Used) list.
63  * Also provides a Google search capability.
64  * Will eventually provide Javahelp too.
65  */

66 public class ThumbelinaFrame
67     extends
68         JFrame JavaDoc
69     implements
70         WindowListener JavaDoc,
71         ActionListener JavaDoc,
72         ItemListener JavaDoc,
73         PropertyChangeListener JavaDoc
74 {
75     /**
76      * Window title.
77      */

78     private static final String JavaDoc TITLE = "Thumbelina";
79
80     /**
81      * Preference name for frame location and size.
82      */

83     private static final String JavaDoc FRAMESIZE = "FrameSize";
84
85     /**
86      * Percent of screen to leave as border when no preferences available.
87      */

88     private static final int BORDERPERCENT = 5;
89
90     /**
91      * Preference name for most recently used count.
92      */

93     private static final String JavaDoc MRULENGTH = "MRULength";
94
95     /**
96      * Preference name for most recently used maximum count.
97      */

98     private static final String JavaDoc MRUMAX = "MRUMax";
99
100     /**
101      * Preference prefix for most recently used list items.
102      */

103     private static final String JavaDoc MRUPREFIX = "MRUListItem";
104
105     /**
106      * Preference name for google query.
107      */

108     private static final String JavaDoc GOOGLEQUERY = "GoogleQuery";
109
110     /**
111      * Default google query when no preferences are available.
112      */

113     private static final String JavaDoc DEFAULTGOOGLEQUERY = "thumbs";
114
115     /**
116      * List of URLs to prime the MRU list with.
117      */

118     private static final String JavaDoc[] DEFAULTMRULIST =
119     {
120         "www.a2zcds.com",
121         "www.stoneschool.com/Japan/",
122         "www.tommys-bookmarks.com",
123         "www.unitedmedia.com/comics/dilbert/archive",
124         "www.pastelartists.com",
125     };
126
127     /**
128      * Send Mozilla headers in request if <code>true</code>.
129      */

130     private static final boolean USE_MOZILLA_HEADERS = false;
131
132     /**
133      * Preference name for status bar visibility state.
134      */

135     private static final String JavaDoc STATUSBARSTATE = "StatusBarVisible";
136
137     /**
138      * Preference name for history list visibility state.
139      */

140     private static final String JavaDoc HISTORYLISTSTATE = "HistoryListVisible";
141
142     /**
143      * Preference name for sequencer active state.
144      */

145     private static final String JavaDoc SEQUENCERACTIVE = "SequencerActive";
146
147     /**
148      * Preference name for background thread active state.
149      */

150     private static final String JavaDoc BACKGROUNDTHREADACTIVE =
151         "BackgroundThreadActive";
152
153     /**
154      * Preference name for sequencer display speed.
155      */

156     private static final String JavaDoc DISPLAYSPEED = "DisplaySpeed";
157
158     /**
159      * Main menu.
160      */

161     protected JMenuBar JavaDoc mMenu;
162
163     /**
164      * URL submenu.
165      */

166     protected JMenu JavaDoc mURL;
167
168     /**
169      * Open menu item.
170      */

171     protected JMenuItem JavaDoc mOpen;
172
173     /**
174      * Google menu item.
175      */

176     protected JMenuItem JavaDoc mGoogle;
177
178     /**
179      * MRU list separator #1.
180      */

181     protected JSeparator JavaDoc mSeparator1;
182
183     /**
184      * MRU list separator #2.
185      */

186     protected JSeparator JavaDoc mSeparator2;
187
188     /**
189      * Exit menu item.
190      */

191     protected JMenuItem JavaDoc mExit;
192
193     /**
194      * View submenu.
195      */

196     protected JMenu JavaDoc mView;
197
198     /**
199      * Status bar visible menu item.
200      */

201     protected JCheckBoxMenuItem JavaDoc mStatusVisible;
202
203     /**
204      * History list visible menu item.
205      */

206     protected JCheckBoxMenuItem JavaDoc mHistoryVisible;
207
208     /**
209      * Vommand menu.
210      */

211     protected JMenu JavaDoc mCommand;
212
213     /**
214      * Reset menu item.
215      */

216     protected JMenuItem JavaDoc mReset;
217
218     /**
219      * Clear menu item
220      */

221     protected JMenuItem JavaDoc mClear;
222
223     /**
224      * Help submenu.
225      */

226     protected JMenu JavaDoc mHelp;
227
228     /**
229      * About menu item.
230      */

231     protected JMenuItem JavaDoc mAbout;
232
233     /**
234      * Construct a new Thumbelina frame with an idle Thumbelina.
235      */

236     public ThumbelinaFrame ()
237     {
238         this (new Thumbelina ());
239     }
240
241     /**
242      * Construct a new Thumbelina frame with a Thumbelina primed with one URL.
243      * @param url The URL to prime the Thumbelina with.
244      * @exception MalformedURLException If the given string doesn't represent
245      * a valid url.
246      */

247     public ThumbelinaFrame (final String JavaDoc url)
248         throws
249             MalformedURLException JavaDoc
250     {
251         this (new Thumbelina (url));
252     }
253
254     /**
255      * Construct a new Thumbelina frame with a Thumbelina primed with one URL.
256      * @param url The URL to prime the Thumbelina with.
257      */

258     public ThumbelinaFrame (final URL JavaDoc url)
259     {
260         this (new Thumbelina (url));
261     }
262
263     /**
264      * Construct a new Thumbelina frame with a given Thumbelina.
265      * @param thumbelina The Thumbelina to encapsulate.
266      */

267     public ThumbelinaFrame (final Thumbelina thumbelina)
268     {
269         setTitle (TITLE);
270         thumbelina.addPropertyChangeListener (this);
271         getContentPane ().add (thumbelina, BorderLayout.CENTER);
272         addWindowListener (this);
273         makeMenu ();
274         setJMenuBar (mMenu);
275         restoreSize ();
276         initState ();
277         updateMenu ();
278     }
279
280     /**
281      * Access the Thumbelina object contained in the frame.
282      * @return The Thumbelina bean.
283      */

284     public Thumbelina getThumbelina ()
285     {
286         return ((Thumbelina)getContentPane ().getComponent (0));
287     }
288
289     /**
290      * Initialize the user preferences.
291      * Reads from the existing user preferences,
292      * or initializes values from the bean directly if they don't exist.
293      * Sets the state of the view checkboxes to match.
294      */

295     public void initState ()
296     {
297         Preferences JavaDoc prefs;
298
299         prefs = Preferences.userNodeForPackage (getClass ());
300         if (-1 == prefs.getInt (MRULENGTH, -1))
301             for (int i = 0; i < DEFAULTMRULIST.length; i++)
302                 updateMRU (DEFAULTMRULIST[i]);
303         getThumbelina ().setStatusBarVisible (
304             prefs.getBoolean (STATUSBARSTATE,
305                 getThumbelina ().getStatusBarVisible ()));
306         mStatusVisible.setSelected (getThumbelina ().getStatusBarVisible ());
307         getThumbelina ().setHistoryListVisible (
308             prefs.getBoolean (HISTORYLISTSTATE,
309                 getThumbelina ().getHistoryListVisible ()));
310         mHistoryVisible.setSelected (getThumbelina ().getHistoryListVisible ());
311         getThumbelina ().setSequencerActive (
312             prefs.getBoolean (SEQUENCERACTIVE,
313                 getThumbelina ().getSequencerActive ()));
314         getThumbelina ().setBackgroundThreadActive (
315             prefs.getBoolean (BACKGROUNDTHREADACTIVE,
316                 getThumbelina ().getBackgroundThreadActive ()));
317         getThumbelina ().setSpeed (
318             prefs.getInt (DISPLAYSPEED, getThumbelina ().getSpeed ()));
319     }
320
321     /**
322      * Saves the current settings in the user preferences.
323      * By default this writes to the thumbelina subdirectory under
324      * .java in the users home directory.
325      */

326     public void saveState ()
327     {
328         Preferences JavaDoc prefs;
329
330         prefs = Preferences.userNodeForPackage (getClass ());
331         // don't save size unless we're in normal state
332
if (NORMAL == getExtendedState ())
333             prefs.put (FRAMESIZE, toString (getBounds ()));
334         prefs.putBoolean (STATUSBARSTATE,
335             getThumbelina ().getStatusBarVisible ());
336         prefs.putBoolean (HISTORYLISTSTATE,
337             getThumbelina ().getHistoryListVisible ());
338         prefs.putBoolean (SEQUENCERACTIVE,
339             getThumbelina ().getSequencerActive ());
340         prefs.putBoolean (BACKGROUNDTHREADACTIVE,
341             getThumbelina ().getBackgroundThreadActive ());
342         prefs.putInt (DISPLAYSPEED,
343             getThumbelina ().getSpeed ());
344         try
345         {
346             prefs.flush ();
347         }
348         catch (BackingStoreException JavaDoc bse)
349         {
350             bse.printStackTrace ();
351         }
352     }
353
354     /**
355      * Sets the frame size if no previous preference has been stored.
356      * It creates a window covering all but <code>BORDERPERCENT</code>
357      * margins.
358      */

359     public void initSize ()
360     {
361         Toolkit JavaDoc tk;
362         Dimension JavaDoc dim;
363         int borderx;
364         int bordery;
365
366         tk = getToolkit ();
367         dim = tk.getScreenSize ();
368         borderx = dim.width * BORDERPERCENT / 100;
369         bordery = dim.height * BORDERPERCENT / 100;
370         setBounds (
371             borderx,
372             bordery,
373             dim.width - (2 * borderx),
374             dim.height - (2 * bordery));
375     }
376
377     /**
378      * Restores the window size based on stored preferences.
379      * If no preferences exist, it calls <code>initSize()</code>.
380      */

381     public void restoreSize ()
382     {
383         Preferences JavaDoc prefs;
384         String JavaDoc size;
385         Rectangle JavaDoc rectangle;
386
387         prefs = Preferences.userNodeForPackage (getClass ());
388         size = prefs.get (FRAMESIZE, "");
389         if ("".equals (size))
390             initSize ();
391         else
392             try
393             {
394                 rectangle = fromString (size);
395                 if (rational (rectangle))
396                     setBounds (
397                         rectangle.x,
398                         rectangle.y,
399                         rectangle.width,
400                         rectangle.height);
401                 else
402                     initSize ();
403             }
404             catch (IllegalArgumentException JavaDoc iae)
405             {
406                 initSize ();
407             }
408     }
409
410     /**
411      * Converts the rectangle to a string.
412      * The rectangle is converted into a string that is of the form
413      * <pre>
414      * [x,y,width,height].
415      * </pre>
416      * @return The string equivalent of the rectangle.
417      * @param r The rectangle containing the window position and size,
418      * as returned by <code>getBounds()</code>.
419      */

420     protected String JavaDoc toString (final Rectangle JavaDoc r)
421     {
422         return ("[" + r.x + "," + r.y + "," + r.width + "," + r.height + "]");
423     }
424
425     /**
426      * Convert the given string to a valid rectangle.
427      * The string is converted to a Rectangle.
428      * @param value The value to parse.
429      * @exception IllegalArgumentException if the format does not match the
430      * form "[x,y,width,height]" with all values integers.
431      * @return Returns the rectangle extracted from the string.
432      */

433     protected Rectangle JavaDoc fromString (final String JavaDoc value)
434         throws
435             IllegalArgumentException JavaDoc
436     {
437         String JavaDoc guts;
438         int current;
439         int[] values;
440         int index;
441         Rectangle JavaDoc ret;
442
443         try
444         {
445             // parse "[x,y,width,height]"
446
if (value.startsWith ("[") && value.endsWith ("]"))
447             {
448                 guts = value.substring (1, value.length () - 1) + ",";
449                 current = 0;
450                 values = new int[4];
451                 for (int i = 0; i < 4; i++)
452                 {
453                     index = guts.indexOf (",", current);
454                     if (-1 == index)
455                         throw new IllegalArgumentException JavaDoc (
456                             "invalid format \"" + value + "\"");
457                     else
458                     {
459                         values[i] = Integer.parseInt (
460                             guts.substring (current, index));
461                         current = index + 1;
462                     }
463                 }
464                 ret = new Rectangle JavaDoc (
465                     values[0], values[1], values[2], values[3]);
466             }
467             else
468                 throw new IllegalArgumentException JavaDoc (
469                     "invalid format \"" + value + "\"");
470         }
471         catch (NumberFormatException JavaDoc nfe)
472         {
473             throw new IllegalArgumentException JavaDoc (nfe.getMessage ());
474         }
475
476         return (ret);
477     }
478
479     /**
480      * Check if the rectangle represents a valid screen position and size.
481      * @param r The rectangle to check.
482      * @return <code>true</code> if this could be a valid frame bounds.
483      */

484     private boolean rational (final Rectangle JavaDoc r)
485     {
486         Toolkit JavaDoc tk;
487         Dimension JavaDoc winsize;
488
489         tk = getToolkit ();
490         winsize = tk.getScreenSize();
491         // all elements must be not stupid w.r.t. the screen size
492
// we assume here that that means no more than 10% off screen
493
// on the left, right and bottom sides
494
return ( (r.x >= r.width / -10)
495                 && (r.y >= 0)
496                 && (r.width > 0)
497                 && (r.height > 0)
498                 && (r.x + r.width <= winsize.width + r.width / 10)
499                 && (r.y + r.height <= winsize.height + r.height / 10));
500     }
501
502     /**
503      * Create the menu.
504      * Initializes the menu and adds it to the frame.
505      */

506     public void makeMenu ()
507     {
508         mMenu = new JMenuBar JavaDoc ();
509         mURL = new JMenu JavaDoc ();
510         mOpen = new JMenuItem JavaDoc ();
511         mGoogle = new JMenuItem JavaDoc ();
512         mSeparator1 = new JSeparator JavaDoc ();
513         mSeparator2 = new JSeparator JavaDoc ();
514         mExit = new JMenuItem JavaDoc ();
515
516         mView = new JMenu JavaDoc ();
517         mStatusVisible = new JCheckBoxMenuItem JavaDoc ();
518         mHistoryVisible = new JCheckBoxMenuItem JavaDoc ();
519
520         mHelp = new JMenu JavaDoc ();
521         mAbout = new JMenuItem JavaDoc ();
522
523         mCommand = new JMenu JavaDoc ();
524         mReset = new JMenuItem JavaDoc ();
525         mClear = new JMenuItem JavaDoc ();
526
527         mURL.setMnemonic ('U');
528         mURL.setText ("URL");
529         mOpen.setMnemonic ('O');
530         mOpen.setText ("Open");
531         mOpen.setToolTipText ("Open a URL.");
532         mURL.add (mOpen);
533
534         mGoogle.setMnemonic ('G');
535         mGoogle.setText ("Google");
536         mGoogle.setToolTipText ("Search Google.");
537         mURL.add (mGoogle);
538
539         mURL.add (mSeparator1);
540         mURL.add (mSeparator2);
541
542         mExit.setMnemonic ('E');
543         mExit.setText ("Exit");
544         mExit.setToolTipText ("Quit Thumbelina.");
545         mURL.add (mExit);
546
547         mMenu.add (mURL);
548
549         mView.setMnemonic ('V');
550         mView.setText ("View");
551         mStatusVisible.setMnemonic ('S');
552         mStatusVisible.setSelected (getThumbelina ().getStatusBarVisible ());
553         mStatusVisible.setText ("Status Bar");
554         mStatusVisible.setToolTipText ("Show/Hide the status bar.");
555         mView.add (mStatusVisible);
556         mHistoryVisible.setMnemonic ('H');
557         mHistoryVisible.setSelected (getThumbelina ().getHistoryListVisible ());
558         mHistoryVisible.setText ("History List");
559         mHistoryVisible.setToolTipText ("Show/Hide the history list.");
560         mView.add (mHistoryVisible);
561         mMenu.add (mView);
562
563         mCommand.setMnemonic ('C');
564         mCommand.setText ("Command");
565         mReset.setMnemonic ('R');
566         mReset.setText ("Reset");
567         mReset.setToolTipText ("Reset Thumbelina.");
568         mClear.setMnemonic ('L');
569         mClear.setText ("Clear");
570         mClear.setToolTipText ("Clear display.");
571         mCommand.add (mReset);
572         mCommand.add (mClear);
573         mCommand.add (mHelp);
574         mMenu.add (mCommand);
575
576         mHelp.setMnemonic ('H');
577         mHelp.setText ("Help");
578         mAbout.setMnemonic ('A');
579         mAbout.setText ("About");
580         mAbout.setToolTipText ("Information about Thumbelina.");
581         mHelp.add (mAbout);
582         mMenu.add (mHelp);
583
584         mOpen.addActionListener (this);
585         mGoogle.addActionListener (this);
586         mExit.addActionListener (this);
587         mStatusVisible.addItemListener (this);
588         mHistoryVisible.addItemListener (this);
589         mReset.addActionListener (this);
590         mClear.addActionListener (this);
591         mAbout.addActionListener (this);
592     }
593
594     /**
595      * Adjusts the menu, by inserting the current MRU list.
596      * Removes the old MRU (Most Recently Used) items and inserts new
597      * ones betweeen the two separators.
598      */

599     public void updateMenu ()
600     {
601         Preferences JavaDoc prefs;
602         int start;
603         int end;
604         Component JavaDoc component;
605         JMenuItem JavaDoc item;
606         int count;
607         String JavaDoc string;
608
609         prefs = Preferences.userNodeForPackage (getClass ());
610         start = -1;
611         end = -1;
612         for (int i = 0; i < mURL.getItemCount (); i++)
613         {
614             component = mURL.getMenuComponent (i);
615             if (component == mSeparator1)
616                 start = i + 1;
617             else if (component == mSeparator2)
618                 end = i;
619         }
620
621         if ((-1 != start) && (-1 != end))
622         {
623             for (int i = start; i < end; i++)
624                 mURL.remove (start);
625
626             count = prefs.getInt (MRULENGTH, 0);
627             for (int i = 0; i < count; i++)
628             {
629                 string = prefs.get (MRUPREFIX + i, "");
630                 if (!"".equals (string))
631                 {
632                     item = new JMenuItem JavaDoc ();
633                     item.setActionCommand (string);
634                     if (string.length () > 40)
635                         string = string.substring (0, 38) + "...";
636                     item.setText (string);
637                     item.addActionListener (this);
638                     mURL.add (item, start++);
639                 }
640             }
641         }
642     }
643
644     //
645
// WindowListener interface
646
//
647

648     /**
649      * Invoked the first time a window is made visible.
650      * <i>Not used.</i>
651      * @param event The window event.
652      */

653     public void windowOpened (final WindowEvent JavaDoc event)
654     {
655     }
656
657     /**
658      * Handles window closing event.
659      * Performs function <code>exitApplication()</code>.
660      * @param event The window event.
661      */

662     public void windowClosing (final WindowEvent JavaDoc event)
663     {
664         exit ();
665     }
666
667     /**
668      * Invoked when a window has been closed as the result
669      * of calling dispose on the window.
670      * <i>Not used.</i>
671      * @param event The window event.
672      */

673     public void windowClosed (final WindowEvent JavaDoc event)
674     {
675     }
676
677     /**
678      * Invoked when a window is changed from a normal to a
679      * minimized state. For many platforms, a minimized window
680      * is displayed as the icon specified in the window's
681      * iconImage property.
682      * <i>Not used.</i>
683      * @param event The window event.
684      */

685     public void windowIconified (final WindowEvent JavaDoc event)
686     {
687     }
688
689     /**
690      * Invoked when a window is changed from a minimized
691      * to a normal state.
692      * <i>Not used.</i>
693      * @param event The window event.
694      */

695     public void windowDeiconified (final WindowEvent JavaDoc event)
696     {
697     }
698
699     /**
700      * Invoked when the window is set to be the user's
701      * active window, which means the window (or one of its
702      * subcomponents) will receive keyboard events.
703      * <i>Not used.</i>
704      * @param event The window event.
705      */

706     public void windowActivated (final WindowEvent JavaDoc event)
707     {
708     }
709
710     /**
711      * Invoked when a window is no longer the user's active
712      * window, which means that keyboard events will no longer
713      * be delivered to the window or its subcomponents.
714      * <i>Not used.</i>
715      * @param event The window event.
716      */

717     public void windowDeactivated (final WindowEvent JavaDoc event)
718     {
719     }
720
721     //
722
// ActionListener interface
723
//
724

725     /**
726      * Handles events from the menu.
727      * Based on the action of the event, executes the necessary subroutine.
728      * @param actionEvent The event describing the user action.
729      */

730     public void actionPerformed (final ActionEvent JavaDoc actionEvent)
731     {
732         String JavaDoc action;
733
734         action = actionEvent.getActionCommand ();
735         if (action.equals ("Open"))
736             open ();
737         else if (action.equals ("Google"))
738             googlesearch ();
739         else if (action.equals ("Reset"))
740             getThumbelina ().reset ();
741         else if (action.equals ("Clear"))
742             getThumbelina ().getPicturePanel ().reset ();
743         else if (action.equals ("About"))
744             about ();
745         else if (action.equals ("Exit"))
746             exit ();
747         else
748         {
749             // must be a URL from the most recently used list
750
getThumbelina ().open (action);
751             updateMRU (action);
752             updateMenu ();
753         }
754     }
755
756     //
757
// ItemListener interface
758
//
759

760     /**
761      * Handles selections on the view state checkboxes.
762      * @param event The event describing the checkbox affected.
763      */

764     public void itemStateChanged (final ItemEvent JavaDoc event)
765     {
766         Object JavaDoc source;
767         boolean visible;
768
769         source = event.getItemSelectable ();
770         visible = ItemEvent.SELECTED == event.getStateChange ();
771         if (source == mStatusVisible)
772             getThumbelina ().setStatusBarVisible (visible);
773         else if (source == mHistoryVisible)
774             getThumbelina ().setHistoryListVisible (visible);
775     }
776
777     //
778
// PropertyChangeListener
779
//
780

781     /**
782      * Handle a property change.
783      * @param event The property old and new values.
784      */

785     public void propertyChange (final PropertyChangeEvent JavaDoc event)
786     {
787         String JavaDoc url;
788
789         if (event.getPropertyName ().equals (
790             Thumbelina.PROP_CURRENT_URL_PROPERTY))
791         {
792             url = (String JavaDoc)event.getNewValue ();
793             if (null == url)
794                 setTitle ("Thumbelina");
795             else
796                 setTitle ("Thumbelina - " + url);
797         }
798     }
799
800     /**
801      * Updates the user preferences based on the most recently used list.
802      * @param url The URL that is to be placed at the top of the MRU list.
803      */

804     public void updateMRU (String JavaDoc url)
805     {
806         Preferences JavaDoc prefs;
807         int count;
808         ArrayList JavaDoc list;
809         String JavaDoc string;
810         int max;
811
812         if (url.startsWith ("http://"))
813             url = url.substring (7);
814         prefs = Preferences.userNodeForPackage (getClass ());
815         count = prefs.getInt (MRULENGTH, -1);
816         list = new ArrayList JavaDoc ();
817         for (int i = 0; i < count; i++)
818         {
819             string = prefs.get (MRUPREFIX + i, "");
820             if (!"".equals (string) && !url.equalsIgnoreCase (string))
821                 list.add (string);
822         }
823         list.add (0, url);
824         max = prefs.getInt (MRUMAX, -1);
825         if (-1 == max)
826             max = 8;
827         while (list.size () > max)
828             list.remove (max);
829         prefs.putInt (MRULENGTH, list.size ());
830         prefs.putInt (MRUMAX, max);
831         for (int i = 0; i < list.size (); i++)
832             prefs.put (MRUPREFIX + i, (String JavaDoc)list.get (i));
833         try
834         {
835             prefs.flush ();
836         }
837         catch (BackingStoreException JavaDoc bse)
838         {
839             bse.printStackTrace ();
840         }
841     }
842
843     /**
844      * Opens a user specified URL.
845      */

846     public void open ()
847     {
848         String JavaDoc result;
849
850         result = JOptionPane.showInputDialog (
851             this,
852             "Enter the URL:",
853             "Open URL",
854             JOptionPane.PLAIN_MESSAGE);
855         if (null != result)
856         {
857             getThumbelina ().open (result);
858             updateMRU (result);
859             updateMenu ();
860         }
861     }
862
863     /**
864      * Query google via user specified keywords and queue results.
865      * Asks the user for keywords, and then submits them as input to the
866      * usual google form:
867      * <pre>
868      * <form action="/search" name=f>
869      * <span id=hf></span>
870      * <table cellspacing=0 cellpadding=0>
871      * <tr valign=middle>
872      * <td width=75>&nbsp;</td>
873      * <td align=center>
874      * <input maxLength=256 size=55 name=q value="">
875      * <input type=hidden name=ie value="UTF-8">
876      * <input type=hidden name=oe value="UTF-8">
877      * <input name=hl type=hidden value=en><br>
878      * <input type=submit value="Google Search" name=btnG>
879      * <input type=submit value="I'm Feeling Lucky" name=btnI>
880      * </td>
881      * <td valign=top nowrap><font size=-2>
882      * &nbsp;&#8226; <a HREF=/advanced_search?hl=en>Advanced Search</a>
883      * <br>&nbsp;&#8226; <a HREF=/preferences?hl=en>Preferences</a>
884      * <br>&nbsp;&#8226; <a HREF=/language_tools?hl=en>Language Tools</a>
885      * </font>
886      * </td>
887      * </tr>
888      * <tr>
889      * <td colspan=3 align=center><font size=-1>
890      * Search: <input id=all type=radio name=meta value="" checked>
891      * <label for=all> the web</label>
892      * <input id=cty type=radio name=meta value="cr=countryCA" >
893      * <label for=cty>pages from Canada</label>
894      * </font>
895      * </td>
896      * </tr>
897      * </table>
898      * </form>
899      * </pre>
900      * Creates a query of the form:
901      * <pre>
902      * http://www.google.ca/search?hl=en&ie=UTF-8&oe=UTF-8&q=thumbs&btnG=Google+Search&meta=
903      * </pre>
904      */

905     public void googlesearch ()
906     {
907
908         Preferences JavaDoc prefs;
909         String JavaDoc query;
910         String JavaDoc terms;
911         StringBuffer JavaDoc buffer;
912         HttpURLConnection JavaDoc connection;
913         URL JavaDoc url;
914         Lexer lexer;
915         URL JavaDoc[][] results;
916
917         prefs = Preferences.userNodeForPackage (getClass ());
918         query = prefs.get (GOOGLEQUERY, DEFAULTGOOGLEQUERY);
919         try
920         {
921             query = (String JavaDoc)JOptionPane.showInputDialog (
922                 this,
923                 "Enter the search term:",
924                 "Search Google",
925                 JOptionPane.PLAIN_MESSAGE,
926                 null,
927                 null,
928                 query);
929             if (null != query)
930             {
931                 // replace spaces with +
932
terms = query.replace (' ', '+');
933                 buffer = new StringBuffer JavaDoc (1024);
934                 buffer.append ("http://www.google.ca/search?");
935                 buffer.append ("q=");
936                 buffer.append (terms);
937                 buffer.append ("&ie=UTF-8");
938                 buffer.append ("&oe=UTF-8");
939                 buffer.append ("&hl=en");
940                 buffer.append ("&btnG=Google+Search");
941                 buffer.append ("&meta=");
942                 url = new URL JavaDoc (buffer.toString ());
943                 connection = (HttpURLConnection JavaDoc)url.openConnection ();
944                 if (USE_MOZILLA_HEADERS)
945                 {
946                     // These are the Mozilla header fields:
947
//Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
948
//Accept-Language: en-us, en;q=0.50
949
//Connection: keep-alive
950
//Host: grc.com
951
//Referer: https://grc.com/x/ne.dll?bh0bkyd2
952
//User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20030225
953
//Content-Length: 27
954
//Content-Type: application/x-www-form-urlencoded
955
//Accept-Encoding: gzip, deflate, compress;q=0.9
956
//Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66
957
//Keep-Alive: 300
958

959                     connection.setRequestProperty ("Referer", "http://www.google.ca");
960                     connection.setRequestProperty ("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1");
961                     connection.setRequestProperty ("Accept-Language", "en-us, en;q=0.50");
962                     connection.setRequestProperty ("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20030225");
963                     connection.setRequestProperty ("Accept-Charset", "ISO-8859-1, utf-8;q=0.66, *;q=0.66");
964                 }
965                 else
966                 {
967                     // These are the IE header fields:
968
//Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
969
//Accept-Language: en-ca
970
//Connection: Keep-Alive
971
//Host: grc.com
972
//User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; trieste; .NET CLR 1.1.4322; .NET CLR 1.0.3705)
973
//Content-Length: 32
974
//Content-Type: application/x-www-form-urlencoded
975
//Accept-Encoding: gzip, deflate
976
//Cache-Control: no-cache
977

978                     connection.setRequestProperty ("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
979                     connection.setRequestProperty ("Accept-Language", "en-ca");
980                     connection.setRequestProperty ("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; trieste; .NET CLR 1.1.4322; .NET CLR 1.0.3705)");
981                 }
982                 connection.setDoOutput (true);
983                 connection.setDoInput (true);
984                 connection.setUseCaches (false);
985                 lexer = new Lexer (connection);
986                 results = getThumbelina ().extractImageLinks (lexer, url);
987                 // add 'em
988
getThumbelina ().reset ();
989                 // remove google links, not just append (results[1]);
990
for (int i = 0; i < results[1].length; i++)
991                 {
992                     String JavaDoc found = results[1][i].toExternalForm ();
993                     if (-1 == found.indexOf ("google"))
994                         getThumbelina ().append (results[1][i]);
995                 }
996                 prefs.put (GOOGLEQUERY, query);
997                 try
998                 {
999                     prefs.flush ();
1000                }
1001                catch (BackingStoreException JavaDoc bse)
1002                {
1003                    bse.printStackTrace ();
1004                }
1005            }
1006        }
1007        catch (Exception JavaDoc e)
1008        {
1009            System.out.println (e.getMessage ());
1010        }
1011    }
1012
1013    /**
1014     * Display information about Thumbelina.
1015     */

1016    public void about ()
1017    {
1018        URL JavaDoc url;
1019
1020        try
1021        {
1022            url = new URL JavaDoc ("http://sourceforge.net/sflogo.php?group_id=24399");
1023        }
1024        catch (MalformedURLException JavaDoc murle)
1025        {
1026            url = null;
1027        }
1028        JOptionPane.showMessageDialog (
1029            this,
1030            "Scan and display the images behind thumbnails.\n"
1031            + "\n"
1032            + "An example application using the HTML Parser project.\n"
1033            + "Visit http://htmlparser.sourceforge.org for the latest\n"
1034            + "version and source code.\n",
1035            "Thumbelina - About",
1036            JOptionPane.PLAIN_MESSAGE,
1037            new ImageIcon JavaDoc (url));
1038    }
1039
1040    /**
1041     * Exits the application.
1042     * Saves user preferences before exiting.
1043     */

1044    public void exit ()
1045    {
1046        saveState ();
1047        System.exit (0);
1048    }
1049
1050    /**
1051     * Alternate mainline for Thumbelina.
1052     * Similar code exists in the Thumbelina class, but this version doesn't
1053     * worry about java version.
1054     * @param args The command line arguments.
1055     * Optionally, arg[0] can be the URL to preload the Thumeblina bean with.
1056     */

1057    public static void main (final String JavaDoc[] args)
1058    {
1059        String JavaDoc url;
1060        ThumbelinaFrame thumbelina;
1061
1062        System.setProperty ("sun.net.client.defaultReadTimeout", "7000");
1063        System.setProperty ("sun.net.client.defaultConnectTimeout", "7000");
1064
1065        url = null;
1066        if (0 != args.length)
1067            if (args[0].equalsIgnoreCase ("help")
1068                || args[0].equalsIgnoreCase ("-help")
1069                || args[0].equalsIgnoreCase ("-h")
1070                || args[0].equalsIgnoreCase ("?")
1071                || args[0].equalsIgnoreCase ("-?"))
1072                Thumbelina.help ();
1073            else
1074                url = args[0];
1075
1076        try
1077        {
1078            thumbelina = new ThumbelinaFrame (url);
1079            thumbelina.setVisible (true);
1080        }
1081        catch (MalformedURLException JavaDoc murle)
1082        {
1083            System.err.println (murle.getMessage ());
1084            Thumbelina.help ();
1085        }
1086    }
1087}
1088
Popular Tags