KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > swingwtx > swing > JEditorPane


1 /*
2    SwingWT
3    Copyright(c)2003-2004, R. Rawson-Tetley
4
5    For more information on distributing and using this program, please
6    see the accompanying "COPYING" file.
7
8    Contact me by electronic mail: bobintetley@users.sourceforge.net
9
10    $Log: JEditorPane.java,v $
11    Revision 1.22 2004/04/30 13:20:43 bobintetley
12    Fix to unrealised peer preferred sizes, forwarding window events to
13    content panes and fix for mouse drag events.
14
15    Revision 1.21 2004/04/28 08:38:11 bobintetley
16    Hierarchy fixes, code cleanup for base classes, additional javadocs and use of flag to identify JComponent descendants with peers
17
18    Revision 1.20 2004/03/18 16:21:37 bobintetley
19    JTextComponent/Caret implementation and fix to JFileChooser for bug in GNU classpath
20
21    Revision 1.19 2004/02/24 09:26:34 bobintetley
22    Better explanation when no Mozilla found
23
24    Revision 1.18 2004/02/24 09:12:17 bobintetley
25    Hyperlink.ENTERED now fires correctly
26
27    Revision 1.17 2004/02/20 10:22:07 bobintetley
28    GCJ/GIJ compatible replacement for StringBuffer.indexOf()
29
30    Revision 1.16 2004/02/12 10:49:45 bobintetley
31    No more ugly runtime exceptions if Mozilla is unavailable
32
33    Revision 1.15 2004/02/12 09:55:53 bobintetley
34    JEditorPane Document support
35
36    Revision 1.14 2004/01/27 09:39:30 bobintetley
37    Text/Document support
38
39    Revision 1.13 2004/01/27 09:05:10 bobintetley
40    ListModel and List Selection implemented. ScrollPane fix so all components
41       scrollable
42
43    Revision 1.12 2003/12/16 17:46:17 bobintetley
44    Additional thread safety methods
45
46    Revision 1.11 2003/12/16 13:14:33 bobintetley
47    Use of SwingWTUtils.isSWTControlAvailable instead of null test
48
49    Revision 1.10 2003/12/15 18:29:57 bobintetley
50    Changed setParent() method to setSwingWTParent() to avoid conflicts with applications
51
52    Revision 1.9 2003/12/15 15:54:25 bobintetley
53    Additional core methods
54
55    Revision 1.8 2003/12/14 09:13:38 bobintetley
56    Added CVS log to source headers
57
58 */

