/* * 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. * <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. * * @param ta a text area * @return the UI */ public static ComponentUI createUI(JComponent ta) { return new BasicTextAreaUI(); } /** * 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. * * @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 * <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. * * @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. * * @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. * * @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} * @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 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. */ 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. */ 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. * * @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. */ 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. * * @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) { } } } }
/*
* 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.
* <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.
*
* @param ta a text area
* @return the UI
*/
public static ComponentUI createUI(JComponent ta) {
return new BasicTextAreaUI();
}
/**
* 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.
*
* @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
* <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.
*
* @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.
*
* @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.
*
* @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}
* @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 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.
*/
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.
*/
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.
*
* @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.
*/
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.
*
* @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) {
}
}
}
}