Styled Text Components


In Volume 1, we discussed the basic text component classes JTextField and JTextArea. Of course, these classes are very useful for obtaining text input from the user. Another useful class, JEditorPane, displays and edits text in HTML and RTF format. (RTF is the "rich text format" that is used by a number of Microsoft applications for document interchange. It is a poorly documented format that doesn't work well even between Microsoft's own applications. We do not cover the RTF capabilities in this book.)

Frankly, at this point, the JEditorPane is limited. The HTML renderer can display simple files, but it chokes at many complex pages that you typically find on the Web. The HTML editor is limited and unstable.

We think that the perfect application for the JEditorPane is to display program help in HTML format. Because you have control over the help files that you provide, you can stay away from features that the JEditorPane does not display well.

NOTE

For more information on an industrial-strength help system, check out JavaHelp at http://java.sun.com/products/javahelp/index.html.


NOTE

The subclass JTextPane of JEditorPane can hold styled text with special fonts and text formats, as well as embedded components. We do not cover that component in this book. If you need to implement a component that allows users of your program to enter styled text, look at the implementation of the StylePad demo that is included in the JDK.


The program in Example 6-15 contains an editor pane that shows the contents of an HTML page. Type a URL into the text field. The URL must start with http: or file:. Then, click the Load button. The selected HTML page is displayed in the editor pane (see Figure 6-39).

Figure 6-39. The editor pane displaying an HTML page


The hyperlinks are active: If you click on a link, the application loads it. The Back button returns to the previous page.

This program is in fact a very simple browser. Of course, it does not have any of the comfort features, such as page caching or bookmark lists, that you expect from a commercial browser. The editor pane does not even display applets!

If you click on the Editable checkbox, then the editor pane becomes editable. You can type in text and use the BACKSPACE key to delete text. The component also understands the CTRL+X, CTRL+C, and CTRL+V shortcuts for cut, copy, and paste. However, you would have to do quite a bit of programming to add support for fonts and formatting.

When the component is editable, then hyperlinks are not active. Also, with some web pages you can see JavaScript commands, comments, and other tags when edit mode is turned on (see Figure 6-40). The example program lets you investigate the editing feature, but we recommend that you omit that feature in your programs.

Figure 6-40. The editor pane in edit mode


TIP

By default, the JEditorPane is in edit mode. You should call editorPane.setEditable(false) to turn it off.


The features of the editor pane that you saw in the example program are easy to use. You use the setPage method to load a new document. For example,

 JEditorPane editorPane = new JEditorPane(); editorPane.setPage(url); 

The parameter is either a string or a URL object. The JEditorPane class extends the JTextComponent class. Therefore, you can call the setText method as wellit simply displays plain text.

TIP

The API documentation is unclear about whether setPage loads the new document in a separate thread (which is generally what you wantthe JEditorPane is no speed demon). However, you can force loading in a separate thread with the following incantation:

 AbstractDocument doc = (AbstractDocument) editorPane.getDocument(); doc.setAsynchronousLoadPriority(0); 


To listen to hyperlink clicks, you add a HyperlinkListener. The HyperlinkListener interface has a single method, hyperlinkUpdate, that is called when the user moves over or clicks on a link. The method has a parameter of type HyperlinkEvent.

You need to call the getEventType method to find out what kind of event occurred. There are three possible return values:

 HyperlinkEvent.EventType.ACTIVATED HyperlinkEvent.EventType.ENTERED HyperlinkEvent.EventType.EXITED 

The first value indicates that the user clicked on the hyperlink. In that case, you typically want to open the new link. You can use the second and third values to give some visual feedback, such as a tooltip, when the mouse hovers over the link.

NOTE

It is a complete mystery why there aren't three separate methods to handle activation, entry, and exit in the HyperlinkListener interface.


The getURL method of the HyperlinkEvent class returns the URL of the hyperlink. For example, here is how you can install a hyperlink listener that follows the links that a user activates:

 editorPane.addHyperlinkListener(new    HyperlinkListener()    {       public void hyperlinkUpdate(HyperlinkEvent event)       {          if (event.getEventType()             == HyperlinkEvent.EventType.ACTIVATED)          {             try             {                editorPane.setPage(event.getURL());             }             catch (IOException e)             {                editorPane.setText("Exception: " + e);             }          }       }    }); 

The event handler simply gets the URL and updates the editor pane. The setPage method can throw an IOException. In that case, we display an error message as plain text.

The program in Example 6-15 shows all the features that you need to put together an HTML help system. Under the hood, the JEditorPane is even more complex than the tree and table components. However, if you don't need to write a text editor or a renderer of a custom text format, that complexity is hidden from you.