59
60
61 package swingwtx.swing;
62
63 import java.io.IOException JavaDoc;
64 import java.net.URL JavaDoc;
65 import java.util.Iterator JavaDoc;
66 import java.util.Vector JavaDoc;
67
68 import org.eclipse.swt.SWT;
69 import org.eclipse.swt.SWTError;
70 import org.eclipse.swt.browser.Browser;
71 import org.eclipse.swt.browser.LocationEvent;
72 import org.eclipse.swt.browser.LocationListener;
73 import org.eclipse.swt.browser.StatusTextEvent;
74 import org.eclipse.swt.browser.StatusTextListener;
75
76 import swingwt.awt.Color;
77 import swingwtx.swing.text.AttributeSet;
78 import swingwtx.swing.text.BadLocationException;
79 import swingwtx.swing.text.Document;
80 import swingwtx.swing.text.EditorKit;
81 import swingwtx.swing.text.Element;
82 import swingwtx.swing.text.Position;
83 import swingwtx.swing.text.Segment;
84 import swingwtx.swing.text.StyleConstants;
85
86 public class JEditorPane extends swingwtx.swing.text.JTextComponent {
87
88     protected Browser ppeer = null;
89     protected String JavaDoc pUrl = "";
90     protected Color selectionColor = Color.BLACK;
91
92     protected Vector JavaDoc hyperListeners = new Vector JavaDoc();
93     
94     public JEditorPane() {}
95     public JEditorPane(String JavaDoc url) throws IOException JavaDoc { pUrl = url; }
96     public JEditorPane(String JavaDoc type, String JavaDoc text) { pText = text; }
97     public JEditorPane(URL JavaDoc url) throws IOException JavaDoc { pUrl = url.toString(); }
98     
99     public String JavaDoc getText() { return pText; }
100     public void setText(String JavaDoc text) { pText = text; try { handleText(); } catch (Exception JavaDoc e) { e.printStackTrace(); } }
101     public String JavaDoc getContentType() { return "text/html"; }
102     public void setContentType(String JavaDoc contentType) { }
103     public boolean isEditable() { return false; }
104     public void setEditable(boolean b) { /* Can never be editable */ }
105     public void setPage(URL JavaDoc url) throws IOException JavaDoc {
106     // Do nothing if the URL is the same
107
String JavaDoc newUrl = url.toString();
108     if (pUrl.equals(newUrl)) return;
109     pUrl = newUrl;
110         SwingUtilities.invokeAsync(new Runnable JavaDoc() {
111             public void run() {
112                 if (SwingWTUtils.isSWTControlAvailable(ppeer))
113                     ppeer.setUrl(pUrl);
114             }
115         });
116     }
117     public void setPage(String JavaDoc url) throws IOException JavaDoc {
118         setPage(new URL JavaDoc(url));
119     }
120     public void addHyperlinkListener(swingwtx.swing.event.HyperlinkListener l) { hyperListeners.add(l); }
121     public void removeHyperlinkListener(swingwtx.swing.event.HyperlinkListener l) { hyperListeners.remove(l); }
122     
123     public void setCaretPosition(int pos) { }
124     public int getCaretPosition() { return 0; }
125     public int getSelectionStart() { return 0; }
126     public int getSelectionEnd() { return 0; }
127     public EditorKit getEditorKit() { return null; }
128     public void setEditorKit(EditorKit k) { }
129     public void setSelectionColor(Color color) { this.selectionColor = color; }
130     public Color getSelectionColor(){ return selectionColor; }
131     
132     /** Handles dumping text to a temporary file and display via a URL to
133      * behave like Swing. The SWT browser under Win supports this ok, but it
134      * crashes horribly with Mozilla, so I have to do it myself...
135      */

136     private void handleText() throws IOException JavaDoc {
137         setPage(SwingWTUtils.stringToTempFile(pText.getBytes(), "html"));
138     }
139     
140     /** Overriden to calculate non-realised
141      * preferred size.
142      */

143     protected swingwt.awt.Dimension calculatePreferredSize() {
144         // Default 300x200
145
swingwt.awt.Dimension size = new swingwt.awt.Dimension(300, 200);
146         setSize(size);
147         return size;
148     }
149     
150     /**
151      * Once a parent component receives an "add" call for a child, this being
152      * the child, this should be called to tell us to instantiate the peer
153      * and load in any cached properties.
154      */

155     public void setSwingWTParent(swingwt.awt.Container parent) throws Exception JavaDoc {
156         descendantHasPeer = true;
157     try {
158         
159         ppeer = new Browser(parent.getComposite(), SWT.NONE);
160         
161             // Cached properties
162
if (!pText.equals("")) handleText();
163             if (!pUrl.equals("")) ppeer.setUrl(pUrl);
164         
165             registerHyperLinkEvents();
166
167             peer = ppeer;
168             this.parent = parent;
169     }
170     catch (SWTError e) {
171         System.out.println("SwingWT JEditorPane/SWT Browser requires at least Mozilla 1.4 to operate.");
172             System.out.println("If you have it installed, then you need to create the file /etc/gre.conf");
173             System.out.println("and in that file, put the following:\n");
174             System.out.println("[VERSION]");
175             System.out.println("GRE_PATH=MOZILLA_PATH\n");
176             System.out.println("Where VERSION is the version of Mozilla you have (eg: 1.4)");
177             System.out.println("and MOZILLA_PATH is the path to Mozilla - eg: /usr/lib/mozilla-1.4");
178     }
179     }
180     
181     /**
182      * Maps Swing HyperLinkListener events to SWT
183      * equivalents for browsers.
184      */

185     protected void registerHyperLinkEvents() {
186        ppeer.addLocationListener(new LocationListener() {
187             public void changed(LocationEvent event) {
188                 processHyperlinkEvent(event.location, swingwtx.swing.event.HyperlinkEvent.EventType.ACTIVATED);
189             }
190             public void changing(LocationEvent event) {}
191         });
192         ppeer.addStatusTextListener(new StatusTextListener() {
193             public void changed(StatusTextEvent event) {
194                 processHyperlinkEvent(event.text, swingwtx.swing.event.HyperlinkEvent.EventType.ENTERED);
195             }
196         });
197     }
198     
199     protected void processHyperlinkEvent(String JavaDoc location, swingwtx.swing.event.HyperlinkEvent.EventType eventType) {
200         // Create a hyperlink event from the SWT location event
201
URL JavaDoc url = null;
202         try { url = new URL JavaDoc(location); } catch (Exception JavaDoc e) {}
203         swingwtx.swing.event.HyperlinkEvent e = new swingwtx.swing.event.HyperlinkEvent(this, eventType, url, location);
204         Iterator JavaDoc i = hyperListeners.iterator();
205         while (i.hasNext()) {
206             ((swingwtx.swing.event.HyperlinkListener) i.next()).hyperlinkUpdate(e);
207         }
208     }
209     
210     public void setDocument(Document newdoc) {
211       System.err.println("Setting document is NOT implemented yet!");
212     }
213     
214     private EditorPaneHTMLDoc doc = new EditorPaneHTMLDoc();
215     
216     /**
217      * Basic class to handle document positions
218      * @author Robin Rawson-Tetley
219      */

220     private class EditorPaneHTMLDocPosition implements Position {
221         private int offset = 0;
222         public EditorPaneHTMLDocPosition(int pos) { offset = pos; }
223         public int getOffset() { return offset; }
224     }
225     
226     /**
227      * HTML representative document that allows modification
228      * integrated by Rob.
229      *
230      * NB: Marco, you don't need to check whether there is a peer to decide
231      * whether or not to modify text - by changing pText, that will be
232      * loaded into the peer once it is created anyway, so just call
233      * handleText() and forget about it.
234      *
235      * @author Marco Hennings
236      */

237     private class EditorPaneHTMLDoc implements Document {
238         
239         String JavaDoc docText="";
240         
241         public Position getEndPosition() {
242             return new EditorPaneHTMLDocPosition(docText.length());
243         }
244         public Position getStartPosition() {
245             return new EditorPaneHTMLDocPosition(0);
246         }
247         
248         /* (non-Javadoc)
249          * @see swingwtx.swing.text.Document#remove(int, int)
250          */

251         public void remove(int i, int j) {
252             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(docText);
253             buffer.replace(i, j, "");
254             docText = buffer.toString();
255             convertText();
256         }
257
258         private void convertText() {
259             pText = "<HTML><BODY>"+docText+"<A name=\"1\"/></BODY></HTML>";
260             try {
261                 handleText();
262             }
263             catch (IOException JavaDoc e) {
264                 e.printStackTrace();
265             }
266         }
267
268         /* (non-Javadoc)
269          * @see swingwtx.swing.text.Document#insertString(int, java.lang.String, swingwtx.swing.text.AttributeSet)
270          */

271         public void insertString(int i, String JavaDoc string, AttributeSet as) {
272             
273             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(docText);
274             StringBuffer JavaDoc nb = new StringBuffer JavaDoc(string);
275             Color foreground=(Color) as.getAttribute(StyleConstants.ColorConstants.Foreground);
276             int index = SwingWTUtils.getStringBufferIndexOf(nb, ">");
277             while (index >-1) {
278                 nb.replace(index, index+1, "&gt;");
279                 index = SwingWTUtils.getStringBufferIndexOf(nb, ">");
280             }
281             index = SwingWTUtils.getStringBufferIndexOf(nb, "<");
282             while (index >-1){
283                 nb.replace(index, index+1, "&lt;");
284                 SwingWTUtils.getStringBufferIndexOf(nb, "<");
285             }
286
287             SwingWTUtils.getStringBufferIndexOf(nb, "http://");
288             while (index > -1) {
289                 int end = Math.min(SwingWTUtils.getStringBufferIndexOf(nb, " ", index) ,SwingWTUtils.getStringBufferIndexOf(nb, "\n", index) );
290                 if(end==-1)
291                     end =nb.length()-1;
292                 String JavaDoc url=nb.substring(index, end);
293                 nb.replace(index, end, "<A HREF=\""+url+"\" " +
294                         //"target=\"_blank\"" +
295
">"+url+"</A> ");
296                 index = SwingWTUtils.getStringBufferIndexOf(nb, "http://", end + (end-index) + 32 );
297             }
298
299             if (foreground!=null){
300                 nb.insert(0, "<font color=\""+encodeColor(foreground)+"\">");
301                 nb.append("</font> ");
302             }
303             index = SwingWTUtils.getStringBufferIndexOf(nb, "\n");
304             while (index >-1){
305                 nb.replace(index, index+1, "<br> ");
306                 SwingWTUtils.getStringBufferIndexOf(nb, "\n");
307             }
308
309             if(i<=0)
310                 buffer.append(nb.toString());
311             else
312                 buffer.insert(i,nb.toString());
313             docText = buffer.toString();
314             convertText();
315             
316         }
317
318         private String JavaDoc encodeColor(Color foreground) {
319             return "#"+Integer.toHexString(foreground.getRed())+Integer.toHexString(foreground.getGreen())+Integer.toHexString(foreground.getBlue());
320         }
321          
322         public void addDocumentListener(swingwtx.swing.event.DocumentListener listener) { }
323         public void addUndoableEditListener(swingwtx.swing.event.UndoableEditListener listener) { }
324         public Position createPosition(int offs) throws BadLocationException { return new EditorPaneHTMLDocPosition(offs); }
325         public Element getDefaultRootElement() { return null; }
326         public int getLength() {return docText.length(); }
327         public Object JavaDoc getProperty(Object JavaDoc key) { return null; }
328         public Element[] getRootElements() { return null; }
329         public String JavaDoc getText(int offset, int length) throws BadLocationException {
330             String JavaDoc ret = null;
331             try {
332                 ret = docText.substring(offset, offset+length);
333             }
334             catch (StringIndexOutOfBoundsException JavaDoc e) { throw new BadLocationException("Invalid range", offset); }
335             return ret;
336         }
337         public void getText(int offset, int length, Segment txt) throws BadLocationException {
338             String JavaDoc ret = null;
339             try {
340                 ret = docText.substring(offset, offset+length);
341             }
342             catch (StringIndexOutOfBoundsException JavaDoc e) { throw new BadLocationException("Invalid range", offset); }
343         txt.array = docText.toCharArray();
344             txt.offset = offset;
345             txt.count = length;
346         }
347         public void putProperty(Object JavaDoc key, Object JavaDoc value) { }
348         public void removeDocumentListener(swingwtx.swing.event.DocumentListener listener) { }
349         public void removeUndoableEditListener(swingwtx.swing.event.UndoableEditListener listener) { }
350         public void render(Runnable JavaDoc r) { }
351         
352     }
353     
354     public Document getDocument() {
355         return doc;
356     }
357     
358 }
359
Popular Tags