23.10 A Custom EditorKit


Although Swing's HTML support is less than ideal, it is sufficient to handle inline help systems and aid in rapid prototyping. Each release of the SDK improves support and usability. It will continue to get better. In the meantime, if you're desperate for serious markup language support, you really should check out XML.

If you're interested in doing your own EditorKit work, look up the more detailed HTMLEditorKit chapters online. You should also check out the javax.swing.text.rtf package. It serves the same basic purpose as the HTML package but reads and writes RTF files. However, be aware that RTF seems to be even more plagued with "acceptable variants" than HTML. Make sure you test your output on an intended target system before rolling out your new commercial editor!

To round out this final section, we'll review the steps involved in creating your own editor kit. These steps include:

  • Creating the EditorKit class

  • Defining the Document type

  • Defining new Actions

  • Creating custom View classes

  • Creating a ViewFactory

  • Creating a "reader" and a "writer"

  • Telling JEditorPane about your new kit

23.10.1 Create the EditorKit Class

First, create your EditorKit class. Depending on the type of documents you're going to support, you can subclass the abstract EditorKit base class or extend any of the existing kits we've covered in this chapter.

Much of the work in creating this class is covered in the steps that follow. In addition to those more complex issues, you should implement the following EditorKit methods:

public abstract Object clone( )

Strangely, the Swing implementations of this method just return a new instance of the editor kit subclass. It is probably a good idea to return a "true clone" here, although this method is not currently used within Swing.

public void install( JEditorPane c)

Implement this method only if you want to access the JEditorPane using your editor kit. One possibility here is to add the kit as a listener of some type.

public void deinstall( JEditorPane c)

Typically, you use this method only if you implement install( ) to add a listener of some sort. This method should remove the listener.

public abstract String getContentType( )

This method should be implemented to describe the type of content your kit handles. The Swing-provided editor kits return text/plain, text/html, and text/rtf. This method is important if you want JEditorPane to be able to use your editor kit automatically when it is asked to display URLs of the appropriate type. When determining which editor kit to use, JEditorPane uses the URLConnection object from the URL passed to its setPage( ) method to determine the content type of the URL.

23.10.2 Define the Document Type

Depending on the complexity of your editor kit, you may need to define a new Document class. The HTMLEditorKit does this, defining HTMLDocument as a subclass of DefaultStyledDocument.

Whether you use an existing document type or create your own, make sure createDefaultDocument( ) returns an instance of the type of document you want your kit to use.

23.10.3 Define New Actions

If you want your kit to assist in the creation of editors for your document type, you may want to define additional Action classes to perform certain activities. The three basic steps for creating any document editor are:

Define the new Action classes

Create any new Action classes you want to provide. Review the discussion of the TextAction and StyledEditorKit.StyledTextAction classes; these may serve as useful base classes for any new Action classes you create.

Define default Action instances

Define instances of your new Action classes (or existing Action classes) that you wish to provide as default actions for the kit. This is typically done by creating a static array. For example:

private static final Action[] defaultActions = {   new MyNewAction(arg1, arg2),   new MyOtherNewAction(arg1) };

Then, implement the getActions( ) method:

public Action[] getActions( ) {   return TextAction.augmentList(super.getActions( ), this.defaultActions); }

This adds your new actions to the set of actions defined by your superclass.

Define constants for default actions

In order for users to take advantage of your new default actions, you need to make the action names publicly available. The common pattern is to define a String constant for each action name. For example:

public static final String MY_NEW_ACTION = "my-new-action"; public static final String ANOTHER_NEW_ACTION = "another-new-action";

The actual values of the String constants should match the Action.NAME properties defined for each of your default actions.

23.10.4 Create Custom View Classes

If you want your documents to be displayed in a special way, you may need to define your own view classes. It's a good idea to take a look at the available classes and see if they do what you need, or if they can be extended to provide the look you want. Also, be sure to take advantage of the static text painting methods provided by the javax.swing.text.Utilities class.

