JEditorPanepublic class JEditorPane extends JTextComponent A text component to edit various kinds of content.
You can find how-to information and examples of using editor panes in
Using Text Components,
a section in The Java Tutorial.
This component uses implementations of the
EditorKit to accomplish its behavior. It effectively
morphs into the proper kind of text editor for the kind
of content it is given. The content type that editor is bound
to at any given time is determined by the EditorKit currently
installed. If the content is set to a new URL, its type is used
to determine the EditorKit that should be used to
load the content.
By default, the following types of content are known:
- text/plain
- Plain text, which is the default the type given isn't
recognized. The kit used in this case is an extension of
DefaultEditorKit that produces a wrapped plain text view.
- text/html
- HTML text. The kit used in this case is the class
javax.swing.text.html.HTMLEditorKit
which provides HTML 3.2 support.
- text/rtf
- RTF text. The kit used in this case is the class
javax.swing.text.rtf.RTFEditorKit
which provides a limited support of the Rich Text Format.
There are several ways to load content into this component.
-
The setText method can be used to initialize
the component from a string. In this case the current
EditorKit will be used, and the content type will be
expected to be of this type.
-
The read method can be used to initialize the
component from a
Reader . Note that if the content type is HTML,
relative references (e.g. for things like images) can't be resolved
unless the <base> tag is used or the Base property
on HTMLDocument is set.
In this case the current EditorKit will be used,
and the content type will be expected to be of this type.
-
The setPage method can be used to initialize
the component from a URL. In this case, the content type will be
determined from the URL, and the registered
EditorKit
for that content type will be set.
Some kinds of content may provide hyperlink support by generating
hyperlink events. The HTML EditorKit will generate
hyperlink events if the JEditorPane is not editable
(JEditorPane.setEditable(false); has been called).
If HTML frames are embedded in the document, the typical response would be
to change a portion of the current document. The following code
fragment is a possible hyperlink listener implementation, that treats
HTML frame events specially, and simply displays any other activated
hyperlinks.
class Hyperactive implements HyperlinkListener {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
JEditorPane pane = (JEditorPane) e.getSource();
if (e instanceof HTMLFrameHyperlinkEvent) {
HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent)e;
HTMLDocument doc = (HTMLDocument)pane.getDocument();
doc.processHTMLFrameHyperlinkEvent(evt);
} else {
try {
pane.setPage(e.getURL());
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
}
For information on customizing how text/html is rendered please see
{@link #W3C_LENGTH_UNITS} and {@link #HONOR_DISPLAY_PROPERTIES}
Culturally dependent information in some documents is handled through
a mechanism called character encoding. Character encoding is an
unambiguous mapping of the members of a character set (letters, ideographs,
digits, symbols, or control functions) to specific numeric code values. It
represents the way the file is stored. Example character encodings are
ISO-8859-1, ISO-8859-5, Shift-jis, Euc-jp, and UTF-8. When the file is
passed to an user agent (JEditorPane ) it is converted to
the document character set (ISO-10646 aka Unicode).
There are multiple ways to get a character set mapping to happen
with JEditorPane .
-
One way is to specify the character set as a parameter of the MIME
type. This will be established by a call to the
setContentType method. If the content
is loaded by the setPage method the content
type will have been set according to the specification of the URL.
It the file is loaded directly, the content type would be expected to
have been set prior to loading.
-
Another way the character set can be specified is in the document itself.
This requires reading the document prior to determining the character set
that is desired. To handle this, it is expected that the
EditorKit .read operation throw a
ChangedCharSetException which will
be caught. The read is then restarted with a new Reader that uses
the character set specified in the ChangedCharSetException
(which is an IOException ).
Newlines
For a discussion on how newlines are handled, see
DefaultEditorKit.
Warning:
Serialized objects of this class will not be compatible with
future Swing releases. The current serialization support is
appropriate for short term storage or RMI between applications running
the same version of Swing. As of 1.4, support for long term storage
of all JavaBeansTM
has been added to the java.beans package.
Please see {@link java.beans.XMLEncoder}. |
Fields Summary |
---|
PageStream | loadingStream currently loading asynchronously (potentially cancelable).
Access to this variable should be synchronized. | private EditorKit | kitCurrent content binding of the editor. | private Hashtable | pageProperties | private Hashtable | typeHandlersTable of registered type handlers for this editor. | private static final Object | kitRegistryKey | private static final Object | kitTypeRegistryKey | private static final Object | kitLoaderRegistryKey | private static final String | uiClassID | public static final String | W3C_LENGTH_UNITSKey for a client property used to indicate whether
w3c compliant length units are used for html rendering.
By default this is not enabled; to enable
it set the client {@link putClientProperty property} with this name
to Boolean.TRUE . | public static final String | HONOR_DISPLAY_PROPERTIESKey for a client property used to indicate whether
the default font and foreground color from the component are
used if a font or foreground color is not specified in the styled
text.
The default varies based on the look and feel;
to enable it set the client {@link putClientProperty property} with
this name to Boolean.TRUE . |
Constructors Summary |
---|
public JEditorPane()Creates a new JEditorPane .
The document model is set to null .
super();
setFocusCycleRoot(true);
setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {
if (focusCycleRoot != JEditorPane.this ||
(!isEditable() && getComponentCount() > 0)) {
return super.getComponentAfter(focusCycleRoot,
aComponent);
} else {
Container rootAncestor = getFocusCycleRootAncestor();
return (rootAncestor != null)
? rootAncestor.getFocusTraversalPolicy().
getComponentAfter(rootAncestor,
JEditorPane.this)
: null;
}
}
public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {
if (focusCycleRoot != JEditorPane.this ||
(!isEditable() && getComponentCount() > 0)) {
return super.getComponentBefore(focusCycleRoot,
aComponent);
} else {
Container rootAncestor = getFocusCycleRootAncestor();
return (rootAncestor != null)
? rootAncestor.getFocusTraversalPolicy().
getComponentBefore(rootAncestor,
JEditorPane.this)
: null;
}
}
public Component getDefaultComponent(Container focusCycleRoot)
{
return (focusCycleRoot != JEditorPane.this ||
(!isEditable() && getComponentCount() > 0))
? super.getDefaultComponent(focusCycleRoot)
: null;
}
protected boolean accept(Component aComponent) {
return (aComponent != JEditorPane.this)
? super.accept(aComponent)
: false;
}
});
LookAndFeel.installProperty(this,
"focusTraversalKeysForward",
JComponent.
getManagingFocusForwardTraversalKeys());
LookAndFeel.installProperty(this,
"focusTraversalKeysBackward",
JComponent.
getManagingFocusBackwardTraversalKeys());
| public JEditorPane(URL initialPage)Creates a JEditorPane based on a specified URL for input.
this();
setPage(initialPage);
| public JEditorPane(String url)Creates a JEditorPane based on a string containing
a URL specification.
this();
setPage(url);
| public JEditorPane(String type, String text)Creates a JEditorPane that has been initialized
to the given text. This is a convenience constructor that calls the
setContentType and setText methods.
this();
setContentType(type);
setText(text);
|
Methods Summary |
---|
public synchronized void | addHyperlinkListener(javax.swing.event.HyperlinkListener listener)Adds a hyperlink listener for notification of any changes, for example
when a link is selected and entered.
listenerList.add(HyperlinkListener.class, listener);
| protected javax.swing.text.EditorKit | createDefaultEditorKit()Creates the default editor kit (PlainEditorKit ) for when
the component is first created.
return new PlainEditorKit();
| public static javax.swing.text.EditorKit | createEditorKitForContentType(java.lang.String type)Creates a handler for the given type from the default registry
of editor kits. The registry is created if necessary. If the
registered class has not yet been loaded, an attempt
is made to dynamically load the prototype of the kit for the
given type. If the type was registered with a ClassLoader ,
that ClassLoader will be used to load the prototype.
If there was no registered ClassLoader ,
Class.forName will be used to load the prototype.
Once a prototype EditorKit instance is successfully
located, it is cloned and the clone is returned.
EditorKit k = null;
Hashtable kitRegistry = getKitRegisty();
k = (EditorKit) kitRegistry.get(type);
if (k == null) {
// try to dynamically load the support
String classname = (String) getKitTypeRegistry().get(type);
ClassLoader loader = (ClassLoader) getKitLoaderRegistry().get(type);
try {
Class c;
if (loader != null) {
c = loader.loadClass(classname);
} else {
// Will only happen if developer has invoked
// registerEditorKitForContentType(type, class, null).
c = Class.forName(classname, true, Thread.currentThread().
getContextClassLoader());
}
k = (EditorKit) c.newInstance();
kitRegistry.put(type, k);
} catch (Throwable e) {
k = null;
}
}
// create a copy of the prototype or null if there
// is no prototype.
if (k != null) {
return (EditorKit) k.clone();
}
return null;
| public void | fireHyperlinkUpdate(javax.swing.event.HyperlinkEvent e)Notifies all listeners that have registered interest for
notification on this event type. This is normally called
by the currently installed EditorKit if a content type
that supports hyperlinks is currently active and there
was activity with a link. The listener list is processed
last to first.
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==HyperlinkListener.class) {
((HyperlinkListener)listeners[i+1]).hyperlinkUpdate(e);
}
}
| public javax.accessibility.AccessibleContext | getAccessibleContext()Gets the AccessibleContext associated with this JEditorPane.
For editor panes, the AccessibleContext takes the form of an
AccessibleJEditorPane.
A new AccessibleJEditorPane instance is created if necessary.
if (accessibleContext == null) {
if (JEditorPane.this.getEditorKit() instanceof HTMLEditorKit) {
accessibleContext = new AccessibleJEditorPaneHTML();
} else {
accessibleContext = new AccessibleJEditorPane();
}
}
return accessibleContext;
| public final java.lang.String | getContentType()Gets the type of content that this editor
is currently set to deal with. This is
defined to be the type associated with the
currently installed EditorKit .
return (kit != null) ? kit.getContentType() : null;
| public javax.swing.text.EditorKit | getEditorKit()Fetches the currently installed kit for handling content.
createDefaultEditorKit is called to set up a default
if necessary.
if (kit == null) {
kit = createDefaultEditorKit();
}
return kit;
| public static java.lang.String | getEditorKitClassNameForContentType(java.lang.String type)Returns the currently registered EditorKit
class name for the type type .
return (String)getKitTypeRegistry().get(type);
| public javax.swing.text.EditorKit | getEditorKitForContentType(java.lang.String type)Fetches the editor kit to use for the given type
of content. This is called when a type is requested
that doesn't match the currently installed type.
If the component doesn't have an EditorKit registered
for the given type, it will try to create an
EditorKit from the default EditorKit registry.
If that fails, a PlainEditorKit is used on the
assumption that all text documents can be represented
as plain text.
This method can be reimplemented to use some
other kind of type registry. This can
be reimplemented to use the Java Activation
Framework, for example.
if (typeHandlers == null) {
typeHandlers = new Hashtable(3);
}
EditorKit k = (EditorKit) typeHandlers.get(type);
if (k == null) {
k = createEditorKitForContentType(type);
if (k != null) {
setEditorKitForContentType(type, k);
}
}
if (k == null) {
k = createDefaultEditorKit();
}
return k;
| public synchronized javax.swing.event.HyperlinkListener[] | getHyperlinkListeners()Returns an array of all the HyperLinkListener s added
to this JEditorPane with addHyperlinkListener().
return (HyperlinkListener[])listenerList.getListeners(
HyperlinkListener.class);
| private static java.util.Hashtable | getKitLoaderRegistry()
loadDefaultKitsIfNecessary();
return (Hashtable)SwingUtilities.appContextGet(kitLoaderRegistryKey);
| private static java.util.Hashtable | getKitRegisty()
Hashtable ht = (Hashtable)SwingUtilities.appContextGet(kitRegistryKey);
if (ht == null) {
ht = new Hashtable(3);
SwingUtilities.appContextPut(kitRegistryKey, ht);
}
return ht;
| private static java.util.Hashtable | getKitTypeRegistry()
loadDefaultKitsIfNecessary();
return (Hashtable)SwingUtilities.appContextGet(kitTypeRegistryKey);
| public java.net.URL | getPage()Gets the current URL being displayed. If a URL was
not specified in the creation of the document, this
will return null , and relative URL's will not be
resolved.
return (URL) getDocument().getProperty(Document.StreamDescriptionProperty);
| public java.awt.Dimension | getPreferredSize()Returns the preferred size for the JEditorPane .
The preferred size for JEditorPane is slightly altered
from the preferred size of the superclass. If the size
of the viewport has become smaller than the minimum size
of the component, the scrollable definition for tracking
width or height will turn to false. The default viewport
layout will give the preferred size, and that is not desired
in the case where the scrollable is tracking. In that case
the normal preferred size is adjusted to the
minimum size. This allows things like HTML tables to
shrink down to their minimum size and then be laid out at
their minimum size, refusing to shrink any further.
Dimension d = super.getPreferredSize();
if (getParent() instanceof JViewport) {
JViewport port = (JViewport)getParent();
TextUI ui = getUI();
int prefWidth = d.width;
int prefHeight = d.height;
if (! getScrollableTracksViewportWidth()) {
int w = port.getWidth();
Dimension min = ui.getMinimumSize(this);
if (w != 0 && w < min.width) {
// Only adjust to min if we have a valid size
prefWidth = min.width;
}
}
if (! getScrollableTracksViewportHeight()) {
int h = port.getHeight();
Dimension min = ui.getMinimumSize(this);
if (h != 0 && h < min.height) {
// Only adjust to min if we have a valid size
prefHeight = min.height;
}
}
if (prefWidth != d.width || prefHeight != d.height) {
d = new Dimension(prefWidth, prefHeight);
}
}
return d;
| public boolean | getScrollableTracksViewportHeight()Returns true if a viewport should always force the height of this
Scrollable to match the height of the viewport.
if (getParent() instanceof JViewport) {
JViewport port = (JViewport)getParent();
TextUI ui = getUI();
int h = port.getHeight();
Dimension min = ui.getMinimumSize(this);
if (h >= min.height) {
Dimension max = ui.getMaximumSize(this);
if (h <= max.height) {
return true;
}
}
}
return false;
| public boolean | getScrollableTracksViewportWidth()Returns true if a viewport should always force the width of this
Scrollable to match the width of the viewport.
if (getParent() instanceof JViewport) {
JViewport port = (JViewport)getParent();
TextUI ui = getUI();
int w = port.getWidth();
Dimension min = ui.getMinimumSize(this);
Dimension max = ui.getMaximumSize(this);
if ((w >= min.width) && (w <= max.width)) {
return true;
}
}
return false;
| protected java.io.InputStream | getStream(java.net.URL page)Fetches a stream for the given URL, which is about to
be loaded by the setPage method. By
default, this simply opens the URL and returns the
stream. This can be reimplemented to do useful things
like fetch the stream from a cache, monitor the progress
of the stream, etc.
This method is expected to have the the side effect of
establishing the content type, and therefore setting the
appropriate EditorKit to use for loading the stream.
If this the stream was an http connection, redirects
will be followed and the resulting URL will be set as
the Document.StreamDescriptionProperty so that relative
URL's can be properly resolved.
URLConnection conn = page.openConnection();
if (conn instanceof HttpURLConnection) {
HttpURLConnection hconn = (HttpURLConnection) conn;
hconn.setInstanceFollowRedirects(false);
int response = hconn.getResponseCode();
boolean redirect = (response >= 300 && response <= 399);
/*
* In the case of a redirect, we want to actually change the URL
* that was input to the new, redirected URL
*/
if (redirect) {
String loc = conn.getHeaderField("Location");
if (loc.startsWith("http", 0)) {
page = new URL(loc);
} else {
page = new URL(page, loc);
}
return getStream(page);
}
}
if (pageProperties == null) {
pageProperties = new Hashtable();
}
String type = conn.getContentType();
if (type != null) {
setContentType(type);
pageProperties.put("content-type", type);
}
pageProperties.put(Document.StreamDescriptionProperty, page);
String enc = conn.getContentEncoding();
if (enc != null) {
pageProperties.put("content-encoding", enc);
}
InputStream in = conn.getInputStream();
return in;
| public java.lang.String | getText()Returns the text contained in this TextComponent
in terms of the
content type of this editor. If an exception is thrown while
attempting to retrieve the text, null will be returned.
This is implemented to call JTextComponent.write with
a StringWriter .
String txt;
try {
StringWriter buf = new StringWriter();
write(buf);
txt = buf.toString();
} catch (IOException ioe) {
txt = null;
}
return txt;
| public java.lang.String | getUIClassID()Gets the class ID for the UI.
return uiClassID;
| private static void | loadDefaultKitsIfNecessary()This is invoked every time the registries are accessed. Loading
is done this way instead of via a static as the static is only
called once when running in plugin resulting in the entries only
appearing in the first applet.
if (SwingUtilities.appContextGet(kitTypeRegistryKey) == null) {
Hashtable ht = new Hashtable();
SwingUtilities.appContextPut(kitTypeRegistryKey, ht);
ht = new Hashtable();
SwingUtilities.appContextPut(kitLoaderRegistryKey, ht);
registerEditorKitForContentType("text/plain",
"javax.swing.JEditorPane$PlainEditorKit");
registerEditorKitForContentType("text/html",
"javax.swing.text.html.HTMLEditorKit");
registerEditorKitForContentType("text/rtf",
"javax.swing.text.rtf.RTFEditorKit");
registerEditorKitForContentType("application/rtf",
"javax.swing.text.rtf.RTFEditorKit");
}
| protected java.lang.String | paramString()Returns a string representation of this JEditorPane .
This method
is intended to be used only for debugging purposes, and the
content and format of the returned string may vary between
implementations. The returned string may be empty but may not
be null .
String kitString = (kit != null ?
kit.toString() : "");
String typeHandlersString = (typeHandlers != null ?
typeHandlers.toString() : "");
return super.paramString() +
",kit=" + kitString +
",typeHandlers=" + typeHandlersString;
| public void | read(java.io.InputStream in, java.lang.Object desc)This method initializes from a stream. If the kit is
set to be of type HTMLEditorKit , and the
desc parameter is an HTMLDocument ,
then it invokes the HTMLEditorKit to initiate
the read. Otherwise it calls the superclass
method which loads the model as plain text.
if (desc instanceof HTMLDocument &&
kit instanceof HTMLEditorKit) {
HTMLDocument hdoc = (HTMLDocument) desc;
setDocument(hdoc);
read(in, hdoc);
} else {
String charset = (String) getClientProperty("charset");
Reader r = (charset != null) ? new InputStreamReader(in, charset) :
new InputStreamReader(in);
super.read(r, desc);
}
| void | read(java.io.InputStream in, javax.swing.text.Document doc)This method invokes the EditorKit to initiate a
read. In the case where a ChangedCharSetException
is thrown this exception will contain the new CharSet.
Therefore the read operation
is then restarted after building a new Reader with the new charset.
try {
String charset = (String) getClientProperty("charset");
Reader r = (charset != null) ? new InputStreamReader(in, charset) :
new InputStreamReader(in);
kit.read(r, doc, 0);
} catch (BadLocationException e) {
throw new IOException(e.getMessage());
} catch (ChangedCharSetException e1) {
String charSetSpec = e1.getCharSetSpec();
if (e1.keyEqualsCharSet()) {
putClientProperty("charset", charSetSpec);
} else {
setCharsetFromContentTypeParameters(charSetSpec);
}
in.close();
URL url = (URL)doc.getProperty(Document.StreamDescriptionProperty);
URLConnection conn = url.openConnection();
in = conn.getInputStream();
try {
doc.remove(0, doc.getLength());
} catch (BadLocationException e) {}
doc.putProperty("IgnoreCharsetDirective", Boolean.valueOf(true));
read(in, doc);
}
| public static void | registerEditorKitForContentType(java.lang.String type, java.lang.String classname)Establishes the default bindings of type to
classname .
The class will be dynamically loaded later when actually
needed, and can be safely changed before attempted uses
to avoid loading unwanted classes. The prototype
EditorKit will be loaded with Class.forName
when registered with this method.
registerEditorKitForContentType(type, classname,Thread.currentThread().
getContextClassLoader());
| public static void | registerEditorKitForContentType(java.lang.String type, java.lang.String classname, java.lang.ClassLoader loader)Establishes the default bindings of type to
classname .
The class will be dynamically loaded later when actually
needed using the given ClassLoader ,
and can be safely changed
before attempted uses to avoid loading unwanted classes.
getKitTypeRegistry().put(type, classname);
getKitLoaderRegistry().put(type, loader);
getKitRegisty().remove(type);
| public synchronized void | removeHyperlinkListener(javax.swing.event.HyperlinkListener listener)Removes a hyperlink listener.
listenerList.remove(HyperlinkListener.class, listener);
| public void | replaceSelection(java.lang.String content)Replaces the currently selected content with new content
represented by the given string. If there is no selection
this amounts to an insert of the given text. If there
is no replacement text (i.e. the content string is empty
or null ) this amounts to a removal of the
current selection. The replacement text will have the
attributes currently defined for input. If the component is not
editable, beep and return.
This method is thread safe, although most Swing methods
are not. Please see
Threads
and Swing for more information.
if (! isEditable()) {
UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
return;
}
EditorKit kit = getEditorKit();
if(kit instanceof StyledEditorKit) {
try {
Document doc = getDocument();
Caret caret = getCaret();
int p0 = Math.min(caret.getDot(), caret.getMark());
int p1 = Math.max(caret.getDot(), caret.getMark());
if (doc instanceof AbstractDocument) {
((AbstractDocument)doc).replace(p0, p1 - p0, content,
((StyledEditorKit)kit).getInputAttributes());
}
else {
if (p0 != p1) {
doc.remove(p0, p1 - p0);
}
if (content != null && content.length() > 0) {
doc.insertString(p0, content, ((StyledEditorKit)kit).
getInputAttributes());
}
}
} catch (BadLocationException e) {
UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
}
}
else {
super.replaceSelection(content);
}
| public void | scrollToReference(java.lang.String reference)Scrolls the view to the given reference location
(that is, the value returned by the UL.getRef
method for the URL being displayed). By default, this
method only knows how to locate a reference in an
HTMLDocument. The implementation calls the
scrollRectToVisible method to
accomplish the actual scrolling. If scrolling to a
reference location is needed for document types other
than HTML, this method should be reimplemented.
This method will have no effect if the component
is not visible.
Document d = getDocument();
if (d instanceof HTMLDocument) {
HTMLDocument doc = (HTMLDocument) d;
HTMLDocument.Iterator iter = doc.getIterator(HTML.Tag.A);
for (; iter.isValid(); iter.next()) {
AttributeSet a = iter.getAttributes();
String nm = (String) a.getAttribute(HTML.Attribute.NAME);
if ((nm != null) && nm.equals(reference)) {
// found a matching reference in the document.
try {
Rectangle r = modelToView(iter.getStartOffset());
if (r != null) {
// the view is visible, scroll it to the
// center of the current visible area.
Rectangle vis = getVisibleRect();
//r.y -= (vis.height / 2);
r.height = vis.height;
scrollRectToVisible(r);
}
} catch (BadLocationException ble) {
UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
}
}
}
}
| private void | setCharsetFromContentTypeParameters(java.lang.String paramlist)This method gets the charset information specified as part
of the content type in the http header information.
String charset = null;
try {
// paramlist is handed to us with a leading ';', strip it.
int semi = paramlist.indexOf(';");
if (semi > -1 && semi < paramlist.length()-1) {
paramlist = paramlist.substring(semi + 1);
}
if (paramlist.length() > 0) {
// parse the paramlist into attr-value pairs & get the
// charset pair's value
HeaderParser hdrParser = new HeaderParser(paramlist);
charset = hdrParser.findValue("charset");
if (charset != null) {
putClientProperty("charset", charset);
}
}
}
catch (IndexOutOfBoundsException e) {
// malformed parameter list, use charset we have
}
catch (NullPointerException e) {
// malformed parameter list, use charset we have
}
catch (Exception e) {
// malformed parameter list, use charset we have; but complain
System.err.println("JEditorPane.getCharsetFromContentTypeParameters failed on: " + paramlist);
e.printStackTrace();
}
| public final void | setContentType(java.lang.String type)Sets the type of content that this editor
handles. This calls getEditorKitForContentType ,
and then setEditorKit if an editor kit can
be successfully located. This is mostly convenience method
that can be used as an alternative to calling
setEditorKit directly.
If there is a charset definition specified as a parameter
of the content type specification, it will be used when
loading input streams using the associated EditorKit .
For example if the type is specified as
text/html; charset=EUC-JP the content
will be loaded using the EditorKit registered for
text/html and the Reader provided to
the EditorKit to load unicode into the document will
use the EUC-JP charset for translating
to unicode. If the type is not recognized, the content
will be loaded using the EditorKit registered
for plain text, text/plain .
// The type could have optional info is part of it,
// for example some charset info. We need to strip that
// of and save it.
int parm = type.indexOf(";");
if (parm > -1) {
// Save the paramList.
String paramList = type.substring(parm);
// update the content type string.
type = type.substring(0, parm).trim();
if (type.toLowerCase().startsWith("text/")) {
setCharsetFromContentTypeParameters(paramList);
}
}
if ((kit == null) || (! type.equals(kit.getContentType()))) {
EditorKit k = getEditorKitForContentType(type);
if (k != null) {
setEditorKit(k);
}
}
| public void | setEditorKit(javax.swing.text.EditorKit kit)Sets the currently installed kit for handling
content. This is the bound property that
establishes the content type of the editor.
Any old kit is first deinstalled, then if kit is
non-null ,
the new kit is installed, and a default document created for it.
A PropertyChange event ("editorKit") is always fired when
setEditorKit is called.
NOTE: This has the side effect of changing the model,
because the EditorKit is the source of how a
particular type
of content is modeled. This method will cause setDocument
to be called on behalf of the caller to ensure integrity
of the internal state.
EditorKit old = this.kit;
if (old != null) {
old.deinstall(this);
}
this.kit = kit;
if (this.kit != null) {
this.kit.install(this);
setDocument(this.kit.createDefaultDocument());
}
firePropertyChange("editorKit", old, kit);
| public void | setEditorKitForContentType(java.lang.String type, javax.swing.text.EditorKit k)Directly sets the editor kit to use for the given type. A
look-and-feel implementation might use this in conjunction
with createEditorKitForContentType to install handlers for
content types with a look-and-feel bias.
if (typeHandlers == null) {
typeHandlers = new Hashtable(3);
}
typeHandlers.put(type, k);
| public void | setPage(java.lang.String url)Sets the current URL being displayed.
if (url == null) {
throw new IOException("invalid url");
}
URL page = new URL(url);
setPage(page);
| public void | setPage(java.net.URL page)Sets the current URL being displayed. The content type of the
pane is set, and if the editor kit for the pane is
non-null , then
a new default document is created and the URL is read into it.
If the URL contains and reference location, the location will
be scrolled to by calling the scrollToReference
method. If the desired URL is the one currently being displayed,
the document will not be reloaded. To force a document
reload it is necessary to clear the stream description property
of the document. The following code shows how this can be done:
Document doc = jEditorPane.getDocument();
doc.putProperty(Document.StreamDescriptionProperty, null);
If the desired URL is not the one currently being
displayed, the getStream method is called to
give subclasses control over the stream provided.
This may load either synchronously or asynchronously
depending upon the document returned by the EditorKit .
If the Document is of type
AbstractDocument and has a value returned by
AbstractDocument.getAsynchronousLoadPriority
that is greater than or equal to zero, the page will be
loaded on a separate thread using that priority.
If the document is loaded synchronously, it will be
filled in with the stream prior to being installed into
the editor with a call to setDocument , which
is bound and will fire a property change event. If an
IOException is thrown the partially loaded
document will
be discarded and neither the document or page property
change events will be fired. If the document is
successfully loaded and installed, a view will be
built for it by the UI which will then be scrolled if
necessary, and then the page property change event
will be fired.
If the document is loaded asynchronously, the document
will be installed into the editor immediately using a
call to setDocument which will fire a
document property change event, then a thread will be
created which will begin doing the actual loading.
In this case, the page property change event will not be
fired by the call to this method directly, but rather will be
fired when the thread doing the loading has finished.
It will also be fired on the event-dispatch thread.
Since the calling thread can not throw an IOException
in the event of failure on the other thread, the page
property change event will be fired when the other
thread is done whether the load was successful or not.
if (page == null) {
throw new IOException("invalid url");
}
URL loaded = getPage();
// reset scrollbar
if (!page.equals(loaded) && page.getRef() == null) {
scrollRectToVisible(new Rectangle(0,0,1,1));
}
boolean reloaded = false;
if ((loaded == null) || (! loaded.sameFile(page))) {
// different url, load the new content
InputStream in = getStream(page);
if (kit != null) {
Document doc = kit.createDefaultDocument();
if (pageProperties != null) {
// transfer properties discovered in stream to the
// document property collection.
for (Enumeration e = pageProperties.keys(); e.hasMoreElements() ;) {
Object key = e.nextElement();
doc.putProperty(key, pageProperties.get(key));
}
pageProperties.clear();
}
if (doc.getProperty(Document.StreamDescriptionProperty) == null) {
doc.putProperty(Document.StreamDescriptionProperty, page);
}
// At this point, one could either load up the model with no
// view notifications slowing it down (i.e. best synchronous
// behavior) or set the model and start to feed it on a separate
// thread (best asynchronous behavior).
synchronized(this) {
if (loading != null) {
// we are loading asynchronously, so we need to cancel
// the old stream.
loading.cancel();
loading = null;
}
}
if (doc instanceof AbstractDocument) {
AbstractDocument adoc = (AbstractDocument) doc;
int p = adoc.getAsynchronousLoadPriority();
if (p >= 0) {
// load asynchronously
setDocument(doc);
synchronized(this) {
loading = new PageStream(in);
Thread pl = new PageLoader(doc, loading, p, loaded, page);
pl.start();
}
return;
}
}
read(in, doc);
setDocument(doc);
reloaded = true;
}
}
final String reference = page.getRef();
if (reference != null) {
if (!reloaded) {
scrollToReference(reference);
}
else {
// Have to scroll after painted.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
scrollToReference(reference);
}
});
}
getDocument().putProperty(Document.StreamDescriptionProperty, page);
}
firePropertyChange("page", loaded, page);
| public void | setText(java.lang.String t)Sets the text of this TextComponent to the specified
content,
which is expected to be in the format of the content type of
this editor. For example, if the type is set to text/html
the string should be specified in terms of HTML.
This is implemented to remove the contents of the current document,
and replace them by parsing the given string using the current
EditorKit . This gives the semantics of the
superclass by not changing
out the model, while supporting the content type currently set on
this component. The assumption is that the previous content is
relatively
small, and that the previous content doesn't have side effects.
Both of those assumptions can be violated and cause undesirable results.
To avoid this, create a new document,
getEditorKit().createDefaultDocument() , and replace the
existing Document with the new one. You are then assured the
previous Document won't have any lingering state.
-
Leaving the existing model in place means that the old view will be
torn down, and a new view created, where replacing the document would
avoid the tear down of the old view.
-
Some formats (such as HTML) can install things into the document that
can influence future contents. HTML can have style information embedded
that would influence the next content installed unexpectedly.
An alternative way to load this component with a string would be to
create a StringReader and call the read method. In this case the model
would be replaced after it was initialized with the contents of the
string.
This method is thread safe, although most Swing methods
are not. Please see
Threads
and Swing for more information.
try {
Document doc = getDocument();
doc.remove(0, doc.getLength());
if (t == null || t.equals("")) {
return;
}
Reader r = new StringReader(t);
EditorKit kit = getEditorKit();
kit.read(r, doc, 0);
} catch (IOException ioe) {
UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
} catch (BadLocationException ble) {
UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
}
| private void | writeObject(java.io.ObjectOutputStream s)See readObject and writeObject in
JComponent for more
information about serialization in Swing.
s.defaultWriteObject();
if (getUIClassID().equals(uiClassID)) {
byte count = JComponent.getWriteObjCounter(this);
JComponent.setWriteObjCounter(this, --count);
if (count == 0 && ui != null) {
ui.installUI(this);
}
}
|
|