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

    1   /*
    2    * Copyright (c) 1997, 2011, 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 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<TableRow>();
   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 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((TableRow) 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        * {@link #layoutColumns layoutColumns} 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 (SizeRequirements req : columnRequirements) {
  372               min += req.minimum;
  373               pref += req.preferred;
  374               max += req.maximum;
  375           }
  376           r.minimum = (int) min;
  377           r.preferred = (int) pref;
  378           r.maximum = (int) max;
  379           r.alignment = 0;
  380           return r;
  381       }
  382   
  383       /*
  384       boolean shouldTrace() {
  385           AttributeSet a = getElement().getAttributes();
  386           Object o = a.getAttribute(HTML.Attribute.ID);
  387           if ((o != null) && o.equals("debug")) {
  388               return true;
  389           }
  390           return false;
  391       }
  392       */
  393   
  394       /**
  395        * Calculate the requirements for each column.  The calculation
  396        * is done as two passes over the table.  The table cells that
  397        * occupy a single column are scanned first to determine the
  398        * maximum of minimum, preferred, and maximum spans along the
  399        * give axis.  Table cells that span multiple columns are excluded
  400        * from the first pass.  A second pass is made to determine if
  401        * the cells that span multiple columns are satisfied.  If the
  402        * column requirements are not satisified, the needs of the
  403        * multi-column cell is mixed into the existing column requirements.
  404        * The calculation of the multi-column distribution is based upon
  405        * the proportions of the existing column requirements and taking
  406        * into consideration any constraining maximums.
  407        */
  408       void calculateColumnRequirements(int axis) {
  409           // pass 1 - single column cells
  410           boolean hasMultiColumn = false;
  411           int nrows = getRowCount();
  412           for (int i = 0; i < nrows; i++) {
  413               TableRow row = getRow(i);
  414               int col = 0;
  415               int ncells = row.getViewCount();
  416               for (int cell = 0; cell < ncells; cell++, col++) {
  417                   View cv = row.getView(cell);
  418                   for (; row.isFilled(col); col++); // advance to a free column
  419                   int rowSpan = getRowsOccupied(cv);
  420                   int colSpan = getColumnsOccupied(cv);
  421                   if (colSpan == 1) {
  422                       checkSingleColumnCell(axis, col, cv);
  423                   } else {
  424                       hasMultiColumn = true;
  425                       col += colSpan - 1;
  426                   }
  427               }
  428           }
  429   
  430           // pass 2 - multi-column cells
  431           if (hasMultiColumn) {
  432               for (int i = 0; i < nrows; i++) {
  433                   TableRow row = getRow(i);
  434                   int col = 0;
  435                   int ncells = row.getViewCount();
  436                   for (int cell = 0; cell < ncells; cell++, col++) {
  437                       View cv = row.getView(cell);
  438                       for (; row.isFilled(col); col++); // advance to a free column
  439                       int colSpan = getColumnsOccupied(cv);
  440                       if (colSpan > 1) {
  441                           checkMultiColumnCell(axis, col, colSpan, cv);
  442                           col += colSpan - 1;
  443                       }
  444                   }
  445               }
  446           }
  447   
  448           /*
  449           if (shouldTrace()) {
  450               System.err.println("calc:");
  451               for (int i = 0; i < columnRequirements.length; i++) {
  452                   System.err.println(" " + i + ": " + columnRequirements[i]);
  453               }
  454           }
  455           */
  456       }
  457   
  458       /**
  459        * check the requirements of a table cell that spans a single column.
  460        */
  461       void checkSingleColumnCell(int axis, int col, View v) {
  462           SizeRequirements req = columnRequirements[col];
  463           req.minimum = Math.max((int) v.getMinimumSpan(axis), req.minimum);
  464           req.preferred = Math.max((int) v.getPreferredSpan(axis), req.preferred);
  465           req.maximum = Math.max((int) v.getMaximumSpan(axis), req.maximum);
  466       }
  467   
  468       /**
  469        * check the requirements of a table cell that spans multiple
  470        * columns.
  471        */
  472       void checkMultiColumnCell(int axis, int col, int ncols, View v) {
  473           // calculate the totals
  474           long min = 0;
  475           long pref = 0;
  476           long max = 0;
  477           for (int i = 0; i < ncols; i++) {
  478               SizeRequirements req = columnRequirements[col + i];
  479               min += req.minimum;
  480               pref += req.preferred;
  481               max += req.maximum;
  482           }
  483   
  484           // check if the minimum size needs adjustment.
  485           int cmin = (int) v.getMinimumSpan(axis);
  486           if (cmin > min) {
  487               /*
  488                * the columns that this cell spans need adjustment to fit
  489                * this table cell.... calculate the adjustments.  The
  490                * maximum for each cell is the maximum of the existing
  491                * maximum or the amount needed by the cell.
  492                */
  493               SizeRequirements[] reqs = new SizeRequirements[ncols];
  494               for (int i = 0; i < ncols; i++) {
  495                   SizeRequirements r = reqs[i] = columnRequirements[col + i];
  496                   r.maximum = Math.max(r.maximum, (int) v.getMaximumSpan(axis));
  497               }
  498               int[] spans = new int[ncols];
  499               int[] offsets = new int[ncols];
  500               SizeRequirements.calculateTiledPositions(cmin, null, reqs,
  501                                                        offsets, spans);
  502               // apply the adjustments
  503               for (int i = 0; i < ncols; i++) {
  504                   SizeRequirements req = reqs[i];
  505                   req.minimum = Math.max(spans[i], req.minimum);
  506                   req.preferred = Math.max(req.minimum, req.preferred);
  507                   req.maximum = Math.max(req.preferred, req.maximum);
  508               }
  509           }
  510   
  511           // check if the preferred size needs adjustment.
  512           int cpref = (int) v.getPreferredSpan(axis);
  513           if (cpref > pref) {
  514               /*
  515                * the columns that this cell spans need adjustment to fit
  516                * this table cell.... calculate the adjustments.  The
  517                * maximum for each cell is the maximum of the existing
  518                * maximum or the amount needed by the cell.
  519                */
  520               SizeRequirements[] reqs = new SizeRequirements[ncols];
  521               for (int i = 0; i < ncols; i++) {
  522                   SizeRequirements r = reqs[i] = columnRequirements[col + i];
  523               }
  524               int[] spans = new int[ncols];
  525               int[] offsets = new int[ncols];
  526               SizeRequirements.calculateTiledPositions(cpref, null, reqs,
  527                                                        offsets, spans);
  528               // apply the adjustments
  529               for (int i = 0; i < ncols; i++) {
  530                   SizeRequirements req = reqs[i];
  531                   req.preferred = Math.max(spans[i], req.preferred);
  532                   req.maximum = Math.max(req.preferred, req.maximum);
  533               }
  534           }
  535   
  536       }
  537   
  538       /**
  539        * Fetches the child view that represents the given position in
  540        * the model.  This is implemented to walk through the children
  541        * looking for a range that contains the given position.  In this
  542        * view the children do not necessarily have a one to one mapping
  543        * with the child elements.
  544        *
  545        * @param pos  the search position >= 0
  546        * @param a  the allocation to the table on entry, and the
  547        *   allocation of the view containing the position on exit
  548        * @return  the view representing the given position, or
  549        *   <code>null</code> if there isn't one
  550        */
  551       protected View getViewAtPosition(int pos, Rectangle a) {
  552           int n = getViewCount();
  553           for (int i = 0; i < n; i++) {
  554               View v = getView(i);
  555               int p0 = v.getStartOffset();
  556               int p1 = v.getEndOffset();
  557               if ((pos >= p0) && (pos < p1)) {
  558                   // it's in this view.
  559                   if (a != null) {
  560                       childAllocation(i, a);
  561                   }
  562                   return v;
  563               }
  564           }
  565           if (pos == getEndOffset()) {
  566               View v = getView(n - 1);
  567               if (a != null) {
  568                   this.childAllocation(n - 1, a);
  569               }
  570               return v;
  571           }
  572           return null;
  573       }
  574   
  575       // ---- variables ----------------------------------------------------
  576   
  577       int[] columnSpans;
  578       int[] columnOffsets;
  579       SizeRequirements[] columnRequirements;
  580       Vector<TableRow> rows;
  581       boolean gridValid;
  582       static final private BitSet EMPTY = new BitSet();
  583   
  584       /**
  585        * View of a row in a row-centric table.
  586        */
  587       public class TableRow extends BoxView {
  588   
  589           /**
  590            * Constructs a TableView for the given element.
  591            *
  592            * @param elem the element that this view is responsible for
  593            * @since 1.4
  594            */
  595           public TableRow(Element elem) {
  596               super(elem, View.X_AXIS);
  597               fillColumns = new BitSet();
  598           }
  599   
  600           void clearFilledColumns() {
  601               fillColumns.and(EMPTY);
  602           }
  603   
  604           void fillColumn(int col) {
  605               fillColumns.set(col);
  606           }
  607   
  608           boolean isFilled(int col) {
  609               return fillColumns.get(col);
  610           }
  611   
  612           /** get location in the overall set of rows */
  613           int getRow() {
  614               return row;
  615           }
  616   
  617           /**
  618            * set location in the overall set of rows, this is
  619            * set by the TableView.updateGrid() method.
  620            */
  621           void setRow(int row) {
  622               this.row = row;
  623           }
  624   
  625           /**
  626            * The number of columns present in this row.
  627            */
  628           int getColumnCount() {
  629               int nfill = 0;
  630               int n = fillColumns.size();
  631               for (int i = 0; i < n; i++) {
  632                   if (fillColumns.get(i)) {
  633                       nfill ++;
  634                   }
  635               }
  636               return getViewCount() + nfill;
  637           }
  638   
  639           /**
  640            * Change the child views.  This is implemented to
  641            * provide the superclass behavior and invalidate the
  642            * grid so that rows and columns will be recalculated.
  643            */
  644           public void replace(int offset, int length, View[] views) {
  645               super.replace(offset, length, views);
  646               invalidateGrid();
  647           }
  648   
  649           /**
  650            * Perform layout for the major axis of the box (i.e. the
  651            * axis that it represents).  The results of the layout should
  652            * be placed in the given arrays which represent the allocations
  653            * to the children along the major axis.
  654            * <p>
  655            * This is re-implemented to give each child the span of the column
  656            * width for the table, and to give cells that span multiple columns
  657            * the multi-column span.
  658            *
  659            * @param targetSpan the total span given to the view, which
  660            *  whould be used to layout the children.
  661            * @param axis the axis being layed out.
  662            * @param offsets the offsets from the origin of the view for
  663            *  each of the child views.  This is a return value and is
  664            *  filled in by the implementation of this method.
  665            * @param spans the span of each child view.  This is a return
  666            *  value and is filled in by the implementation of this method.
  667            */
  668           protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
  669               int col = 0;
  670               int ncells = getViewCount();
  671               for (int cell = 0; cell < ncells; cell++, col++) {
  672                   View cv = getView(cell);
  673                   for (; isFilled(col); col++); // advance to a free column
  674                   int colSpan = getColumnsOccupied(cv);
  675                   spans[cell] = columnSpans[col];
  676                   offsets[cell] = columnOffsets[col];
  677                   if (colSpan > 1) {
  678                       int n = columnSpans.length;
  679                       for (int j = 1; j < colSpan; j++) {
  680                           // Because the table may be only partially formed, some
  681                           // of the columns may not yet exist.  Therefore we check
  682                           // the bounds.
  683                           if ((col+j) < n) {
  684                               spans[cell] += columnSpans[col+j];
  685                           }
  686                       }
  687                       col += colSpan - 1;
  688                   }
  689               }
  690           }
  691   
  692           /**
  693            * Perform layout for the minor axis of the box (i.e. the
  694            * axis orthoginal to the axis that it represents).  The results
  695            * of the layout should be placed in the given arrays which represent
  696            * the allocations to the children along the minor axis.  This
  697            * is called by the superclass whenever the layout needs to be
  698            * updated along the minor axis.
  699            * <p>
  700            * This is implemented to delegate to the superclass, then adjust
  701            * the span for any cell that spans multiple rows.
  702            *
  703            * @param targetSpan the total span given to the view, which
  704            *  whould be used to layout the children.
  705            * @param axis the axis being layed out.
  706            * @param offsets the offsets from the origin of the view for
  707            *  each of the child views.  This is a return value and is
  708            *  filled in by the implementation of this method.
  709            * @param spans the span of each child view.  This is a return
  710            *  value and is filled in by the implementation of this method.
  711            */
  712           protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
  713               super.layoutMinorAxis(targetSpan, axis, offsets, spans);
  714               int col = 0;
  715               int ncells = getViewCount();
  716               for (int cell = 0; cell < ncells; cell++, col++) {
  717                   View cv = getView(cell);
  718                   for (; isFilled(col); col++); // advance to a free column
  719                   int colSpan = getColumnsOccupied(cv);
  720                   int rowSpan = getRowsOccupied(cv);
  721                   if (rowSpan > 1) {
  722                       for (int j = 1; j < rowSpan; j++) {
  723                           // test bounds of each row because it may not exist
  724                           // either because of error or because the table isn't
  725                           // fully loaded yet.
  726                           int row = getRow() + j;
  727                           if (row < TableView.this.getViewCount()) {
  728                               int span = TableView.this.getSpan(Y_AXIS, getRow()+j);
  729                               spans[cell] += span;
  730                           }
  731                       }
  732                   }
  733                   if (colSpan > 1) {
  734                       col += colSpan - 1;
  735                   }
  736               }
  737           }
  738   
  739           /**
  740            * Determines the resizability of the view along the
  741            * given axis.  A value of 0 or less is not resizable.
  742            *
  743            * @param axis may be either View.X_AXIS or View.Y_AXIS
  744            * @return the resize weight
  745            * @exception IllegalArgumentException for an invalid axis
  746            */
  747           public int getResizeWeight(int axis) {
  748               return 1;
  749           }
  750   
  751           /**
  752            * Fetches the child view that represents the given position in
  753            * the model.  This is implemented to walk through the children
  754            * looking for a range that contains the given position.  In this
  755            * view the children do not necessarily have a one to one mapping
  756            * with the child elements.
  757            *
  758            * @param pos  the search position >= 0
  759            * @param a  the allocation to the table on entry, and the
  760            *   allocation of the view containing the position on exit
  761            * @return  the view representing the given position, or
  762            *   <code>null</code> if there isn't one
  763            */
  764           protected View getViewAtPosition(int pos, Rectangle a) {
  765               int n = getViewCount();
  766               for (int i = 0; i < n; i++) {
  767                   View v = getView(i);
  768                   int p0 = v.getStartOffset();
  769                   int p1 = v.getEndOffset();
  770                   if ((pos >= p0) && (pos < p1)) {
  771                       // it's in this view.
  772                       if (a != null) {
  773                           childAllocation(i, a);
  774                       }
  775                       return v;
  776                   }
  777               }
  778               if (pos == getEndOffset()) {
  779                   View v = getView(n - 1);
  780                   if (a != null) {
  781                       this.childAllocation(n - 1, a);
  782                   }
  783                   return v;
  784               }
  785               return null;
  786           }
  787   
  788           /** columns filled by multi-column or multi-row cells */
  789           BitSet fillColumns;
  790           /** the row within the overall grid */
  791           int row;
  792       }
  793   
  794       /**
  795        * @deprecated  A table cell can now be any View implementation.
  796        */
  797       @Deprecated
  798       public class TableCell extends BoxView implements GridCell {
  799   
  800           /**
  801            * Constructs a TableCell for the given element.
  802            *
  803            * @param elem the element that this view is responsible for
  804            * @since 1.4
  805            */
  806           public TableCell(Element elem) {
  807               super(elem, View.Y_AXIS);
  808           }
  809   
  810           // --- GridCell methods -------------------------------------
  811   
  812           /**
  813            * Gets the number of columns this cell spans (e.g. the
  814            * grid width).
  815            *
  816            * @return the number of columns
  817            */
  818           public int getColumnCount() {
  819               return 1;
  820           }
  821   
  822           /**
  823            * Gets the number of rows this cell spans (that is, the
  824            * grid height).
  825            *
  826            * @return the number of rows
  827            */
  828           public int getRowCount() {
  829               return 1;
  830           }
  831   
  832   
  833           /**
  834            * Sets the grid location.
  835            *
  836            * @param row the row >= 0
  837            * @param col the column >= 0
  838            */
  839           public void setGridLocation(int row, int col) {
  840               this.row = row;
  841               this.col = col;
  842           }
  843   
  844           /**
  845            * Gets the row of the grid location
  846            */
  847           public int getGridRow() {
  848               return row;
  849           }
  850   
  851           /**
  852            * Gets the column of the grid location
  853            */
  854           public int getGridColumn() {
  855               return col;
  856           }
  857   
  858           int row;
  859           int col;
  860       }
  861   
  862       /**
  863        * <em>
  864        * THIS IS NO LONGER USED, AND WILL BE REMOVED IN THE
  865        * NEXT RELEASE.  THE JCK SIGNATURE TEST THINKS THIS INTERFACE
  866        * SHOULD EXIST
  867        * </em>
  868        */
  869       interface GridCell {
  870   
  871           /**
  872            * Sets the grid location.
  873            *
  874            * @param row the row >= 0
  875            * @param col the column >= 0
  876            */
  877           public void setGridLocation(int row, int col);
  878   
  879           /**
  880            * Gets the row of the grid location
  881            */
  882           public int getGridRow();
  883   
  884           /**
  885            * Gets the column of the grid location
  886            */
  887           public int getGridColumn();
  888   
  889           /**
  890            * Gets the number of columns this cell spans (e.g. the
  891            * grid width).
  892            *
  893            * @return the number of columns
  894            */
  895           public int getColumnCount();
  896   
  897           /**
  898            * Gets the number of rows this cell spans (that is, the
  899            * grid height).
  900            *
  901            * @return the number of rows
  902            */
  903           public int getRowCount();
  904   
  905       }
  906   
  907   }

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