Note that you are not under any obligation to keep a one-to-one mapping from Elements to View objects. It's perfectly reasonable to define a single View that is responsible for a group of elements such as a table cell, row, or the entire table. The trade-off between many simple Views and fewer complex ones (right up to a single View that draws the entire document) is an architectural design choice that you'll make based on the normal considerations of performance, code complexity, and the like.

23.10.5 Create a ViewFactory Interface and View Classes

If you want to control the types of View objects created for the different types of Elements in your documents, implement a ViewFactory . This interface contains one method, create( ). A typical implementation of this interface looks something like this:

class MyFactory implements ViewFactory {   public View create(Element e) {     String name = e.getName( );     if (name != null) {       if (name.equals(AbstractDocument.ContentElementName)) {         return new LabelView(e);       }       if (name.equals(SomeOtherElementName)) {         return new SomeOtherView(e);       }     }     return new LabelView(e); // A default   } }

The key thing is to ensure that the correct type of View is created for any Element types allowed in your documents. Note that you need to write this factory from scratch; there are no existing public factories (except for HTMLEditorKit.HTMLFactory) to subclass.

If you do implement your own ViewFactory, remember to implement the EditorKit.getViewFactory( ) method to return an instance of your factory class.

23.10.6 Create a "Reader" and a "Writer"

Potentially, the most time-consuming and challenging part of creating your own editor kit is defining and implementing a strategy for reading and writing documents in the correct format. For complex document types, it makes the most sense to implement this code in separate classes outside the editor kit.

However you choose to implement the parsing and saving operations (perhaps taking advantage of the AbstractWriter class), you need to provide implementations of the read( ) and write( ) methods (unless the implementations provided by the class you're extending serve your purposes). Unless you have special requirements, you implement only the methods that work with the java.io Reader and Writer classes. If you're extending DefaultEditorKit, the other versions just call these.

Earlier in this chapter, we discussed the strategy of reading and writing styled documents using the built-in Java serialization mechanism. Depending on your needs, this may be a reasonable approach. Keep in mind that if you read in a serialized document, you'll have to copy all the attributes and content over to the document passed in to the read( ) method. While this may be a pain, it may be less trouble than defining your own document format and parser.

23.10.7 Tell JEditorPane About Your New Kit

If you want JEditorPane to use your editor kit when it encounters URLs of the appropriate MIME type, you need to register the kit with the JEditorPane class. This is done by calling either the static method registerEditorKitForContentType( ) or the nonstatic setEditorKitForContentType( ). The first method takes two strings: the content type your kit works with and the class name of your kit. You might call it like this:

JEditorPane.registerEditorKitForContentType("text/foo","mypackage.FooEdKit");

The other option takes the content type and an instance of the kit. For example:

JEditorPane ed = new JEditorPane( ); ed.setEditorKitForContentType("text/foo", new FooEditorKit( ));

If you go with the first version (which applies to all JEditorPane objects), keep in mind that JEditorPane won't know about your kit until this call is made, so you need to be sure to make the call before you expect your kit to be used.

This step is required only if you are using a standard MIME type that the java.net.URLConnection class knows about. This is the class JEditorPane uses to determine which editor kit to use when a new URL is specified. Of course, you can still register your editor kit even if you're not using a well-known MIME type, but you'll also need to call setContentType( ) on your JEditorPane since your document type won't be recognized automatically. The other option is to skip this step altogether and just call setEditorKit( ) on the JEditorPane.

At last, we've come to the close of this multi-chapter novella on the Swing text framework. If you've actually read it from beginning to end, congratulations! You now know everything there is to know about the powerful Swing text architecture. Well, OK, you may not know everything, but at least you know where to start looking.

No matter which road you took to reach this final paragraph, it's important not to let all the complexity scare you away from using the Swing text components. If you just need to do simple things, go back to Chapter 19 and revisit the examples provided there. If your requirements are more demanding, we hope the last four chapters have given you a better understanding of the framework.



Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

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