8aa540d2f7
Imported GNU Classpath 0.90 * scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore. * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant. * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5. * java/lang/Math.java: New override file. * java/lang/Character.java: Merged from Classpath. (start, end): Now 'int's. (canonicalName): New field. (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants. (UnicodeBlock): Added argument. (of): New overload. (forName): New method. Updated unicode blocks. (sets): Updated. * sources.am: Regenerated. * Makefile.in: Likewise. From-SVN: r111942
977 lines
29 KiB
Java
977 lines
29 KiB
Java
/* JEditorPane.java --
|
|
Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
|
|
|
|
This file is part of GNU Classpath.
|
|
|
|
GNU Classpath is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
GNU Classpath is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GNU Classpath; see the file COPYING. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301 USA.
|
|
|
|
Linking this library statically or dynamically with other modules is
|
|
making a combined work based on this library. Thus, the terms and
|
|
conditions of the GNU General Public License cover the whole
|
|
combination.
|
|
|
|
As a special exception, the copyright holders of this library give you
|
|
permission to link this library with independent modules to produce an
|
|
executable, regardless of the license terms of these independent
|
|
modules, and to copy and distribute the resulting executable under
|
|
terms of your choice, provided that you also meet, for each linked
|
|
independent module, the terms and conditions of the license of that
|
|
module. An independent module is a module which is not derived from
|
|
or based on this library. If you modify this library, you may extend
|
|
this exception to your version of the library, but you are not
|
|
obligated to do so. If you do not wish to do so, delete this
|
|
exception statement from your version. */
|
|
|
|
|
|
package javax.swing;
|
|
|
|
import java.awt.Container;
|
|
import java.awt.Dimension;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.Reader;
|
|
import java.io.StringReader;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.util.HashMap;
|
|
|
|
import javax.accessibility.AccessibleContext;
|
|
import javax.accessibility.AccessibleHyperlink;
|
|
import javax.accessibility.AccessibleHypertext;
|
|
import javax.accessibility.AccessibleStateSet;
|
|
import javax.accessibility.AccessibleText;
|
|
import javax.swing.event.HyperlinkEvent;
|
|
import javax.swing.event.HyperlinkListener;
|
|
import javax.swing.text.BadLocationException;
|
|
import javax.swing.text.DefaultEditorKit;
|
|
import javax.swing.text.Document;
|
|
import javax.swing.text.EditorKit;
|
|
import javax.swing.text.Element;
|
|
import javax.swing.text.JTextComponent;
|
|
import javax.swing.text.View;
|
|
import javax.swing.text.ViewFactory;
|
|
import javax.swing.text.WrappedPlainView;
|
|
import javax.swing.text.html.HTML;
|
|
import javax.swing.text.html.HTMLDocument;
|
|
import javax.swing.text.html.HTMLEditorKit;
|
|
|
|
/**
|
|
* A powerful text editor component that can handle different types of
|
|
* content.
|
|
*
|
|
* The JEditorPane text component is driven by an instance of
|
|
* {@link EditorKit}. The editor kit is responsible for providing
|
|
* a default {@link Document} implementation, a mechanism for loading
|
|
* and saving documents of its supported content type and providing
|
|
* a set of {@link Action}s for manipulating the content.
|
|
*
|
|
* By default the following content types are supported:
|
|
* <ul>
|
|
* <li><code>text/plain</code>: Plain text, handled by
|
|
* {@link javax.swing.text.DefaultEditorKit}.</li>
|
|
* <li><code>text/html</code>: HTML 4.0 styled text, handled by
|
|
* {@link javax.swing.text.html.HTMLEditorKit}.</li>
|
|
* <li><code>text/rtf</code>: RTF text, handled by
|
|
* {@link javax.swing.text.rtf.RTFEditorKit}.</li>
|
|
* </ul>
|
|
*
|
|
* @author original author unknown
|
|
* @author Roman Kennke (roman@kennke.org)
|
|
* @author Anthony Balkissoon abalkiss at redhat dot com
|
|
*/
|
|
public class JEditorPane extends JTextComponent
|
|
{
|
|
/**
|
|
* Provides accessibility support for <code>JEditorPane</code>.
|
|
*
|
|
* @author Roman Kennke (kennke@aicas.com)
|
|
*/
|
|
protected class AccessibleJEditorPane extends AccessibleJTextComponent
|
|
{
|
|
|
|
/**
|
|
* Creates a new <code>AccessibleJEditorPane</code> object.
|
|
*/
|
|
protected AccessibleJEditorPane()
|
|
{
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Returns a description of this <code>AccessibleJEditorPane</code>. If
|
|
* this property is not set, then this returns the content-type of the
|
|
* editor pane.
|
|
*
|
|
* @return a description of this AccessibleJEditorPane
|
|
*/
|
|
public String getAccessibleDescription()
|
|
{
|
|
String descr = super.getAccessibleDescription();
|
|
if (descr == null)
|
|
return getContentType();
|
|
else
|
|
return descr;
|
|
}
|
|
|
|
/**
|
|
* Returns the accessible state of this <code>AccessibleJEditorPane</code>.
|
|
*
|
|
* @return the accessible state of this <code>AccessibleJEditorPane</code>
|
|
*/
|
|
public AccessibleStateSet getAccessibleStateSet()
|
|
{
|
|
AccessibleStateSet state = super.getAccessibleStateSet();
|
|
// TODO: Figure out what state must be added here to the super's state.
|
|
return state;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Provides accessibility support for <code>JEditorPane</code>s, when the
|
|
* editor kit is an instance of {@link HTMLEditorKit}.
|
|
*
|
|
* @author Roman Kennke (kennke@aicas.com)
|
|
*/
|
|
protected class AccessibleJEditorPaneHTML extends AccessibleJEditorPane
|
|
{
|
|
/**
|
|
* Returns the accessible text of the <code>JEditorPane</code>. This will
|
|
* be an instance of
|
|
* {@link JEditorPaneAccessibleHypertextSupport}.
|
|
*
|
|
* @return the accessible text of the <code>JEditorPane</code>
|
|
*/
|
|
public AccessibleText getAccessibleText()
|
|
{
|
|
return new JEditorPaneAccessibleHypertextSupport();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This is the accessible text that is returned by
|
|
* {@link AccessibleJEditorPaneHTML#getAccessibleText()}.
|
|
*
|
|
* @author Roman Kennke (kennke@aicas.com)
|
|
*/
|
|
protected class JEditorPaneAccessibleHypertextSupport
|
|
extends AccessibleJEditorPane implements AccessibleHypertext
|
|
{
|
|
|
|
/**
|
|
* Creates a new JEditorPaneAccessibleHypertextSupport object.
|
|
*/
|
|
public JEditorPaneAccessibleHypertextSupport()
|
|
{
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* The accessible representation of a HTML link.
|
|
*
|
|
* @author Roman Kennke (kennke@aicas.com)
|
|
*/
|
|
public class HTMLLink extends AccessibleHyperlink
|
|
{
|
|
|
|
/**
|
|
* The element in the document that represents the link.
|
|
*/
|
|
Element element;
|
|
|
|
/**
|
|
* Creates a new <code>HTMLLink</code>.
|
|
*
|
|
* @param el the link element
|
|
*/
|
|
public HTMLLink(Element el)
|
|
{
|
|
this.element = el;
|
|
}
|
|
|
|
/**
|
|
* Returns <code>true</code> if this <code>HTMLLink</code> is still
|
|
* valid. A <code>HTMLLink</code> can become invalid when the document
|
|
* changes.
|
|
*
|
|
* @return <code>true</code> if this <code>HTMLLink</code> is still
|
|
* valid
|
|
*/
|
|
public boolean isValid()
|
|
{
|
|
// I test here if the element at our element's start offset is the
|
|
// same as the element in the document at this offset. If this is true,
|
|
// I consider the link valid, if not, then this link no longer
|
|
// represented by this HTMLLink and therefor invalid.
|
|
HTMLDocument doc = (HTMLDocument) getDocument();
|
|
return doc.getCharacterElement(element.getStartOffset()) == element;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of AccessibleActions in this link object. In
|
|
* general, link have 1 AccessibleAction associated with them. There are
|
|
* special cases where links can have multiple actions associated, like
|
|
* in image maps.
|
|
*
|
|
* @return the number of AccessibleActions in this link object
|
|
*/
|
|
public int getAccessibleActionCount()
|
|
{
|
|
// TODO: Implement the special cases.
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Performs the specified action on the link object. This ususally means
|
|
* activating the link.
|
|
*
|
|
* @return <code>true</code> if the action has been performed
|
|
* successfully, <code>false</code> otherwise
|
|
*/
|
|
public boolean doAccessibleAction(int i)
|
|
{
|
|
String href = (String) element.getAttributes().getAttribute("href");
|
|
HTMLDocument doc = (HTMLDocument) getDocument();
|
|
try
|
|
{
|
|
URL url = new URL(doc.getBase(), href);
|
|
setPage(url);
|
|
String desc = doc.getText(element.getStartOffset(),
|
|
element.getEndOffset() - element.getStartOffset());
|
|
HyperlinkEvent ev =
|
|
new HyperlinkEvent(JEditorPane.this,
|
|
HyperlinkEvent.EventType.ACTIVATED, url, desc,
|
|
element);
|
|
fireHyperlinkUpdate(ev);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the description of the action at action index <code>i</code>.
|
|
* This method returns the text within the element associated with this
|
|
* link.
|
|
*
|
|
* @param i the action index
|
|
*
|
|
* @return the description of the action at action index <code>i</code>
|
|
*/
|
|
public String getAccessibleActionDescription(int i)
|
|
{
|
|
HTMLDocument doc = (HTMLDocument) getDocument();
|
|
try
|
|
{
|
|
return doc.getText(element.getStartOffset(),
|
|
element.getEndOffset() - element.getStartOffset());
|
|
}
|
|
catch (BadLocationException ex)
|
|
{
|
|
throw (AssertionError)
|
|
new AssertionError("BadLocationException must not be thrown "
|
|
+ "here.")
|
|
.initCause(ex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns an {@link URL} object, that represents the action at action
|
|
* index <code>i</code>.
|
|
*
|
|
* @param i the action index
|
|
*
|
|
* @return an {@link URL} object, that represents the action at action
|
|
* index <code>i</code>
|
|
*/
|
|
public Object getAccessibleActionObject(int i)
|
|
{
|
|
String href = (String) element.getAttributes().getAttribute("href");
|
|
HTMLDocument doc = (HTMLDocument) getDocument();
|
|
try
|
|
{
|
|
URL url = new URL(doc.getBase(), href);
|
|
return url;
|
|
}
|
|
catch (MalformedURLException ex)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns an object that represents the link anchor. For examples, if
|
|
* the link encloses a string, then a <code>String</code> object is
|
|
* returned, if the link encloses an <img> tag, then an
|
|
* <code>ImageIcon</code> object is returned.
|
|
*
|
|
* @return an object that represents the link anchor
|
|
*/
|
|
public Object getAccessibleActionAnchor(int i)
|
|
{
|
|
// TODO: This is only the String case. Implement all cases.
|
|
return getAccessibleActionDescription(i);
|
|
}
|
|
|
|
/**
|
|
* Returns the start index of the hyperlink element.
|
|
*
|
|
* @return the start index of the hyperlink element
|
|
*/
|
|
public int getStartIndex()
|
|
{
|
|
return element.getStartOffset();
|
|
}
|
|
|
|
/**
|
|
* Returns the end index of the hyperlink element.
|
|
*
|
|
* @return the end index of the hyperlink element
|
|
*/
|
|
public int getEndIndex()
|
|
{
|
|
return element.getEndOffset();
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns the number of hyperlinks in the document.
|
|
*
|
|
* @return the number of hyperlinks in the document
|
|
*/
|
|
public int getLinkCount()
|
|
{
|
|
HTMLDocument doc = (HTMLDocument) getDocument();
|
|
HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
|
|
int count = 0;
|
|
while (linkIter.isValid())
|
|
{
|
|
count++;
|
|
linkIter.next();
|
|
}
|
|
return count;
|
|
}
|
|
|
|
/**
|
|
* Returns the <code>i</code>-th hyperlink in the document or
|
|
* <code>null</code> if there is no hyperlink with the specified index.
|
|
*
|
|
* @param i the index of the hyperlink to return
|
|
*
|
|
* @return the <code>i</code>-th hyperlink in the document or
|
|
* <code>null</code> if there is no hyperlink with the specified
|
|
* index
|
|
*/
|
|
public AccessibleHyperlink getLink(int i)
|
|
{
|
|
HTMLDocument doc = (HTMLDocument) getDocument();
|
|
HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
|
|
int count = 0;
|
|
while (linkIter.isValid())
|
|
{
|
|
count++;
|
|
if (count == i)
|
|
break;
|
|
linkIter.next();
|
|
}
|
|
if (linkIter.isValid())
|
|
{
|
|
int offset = linkIter.getStartOffset();
|
|
// TODO: I fetch the element for the link via getCharacterElement().
|
|
// I am not sure that this is correct, maybe we must use
|
|
// getParagraphElement()?
|
|
Element el = doc.getCharacterElement(offset);
|
|
HTMLLink link = new HTMLLink(el);
|
|
return link;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Returns the index of the link element at the character position
|
|
* <code>c</code> within the document, or <code>-1</code> if there is no
|
|
* link at the specified position.
|
|
*
|
|
* @param c the character index from which to fetch the link index
|
|
*
|
|
* @return the index of the link element at the character position
|
|
* <code>c</code> within the document, or <code>-1</code> if there
|
|
* is no link at the specified position
|
|
*/
|
|
public int getLinkIndex(int c)
|
|
{
|
|
HTMLDocument doc = (HTMLDocument) getDocument();
|
|
HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
|
|
int count = 0;
|
|
while (linkIter.isValid())
|
|
{
|
|
if (linkIter.getStartOffset() <= c && linkIter.getEndOffset() > c)
|
|
break;
|
|
count++;
|
|
linkIter.next();
|
|
}
|
|
if (linkIter.isValid())
|
|
return count;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Returns the link text of the link at index <code>i</code>, or
|
|
* <code>null</code>, if there is no link at the specified position.
|
|
*
|
|
* @param i the index of the link
|
|
*
|
|
* @return the link text of the link at index <code>i</code>, or
|
|
* <code>null</code>, if there is no link at the specified
|
|
* position
|
|
*/
|
|
public String getLinkText(int i)
|
|
{
|
|
HTMLDocument doc = (HTMLDocument) getDocument();
|
|
HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
|
|
int count = 0;
|
|
while (linkIter.isValid())
|
|
{
|
|
count++;
|
|
if (count == i)
|
|
break;
|
|
linkIter.next();
|
|
}
|
|
if (linkIter.isValid())
|
|
{
|
|
int offset = linkIter.getStartOffset();
|
|
// TODO: I fetch the element for the link via getCharacterElement().
|
|
// I am not sure that this is correct, maybe we must use
|
|
// getParagraphElement()?
|
|
Element el = doc.getCharacterElement(offset);
|
|
try
|
|
{
|
|
String text = doc.getText(el.getStartOffset(),
|
|
el.getEndOffset() - el.getStartOffset());
|
|
return text;
|
|
}
|
|
catch (BadLocationException ex)
|
|
{
|
|
throw (AssertionError)
|
|
new AssertionError("BadLocationException must not be thrown "
|
|
+ "here.")
|
|
.initCause(ex);
|
|
}
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An EditorKit used for plain text. This is the default editor kit for
|
|
* JEditorPanes.
|
|
*
|
|
* @author Roman Kennke (kennke@aicas.com)
|
|
*/
|
|
private static class PlainEditorKit extends DefaultEditorKit
|
|
{
|
|
|
|
/**
|
|
* Returns a ViewFactory that supplies WrappedPlainViews.
|
|
*/
|
|
public ViewFactory getViewFactory()
|
|
{
|
|
return new ViewFactory()
|
|
{
|
|
public View create(Element el)
|
|
{
|
|
return new WrappedPlainView(el);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
private static final long serialVersionUID = 3140472492599046285L;
|
|
|
|
private URL page;
|
|
private EditorKit editorKit;
|
|
|
|
boolean focus_root;
|
|
|
|
// A mapping between content types and registered EditorKit types
|
|
static HashMap registerMap;
|
|
|
|
// A mapping between content types and used EditorKits
|
|
HashMap editorMap;
|
|
|
|
public JEditorPane()
|
|
{
|
|
init();
|
|
setEditorKit(createDefaultEditorKit());
|
|
}
|
|
|
|
public JEditorPane(String url) throws IOException
|
|
{
|
|
this(new URL(url));
|
|
}
|
|
|
|
public JEditorPane(String type, String text)
|
|
{
|
|
init();
|
|
setEditorKit(createEditorKitForContentType(type));
|
|
setText(text);
|
|
}
|
|
|
|
public JEditorPane(URL url) throws IOException
|
|
{
|
|
init ();
|
|
setEditorKit (createEditorKitForContentType("text/html"));;
|
|
setPage(url);
|
|
}
|
|
|
|
/**
|
|
* Called by the constructors to set up the default bindings for content
|
|
* types and EditorKits.
|
|
*/
|
|
void init()
|
|
{
|
|
editorMap = new HashMap();
|
|
registerMap = new HashMap();
|
|
registerEditorKitForContentType("application/rtf",
|
|
"javax.swing.text.rtf.RTFEditorKit");
|
|
registerEditorKitForContentType("text/plain",
|
|
"javax.swing.JEditorPane$PlainEditorKit");
|
|
registerEditorKitForContentType("text/html",
|
|
"javax.swing.text.html.HTMLEditorKit");
|
|
registerEditorKitForContentType("text/rtf",
|
|
"javax.swing.text.rtf.RTFEditorKit");
|
|
}
|
|
|
|
protected EditorKit createDefaultEditorKit()
|
|
{
|
|
return new PlainEditorKit();
|
|
}
|
|
|
|
/**
|
|
* Creates and returns an EditorKit that is appropriate for the given
|
|
* content type. This is created using the default recognized types
|
|
* plus any EditorKit types that have been registered.
|
|
*
|
|
* @see #registerEditorKitForContentType(String, String)
|
|
* @see #registerEditorKitForContentType(String, String, ClassLoader)
|
|
* @param type the content type
|
|
* @return an EditorKit for use with the given content type
|
|
*/
|
|
public static EditorKit createEditorKitForContentType(String type)
|
|
{
|
|
// TODO: Have to handle the case where a ClassLoader was specified
|
|
// when the EditorKit was registered
|
|
EditorKit e = null;
|
|
String className = (String)registerMap.get(type);
|
|
if (className != null)
|
|
{
|
|
try
|
|
{
|
|
e = (EditorKit) Class.forName(className).newInstance();
|
|
}
|
|
catch (Exception e2)
|
|
{
|
|
// TODO: Not sure what to do here.
|
|
}
|
|
}
|
|
return e;
|
|
}
|
|
|
|
/**
|
|
* Sends a given <code>HyperlinkEvent</code> to all registered listeners.
|
|
*
|
|
* @param event the event to send
|
|
*/
|
|
public void fireHyperlinkUpdate(HyperlinkEvent event)
|
|
{
|
|
HyperlinkListener[] listeners = getHyperlinkListeners();
|
|
|
|
for (int index = 0; index < listeners.length; ++index)
|
|
listeners[index].hyperlinkUpdate(event);
|
|
}
|
|
|
|
/**
|
|
* Returns the accessible context associated with this editor pane.
|
|
*
|
|
* @return the accessible context associated with this editor pane
|
|
*/
|
|
public AccessibleContext getAccessibleContext()
|
|
{
|
|
if (accessibleContext == null)
|
|
{
|
|
if (getEditorKit() instanceof HTMLEditorKit)
|
|
accessibleContext = new AccessibleJEditorPaneHTML();
|
|
else
|
|
accessibleContext = new AccessibleJEditorPane();
|
|
}
|
|
return accessibleContext;
|
|
}
|
|
|
|
public final String getContentType()
|
|
{
|
|
return getEditorKit().getContentType();
|
|
}
|
|
|
|
/**
|
|
* Returns the EditorKit. If there is no EditorKit set this method
|
|
* calls createDefaultEditorKit() and setEditorKit() first.
|
|
*/
|
|
public EditorKit getEditorKit()
|
|
{
|
|
if (editorKit == null)
|
|
setEditorKit(createDefaultEditorKit());
|
|
return editorKit;
|
|
}
|
|
|
|
/**
|
|
* Returns the class name of the EditorKit associated with the given
|
|
* content type.
|
|
*
|
|
* @since 1.3
|
|
* @param type the content type
|
|
* @return the class name of the EditorKit associated with this content type
|
|
*/
|
|
public static String getEditorKitClassNameForContentType(String type)
|
|
{
|
|
return (String) registerMap.get(type);
|
|
}
|
|
|
|
/**
|
|
* Returns the EditorKit to use for the given content type. If an
|
|
* EditorKit has been explicitly set via
|
|
* <code>setEditorKitForContentType</code>
|
|
* then it will be returned. Otherwise an attempt will be made to create
|
|
* an EditorKit from the default recognzied content types or any
|
|
* EditorKits that have been registered. If none can be created, a
|
|
* PlainEditorKit is created.
|
|
*
|
|
* @see #registerEditorKitForContentType(String, String)
|
|
* @see #registerEditorKitForContentType(String, String, ClassLoader)
|
|
* @param type the content type
|
|
* @return an appropriate EditorKit for the given content type
|
|
*/
|
|
public EditorKit getEditorKitForContentType(String type)
|
|
{
|
|
// First check if an EditorKit has been explicitly set.
|
|
EditorKit e = (EditorKit) editorMap.get(type);
|
|
// Then check to see if we can create one.
|
|
if (e == null)
|
|
e = createEditorKitForContentType(type);
|
|
// Otherwise default to PlainEditorKit.
|
|
if (e == null)
|
|
e = new PlainEditorKit();
|
|
return e;
|
|
}
|
|
|
|
/**
|
|
* Returns the preferred size for the JEditorPane. This is implemented to
|
|
* return the super's preferred size, unless one of
|
|
* {@link #getScrollableTracksViewportHeight()} or
|
|
* {@link #getScrollableTracksViewportWidth()} returns <code>true</code>,
|
|
* in which case the preferred width and/or height is replaced by the UI's
|
|
* minimum size.
|
|
*
|
|
* @return the preferred size for the JEditorPane
|
|
*/
|
|
public Dimension getPreferredSize()
|
|
{
|
|
Dimension pref = super.getPreferredSize();
|
|
if (getScrollableTracksViewportWidth())
|
|
pref.width = getUI().getMinimumSize(this).width;
|
|
if (getScrollableTracksViewportHeight())
|
|
pref.height = getUI().getMinimumSize(this).height;
|
|
return pref;
|
|
}
|
|
|
|
/**
|
|
* Returns <code>true</code> when a Viewport should force the height of
|
|
* this component to match the viewport height. This is implemented to return
|
|
* <code>true</code> when the parent is an instance of JViewport and
|
|
* the viewport height > the UI's minimum height.
|
|
*
|
|
* @return <code>true</code> when a Viewport should force the height of
|
|
* this component to match the viewport height
|
|
*/
|
|
public boolean getScrollableTracksViewportHeight()
|
|
{
|
|
// Tests show that this returns true when the parent is a JViewport
|
|
// and has a height > minimum UI height.
|
|
Container parent = getParent();
|
|
return parent instanceof JViewport
|
|
&& parent.getHeight() > getUI().getMinimumSize(this).height;
|
|
}
|
|
|
|
/**
|
|
* Returns <code>true</code> when a Viewport should force the width of
|
|
* this component to match the viewport width. This is implemented to return
|
|
* <code>true</code> when the parent is an instance of JViewport and
|
|
* the viewport width > the UI's minimum width.
|
|
*
|
|
* @return <code>true</code> when a Viewport should force the width of
|
|
* this component to match the viewport width
|
|
*/
|
|
public boolean getScrollableTracksViewportWidth()
|
|
{
|
|
// Tests show that this returns true when the parent is a JViewport
|
|
// and has a width > minimum UI width.
|
|
Container parent = getParent();
|
|
return parent != null && parent instanceof JViewport
|
|
&& parent.getWidth() > getUI().getMinimumSize(this).width;
|
|
}
|
|
|
|
public URL getPage()
|
|
{
|
|
return page;
|
|
}
|
|
|
|
protected InputStream getStream(URL page)
|
|
throws IOException
|
|
{
|
|
return page.openStream();
|
|
}
|
|
|
|
public String getText()
|
|
{
|
|
return super.getText();
|
|
}
|
|
|
|
public String getUIClassID()
|
|
{
|
|
return "EditorPaneUI";
|
|
}
|
|
|
|
public boolean isFocusCycleRoot()
|
|
{
|
|
return focus_root;
|
|
}
|
|
|
|
protected String paramString()
|
|
{
|
|
return "JEditorPane";
|
|
}
|
|
|
|
/**
|
|
* This method initializes from a stream.
|
|
*/
|
|
public void read(InputStream in, Object desc) throws IOException
|
|
{
|
|
EditorKit kit = getEditorKit();
|
|
if (kit instanceof HTMLEditorKit && desc instanceof HTMLDocument)
|
|
{
|
|
Document doc = (Document) desc;
|
|
try
|
|
{
|
|
kit.read(in, doc, 0);
|
|
}
|
|
catch (BadLocationException ex)
|
|
{
|
|
assert false : "BadLocationException must not be thrown here.";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Reader inRead = new InputStreamReader(in);
|
|
super.read(inRead, desc);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Establishes a binding between type and classname. This enables
|
|
* us to create an EditorKit later for the given content type.
|
|
*
|
|
* @param type the content type
|
|
* @param classname the name of the class that is associated with this
|
|
* content type
|
|
*/
|
|
public static void registerEditorKitForContentType(String type,
|
|
String classname)
|
|
{
|
|
registerMap.put(type, classname);
|
|
}
|
|
|
|
/**
|
|
* Establishes the default bindings of type to classname.
|
|
*/
|
|
public static void registerEditorKitForContentType(String type,
|
|
String classname,
|
|
ClassLoader loader)
|
|
{
|
|
// TODO: Implement this properly.
|
|
}
|
|
|
|
/**
|
|
* Replaces the currently selected content with new content represented
|
|
* by the given string.
|
|
*/
|
|
public void replaceSelection(String content)
|
|
{
|
|
// TODO: Implement this properly.
|
|
super.replaceSelection(content);
|
|
}
|
|
|
|
/**
|
|
* Scrolls the view to the given reference location (that is, the value
|
|
* returned by the UL.getRef method for the URL being displayed).
|
|
*/
|
|
public void scrollToReference(String reference)
|
|
{
|
|
// TODO: Implement this properly.
|
|
}
|
|
|
|
public final void setContentType(String type)
|
|
{
|
|
if (editorKit != null
|
|
&& editorKit.getContentType().equals(type))
|
|
return;
|
|
|
|
EditorKit kit = getEditorKitForContentType(type);
|
|
|
|
if (kit != null)
|
|
setEditorKit(kit);
|
|
}
|
|
|
|
public void setEditorKit(EditorKit newValue)
|
|
{
|
|
if (editorKit == newValue)
|
|
return;
|
|
|
|
if (editorKit != null)
|
|
editorKit.deinstall(this);
|
|
|
|
EditorKit oldValue = editorKit;
|
|
editorKit = newValue;
|
|
|
|
if (editorKit != null)
|
|
{
|
|
editorKit.install(this);
|
|
setDocument(editorKit.createDefaultDocument());
|
|
}
|
|
|
|
firePropertyChange("editorKit", oldValue, newValue);
|
|
invalidate();
|
|
repaint();
|
|
// Reset the accessibleContext since this depends on the editorKit.
|
|
accessibleContext = null;
|
|
}
|
|
|
|
/**
|
|
* Explicitly sets an EditorKit to be used for the given content type.
|
|
* @param type the content type
|
|
* @param k the EditorKit to use for the given content type
|
|
*/
|
|
public void setEditorKitForContentType(String type, EditorKit k)
|
|
{
|
|
editorMap.put(type, k);
|
|
}
|
|
|
|
/**
|
|
* Sets the current URL being displayed.
|
|
*/
|
|
public void setPage(String url) throws IOException
|
|
{
|
|
setPage(new URL(url));
|
|
}
|
|
|
|
/**
|
|
* Sets the current URL being displayed.
|
|
*/
|
|
public void setPage(URL page) throws IOException
|
|
{
|
|
if (page == null)
|
|
throw new IOException("invalid url");
|
|
|
|
try
|
|
{
|
|
this.page = page;
|
|
getEditorKit().read(page.openStream(), getDocument(), 0);
|
|
}
|
|
catch (BadLocationException e)
|
|
{
|
|
// Ignored. '0' is always a valid offset.
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the text of the JEditorPane. The argument <code>t</code>
|
|
* is expected to be in the format of the current EditorKit. This removes
|
|
* the content of the current document and uses the EditorKit to read in the
|
|
* new text. This allows the EditorKit to handle the String rather than just
|
|
* inserting in plain text.
|
|
*
|
|
* @param t the text to display in this JEditorPane
|
|
*/
|
|
public void setText(String t)
|
|
{
|
|
try
|
|
{
|
|
// Remove the current content.
|
|
Document doc = getDocument();
|
|
doc.remove(0, doc.getLength());
|
|
if (t == null || t.equals(""))
|
|
return;
|
|
|
|
// Let the EditorKit read the text into the Document.
|
|
getEditorKit().read(new StringReader(t), doc, 0);
|
|
}
|
|
catch (BadLocationException ble)
|
|
{
|
|
// TODO: Don't know what to do here.
|
|
}
|
|
catch (IOException ioe)
|
|
{
|
|
// TODO: Don't know what to do here.
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a <code>HyperlinkListener</code> object to this editor pane.
|
|
*
|
|
* @param listener the listener to add
|
|
*/
|
|
public void addHyperlinkListener(HyperlinkListener listener)
|
|
{
|
|
listenerList.add(HyperlinkListener.class, listener);
|
|
}
|
|
|
|
/**
|
|
* Removes a <code>HyperlinkListener</code> object to this editor pane.
|
|
*
|
|
* @param listener the listener to remove
|
|
*/
|
|
public void removeHyperlinkListener(HyperlinkListener listener)
|
|
{
|
|
listenerList.remove(HyperlinkListener.class, listener);
|
|
}
|
|
|
|
/**
|
|
* Returns all added <code>HyperlinkListener</code> objects.
|
|
*
|
|
* @return array of listeners
|
|
*
|
|
* @since 1.4
|
|
*/
|
|
public HyperlinkListener[] getHyperlinkListeners()
|
|
{
|
|
return (HyperlinkListener[]) getListeners(HyperlinkListener.class);
|
|
}
|
|
}
|