XJEditorPane.java
001 package gate.swing;
002 
003 import gate.event.StatusListener;
004 import gate.gui.MainFrame;
005 import gate.util.Err;
006 
007 import java.awt.event.ActionEvent;
008 import java.io.IOException;
009 import java.net.URL;
010 import java.util.LinkedList;
011 import java.util.Vector;
012 
013 import javax.swing.AbstractAction;
014 import javax.swing.Action;
015 import javax.swing.JEditorPane;
016 import javax.swing.event.HyperlinkEvent;
017 import javax.swing.event.HyperlinkListener;
018 import javax.swing.text.html.HTMLDocument;
019 import javax.swing.text.html.HTMLFrameHyperlinkEvent;
020 
021 /**
022  * An enhanced version of {@link javax.swing.JEditorPane} that is able of
023  * handling hyperlinks from the HTML document displayed.
024  */
025 @SuppressWarnings("serial")
026 public class XJEditorPane extends JEditorPane {
027 
028   public XJEditorPane(){
029     super();
030     init();
031   }
032 
033   public XJEditorPane(String urlthrows IOException{
034     super(url);
035     init();
036   }
037 
038   public XJEditorPane(URL initialPage)throws IOException{
039     super(initialPage);
040     init();
041   }
042 
043   protected void init(){
044     initLocalData();
045     initListeners();
046   }//protected void init()
047 
048   protected void initLocalData(){
049     backUrls = new LinkedList<URL>();
050     forwardUrls = new LinkedList<URL>();
051     try{
052       backAction = new BackAction();
053       forwardAction = new ForwardAction();
054     }catch(IOException ioe){
055       Err.prln("Resource mising! Is your classpath OK?");
056       ioe.printStackTrace(Err.getPrintWriter());
057     }
058   }//protected void initLocalData()
059 
060   protected void initListeners(){
061     addHyperlinkListener(new HyperlinkListener() {
062       @Override
063       public void hyperlinkUpdate(HyperlinkEvent e){
064         if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED){
065           if (instanceof HTMLFrameHyperlinkEvent) {
066               HTMLFrameHyperlinkEvent  evt = (HTMLFrameHyperlinkEvent)e;
067               HTMLDocument doc = (HTMLDocument)getDocument();
068               doc.processHTMLFrameHyperlinkEvent(evt);
069           }else{
070             try {
071               backUrls.addLast(getPage());
072               forwardUrls.clear();
073               setPage(e.getURL().toExternalForm());
074             }catch (Throwable t){
075               t.printStackTrace(Err.getPrintWriter());
076             }
077           }
078         }else if(e.getEventType() == HyperlinkEvent.EventType.ENTERED){
079           fireStatusChanged(e.getURL().toExternalForm());
080         }else if(e.getEventType() == HyperlinkEvent.EventType.EXITED){
081           fireStatusChanged("");
082         }
083       }//public void hyperlinkUpdate(HyperlinkEvent e)
084     });
085   }//protected void initListeners()
086 
087   public Action getForwardAction(){
088     return forwardAction;
089   }
090 
091   public Action getBackAction(){
092     return backAction;
093   }
094 
095   @Override
096   public void setPage(URL pagethrows IOException{
097     try{
098       super.setPage(page);
099     }catch(Exception e){
100       fireStatusChanged(e.toString());
101       e.printStackTrace(Err.getPrintWriter());
102     }
103     updateEnableState();
104   }
105 
106   class ForwardAction extends AbstractAction{
107     private ForwardAction() throws IOException{
108       super("Forward", MainFrame.getIcon("forward"));
109     }
110 
111     @Override
112     public void actionPerformed(ActionEvent e){
113       backUrls.addLast(getPage());
114       try{
115         setPage(forwardUrls.removeFirst());
116       }catch(IOException ioe){
117         ioe.printStackTrace(Err.getPrintWriter());
118       }
119     }
120   }//class ForwardAction extends AbstractAction
121 
122   class BackAction extends AbstractAction{
123     private BackAction() throws IOException{
124       super("Back", MainFrame.getIcon("back"));
125     }
126 
127     @Override
128     public void actionPerformed(ActionEvent e){
129       forwardUrls.addFirst(getPage());
130       try{
131         setPage(backUrls.removeLast());
132       }catch(IOException ioe){
133         ioe.printStackTrace(Err.getPrintWriter());
134       }
135     }
136   }//class ForwardAction extends AbstractAction
137 
138 
139   /**
140    * Updates the enabled/disabled state for the back/forward actions
141    */
142   protected void updateEnableState(){
143     forwardAction.setEnabled(!forwardUrls.isEmpty());
144     backAction.setEnabled(!backUrls.isEmpty());
145   }
146   public synchronized void removeStatusListener(StatusListener l) {
147     if (statusListeners != null && statusListeners.contains(l)) {
148       @SuppressWarnings("unchecked")
149       Vector<StatusListener> v = (Vector<StatusListener>statusListeners.clone();
150       v.removeElement(l);
151       statusListeners = v;
152     }
153   }
154   public synchronized void addStatusListener(StatusListener l) {
155     @SuppressWarnings("unchecked")
156     Vector<StatusListener> v = statusListeners == null new Vector<StatusListener>(2(Vector<StatusListener>statusListeners.clone();
157     if (!v.contains(l)) {
158       v.addElement(l);
159       statusListeners = v;
160     }
161   }
162 
163   protected LinkedList<URL> backUrls;
164   protected LinkedList<URL> forwardUrls;
165   protected Action backAction;
166   protected Action forwardAction;
167   private transient Vector<StatusListener> statusListeners;
168   protected void fireStatusChanged(String e) {
169     if (statusListeners != null) {
170       Vector<StatusListener> listeners = statusListeners;
171       int count = listeners.size();
172       for (int i = 0; i < count; i++) {
173         listeners.elementAt(i).statusChanged(e);
174       }
175     }
176   }
177 }//public class XJEditorPane extends JEditorPane