Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package javax.swing.plaf.basic;
   26   
   27   import java.beans;
   28   import java.awt;
   29   import java.awt.event.KeyEvent;
   30   import java.awt.event.InputEvent;
   31   import javax.swing;
   32   import javax.swing.event.DocumentEvent;
   33   import javax.swing.text;
   34   import javax.swing.plaf;
   35   
   36   /**
   37    * Provides the look and feel for a plain text editor.  In this
   38    * implementation the default UI is extended to act as a simple
   39    * view factory.
   40    * <p>
   41    * <strong>Warning:</strong>
   42    * Serialized objects of this class will not be compatible with
   43    * future Swing releases. The current serialization support is
   44    * appropriate for short term storage or RMI between applications running
   45    * the same version of Swing.  As of 1.4, support for long term storage
   46    * of all JavaBeans<sup><font size="-2">TM</font></sup>
   47    * has been added to the <code>java.beans</code> package.
   48    * Please see {@link java.beans.XMLEncoder}.
   49    *
   50    * @author  Timothy Prinzing
   51    */
   52   public class BasicTextAreaUI extends BasicTextUI {
   53   
   54       /**
   55        * Creates a UI for a JTextArea.
   56        *
   57        * @param ta a text area
   58        * @return the UI
   59        */
   60       public static ComponentUI createUI(JComponent ta) {
   61           return new BasicTextAreaUI();
   62       }
   63   
   64       /**
   65        * Constructs a new BasicTextAreaUI object.
   66        */
   67       public BasicTextAreaUI() {
   68           super();
   69       }
   70   
   71       /**
   72        * Fetches the name used as a key to look up properties through the
   73        * UIManager.  This is used as a prefix to all the standard
   74        * text properties.
   75        *
   76        * @return the name ("TextArea")
   77        */
   78       protected String getPropertyPrefix() {
   79           return "TextArea";
   80       }
   81   
   82       protected void installDefaults() {
   83           super.installDefaults();
   84           //the fix for 4785160 is undone
   85       }
   86   
   87       /**
   88        * This method gets called when a bound property is changed
   89        * on the associated JTextComponent.  This is a hook
   90        * which UI implementations may change to reflect how the
   91        * UI displays bound properties of JTextComponent subclasses.
   92        * This is implemented to rebuild the View when the
   93        * <em>WrapLine</em> or the <em>WrapStyleWord</em> property changes.
   94        *
   95        * @param evt the property change event
   96        */
   97       protected void propertyChange(PropertyChangeEvent evt) {
   98           super.propertyChange(evt);
   99           if (evt.getPropertyName().equals("lineWrap") ||
  100               evt.getPropertyName().equals("wrapStyleWord") ||
  101                   evt.getPropertyName().equals("tabSize")) {
  102               // rebuild the view
  103               modelChanged();
  104           } else if ("editable".equals(evt.getPropertyName())) {
  105               updateFocusTraversalKeys();
  106           }
  107       }
  108   
  109   
  110       /**
  111        * The method is overridden to take into account caret width.
  112        *
  113        * @param c the editor component
  114        * @return the preferred size
  115        * @throws IllegalArgumentException if invalid value is passed
  116        *
  117        * @since 1.5
  118        */
  119       public Dimension getPreferredSize(JComponent c) {
  120           return super.getPreferredSize(c);
  121           //the fix for 4785160 is undone
  122       }
  123   
  124       /**
  125        * The method is overridden to take into account caret width.
  126        *
  127        * @param c the editor component
  128        * @return the minimum size
  129        * @throws IllegalArgumentException if invalid value is passed
  130        *
  131        * @since 1.5
  132        */
  133       public Dimension getMinimumSize(JComponent c) {
  134           return super.getMinimumSize(c);
  135           //the fix for 4785160 is undone
  136       }
  137   
  138       /**
  139        * Creates the view for an element.  Returns a WrappedPlainView or
  140        * PlainView.
  141        *
  142        * @param elem the element
  143        * @return the view
  144        */
  145       public View create(Element elem) {
  146           Document doc = elem.getDocument();
  147           Object i18nFlag = doc.getProperty("i18n"/*AbstractDocument.I18NProperty*/);
  148           if ((i18nFlag != null) && i18nFlag.equals(Boolean.TRUE)) {
  149               // build a view that support bidi
  150               return createI18N(elem);
  151           } else {
  152               JTextComponent c = getComponent();
  153               if (c instanceof JTextArea) {
  154                   JTextArea area = (JTextArea) c;
  155                   View v;
  156                   if (area.getLineWrap()) {
  157                       v = new WrappedPlainView(elem, area.getWrapStyleWord());
  158                   } else {
  159                       v = new PlainView(elem);
  160                   }
  161                   return v;
  162               }
  163           }
  164           return null;
  165       }
  166   
  167       View createI18N(Element elem) {
  168           String kind = elem.getName();
  169           if (kind != null) {
  170               if (kind.equals(AbstractDocument.ContentElementName)) {
  171                   return new PlainParagraph(elem);
  172               } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
  173                   return new BoxView(elem, View.Y_AXIS);
  174               }
  175           }
  176           return null;
  177       }
  178   
  179       /**
  180        * Returns the baseline.
  181        *
  182        * @throws NullPointerException {@inheritDoc}
  183        * @throws IllegalArgumentException {@inheritDoc}
  184        * @see javax.swing.JComponent#getBaseline(int, int)
  185        * @since 1.6
  186        */
  187       public int getBaseline(JComponent c, int width, int height) {
  188           super.getBaseline(c, width, height);
  189           Object i18nFlag = ((JTextComponent)c).getDocument().
  190                                                 getProperty("i18n");
  191           Insets insets = c.getInsets();
  192           if (Boolean.TRUE.equals(i18nFlag)) {
  193               View rootView = getRootView((JTextComponent)c);
  194               if (rootView.getViewCount() > 0) {
  195                   height = height - insets.top - insets.bottom;
  196                   int baseline = insets.top;
  197                   int fieldBaseline = BasicHTML.getBaseline(
  198                           rootView.getView(0), width - insets.left -
  199                           insets.right, height);
  200                   if (fieldBaseline < 0) {
  201                       return -1;
  202                   }
  203                   return baseline + fieldBaseline;
  204               }
  205               return -1;
  206           }
  207           FontMetrics fm = c.getFontMetrics(c.getFont());
  208           return insets.top + fm.getAscent();
  209       }
  210   
  211       /**
  212        * Returns an enum indicating how the baseline of the component
  213        * changes as the size changes.
  214        *
  215        * @throws NullPointerException {@inheritDoc}
  216        * @see javax.swing.JComponent#getBaseline(int, int)
  217        * @since 1.6
  218        */
  219       public Component.BaselineResizeBehavior getBaselineResizeBehavior(
  220               JComponent c) {
  221           super.getBaselineResizeBehavior(c);
  222           return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
  223       }
  224   
  225   
  226       /**
  227        * Paragraph for representing plain-text lines that support
  228        * bidirectional text.
  229        */
  230       static class PlainParagraph extends ParagraphView {
  231   
  232           PlainParagraph(Element elem) {
  233               super(elem);
  234               layoutPool = new LogicalView(elem);
  235               layoutPool.setParent(this);
  236           }
  237   
  238           public void setParent(View parent) {
  239               super.setParent(parent);
  240               if (parent != null) {
  241                   setPropertiesFromAttributes();
  242               }
  243           }
  244   
  245           protected void setPropertiesFromAttributes() {
  246               Component c = getContainer();
  247               if ((c != null) && (! c.getComponentOrientation().isLeftToRight())) {
  248                   setJustification(StyleConstants.ALIGN_RIGHT);
  249               } else {
  250                   setJustification(StyleConstants.ALIGN_LEFT);
  251               }
  252           }
  253   
  254           /**
  255            * Fetch the constraining span to flow against for
  256            * the given child index.
  257            */
  258           public int getFlowSpan(int index) {
  259               Component c = getContainer();
  260               if (c instanceof JTextArea) {
  261                   JTextArea area = (JTextArea) c;
  262                   if (! area.getLineWrap()) {
  263                       // no limit if unwrapped
  264                       return Integer.MAX_VALUE;
  265                   }
  266               }
  267               return super.getFlowSpan(index);
  268           }
  269   
  270           protected SizeRequirements calculateMinorAxisRequirements(int axis,
  271                                                                     SizeRequirements r) {
  272               SizeRequirements req = super.calculateMinorAxisRequirements(axis, r);
  273               Component c = getContainer();
  274               if (c instanceof JTextArea) {
  275                   JTextArea area = (JTextArea) c;
  276                   if (! area.getLineWrap()) {
  277                       // min is pref if unwrapped
  278                       req.minimum = req.preferred;
  279                   } else {
  280                       req.minimum = 0;
  281                       req.preferred = getWidth();
  282                       if (req.preferred == Integer.MAX_VALUE) {
  283                           // We have been initially set to MAX_VALUE, but we
  284                           // don't want this as our preferred.
  285                           req.preferred = 100;
  286                       }
  287                   }
  288               }
  289               return req;
  290           }
  291   
  292           /**
  293            * Sets the size of the view.  If the size has changed, layout
  294            * is redone.  The size is the full size of the view including
  295            * the inset areas.
  296            *
  297            * @param width the width >= 0
  298            * @param height the height >= 0
  299            */
  300           public void setSize(float width, float height) {
  301               if ((int) width != getWidth()) {
  302                   preferenceChanged(null, true, true);
  303               }
  304               super.setSize(width, height);
  305           }
  306   
  307           /**
  308            * This class can be used to represent a logical view for
  309            * a flow.  It keeps the children updated to reflect the state
  310            * of the model, gives the logical child views access to the
  311            * view hierarchy, and calculates a preferred span.  It doesn't
  312            * do any rendering, layout, or model/view translation.
  313            */
  314           static class LogicalView extends CompositeView {
  315   
  316               LogicalView(Element elem) {
  317                   super(elem);
  318               }
  319   
  320               protected int getViewIndexAtPosition(int pos) {
  321                   Element elem = getElement();
  322                   if (elem.getElementCount() > 0) {
  323                       return elem.getElementIndex(pos);
  324                   }
  325                   return 0;
  326               }
  327   
  328               protected boolean updateChildren(DocumentEvent.ElementChange ec,
  329                                                DocumentEvent e, ViewFactory f) {
  330                   return false;
  331               }
  332   
  333               protected void loadChildren(ViewFactory f) {
  334                   Element elem = getElement();
  335                   if (elem.getElementCount() > 0) {
  336                       super.loadChildren(f);
  337                   } else {
  338                       View v = new GlyphView(elem);
  339                       append(v);
  340                   }
  341               }
  342   
  343               public float getPreferredSpan(int axis) {
  344                   if( getViewCount() != 1 )
  345                       throw new Error("One child view is assumed.");
  346   
  347                   View v = getView(0);
  348                   return v.getPreferredSpan(axis);
  349               }
  350   
  351               /**
  352                * Forward the DocumentEvent to the given child view.  This
  353                * is implemented to reparent the child to the logical view
  354                * (the children may have been parented by a row in the flow
  355                * if they fit without breaking) and then execute the superclass
  356                * behavior.
  357                *
  358                * @param v the child view to forward the event to.
  359                * @param e the change information from the associated document
  360                * @param a the current allocation of the view
  361                * @param f the factory to use to rebuild if the view has children
  362                * @see #forwardUpdate
  363                * @since 1.3
  364                */
  365               protected void forwardUpdateToView(View v, DocumentEvent e,
  366                                                  Shape a, ViewFactory f) {
  367                   v.setParent(this);
  368                   super.forwardUpdateToView(v, e, a, f);
  369               }
  370   
  371               // The following methods don't do anything useful, they
  372               // simply keep the class from being abstract.
  373   
  374               public void paint(Graphics g, Shape allocation) {
  375               }
  376   
  377               protected boolean isBefore(int x, int y, Rectangle alloc) {
  378                   return false;
  379               }
  380   
  381               protected boolean isAfter(int x, int y, Rectangle alloc) {
  382                   return false;
  383               }
  384   
  385               protected View getViewAtPoint(int x, int y, Rectangle alloc) {
  386                   return null;
  387               }
  388   
  389               protected void childAllocation(int index, Rectangle a) {
  390               }
  391           }
  392       }
  393   
  394   }

Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]