Example 6-15. EditorPaneTest.java
   1. import java.awt.*;   2. import java.awt.event.*;   3. import java.io.*;   4. import java.net.*;   5. import java.util.*;   6. import javax.swing.*;   7. import javax.swing.event.*;   8.   9. /**  10.    This program demonstrates how to display HTML documents  11.    in an editor pane.  12. */  13. public class EditorPaneTest  14. {  15.    public static void main(String[] args)  16.    {  17.       JFrame frame = new EditorPaneFrame();  18.       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  19.       frame.setVisible(true);  20.    }  21. }  22.  23. /**  24.    This frame contains an editor pane, a text field and button  25.    to enter a URL and load a document, and a Back button to  26.    return to a previously loaded document.  27. */  28. class EditorPaneFrame extends JFrame  29. {  30.    public EditorPaneFrame()  31.    {  32.       setTitle("EditorPaneTest");  33.       setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);  34.  35.       final Stack<String> urlStack = new Stack<String>();  36.       final JEditorPane editorPane = new JEditorPane();  37.       final JTextField url = new JTextField(30);  38.  39.       // set up hyperlink listener  40.  41.       editorPane.setEditable(false);  42.       editorPane.addHyperlinkListener(new  43.          HyperlinkListener()  44.          {  45.             public void hyperlinkUpdate(HyperlinkEvent event)  46.             {  47.                if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED)  48.                {  49.                   try  50.                   {  51.                      // remember URL for back button  52.                      urlStack.push(event.getURL().toString());  53.                      // show URL in text field  54.                      url.setText(event.getURL().toString());  55.                      editorPane.setPage(event.getURL());  56.                   }  57.                   catch (IOException e)  58.                   {  59.                      editorPane.setText("Exception: " + e);  60.                   }  61.                }  62.             }  63.          });  64.  65.       // set up checkbox for toggling edit mode  66.  67.       final JCheckBox editable = new JCheckBox();  68.       editable.addActionListener(new  69.          ActionListener()  70.          {  71.             public void actionPerformed(ActionEvent event)  72.             {  73.                editorPane.setEditable(editable.isSelected());  74.             }  75.          });  76.  77.       // set up load button for loading URL  78.  79.       ActionListener listener = new  80.          ActionListener()  81.          {  82.             public void actionPerformed(ActionEvent event)  83.             {  84.                try  85.                {  86.                   // remember URL for back button  87.                   urlStack.push(url.getText());  88.                   editorPane.setPage(url.getText());  89.                }  90.                catch (IOException e)  91.                {  92.                   editorPane.setText("Exception: " + e);  93.                }  94.             }  95.          };  96.  97.       JButton loadButton = new JButton("Load");  98.       loadButton.addActionListener(listener);  99.       url.addActionListener(listener); 100. 101.       // set up back button and button action 102. 103.       JButton backButton = new JButton("Back"); 104.       backButton.addActionListener(new 105.          ActionListener() 106.          { 107.             public void actionPerformed(ActionEvent event) 108.             { 109.                if (urlStack.size() <= 1) return; 110.                try 111.                { 112.                   // get URL from back button 113.                   urlStack.pop(); 114.                   // show URL in text field 115.                   String urlString = urlStack.peek(); 116.                   url.setText(urlString); 117.                   editorPane.setPage(urlString); 118.                } 119.                catch (IOException e) 120.                { 121.                   editorPane.setText("Exception: " + e); 122.                } 123.             } 124.          }); 125. 126.       add(new JScrollPane(editorPane), BorderLayout.CENTER); 127. 128.       // put all control components in a panel 129. 130.       JPanel panel = new JPanel(); 131.       panel.add(new JLabel("URL")); 132.       panel.add(url); 133.       panel.add(loadButton); 134.       panel.add(backButton); 135.       panel.add(new JLabel("Editable")); 136.       panel.add(editable); 137. 138.       add(panel, BorderLayout.SOUTH); 139.    } 140. 141.    private static final int DEFAULT_WIDTH = 600; 142.    private static final int DEFAULT_HEIGHT = 400; 143. } 


 javax.swing.JEditorPane 1.2 

  • void setPage(URL url)

    loads the page from url into the editor pane.

  • void addHyperlinkListener(HyperLinkListener listener)

    adds a hyperlink listener to this editor pane.


 javax.swing.event.HyperlinkListener 1.2 

  • void hyperlinkUpdate(HyperlinkEvent event)

    is called whenever a hyperlink was selected.


 javax.swing.HyperlinkEvent 1.2 

  • URL getURL()

    returns the URL of the selected hyperlink.



    Core JavaT 2 Volume II - Advanced Features
    Building an On Demand Computing Environment with IBM: How to Optimize Your Current Infrastructure for Today and Tomorrow (MaxFacts Guidebook series)
    ISBN: 193164411X
    EAN: 2147483647
    Year: 2003
    Pages: 156
    Authors: Jim Hoskins

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net