Save This Page
Home » openjdk-7 » javax » swing » text » [javadoc | source]
    1   /*
    2    * Copyright 1997-2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   package javax.swing.text;
   26   
   27   import java.awt;
   28   import java.util.BitSet;
   29   import java.util.Vector;
   30   import javax.swing.SizeRequirements;
   31   import javax.swing.event.DocumentEvent;
   32   
   33   import javax.swing.text.html.HTML;
   34   
   35   /**
   36    * <p>
   37    * Implements View interface for a table, that is composed of an
   38    * element structure where the child elements of the element
   39    * this view is responsible for represent rows and the child
   40    * elements of the row elements are cells.  The cell elements can
   41    * have an arbitrary element structure under them, which will
   42    * be built with the ViewFactory returned by the getViewFactory
   43    * method.
   44    * <pre>
   45    *
   46    * &nbsp;  TABLE
   47    * &nbsp;    ROW
   48    * &nbsp;      CELL
   49    * &nbsp;      CELL
   50    * &nbsp;    ROW
   51    * &nbsp;      CELL
   52    * &nbsp;      CELL
   53    *
   54    * </pre>
   55    * <p>
   56    * This is implemented as a hierarchy of boxes, the table itself
   57    * is a vertical box, the rows are horizontal boxes, and the cells
   58    * are vertical boxes.  The cells are allowed to span multiple
   59    * columns and rows.  By default, the table can be thought of as
   60    * being formed over a grid (i.e. somewhat like one would find in
   61    * gridbag layout), where table cells can request to span more
   62    * than one grid cell.  The default horizontal span of table cells
   63    * will be based upon this grid, but can be changed by reimplementing
   64    * the requested span of the cell (i.e. table cells can have independant
   65    * spans if desired).
   66    *
   67    * @author  Timothy Prinzing
   68    * @see     View
   69    */
   70   public abstract class TableView extends BoxView {
   71   
   72       /**
   73        * Constructs a TableView for the given element.
   74        *
   75        * @param elem the element that this view is responsible for
   76        */
   77       public TableView(Element elem) {
   78           super(elem, View.Y_AXIS);
   79           rows = new Vector();
   80           gridValid = false;
   81       }
   82   
   83       /**
   84        * Creates a new table row.
   85        *
   86        * @param elem an element
   87        * @return the row
   88        */
   89       protected TableRow createTableRow(Element elem) {
   90           return new TableRow(elem);
   91       }
   92   
   93       /**
   94        * @deprecated Table cells can now be any arbitrary
   95        * View implementation and should be produced by the
   96        * ViewFactory rather than the table.
   97        *
   98        * @param elem an element
   99        * @return the cell
  100        */
  101       @Deprecated
  102       protected TableCell createTableCell(Element elem) {
  103           return new TableCell(elem);
  104       }
  105   
  106       /**
  107        * The number of columns in the table.
  108        */
  109       int getColumnCount() {
  110           return columnSpans.length;
  111       }
  112   
  113       /**
  114        * Fetches the span (width) of the given column.
  115        * This is used by the nested cells to query the
  116        * sizes of grid locations outside of themselves.
  117        */
  118       int getColumnSpan(int col) {
  119           return columnSpans[col];
  120       }
  121   
  122       /**
  123        * The number of rows in the table.
  124        */
  125       int getRowCount() {
  126           return rows.size();
  127       }
  128   
  129       /**
  130        * Fetches the span (height) of the given row.
  131        */
  132       int getRowSpan(int row) {
  133           View rv = getRow(row);
  134           if (rv != null) {
  135               return (int) rv.getPreferredSpan(Y_AXIS);
  136           }
  137           return 0;
  138       }
  139   
  140       TableRow getRow(int row) {
  141           if (row < rows.size()) {
  142               return (TableRow) rows.elementAt(row);
  143           }
  144           return null;
  145       }
  146   
  147       /**
  148        * Determines the number of columns occupied by
  149        * the table cell represented by given element.
  150        */
  151       /*protected*/ int getColumnsOccupied(View v) {
  152           // PENDING(prinz) this code should be in the html
  153           // paragraph, but we can't add api to enable it.
  154           AttributeSet a = v.getElement().getAttributes();
  155           String s = (String) a.getAttribute(HTML.Attribute.COLSPAN);
  156           if (s != null) {
  157               try {
  158                   return Integer.parseInt(s);
  159               } catch (NumberFormatException nfe) {
  160                   // fall through to one column
  161               }
  162           }
  163   
  164           return 1;
  165       }
  166   
  167       /**
  168        * Determines the number of rows occupied by
  169        * the table cell represented by given element.
  170        */
  171       /*protected*/ int getRowsOccupied(View v) {
  172           // PENDING(prinz) this code should be in the html
  173           // paragraph, but we can't add api to enable it.
  174           AttributeSet a = v.getElement().getAttributes();
  175           String s = (String) a.getAttribute(HTML.Attribute.ROWSPAN);
  176           if (s != null) {
  177               try {
  178                   return Integer.parseInt(s);
  179               } catch (NumberFormatException nfe) {
  180                   // fall through to one row
  181               }
  182           }
  183   
  184           return 1;
  185       }
  186   
  187       /*protected*/ void invalidateGrid() {
  188           gridValid = false;
  189       }
  190   
  191       protected void forwardUpdate(DocumentEvent.ElementChange ec,
  192                                        DocumentEvent e, Shape a, ViewFactory f) {
  193           super.forwardUpdate(ec, e, a, f);
  194           // A change in any of the table cells usually effects the whole table,
  195           // so redraw it all!
  196           if (a != null) {
  197               Component c = getContainer();
  198               if (c != null) {
  199                   Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a :
  200                                      a.getBounds();
  201                   c.repaint(alloc.x, alloc.y, alloc.width, alloc.height);
  202               }
  203           }
  204       }
  205   
  206       /**
  207        * Change the child views.  This is implemented to
  208        * provide the superclass behavior and invalidate the
  209        * grid so that rows and columns will be recalculated.
  210        */
  211       public void replace(int offset, int length, View[] views) {
  212           super.replace(offset, length, views);
  213           invalidateGrid();
  214       }
  215   
  216       /**
  217        * Fill in the grid locations that are placeholders
  218        * for multi-column, multi-row, and missing grid
  219        * locations.
  220        */
  221       void updateGrid() {
  222           if (! gridValid) {
  223               // determine which views are table rows and clear out
  224               // grid points marked filled.
  225               rows.removeAllElements();
  226               int n = getViewCount();
  227               for (int i = 0; i < n; i++) {
  228                   View v = getView(i);
  229                   if (v instanceof TableRow) {
  230                       rows.addElement(v);
  231                       TableRow rv = (TableRow) v;
  232                       rv.clearFilledColumns();
  233                       rv.setRow(i);
  234                   }
  235               }
  236   
  237               int maxColumns = 0;
  238               int nrows = rows.size();
  239               for (int row = 0; row < nrows; row++) {
  240                   TableRow rv = getRow(row);
  241                   int col = 0;
  242                   for (int cell = 0; cell < rv.getViewCount(); cell++, col++) {
  243                       View cv = rv.getView(cell);
  244                       // advance to a free column
  245                       for (; rv.isFilled(col); col++);
  246                       int rowSpan = getRowsOccupied(cv);
  247                       int colSpan = getColumnsOccupied(cv);
  248                       if ((colSpan > 1) || (rowSpan > 1)) {
  249                           // fill in the overflow entries for this cell
  250                           int rowLimit = row + rowSpan;
  251                           int colLimit = col + colSpan;
  252                           for (int i = row; i < rowLimit; i++) {
  253                               for (int j = col; j < colLimit; j++) {
  254                                   if (i != row || j != col) {
  255                                       addFill(i, j);
  256                                   }
  257                               }
  258                           }
  259                           if (colSpan > 1) {
  260                               col += colSpan - 1;
  261                           }
  262                       }
  263                   }
  264                   maxColumns = Math.max(maxColumns, col);
  265               }
  266   
  267               // setup the column layout/requirements
  268               columnSpans = new int[maxColumns];
  269               columnOffsets = new int[maxColumns];
  270               columnRequirements = new SizeRequirements[maxColumns];
  271               for (int i = 0; i < maxColumns; i++) {
  272                   columnRequirements[i] = new SizeRequirements();
  273               }
  274               gridValid = true;
  275           }
  276       }
  277   
  278       /**
  279        * Mark a grid location as filled in for a cells overflow.
  280        */
  281       void addFill(int row, int col) {
  282           TableRow rv = getRow(row);
  283           if (rv != null) {
  284               rv.fillColumn(col);
  285           }
  286       }
  287   
  288       /**
  289        * Lays out the columns to fit within the given target span.
  290        * Returns the results through {@code offsets} and {@code spans}.
  291        *
  292        * @param targetSpan the given span for total of all the table
  293        *  columns
  294        * @param reqs the requirements desired for each column.  This
  295        *  is the column maximum of the cells minimum, preferred, and
  296        *  maximum requested span
  297        * @param spans the return value of how much to allocated to
  298        *  each column
  299        * @param offsets the return value of the offset from the
  300        *  origin for each column
  301        */
  302       protected void layoutColumns(int targetSpan, int[] offsets, int[] spans,
  303                                    SizeRequirements[] reqs) {
  304           // allocate using the convenience method on SizeRequirements
  305           SizeRequirements.calculateTiledPositions(targetSpan, null, reqs,
  306                                                    offsets, spans);
  307       }
  308   
  309       /**
  310        * Perform layout for the minor axis of the box (i.e. the
  311        * axis orthoginal to the axis that it represents).  The results
  312        * of the layout should be placed in the given arrays which represent
  313        * the allocations to the children along the minor axis.  This
  314        * is called by the superclass whenever the layout needs to be
  315        * updated along the minor axis.
  316        * <p>
  317        * This is implemented to call the
  318        * <a href="#layoutColumns">layoutColumns</a> method, and then
  319        * forward to the superclass to actually carry out the layout
  320        * of the tables rows.
  321        *
  322        * @param targetSpan the total span given to the view, which
  323        *  whould be used to layout the children.
  324        * @param axis the axis being layed out.
  325        * @param offsets the offsets from the origin of the view for
  326        *  each of the child views.  This is a return value and is
  327        *  filled in by the implementation of this method.
  328        * @param spans the span of each child view.  This is a return
  329        *  value and is filled in by the implementation of this method.
  330        */
  331       protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
  332           // make grid is properly represented
  333           updateGrid();
  334   
  335           // all of the row layouts are invalid, so mark them that way
  336           int n = getRowCount();
  337           for (int i = 0; i < n; i++) {
  338               TableRow row = getRow(i);
  339               row.layoutChanged(axis);
  340           }
  341   
  342           // calculate column spans
  343           layoutColumns(targetSpan, columnOffsets, columnSpans, columnRequirements);
  344   
  345           // continue normal layout
  346           super.layoutMinorAxis(targetSpan, axis, offsets, spans);
  347       }
  348   
  349       /**
  350        * Calculate the requirements for the minor axis.  This is called by
  351        * the superclass whenever the requirements need to be updated (i.e.
  352        * a preferenceChanged was messaged through this view).
  353        * <p>
  354        * This is implemented to calculate the requirements as the sum of the
  355        * requirements of the columns.
  356        */
  357       protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
  358           updateGrid();
  359   
  360           // calculate column requirements for each column
  361           calculateColumnRequirements(axis);
  362   
  363   
  364           // the requirements are the sum of the columns.
  365           if (r == null) {
  366               r = new SizeRequirements();
  367           }
  368           long min = 0;
  369           long pref = 0;
  370           long max = 0;
  371           for (int i = 0; i < columnRequirements.length; i++) {
  372               SizeRequirements req = columnRequirements[i];
  373               min += req.minimum;
  374               pref += req.preferred;
  375               max += req.maximum;
  376           }
  377           r.minimum = (int) min;
  378           r.preferred = (int) pref;
  379           r.maximum = (int) max;
  380           r.alignment = 0;
  381           return r;
  382       }
  383   
  384       /*
  385       boolean shouldTrace() {
  386           AttributeSet a = getElement().getAttributes();
  387           Object o = a.getAttribute(HTML.Attribute.ID);
  388           if ((o != null) && o.equals("debug")) {
  389               return true;
  390           }
  391           return false;
  392       }
  393       */
  394   
  395       /**
  396        * Calculate the requirements for each column.  The calculation
  397        * is done as two passes over the table.  The table cells that
  398        * occupy a single column are scanned first to determine the
  399        * maximum of minimum, preferred, and maximum spans along the
  400        * give axis.  Table cells that span multiple columns are excluded
  401        * from the first pass.  A second pass is made to determine if
  402        * the cells that span multiple columns are satisfied.  If the
  403        * column requirements are not satisified, the needs of the
  404        * multi-column cell is mixed into the existing column requirements.
  405        * The calculation of the multi-column distribution is based upon
  406        * the proportions of the existing column requirements and taking
  407        * into consideration any constraining maximums.
  408        */
  409       void calculateColumnRequirements(int axis) {
  410           // pass 1 - single column cells
  411           boolean hasMultiColumn = false;
  412           int nrows = getRowCount();
  413           for (int i = 0; i < nrows; i++) {
  414               TableRow row = getRow(i);
  415               int col = 0;
  416               int ncells = row.getViewCount();
  417               for (int cell = 0; cell < ncells; cell++, col++) {
  418                   View cv = row.getView(cell);
  419                   for (; row.isFilled(col); col++); // advance to a free column
  420                   int rowSpan = getRowsOccupied(cv);
  421                   int colSpan = getColumnsOccupied(cv);
  422                   if (colSpan == 1) {
  423                       checkSingleColumnCell(axis, col, cv);
  424                   } else {
  425                       hasMultiColumn = true;
  426                       col += colSpan - 1;
  427                   }
  428               }
  429           }
  430   
  431           // pass 2 - multi-column cells
  432           if (hasMultiColumn) {
  433               for (int i = 0; i < nrows; i++) {
  434                   TableRow row = getRow(i);
  435                   int col = 0;
  436                   int ncells = row.getViewCount();
  437                   for (int cell = 0; cell < ncells; cell++, col++) {
  438                       View cv = row.getView(cell);
  439                       for (; row.isFilled(col); col++); // advance to a free column
  440                       int colSpan = getColumnsOccupied(cv);
  441                       if (colSpan > 1) {
  442                           checkMultiColumnCell(axis, col, colSpan, cv);
  443                           col += colSpan - 1;
  444                       }
  445                   }
  446               }
  447           }
  448   
  449           /*
  450           if (shouldTrace()) {
  451               System.err.println("calc:");
  452               for (int i = 0; i < columnRequirements.length; i++) {
  453                   System.err.println(" " + i + ": " + columnRequirements[i]);
  454               }
  455           }
  456           */
  457       }
  458   
  459       /**
  460        * check the requirements of a table cell that spans a single column.
  461        */
  462       void checkSingleColumnCell(int axis, int col, View v) {
  463           SizeRequirements req = columnRequirements[col];
  464           req.minimum = Math.max((int) v.getMinimumSpan(axis), req.minimum);
  465           req.preferred = Math.max((int) v.getPreferredSpan(axis), req.preferred);
  466           req.maximum = Math.max((int) v.getMaximumSpan(axis), req.maximum);
  467       }
  468   
  469       /**
  470        * check the requirements of a table cell that spans multiple
  471        * columns.
  472        */
  473       void checkMultiColumnCell(int axis, int col, int ncols, View v) {
  474           // calculate the totals
  475           long min = 0;
  476           long pref = 0;
  477           long max = 0;
  478           for (int i = 0; i < ncols; i++) {
  479               SizeRequirements req = columnRequirements[col + i];
  480               min += req.minimum;
  481               pref += req.preferred;
  482               max += req.maximum;
  483           }
  484   
  485           // check if the minimum size needs adjustment.
  486           int cmin = (int) v.getMinimumSpan(axis);
  487           if (cmin > min) {
  488               /*
  489                * the columns that this cell spans need adjustment to fit
  490                * this table cell.... calculate the adjustments.  The
  491                * maximum for each cell is the maximum of the existing
  492                * maximum or the amount needed by the cell.
  493                */
  494               SizeRequirements[] reqs = new SizeRequirements[ncols];
  495               for (int i = 0; i < ncols; i++) {
  496                   SizeRequirements r = reqs[i] = columnRequirements[col + i];
  497                   r.maximum = Math.max(r.maximum, (int) v.getMaximumSpan(axis));
  498               }
  499               int[] spans = new int[ncols];
  500               int[] offsets = new int[ncols];
  501               SizeRequirements.calculateTiledPositions(cmin, null, reqs,
  502                                                        offsets, spans);
  503               // apply the adjustments
  504               for (int i = 0; i < ncols; i++) {
  505                   SizeRequirements req = reqs[i];
  506                   req.minimum = Math.max(spans[i], req.minimum);
  507                   req.preferred = Math.max(req.minimum, req.preferred);
  508                   req.maximum = Math.max(req.preferred, req.maximum);
  509               }
  510           }
  511   
  512           // check if the preferred size needs adjustment.
  513           int cpref = (int) v.getPreferredSpan(axis);
  514           if (cpref > pref) {
  515               /*
  516                * the columns that this cell spans need adjustment to fit
  517                * this table cell.... calculate the adjustments.  The
  518                * maximum for each cell is the maximum of the existing
  519                * maximum or the amount needed by the cell.
  520                */
  521               SizeRequirements[] reqs = new SizeRequirements[ncols];
  522               for (int i = 0; i < ncols; i++) {
  523                   SizeRequirements r = reqs[i] = columnRequirements[col + i];
  524               }
  525               int[] spans = new int[ncols];
  526               int[] offsets = new int[ncols];
  527               SizeRequirements.calculateTiledPositions(cpref, null, reqs,
  528                                                        offsets, spans);
  529               // apply the adjustments
  530               for (int i = 0; i < ncols; i++) {
  531                   SizeRequirements req = reqs[i];
  532                   req.preferred = Math.max(spans[i], req.preferred);
  533                   req.maximum = Math.max(req.preferred, req.maximum);
  534               }
  535           }
  536   
  537       }
  538   
  539       /**
  540        * Fetches the child view that represents the given position in
  541        * the model.  This is implemented to walk through the children
  542        * looking for a range that contains the given position.  In this
  543        * view the children do not necessarily have a one to one mapping
  544        * with the child elements.
  545        *
  546        * @param pos  the search position >= 0
  547        * @param a  the allocation to the table on entry, and the
  548        *   allocation of the view containing the position on exit
  549        * @return  the view representing the given position, or
  550        *   <code>null</code> if there isn't one
  551        */
  552       protected View getViewAtPosition(int pos, Rectangle a) {
  553           int n = getViewCount();
  554           for (int i = 0; i < n; i++) {
  555               View v = getView(i);
  556               int p0 = v.getStartOffset();
  557               int p1 = v.getEndOffset();
  558               if ((pos >= p0) && (pos < p1)) {
  559                   // it's in this view.
  560                   if (a != null) {
  561                       childAllocation(i, a);
  562                   }
  563                   return v;
  564               }
  565           }
  566           if (pos == getEndOffset()) {
  567               View v = getView(n - 1);
  568               if (a != null) {
  569                   this.childAllocation(n - 1, a);
  570               }
  571               return v;
  572           }
  573           return null;
  574       }
  575   
  576       // ---- variables ----------------------------------------------------
  577   
  578       int[] columnSpans;
  579       int[] columnOffsets;
  580       SizeRequirements[] columnRequirements;
  581       Vector rows;
  582       boolean gridValid;
  583       static final private BitSet EMPTY = new BitSet();
  584   
  585       /**
  586        * View of a row in a row-centric table.
  587        */
  588       public class TableRow extends BoxView {
  589   
  590           /**
  591            * Constructs a TableView for the given element.
  592            *
  593            * @param elem the element that this view is responsible for
  594            * @since 1.4
  595            */
  596           public TableRow(Element elem) {
  597               super(elem, View.X_AXIS);
  598               fillColumns = new BitSet();
  599           }
  600   
  601           void clearFilledColumns() {
  602               fillColumns.and(EMPTY);
  603           }
  604   
  605           void fillColumn(int col) {
  606               fillColumns.set(col);
  607           }
  608   
  609           boolean isFilled(int col) {
  610               return fillColumns.get(col);
  611           }
  612   
  613           /** get location in the overall set of rows */
  614           int getRow() {
  615               return row;
  616           }
  617   
  618           /**
  619            * set location in the overall set of rows, this is
  620            * set by the TableView.updateGrid() method.
  621            */
  622           void setRow(int row) {
  623               this.row = row;
  624           }
  625   
  626           /**
  627            * The number of columns present in this row.
  628            */
  629           int getColumnCount() {
  630               int nfill = 0;
  631               int n = fillColumns.size();
  632               for (int i = 0; i < n; i++) {
  633                   if (fillColumns.get(i)) {
  634                       nfill ++;
  635                   }
  636               }
  637               return getViewCount() + nfill;
  638           }
  639   
  640           /**
  641            * Change the child views.  This is implemented to
  642            * provide the superclass behavior and invalidate the
  643            * grid so that rows and columns will be recalculated.
  644            */
  645           public void replace(int offset, int length, View[] views) {
  646               super.replace(offset, length, views);
  647               invalidateGrid();
  648           }
  649   
  650           /**
  651            * Perform layout for the major axis of the box (i.e. the
  652            * axis that it represents).  The results of the layout should
  653            * be placed in the given arrays which represent the allocations
  654            * to the children along the major axis.
  655            * <p>
  656            * This is re-implemented to give each child the span of the column
  657            * width for the table, and to give cells that span multiple columns
  658            * the multi-column span.
  659            *
  660            * @param targetSpan the total span given to the view, which
  661            *  whould be used to layout the children.
  662            * @param axis the axis being layed out.
  663            * @param offsets the offsets from the origin of the view for
  664            *  each of the child views.  This is a return value and is
  665            *  filled in by the implementation of this method.
  666            * @param spans the span of each child view.  This is a return
  667            *  value and is filled in by the implementation of this method.
  668            */
  669           protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
  670               int col = 0;
  671               int ncells = getViewCount();
  672               for (int cell = 0; cell < ncells; cell++, col++) {
  673                   View cv = getView(cell);
  674                   for (; isFilled(col); col++); // advance to a free column
  675                   int colSpan = getColumnsOccupied(cv);
  676                   spans[cell] = columnSpans[col];
  677                   offsets[cell] = columnOffsets[col];
  678                   if (colSpan > 1) {
  679                       int n = columnSpans.length;
  680                       for (int j = 1; j < colSpan; j++) {
  681                           // Because the table may be only partially formed, some
  682                           // of the columns may not yet exist.  Therefore we check
  683                           // the bounds.
  684                           if ((col+j) < n) {
  685                               spans[cell] += columnSpans[col+j];
  686                           }
  687                       }
  688                       col += colSpan - 1;
  689                   }
  690               }
  691           }
  692   
  693           /**
  694            * Perform layout for the minor axis of the box (i.e. the
  695            * axis orthoginal to the axis that it represents).  The results
  696            * of the layout should be placed in the given arrays which represent
  697            * the allocations to the children along the minor axis.  This
  698            * is called by the superclass whenever the layout needs to be
  699            * updated along the minor axis.
  700            * <p>
  701            * This is implemented to delegate to the superclass, then adjust
  702            * the span for any cell that spans multiple rows.
  703            *
  704            * @param targetSpan the total span given to the view, which
  705            *  whould be used to layout the children.
  706            * @param axis the axis being layed out.
  707            * @param offsets the offsets from the origin of the view for
  708            *  each of the child views.  This is a return value and is
  709            *  filled in by the implementation of this method.
  710            * @param spans the span of each child view.  This is a return
  711            *  value and is filled in by the implementation of this method.
  712            */
  713           protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
  714               super.layoutMinorAxis(targetSpan, axis, offsets, spans);
  715               int col = 0;
  716               int ncells = getViewCount();
  717               for (int cell = 0; cell < ncells; cell++, col++) {
  718                   View cv = getView(cell);
  719                   for (; isFilled(col); col++); // advance to a free column
  720                   int colSpan = getColumnsOccupied(cv);
  721                   int rowSpan = getRowsOccupied(cv);
  722                   if (rowSpan > 1) {
  723                       for (int j = 1; j < rowSpan; j++) {
  724                           // test bounds of each row because it may not exist
  725                           // either because of error or because the table isn't
  726                           // fully loaded yet.
  727                           int row = getRow() + j;
  728                           if (row < TableView.this.getViewCount()) {
  729                               int span = TableView.this.getSpan(Y_AXIS, getRow()+j);
  730                               spans[cell] += span;
  731                           }
  732                       }
  733                   }
  734                   if (colSpan > 1) {
  735                       col += colSpan - 1;
  736                   }
  737               }
  738           }
  739   
  740           /**
  741            * Determines the resizability of the view along the
  742            * given axis.  A value of 0 or less is not resizable.
  743            *
  744            * @param axis may be either View.X_AXIS or View.Y_AXIS
  745            * @return the resize weight
  746            * @exception IllegalArgumentException for an invalid axis
  747            */
  748           public int getResizeWeight(int axis) {
  749               return 1;
  750           }
  751   
  752           /**
  753            * Fetches the child view that represents the given position in
  754            * the model.  This is implemented to walk through the children
  755            * looking for a range that contains the given position.  In this
  756            * view the children do not necessarily have a one to one mapping
  757            * with the child elements.
  758            *
  759            * @param pos  the search position >= 0
  760            * @param a  the allocation to the table on entry, and the
  761            *   allocation of the view containing the position on exit
  762            * @return  the view representing the given position, or
  763            *   <code>null</code> if there isn't one
  764            */
  765           protected View getViewAtPosition(int pos, Rectangle a) {
  766               int n = getViewCount();
  767               for (int i = 0; i < n; i++) {
  768                   View v = getView(i);
  769                   int p0 = v.getStartOffset();
  770                   int p1 = v.getEndOffset();
  771                   if ((pos >= p0) && (pos < p1)) {
  772                       // it's in this view.
  773                       if (a != null) {
  774                           childAllocation(i, a);
  775                       }
  776                       return v;
  777                   }
  778               }
  779               if (pos == getEndOffset()) {
  780                   View v = getView(n - 1);
  781                   if (a != null) {
  782                       this.childAllocation(n - 1, a);
  783                   }
  784                   return v;
  785               }
  786               return null;
  787           }
  788   
  789           /** columns filled by multi-column or multi-row cells */
  790           BitSet fillColumns;
  791           /** the row within the overall grid */
  792           int row;
  793       }
  794   
  795       /**
  796        * @deprecated  A table cell can now be any View implementation.
  797        */
  798       @Deprecated
  799       public class TableCell extends BoxView implements GridCell {
  800   
  801           /**
  802            * Constructs a TableCell for the given element.
  803            *
  804            * @param elem the element that this view is responsible for
  805            * @since 1.4
  806            */
  807           public TableCell(Element elem) {
  808               super(elem, View.Y_AXIS);
  809           }
  810   
  811           // --- GridCell methods -------------------------------------
  812   
  813           /**
  814            * Gets the number of columns this cell spans (e.g. the
  815            * grid width).
  816            *
  817            * @return the number of columns
  818            */
  819           public int getColumnCount() {
  820               return 1;
  821           }
  822   
  823           /**
  824            * Gets the number of rows this cell spans (that is, the
  825            * grid height).
  826            *
  827            * @return the number of rows
  828            */
  829           public int getRowCount() {
  830               return 1;
  831           }
  832   
  833   
  834           /**
  835            * Sets the grid location.
  836            *
  837            * @param row the row >= 0
  838            * @param col the column >= 0
  839            */
  840           public void setGridLocation(int row, int col) {
  841               this.row = row;
  842               this.col = col;
  843           }
  844   
  845           /**
  846            * Gets the row of the grid location
  847            */
  848           public int getGridRow() {
  849               return row;
  850           }
  851   
  852           /**
  853            * Gets the column of the grid location
  854            */
  855           public int getGridColumn() {
  856               return col;
  857           }
  858   
  859           int row;
  860           int col;
  861       }
  862   
  863       /**
  864        * <em>
  865        * THIS IS NO LONGER USED, AND WILL BE REMOVED IN THE
  866        * NEXT RELEASE.  THE JCK SIGNATURE TEST THINKS THIS INTERFACE
  867        * SHOULD EXIST
  868        * </em>
  869        */
  870       interface GridCell {
  871   
  872           /**
  873            * Sets the grid location.
  874            *
  875            * @param row the row >= 0
  876            * @param col the column >= 0
  877            */
  878           public void setGridLocation(int row, int col);
  879   
  880           /**
  881            * Gets the row of the grid location
  882            */
  883           public int getGridRow();
  884   
  885           /**
  886            * Gets the column of the grid location
  887            */
  888           public int getGridColumn();
  889   
  890           /**
  891            * Gets the number of columns this cell spans (e.g. the
  892            * grid width).
  893            *
  894            * @return the number of columns
  895            */
  896           public int getColumnCount();
  897   
  898           /**
  899            * Gets the number of rows this cell spans (that is, the
  900            * grid height).
  901            *
  902            * @return the number of rows
  903            */
  904           public int getRowCount();
  905   
  906       }
  907   
  908   }

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