1 /********************************************************************
2 *
3 *  This library is free software; you can redistribute it and/or
4 *  modify it under the terms of the GNU Library General Public
5 *  License as published by the Free Software Foundation; either
6 *  version 2 of the License, or (at your option) any later version.
7 *
8 *  This library is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 *  Library General Public License for more details.
12 *
13 *  You should have received a copy of the GNU Library General Public
14 *  License along with this library; if not, write to the
15 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 *  Boston, MA  02111-1307, USA.
17 *
18 *  @author: Copyright (C) Tim Carver
19 *
20 ********************************************************************/
21 
22 package org.emboss.jemboss.gui;
23 
24 
25 import java.awt.BasicStroke;
26 import java.awt.BorderLayout;
27 import java.awt.Color;
28 import java.awt.Cursor;
29 import java.awt.Dimension;
30 import java.awt.Graphics;
31 import java.awt.Graphics2D;
32 import java.awt.event.ActionEvent;
33 import java.awt.event.ActionListener;
34 import java.awt.event.KeyEvent;
35 import java.awt.geom.GeneralPath;
36 import java.io.IOException;
37 import java.net.MalformedURLException;
38 import java.net.URL;
39 import java.util.Vector;
40 
41 import javax.swing.BorderFactory;
42 import javax.swing.Box;
43 import javax.swing.ImageIcon;
44 import javax.swing.JButton;
45 import javax.swing.JCheckBoxMenuItem;
46 import javax.swing.JEditorPane;
47 import javax.swing.JFrame;
48 import javax.swing.JLabel;
49 import javax.swing.JMenu;
50 import javax.swing.JMenuBar;
51 import javax.swing.JMenuItem;
52 import javax.swing.JOptionPane;
53 import javax.swing.JPanel;
54 import javax.swing.JScrollPane;
55 import javax.swing.JSplitPane;
56 import javax.swing.JTextField;
57 import javax.swing.JToolBar;
58 import javax.swing.JTree;
59 import javax.swing.KeyStroke;
60 import javax.swing.border.Border;
61 import javax.swing.event.HyperlinkEvent;
62 import javax.swing.event.HyperlinkListener;
63 import javax.swing.event.TreeSelectionEvent;
64 import javax.swing.event.TreeSelectionListener;
65 import javax.swing.text.Document;
66 import javax.swing.text.html.HTMLDocument;
67 import javax.swing.text.html.HTMLEditorKit;
68 import javax.swing.tree.DefaultMutableTreeNode;
69 import javax.swing.tree.TreeSelectionModel;
70 
71 import org.emboss.jemboss.Jemboss;
72 import org.emboss.jemboss.JembossParams;
73 import org.emboss.jemboss.server.JembossServer;
74 import org.emboss.jemboss.soap.GetVersion;
75 
76 
77 /**
78 *
79 * Jemboss web browser
80 *
81 */
82 public class Browser extends JFrame
83                      implements HyperlinkListener, ActionListener
84 {
85 
86   /** status field */
87   private JTextField statusField;
88   /** URL cache combo field */
89   private MemoryComboBox urlField;
90   /** HTML pane   */
91   private JEditorPane htmlPane;
92   /** busy cursor */
93   private Cursor cbusy = new Cursor(Cursor.WAIT_CURSOR);
94   /** done cursor */
95   private Cursor cdone = new Cursor(Cursor.DEFAULT_CURSOR);
96   /** Help topics */
97   private String topics[] = { "Home", "About",
98                               "User Guide",
99                               "File Manager",
100                               "Results Manager",
101                               "Sequence List",
102                               "Alignment Editor"};
103   private String embossTopics[] =
104                             { "Home", "Apps"};
105 
106   /** JSplitPane sp */
107   private JSplitPane sp;
108   /** Back menu option */
109   private JMenuItem backMenu;
110   /** Back button option */
111   private JButton backBt;
112   /** Forward menu option */
113   private JMenuItem fwdMenu;
114   /** Forward button option */
115   private JButton fwdBt;
116   /** version of EMBOSS programs */
117   String embossVersion = "6.1";
118 
119   /**
120   *
121   * @param initialURL	initial URL
122   * @param name		browser frame title
123   * @param mysettings	jemboss settings
124   *
125   */
Browser(String initialURL, String name, JembossParams mysettings)126   public Browser(String initialURL, String name,
127                  JembossParams mysettings) throws IOException
128   {
129     this(initialURL,name,false,"",mysettings);
130   }
131 
132   public class HTMLEditorKit2 extends HTMLEditorKit{
createDefaultDocument()133 	  public Document createDefaultDocument(){
134 	  HTMLDocument doc = (HTMLDocument)(super.createDefaultDocument());
135 	  doc.setAsynchronousLoadPriority(-1); //do synchronous load
136 	  return doc;
137 	  }
138 	  }
139 
140 
141   /**
142   *
143   * @param initialURL   initial URL
144   * @param name         browser frame title
145   * @param ltext	true if html as string past to web browser
146   * @param text		html as string
147   * @param mysettings   jemboss settings
148   *
149   */
Browser(String initialURL, String name, boolean ltext, String text, JembossParams mysettings)150   public Browser(String initialURL, String name,  boolean ltext,
151                  String text, JembossParams mysettings) throws IOException
152   {
153     super(name);
154 
155     if(mysettings.isBrowserProxy())
156     {
157       System.setProperty("http.proxyHost",mysettings.getBrowserProxyHost());
158       System.setProperty("http.proxyPort", Integer.toString(
159                           mysettings.getBrowserProxyPort()));
160 
161       System.setProperty("proxyHost",mysettings.getBrowserProxyHost());
162       System.setProperty("proxyPort", Integer.toString(
163                           mysettings.getBrowserProxyPort()));
164     }
165 
166     if(ltext)
167     {
168       htmlPane = new JEditorPane();
169       if( (text.indexOf("<html>") > -1) ||
170           (text.indexOf("<HTML>") > -1) )
171         htmlPane.setContentType("text/html");
172       htmlPane.setText(text);
173       htmlPane.addHyperlinkListener(this);
174       setBrowserSize();
175       Vector urlCache = new Vector();
176       urlCache.add(name+".html");
177       setUpJMenuBar(urlCache);
178       addToScrollPane();
179       setVisible(true);
180     }
181     else
182     {
183       URL pageURL = new URL(initialURL);
184       setURL(pageURL,initialURL);
185     }
186     if (Jemboss.withSoap){
187     	embossVersion = GetVersion.getVersion(mysettings);
188     }
189   }
190 
191 
192   /**
193   *
194   * @param urlName	URL to display
195   * @param initialURL   initial URL
196   *
197   */
Browser(URL urlName, String initialURL)198   public Browser(URL urlName, String initialURL) throws IOException
199   {
200     super(initialURL);
201     setURL(urlName,initialURL);
202   }
203 
204 
205   /**
206   *
207   * Set the URL in the browser
208   * @param url		URL to display
209   * @param name 	URL name
210   *
211   */
setURL(URL url, String name)212   public void setURL(URL url, String name)
213   {
214     try
215     {
216 
217 	  JEditorPane.registerEditorKitForContentType("text/html",
218 	  "HTMLEditorKit2");
219 	  htmlPane = new JEditorPane();
220 	  htmlPane.setEditorKitForContentType("text/html", new HTMLEditorKit2());
221 
222       htmlPane.setPage(url);
223 
224       htmlPane.addHyperlinkListener(this);
225 
226       Vector urlCache = new Vector();
227       urlCache.add(url);
228       setBrowserSize();
229       setUpJMenuBar(urlCache);
230       setTitle(name);
231       addToScrollPane();
232       setVisible(true);
233     }
234     catch(IOException ioe)
235     {
236       JOptionPane.showMessageDialog(null,
237                               "Cannot Load URL\n"+name,
238                               "Error", JOptionPane.ERROR_MESSAGE);
239     }
240   }
241 
242 
243   /**
244   *
245   * Method to create the frames menu and tool bar.
246   * @param urlCache	URL cache
247   *
248   */
setUpJMenuBar(Vector urlCache)249   private void setUpJMenuBar(Vector urlCache)
250   {
251     JMenuBar menuBar = new JMenuBar();
252     JToolBar toolBarURL  = new JToolBar();
253     JToolBar toolBarIcon = new JToolBar();
254 
255     JMenu fileMenu = new JMenu("File");
256     fileMenu.setMnemonic(KeyEvent.VK_F);
257     menuBar.add(fileMenu);
258 
259     // back
260     backMenu = new JMenuItem("Back");
261     backMenu.setAccelerator(KeyStroke.getKeyStroke(
262               KeyEvent.VK_B, ActionEvent.CTRL_MASK));
263     backMenu.setActionCommand("BACK");
264     backMenu.addActionListener(this);
265     fileMenu.add(backMenu);
266     backMenu.setEnabled(false);
267 
268     fwdMenu = new JMenuItem("Forward");
269     fwdMenu.setAccelerator(KeyStroke.getKeyStroke(
270               KeyEvent.VK_F, ActionEvent.CTRL_MASK));
271     fwdMenu.setActionCommand("FWD");
272     fwdMenu.addActionListener(this);
273     fileMenu.add(fwdMenu);
274 
275     // close
276     fileMenu.addSeparator();
277     JMenuItem closeMenu = new JMenuItem("Close");
278     closeMenu.setAccelerator(KeyStroke.getKeyStroke(
279               KeyEvent.VK_E, ActionEvent.CTRL_MASK));
280 
281     closeMenu.addActionListener(new ActionListener()
282     {
283       public void actionPerformed(ActionEvent e)
284       {
285         setVisible(false);
286       }
287     });
288     fileMenu.add(closeMenu);
289 
290     // view
291     JMenu viewMenu = new JMenu("View");
292     viewMenu.setMnemonic(KeyEvent.VK_V);
293     menuBar.add(viewMenu);
294     JCheckBoxMenuItem sideTopics = new JCheckBoxMenuItem(
295                                        "Display help topics");
296     sideTopics.setSelected(true);
297     sideTopics.setAccelerator(KeyStroke.getKeyStroke(
298               KeyEvent.VK_L, ActionEvent.CTRL_MASK));
299     sideTopics.addActionListener(new ActionListener()
300     {
301       public void actionPerformed(ActionEvent e)
302       {
303         if(sp.getDividerLocation() > 5)
304           sp.setDividerLocation(0);
305         else
306           sp.setDividerLocation(100);
307       }
308     });
309     viewMenu.add(sideTopics);
310 
311     // jemboss logo button
312     ClassLoader cl = this.getClass().getClassLoader();
313     ImageIcon jem = new ImageIcon(cl.getResource(
314                                "images/Jemboss_logo_small.gif"));
315     JIconButton jembossButton = new JIconButton(jem);
316     jembossButton.addActionListener(this);
317     jembossButton.setActionCommand("JEMBOSS");
318 
319     // url field
320     JLabel urlLabel = new JLabel("URL:");
321     urlField = new MemoryComboBox(urlCache);
322     urlField.addActionListener(this);
323     int urlFieldHeight = (int)urlField.getPreferredSize().getHeight();
324 
325 // Icon tool bar
326     // Back JButton
327     backBt = new JButton()
328     {
329       public void paintComponent(Graphics g)
330       {
331         super.paintComponent(g);
332         Graphics2D g2 = (Graphics2D)g;
333 
334         g2.setColor(new Color(0,128,0));
335 
336         float loc1[][] = { {4,12}, {14,22}, {14,16},
337                                    {18,16}, {18,12} };
338         g2.fill(Browser.makeShape(loc1));
339         g2.setColor(Color.green);
340 
341         float loc2[][] = { {4,12}, {14,2}, {14,8},
342                                    {18,8}, {18,12} };
343         g2.fill(Browser.makeShape(loc2));
344 
345         if(!isEnabled())
346         {
347           g2.setColor(Color.gray);
348           float loc3[][] = { {5,12}, {14,21}, {14,15},
349                                      {18,15}, {18,12} };
350           g2.fill(Browser.makeShape(loc3));
351           g2.setColor(Color.lightGray);
352           float loc4[][] = { {5,12}, {14,3}, {14,9},
353                                      {18,9}, {18,12} };
354           g2.fill(Browser.makeShape(loc4));
355         }
356         setSize(22,24);
357       }
358     };
359     Dimension dBut = new Dimension(22,24);
360     backBt.setPreferredSize(dBut);
361     backBt.setMaximumSize(dBut);
362     backBt.setPreferredSize(new Dimension(15,15));
363     backBt.setActionCommand("BACK");
364     backBt.addActionListener(this);
365     backBt.setEnabled(false);
366 
367     // Forward JButton
368     fwdBt = new JButton()
369     {
370       public void paintComponent(Graphics g)
371       {
372         super.paintComponent(g);
373         Graphics2D g2 = (Graphics2D)g;
374 
375         g2.setColor(new Color(0,128,0));
376 
377         float loc1[][] = { {4,12}, {4,16}, {8,16},
378                                    {8,22}, {18,12} };
379 
380         g2.fill(Browser.makeShape(loc1));
381         g2.setColor(Color.green);
382 
383         float loc2[][] = { {4,12}, {4,8}, {8,8},
384                                    {8,2}, {18,12} };
385         g2.fill(Browser.makeShape(loc2));
386 
387         if(!isEnabled())
388         {
389           g2.setColor(Color.gray);
390           float loc3[][] = { {4,12}, {4,15}, {8,15},
391                                      {8,21}, {17,12} };
392           g2.fill(Browser.makeShape(loc3));
393           g2.setColor(Color.lightGray);
394           float loc4[][] = { {4,12}, {4,7}, {8,7},
395                                      {8,3}, {17,12} };
396           g2.fill(Browser.makeShape(loc4));
397         }
398 
399         setSize(22,24);
400       }
401     };
402     fwdBt.setPreferredSize(dBut);
403     fwdBt.setMaximumSize(dBut);
404     fwdBt.setActionCommand("FWD");
405     fwdBt.addActionListener(this);
406     fwdBt.setEnabled(false);
407 
408     toolBarIcon.add(backBt);
409     toolBarIcon.add(fwdBt);
410     toolBarIcon.add(jembossButton);
411 
412     toolBarURL.add(urlLabel);
413     toolBarURL.add(urlField);
414 
415     setJMenuBar(menuBar);
416 
417     JPanel toolBars = new JPanel(new BorderLayout());
418     toolBars.add(toolBarIcon, BorderLayout.NORTH);
419     toolBars.add(toolBarURL, BorderLayout.SOUTH);
420     getContentPane().add(toolBars, BorderLayout.NORTH);
421 
422     int urlFieldWidth  = (int)toolBarURL.getPreferredSize().getWidth();
423     Dimension d = new Dimension(urlFieldWidth,urlFieldHeight);
424     urlField.setMaximumSize(d);
425 
426     int iconBarWidth  = (int)toolBarIcon.getPreferredSize().getWidth();
427     int iconBarHeight = jem.getIconHeight();
428     d = new Dimension(iconBarWidth,iconBarHeight);
429     toolBarIcon.setPreferredSize(d);
430   }
431 
432 
433   /**
434   *
435   * Set the Jemboss web browser size
436   *
437   */
setBrowserSize()438   private void setBrowserSize()
439   {
440     Dimension screenSize = getToolkit().getScreenSize();
441     int width  = (int)(screenSize.width * 0.6);
442     int height = (int)(screenSize.height * 0.85);
443     setBounds((int)(width*.59), (int)(height*.02), width, height);
444   }
445 
446 
447   /**
448   *
449   * Add the html pane to a scrollpane, list and splitpane and set the
450   * size of the html pane
451   *
452   */
addToScrollPane()453   private void addToScrollPane()
454   {
455     htmlPane.setEditable(false);
456 
457     Box bacross = Box.createHorizontalBox();
458     bacross.add(Box.createHorizontalGlue());
459     JButton listClose = new JButton()
460     {
461       public void paintComponent(Graphics g)
462       {
463         super.paintComponent(g);
464         BasicStroke stroke = new BasicStroke(2.0f);
465         Graphics2D g2 = (Graphics2D) g;
466 
467         g2.setStroke(stroke);
468         g2.setColor(Color.gray);
469         g2.drawLine(4,5,9,10);
470         g2.drawLine(9,5,4,10);
471 
472         g2.setColor(Color.black);
473         g2.drawLine(4,4,9,9);
474         g2.drawLine(9,3,3,9);
475         setSize(15,15);
476       }
477     };
478     listClose.addActionListener(this);
479     listClose.setActionCommand("CLOSE");
480     listClose.setPreferredSize(new Dimension(15,15));
481     bacross.add(listClose);
482 
483     JPanel leftPane = new JPanel(new BorderLayout());
484     JScrollPane leftScroll = new JScrollPane(getWebScape());
485     leftPane.add(bacross, BorderLayout.NORTH);
486     leftPane.add(leftScroll, BorderLayout.CENTER);
487     leftScroll.getViewport().setBackground(Color.white);
488 
489 
490     sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
491 		        leftPane, htmlPane);
492     sp.setDividerSize(8);
493     sp.setDividerLocation(100);
494     sp.setOneTouchExpandable(true);
495     JScrollPane scrollPane = new JScrollPane(htmlPane);
496     sp.add(scrollPane);
497 
498     // ensures html wraps properly
499     htmlPane.setPreferredSize(getPreferredSize());
500     getContentPane().add(sp, BorderLayout.CENTER);
501 
502     // status field
503     Border loweredbevel = BorderFactory.createLoweredBevelBorder();
504     Border raisedbevel = BorderFactory.createRaisedBevelBorder();
505     Border compound = BorderFactory.createCompoundBorder(raisedbevel,loweredbevel);
506     statusField = new JTextField();
507     statusField.setBorder(compound);
508     statusField.setEditable(false);
509     getContentPane().add(statusField, BorderLayout.SOUTH);
510   }
511 
512   /**
513   *
514   * Override actionPerformed
515   * @param event 	action event
516   *
517   */
actionPerformed(ActionEvent event)518   public void actionPerformed(ActionEvent event)
519   {
520     URL url = null;
521     setCursor(cbusy);
522     if (event.getSource() == urlField)
523     {
524       Object select = urlField.getSelectedItem();
525       if(select instanceof String)
526       {
527         try
528         {
529           url = new URL((String)select);
530         }
531         catch(MalformedURLException me){}
532       }
533       else
534         url = (URL)select;
535     }
536     else if (event.getActionCommand().equals("JEMBOSS"))
537     {
538       try
539       {
540         url = new URL("http://emboss.sourceforge.net/Jemboss/");
541       }
542       catch(MalformedURLException me){}
543     }
544     else if (event.getActionCommand().equals("BACK"))
545     {
546       int index = urlField.getIndexOf(urlField.getSelectedItem())-1;
547       if(index > -1 && index < urlField.getItemCount())
548         url = urlField.getURLAt(index);
549     }
550     else if (event.getActionCommand().equals("FWD"))
551     {
552       int index = urlField.getIndexOf(urlField.getSelectedItem())+1;
553       if(index > -1 && index < urlField.getItemCount())
554         url = urlField.getURLAt(index);
555     }
556     else if (event.getActionCommand().equals("CLOSE"))
557     {
558       setCursor(cdone);
559       sp.setDividerLocation(0);
560       return;
561     }
562 
563     try
564     {
565       htmlPane.setPage(url);
566       if(!urlField.isItem(url))
567         urlField.addURL(url);
568       else
569       {
570         urlField.setSelectedItem(url);
571       }
572       backMenu.setEnabled(urlField.isBackPage());
573       backBt.setEnabled(urlField.isBackPage());
574 
575       fwdMenu.setEnabled(urlField.isForwardPage());
576       fwdBt.setEnabled(urlField.isForwardPage());
577     }
578     catch(IOException ioe)
579     {
580       setCursor(cdone);
581       warnUser("Can't follow link to " + url );
582     }
583     setCursor(cdone);
584   }
585 
586 
587 
588   /**
589   *
590   * Method to handle hyper link events.
591   * @param event	hyper link event
592   *
593   */
hyperlinkUpdate(HyperlinkEvent event)594   public void hyperlinkUpdate(HyperlinkEvent event)
595   {
596     if(event.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
597     {
598       setCursor(cbusy);
599       try
600       {
601 	URL url = event.getURL();
602         htmlPane.setPage(url);
603         if(!urlField.isItem(url))
604           urlField.addURL(url);
605         else
606 	{
607           urlField.setSelectedItem(url);
608           urlField.setLastIndex(url);
609         }
610       }
611       catch(IOException ioe)
612       {
613         setCursor(cdone);
614         warnUser("Can't follow link to " +
615                   event.getDescription() );
616       }
617       finally {
618           setCursor(cdone);
619       }
620     }
621     else if(event.getEventType() == HyperlinkEvent.EventType.ENTERED)
622       statusField.setText(event.getDescription());
623     else if(event.getEventType() == HyperlinkEvent.EventType.EXITED)
624       statusField.setText("");
625   }
626 
627 
628   /**
629   *
630   * Display a warning message
631   * @param message	message to display
632   *
633   */
warnUser(String message)634   private void warnUser(String message)
635   {
636     JOptionPane.showMessageDialog(this, message, "Warning",
637                                   JOptionPane.ERROR_MESSAGE);
638   }
639 
640 
641   /**
642   *
643   * Used to draw a Shape.
644   *
645   */
makeShape(float loc[][])646   public static GeneralPath makeShape(float loc[][])
647   {
648     GeneralPath path = new GeneralPath(GeneralPath.WIND_NON_ZERO);
649 
650     path.moveTo(loc[0][0],loc[0][1]);
651 
652     for(int i=1; i<loc.length; i++)
653       path.lineTo(loc[i][0],loc[i][1]);
654 
655     return path;
656   }
657 
658 
659 
660 
661   /**
662   *
663   * Jemboss icon button
664   *
665   */
666   public class JIconButton extends JButton
667   {
JIconButton(ImageIcon ii)668     public JIconButton(ImageIcon ii)
669     {
670       super(ii);
671       setContentAreaFilled(false);
672       setBorderPainted(false);
673       setFocusPainted(false);
674     }
675   }
676 
677 
getWebScape()678   public JTree getWebScape()
679   {
680     DefaultMutableTreeNode top =
681         new DefaultMutableTreeNode("Jemboss WebScape");
682     createNodes(top);
683 
684     final JTree webScape = new JTree(top);
685     webScape.setShowsRootHandles(true);
686     webScape.expandRow(1);
687     webScape.getSelectionModel().setSelectionMode
688             (TreeSelectionModel.SINGLE_TREE_SELECTION);
689     webScape.addTreeSelectionListener(new TreeSelectionListener()
690     {
691       public void valueChanged(TreeSelectionEvent e)
692       {
693         ClassLoader cl = this.getClass().getClassLoader();
694         DefaultMutableTreeNode node = (DefaultMutableTreeNode)
695                        webScape.getLastSelectedPathComponent();
696 
697         if (node == null) return;
698         Object nodeInfo = node.getUserObject();
699         if(node.isLeaf())
700         {
701           String loc = null;
702           DefaultMutableTreeNode parent = (DefaultMutableTreeNode)node.getParent();
703           String category = (String)parent.getUserObject();
704 
705           String selectedValue = (String)nodeInfo;
706           URL inURL = null;
707           if(selectedValue.equals("File Manager"))
708             inURL = cl.getResource("resources/filemgr.html");
709           else if(selectedValue.equals("About"))
710             inURL = cl.getResource("resources/readme.html");
711           else if(selectedValue.equals("Alignment Editor"))
712             inURL = cl.getResource("resources/readmeAlign.html");
713           else if(selectedValue.equals("Sequence List"))
714             inURL = cl.getResource("resources/seqList.html");
715           else if(selectedValue.equals("Results Manager"))
716             inURL = cl.getResource("resources/results.html");
717           else if (selectedValue.equals("User Guide"))
718             loc = "http://emboss.sourceforge.net/Jemboss/guide.html";
719           else if(selectedValue.equals("Home") && category.equals("Jemboss"))
720             loc = "http://emboss.sourceforge.net/Jemboss/";
721           else if(selectedValue.equals("Home") && category.equals("EMBOSS"))
722             loc = "http://emboss.sourceforge.net/";
723           else if(selectedValue.equals("Apps") && category.equals("EMBOSS")){
724         	if (!JembossParams.isJembossServer()){
725         	  	embossVersion = new JembossServer().version();
726         	  	embossVersion = embossVersion.split("\\.")[0]+"."+embossVersion.split("\\.")[1];
727         	}
728             loc = "http://emboss.sourceforge.net/apps/release/"+embossVersion+"/emboss/apps/";
729           }
730 
731           if(loc != null)
732           {
733             try
734             {
735               inURL = new URL(loc);
736             }
737             catch(MalformedURLException me)
738             {
739               warnUser("Can't follow link to " + loc);
740             }
741           }
742 
743           if(inURL != null)
744           {
745             try
746             {
747               htmlPane.setPage(inURL);
748               if(!urlField.isItem(inURL))
749                 urlField.addURL(inURL);
750               else
751               {
752                 urlField.setSelectedItem(inURL);
753                 urlField.setLastIndex(inURL);
754               }
755             }
756             catch(IOException ioe)
757             {
758               setCursor(cdone);
759               warnUser("Can't follow link to " + inURL );
760             }
761             backMenu.setEnabled(urlField.isBackPage());
762             backBt.setEnabled(urlField.isBackPage());
763 
764             fwdMenu.setEnabled(urlField.isForwardPage());
765             fwdBt.setEnabled(urlField.isForwardPage());
766           }
767         }
768       }
769     });
770 
771     webScape.setRootVisible(false);
772     return webScape;
773   }
774 
createNodes(DefaultMutableTreeNode top)775   private void createNodes(DefaultMutableTreeNode top)
776   {
777     DefaultMutableTreeNode category = null;
778     DefaultMutableTreeNode topic    = null;
779 
780     category = new DefaultMutableTreeNode("Jemboss");
781     top.add(category);
782 
783     for(int i=0; i<topics.length; i++)
784     {
785       topic = new DefaultMutableTreeNode(topics[i]);
786       category.add(topic);
787     }
788 
789     category = new DefaultMutableTreeNode("EMBOSS");
790     top.add(category);
791 
792     for(int i=0; i<embossTopics.length; i++)
793     {
794       topic = new DefaultMutableTreeNode(embossTopics[i]);
795       category.add(topic);
796     }
797 
798   }
799 
main(String args[])800   public static void main(String args[])
801   {
802     ClassLoader cl = ClassLoader.getSystemClassLoader();
803     try
804     {
805       URL inURL = cl.getResource("resources/seqList.html");
806       new Browser(inURL,"resources/seqList.html");
807     }
808     catch (Exception iex)
809     {
810       System.out.println("Didn't find resources/seqList.html");
811     }
812   }
813 
814 }
815