/*
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.plaf.basic;
import java.beans.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.text.*;
import javax.swing.plaf.*;
Provides the look and feel for a plain text editor. In this
implementation the default UI is extended to act as a simple
view factory.
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 XMLEncoder
.
Author: Timothy Prinzing
/**
* Provides the look and feel for a plain text editor. In this
* implementation the default UI is extended to act as a simple
* view factory.
* <p>
* <strong>Warning:</strong>
* 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 JavaBeans<sup><font size="-2">TM</font></sup>
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Timothy Prinzing
*/
public class BasicTextAreaUI extends BasicTextUI {
Creates a UI for a JTextArea.
Params: - ta – a text area
Returns: the UI
/**
* Creates a UI for a JTextArea.
*
* @param ta a text area
* @return the UI
*/
public static ComponentUI createUI(JComponent ta) {
return new BasicTextAreaUI();
}
Constructs a new BasicTextAreaUI object.
/**
* Constructs a new BasicTextAreaUI object.
*/
public BasicTextAreaUI() {
super();
}
Fetches the name used as a key to look up properties through the
UIManager. This is used as a prefix to all the standard
text properties.
Returns: the name ("TextArea")
/**
* Fetches the name used as a key to look up properties through the
* UIManager. This is used as a prefix to all the standard
* text properties.
*
* @return the name ("TextArea")
*/
protected String getPropertyPrefix() {
return "TextArea";
}
protected void installDefaults() {
super.installDefaults();
//the fix for 4785160 is undone
}
This method gets called when a bound property is changed
on the associated JTextComponent. This is a hook
which UI implementations may change to reflect how the
UI displays bound properties of JTextComponent subclasses.
This is implemented to rebuild the View when the
WrapLine or the WrapStyleWord property changes.
Params: - evt – the property change event
/**
* This method gets called when a bound property is changed
* on the associated JTextComponent. This is a hook
* which UI implementations may change to reflect how the
* UI displays bound properties of JTextComponent subclasses.
* This is implemented to rebuild the View when the
* <em>WrapLine</em> or the <em>WrapStyleWord</em> property changes.
*
* @param evt the property change event
*/
protected void propertyChange(PropertyChangeEvent evt) {
super.propertyChange(evt);
if (evt.getPropertyName().equals("lineWrap") ||
evt.getPropertyName().equals("wrapStyleWord") ||
evt.getPropertyName().equals("tabSize")) {
// rebuild the view
modelChanged();
} else if ("editable".equals(evt.getPropertyName())) {
updateFocusTraversalKeys();
}
}
The method is overridden to take into account caret width.
Params: - c – the editor component
Throws: - IllegalArgumentException – if invalid value is passed
Returns: the preferred size Since: 1.5
/**
* The method is overridden to take into account caret width.
*
* @param c the editor component
* @return the preferred size
* @throws IllegalArgumentException if invalid value is passed
*
* @since 1.5
*/
public Dimension getPreferredSize(JComponent c) {
return super.getPreferredSize(c);
//the fix for 4785160 is undone
}
The method is overridden to take into account caret width.
Params: - c – the editor component
Throws: - IllegalArgumentException – if invalid value is passed
Returns: the minimum size Since: 1.5
/**
* The method is overridden to take into account caret width.
*
* @param c the editor component
* @return the minimum size
* @throws IllegalArgumentException if invalid value is passed
*
* @since 1.5
*/
public Dimension getMinimumSize(JComponent c) {
return super.getMinimumSize(c);
//the fix for 4785160 is undone
}
Creates the view for an element. Returns a WrappedPlainView or
PlainView.
Params: - elem – the element
Returns: the view
/**
* Creates the view for an element. Returns a WrappedPlainView or
* PlainView.
*
* @param elem the element
* @return the view
*/
public View create(Element elem) {
Document doc = elem.getDocument();
Object i18nFlag = doc.getProperty("i18n"/*AbstractDocument.I18NProperty*/);
if ((i18nFlag != null) && i18nFlag.equals(Boolean.TRUE)) {
// build a view that support bidi
return createI18N(elem);
} else {
JTextComponent c = getComponent();
if (c instanceof JTextArea) {
JTextArea area = (JTextArea) c;
View v;
if (area.getLineWrap()) {
v = new WrappedPlainView(elem, area.getWrapStyleWord());
} else {
v = new PlainView(elem);
}
return v;
}
}
return null;
}
View createI18N(Element elem) {
String kind = elem.getName();
if (kind != null) {
if (kind.equals(AbstractDocument.ContentElementName)) {
return new PlainParagraph(elem);
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new BoxView(elem, View.Y_AXIS);
}
}
return null;
}
Returns the baseline.
Throws: - NullPointerException – {@inheritDoc}
- IllegalArgumentException – {@inheritDoc}
See Also: Since: 1.6
/**
* Returns the baseline.
*
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public int getBaseline(JComponent c, int width, int height) {
super.getBaseline(c, width, height);
Object i18nFlag = ((JTextComponent)c).getDocument().
getProperty("i18n");
Insets insets = c.getInsets();
if (Boolean.TRUE.equals(i18nFlag)) {
View rootView = getRootView((JTextComponent)c);
if (rootView.getViewCount() > 0) {
height = height - insets.top - insets.bottom;
int baseline = insets.top;
int fieldBaseline = BasicHTML.getBaseline(
rootView.getView(0), width - insets.left -
insets.right, height);
if (fieldBaseline < 0) {
return -1;
}
return baseline + fieldBaseline;
}
return -1;
}
FontMetrics fm = c.getFontMetrics(c.getFont());
return insets.top + fm.getAscent();
}
Returns an enum indicating how the baseline of the component
changes as the size changes.
Throws: - NullPointerException – {@inheritDoc}
See Also: Since: 1.6
/**
* Returns an enum indicating how the baseline of the component
* changes as the size changes.
*
* @throws NullPointerException {@inheritDoc}
* @see javax.swing.JComponent#getBaseline(int, int)
* @since 1.6
*/
public Component.BaselineResizeBehavior getBaselineResizeBehavior(
JComponent c) {
super.getBaselineResizeBehavior(c);
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
Paragraph for representing plain-text lines that support
bidirectional text.
/**
* Paragraph for representing plain-text lines that support
* bidirectional text.
*/
static class PlainParagraph extends ParagraphView {
PlainParagraph(Element elem) {
super(elem);
layoutPool = new LogicalView(elem);
layoutPool.setParent(this);
}
public void setParent(View parent) {
super.setParent(parent);
if (parent != null) {
setPropertiesFromAttributes();
}
}
protected void setPropertiesFromAttributes() {
Component c = getContainer();
if ((c != null) && (! c.getComponentOrientation().isLeftToRight())) {
setJustification(StyleConstants.ALIGN_RIGHT);
} else {
setJustification(StyleConstants.ALIGN_LEFT);
}
}
Fetch the constraining span to flow against for
the given child index.
/**
* Fetch the constraining span to flow against for
* the given child index.
*/
public int getFlowSpan(int index) {
Component c = getContainer();
if (c instanceof JTextArea) {
JTextArea area = (JTextArea) c;
if (! area.getLineWrap()) {
// no limit if unwrapped
return Integer.MAX_VALUE;
}
}
return super.getFlowSpan(index);
}
protected SizeRequirements calculateMinorAxisRequirements(int axis,
SizeRequirements r) {
SizeRequirements req = super.calculateMinorAxisRequirements(axis, r);
Component c = getContainer();
if (c instanceof JTextArea) {
JTextArea area = (JTextArea) c;
if (! area.getLineWrap()) {
// min is pref if unwrapped
req.minimum = req.preferred;
} else {
req.minimum = 0;
req.preferred = getWidth();
if (req.preferred == Integer.MAX_VALUE) {
// We have been initially set to MAX_VALUE, but we
// don't want this as our preferred.
req.preferred = 100;
}
}
}
return req;
}
Sets the size of the view. If the size has changed, layout
is redone. The size is the full size of the view including
the inset areas.
Params: - width – the width >= 0
- height – the height >= 0
/**
* Sets the size of the view. If the size has changed, layout
* is redone. The size is the full size of the view including
* the inset areas.
*
* @param width the width >= 0
* @param height the height >= 0
*/
public void setSize(float width, float height) {
if ((int) width != getWidth()) {
preferenceChanged(null, true, true);
}
super.setSize(width, height);
}
This class can be used to represent a logical view for
a flow. It keeps the children updated to reflect the state
of the model, gives the logical child views access to the
view hierarchy, and calculates a preferred span. It doesn't
do any rendering, layout, or model/view translation.
/**
* This class can be used to represent a logical view for
* a flow. It keeps the children updated to reflect the state
* of the model, gives the logical child views access to the
* view hierarchy, and calculates a preferred span. It doesn't
* do any rendering, layout, or model/view translation.
*/
static class LogicalView extends CompositeView {
LogicalView(Element elem) {
super(elem);
}
protected int getViewIndexAtPosition(int pos) {
Element elem = getElement();
if (elem.getElementCount() > 0) {
return elem.getElementIndex(pos);
}
return 0;
}
protected boolean updateChildren(DocumentEvent.ElementChange ec,
DocumentEvent e, ViewFactory f) {
return false;
}
protected void loadChildren(ViewFactory f) {
Element elem = getElement();
if (elem.getElementCount() > 0) {
super.loadChildren(f);
} else {
View v = new GlyphView(elem);
append(v);
}
}
public float getPreferredSpan(int axis) {
if( getViewCount() != 1 )
throw new Error("One child view is assumed.");
View v = getView(0);
return v.getPreferredSpan(axis);
}
Forward the DocumentEvent to the given child view. This
is implemented to reparent the child to the logical view
(the children may have been parented by a row in the flow
if they fit without breaking) and then execute the superclass
behavior.
Params: - v – the child view to forward the event to.
- e – the change information from the associated document
- a – the current allocation of the view
- f – the factory to use to rebuild if the view has children
See Also: Since: 1.3
/**
* Forward the DocumentEvent to the given child view. This
* is implemented to reparent the child to the logical view
* (the children may have been parented by a row in the flow
* if they fit without breaking) and then execute the superclass
* behavior.
*
* @param v the child view to forward the event to.
* @param e the change information from the associated document
* @param a the current allocation of the view
* @param f the factory to use to rebuild if the view has children
* @see #forwardUpdate
* @since 1.3
*/
protected void forwardUpdateToView(View v, DocumentEvent e,
Shape a, ViewFactory f) {
v.setParent(this);
super.forwardUpdateToView(v, e, a, f);
}
// The following methods don't do anything useful, they
// simply keep the class from being abstract.
public void paint(Graphics g, Shape allocation) {
}
protected boolean isBefore(int x, int y, Rectangle alloc) {
return false;
}
protected boolean isAfter(int x, int y, Rectangle alloc) {
return false;
}
protected View getViewAtPoint(int x, int y, Rectangle alloc) {
return null;
}
protected void childAllocation(int index, Rectangle a) {
}
}
}
}