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

    1   /*
    2    * Copyright (c) 1997, 2005, 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.text;
   26   
   27   import java.awt;
   28   import javax.swing;
   29   import javax.swing.event;
   30   
   31   /**
   32    * Extends the multi-line plain text view to be suitable
   33    * for a single-line editor view.  If the view is
   34    * allocated extra space, the field must adjust for it.
   35    * If the hosting component is a JTextField, this view
   36    * will manage the ranges of the associated BoundedRangeModel
   37    * and will adjust the horizontal allocation to match the
   38    * current visibility settings of the JTextField.
   39    *
   40    * @author  Timothy Prinzing
   41    * @see     View
   42    */
   43   public class FieldView extends PlainView {
   44   
   45       /**
   46        * Constructs a new FieldView wrapped on an element.
   47        *
   48        * @param elem the element
   49        */
   50       public FieldView(Element elem) {
   51           super(elem);
   52       }
   53   
   54       /**
   55        * Fetches the font metrics associated with the component hosting
   56        * this view.
   57        *
   58        * @return the metrics
   59        */
   60       protected FontMetrics getFontMetrics() {
   61           Component c = getContainer();
   62           return c.getFontMetrics(c.getFont());
   63       }
   64   
   65       /**
   66        * Adjusts the allocation given to the view
   67        * to be a suitable allocation for a text field.
   68        * If the view has been allocated more than the
   69        * preferred span vertically, the allocation is
   70        * changed to be centered vertically.  Horizontally
   71        * the view is adjusted according to the horizontal
   72        * alignment property set on the associated JTextField
   73        * (if that is the type of the hosting component).
   74        *
   75        * @param a the allocation given to the view, which may need
   76        *  to be adjusted.
   77        * @return the allocation that the superclass should use.
   78        */
   79       protected Shape adjustAllocation(Shape a) {
   80           if (a != null) {
   81               Rectangle bounds = a.getBounds();
   82               int vspan = (int) getPreferredSpan(Y_AXIS);
   83               int hspan = (int) getPreferredSpan(X_AXIS);
   84               if (bounds.height != vspan) {
   85                   int slop = bounds.height - vspan;
   86                   bounds.y += slop / 2;
   87                   bounds.height -= slop;
   88               }
   89   
   90               // horizontal adjustments
   91               Component c = getContainer();
   92               if (c instanceof JTextField) {
   93                   JTextField field = (JTextField) c;
   94                   BoundedRangeModel vis = field.getHorizontalVisibility();
   95                   int max = Math.max(hspan, bounds.width);
   96                   int value = vis.getValue();
   97                   int extent = Math.min(max, bounds.width - 1);
   98                   if ((value + extent) > max) {
   99                       value = max - extent;
  100                   }
  101                   vis.setRangeProperties(value, extent, vis.getMinimum(),
  102                                          max, false);
  103                   if (hspan < bounds.width) {
  104                       // horizontally align the interior
  105                       int slop = bounds.width - 1 - hspan;
  106   
  107                       int align = ((JTextField)c).getHorizontalAlignment();
  108                       if(Utilities.isLeftToRight(c)) {
  109                           if(align==LEADING) {
  110                               align = LEFT;
  111                           }
  112                           else if(align==TRAILING) {
  113                               align = RIGHT;
  114                           }
  115                       }
  116                       else {
  117                           if(align==LEADING) {
  118                               align = RIGHT;
  119                           }
  120                           else if(align==TRAILING) {
  121                               align = LEFT;
  122                           }
  123                       }
  124   
  125                       switch (align) {
  126                       case SwingConstants.CENTER:
  127                           bounds.x += slop / 2;
  128                           bounds.width -= slop;
  129                           break;
  130                       case SwingConstants.RIGHT:
  131                           bounds.x += slop;
  132                           bounds.width -= slop;
  133                           break;
  134                       }
  135                   } else {
  136                       // adjust the allocation to match the bounded range.
  137                       bounds.width = hspan;
  138                       bounds.x -= vis.getValue();
  139                   }
  140               }
  141               return bounds;
  142           }
  143           return null;
  144       }
  145   
  146       /**
  147        * Update the visibility model with the associated JTextField
  148        * (if there is one) to reflect the current visibility as a
  149        * result of changes to the document model.  The bounded
  150        * range properties are updated.  If the view hasn't yet been
  151        * shown the extent will be zero and we just set it to be full
  152        * until determined otherwise.
  153        */
  154       void updateVisibilityModel() {
  155           Component c = getContainer();
  156           if (c instanceof JTextField) {
  157               JTextField field = (JTextField) c;
  158               BoundedRangeModel vis = field.getHorizontalVisibility();
  159               int hspan = (int) getPreferredSpan(X_AXIS);
  160               int extent = vis.getExtent();
  161               int maximum = Math.max(hspan, extent);
  162               extent = (extent == 0) ? maximum : extent;
  163               int value = maximum - extent;
  164               int oldValue = vis.getValue();
  165               if ((oldValue + extent) > maximum) {
  166                   oldValue = maximum - extent;
  167               }
  168               value = Math.max(0, Math.min(value, oldValue));
  169               vis.setRangeProperties(value, extent, 0, maximum, false);
  170           }
  171       }
  172   
  173       // --- View methods -------------------------------------------
  174   
  175       /**
  176        * Renders using the given rendering surface and area on that surface.
  177        * The view may need to do layout and create child views to enable
  178        * itself to render into the given allocation.
  179        *
  180        * @param g the rendering surface to use
  181        * @param a the allocated region to render into
  182        *
  183        * @see View#paint
  184        */
  185       public void paint(Graphics g, Shape a) {
  186           Rectangle r = (Rectangle) a;
  187           g.clipRect(r.x, r.y, r.width, r.height);
  188           super.paint(g, a);
  189       }
  190   
  191       /**
  192        * Adjusts <code>a</code> based on the visible region and returns it.
  193        */
  194       Shape adjustPaintRegion(Shape a) {
  195           return adjustAllocation(a);
  196       }
  197   
  198       /**
  199        * Determines the preferred span for this view along an
  200        * axis.
  201        *
  202        * @param axis may be either View.X_AXIS or View.Y_AXIS
  203        * @return   the span the view would like to be rendered into >= 0.
  204        *           Typically the view is told to render into the span
  205        *           that is returned, although there is no guarantee.
  206        *           The parent may choose to resize or break the view.
  207        */
  208       public float getPreferredSpan(int axis) {
  209           switch (axis) {
  210           case View.X_AXIS:
  211               Segment buff = SegmentCache.getSharedSegment();
  212               Document doc = getDocument();
  213               int width;
  214               try {
  215                   FontMetrics fm = getFontMetrics();
  216                   doc.getText(0, doc.getLength(), buff);
  217                   width = Utilities.getTabbedTextWidth(buff, fm, 0, this, 0);
  218                   if (buff.count > 0) {
  219                       Component c = getContainer();
  220                       firstLineOffset = sun.swing.SwingUtilities2.
  221                           getLeftSideBearing((c instanceof JComponent) ?
  222                                              (JComponent)c : null, fm,
  223                                              buff.array[buff.offset]);
  224                       firstLineOffset = Math.max(0, -firstLineOffset);
  225                   }
  226                   else {
  227                       firstLineOffset = 0;
  228                   }
  229               } catch (BadLocationException bl) {
  230                   width = 0;
  231               }
  232               SegmentCache.releaseSharedSegment(buff);
  233               return width + firstLineOffset;
  234           default:
  235               return super.getPreferredSpan(axis);
  236           }
  237       }
  238   
  239       /**
  240        * Determines the resizability of the view along the
  241        * given axis.  A value of 0 or less is not resizable.
  242        *
  243        * @param axis View.X_AXIS or View.Y_AXIS
  244        * @return the weight -> 1 for View.X_AXIS, else 0
  245        */
  246       public int getResizeWeight(int axis) {
  247           if (axis == View.X_AXIS) {
  248               return 1;
  249           }
  250           return 0;
  251       }
  252   
  253       /**
  254        * Provides a mapping from the document model coordinate space
  255        * to the coordinate space of the view mapped to it.
  256        *
  257        * @param pos the position to convert >= 0
  258        * @param a the allocated region to render into
  259        * @return the bounding box of the given position
  260        * @exception BadLocationException  if the given position does not
  261        *   represent a valid location in the associated document
  262        * @see View#modelToView
  263        */
  264       public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
  265           return super.modelToView(pos, adjustAllocation(a), b);
  266       }
  267   
  268       /**
  269        * Provides a mapping from the view coordinate space to the logical
  270        * coordinate space of the model.
  271        *
  272        * @param fx the X coordinate >= 0.0f
  273        * @param fy the Y coordinate >= 0.0f
  274        * @param a the allocated region to render into
  275        * @return the location within the model that best represents the
  276        *  given point in the view
  277        * @see View#viewToModel
  278        */
  279       public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) {
  280           return super.viewToModel(fx, fy, adjustAllocation(a), bias);
  281       }
  282   
  283       /**
  284        * Gives notification that something was inserted into the document
  285        * in a location that this view is responsible for.
  286        *
  287        * @param changes the change information from the associated document
  288        * @param a the current allocation of the view
  289        * @param f the factory to use to rebuild if the view has children
  290        * @see View#insertUpdate
  291        */
  292       public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
  293           super.insertUpdate(changes, adjustAllocation(a), f);
  294           updateVisibilityModel();
  295       }
  296   
  297       /**
  298        * Gives notification that something was removed from the document
  299        * in a location that this view is responsible for.
  300        *
  301        * @param changes the change information from the associated document
  302        * @param a the current allocation of the view
  303        * @param f the factory to use to rebuild if the view has children
  304        * @see View#removeUpdate
  305        */
  306       public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
  307           super.removeUpdate(changes, adjustAllocation(a), f);
  308           updateVisibilityModel();
  309       }
  310   
  311   }

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