Source for javax.swing.text.html.FrameSetView

   1: /* FrameSetView.java -- Implements HTML frameset
   2:    Copyright (C) 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing.text.html;
  40: 
  41: import java.util.StringTokenizer;
  42: 
  43: import javax.swing.text.AttributeSet;
  44: import javax.swing.text.BoxView;
  45: import javax.swing.text.Element;
  46: import javax.swing.text.View;
  47: import javax.swing.text.ViewFactory;
  48: 
  49: /**
  50:  * Implements HTML framesets. This is implemented as a vertical box that
  51:  * holds the rows of the frameset. Each row is again a horizontal box that
  52:  * holds the actual columns.
  53:  */
  54: public class FrameSetView
  55:   extends BoxView
  56: {
  57: 
  58:   /**
  59:    * A row of a frameset.
  60:    */
  61:   private class FrameSetRow
  62:     extends BoxView
  63:   {
  64:     private int row;
  65:     FrameSetRow(Element el, int r)
  66:     {
  67:       super(el, X_AXIS);
  68:       row = r;
  69:     }
  70: 
  71:     protected void loadChildren(ViewFactory f)
  72:     {
  73:       // Load the columns here.
  74:       Element el = getElement();
  75:       View[] columns = new View[numViews[X_AXIS]];
  76:       int offset = row * numViews[X_AXIS];
  77:       for (int c = 0; c < numViews[X_AXIS]; c++)
  78:         {
  79:           Element child = el.getElement(offset + c);
  80:           columns[c] = f.create(child);
  81:         }
  82:       replace(0, 0, columns);
  83:     }
  84: 
  85:     protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
  86:                                    int[] spans)
  87:     {
  88:       int numRows = numViews[X_AXIS];
  89:       int[] abs = absolute[X_AXIS];
  90:       int[] rel = relative[X_AXIS];
  91:       int[] perc = percent[X_AXIS];
  92:       layoutViews(targetSpan, axis, offsets, spans, numRows, abs, rel, perc);
  93:     }
  94:   }
  95: 
  96:   /**
  97:    * Holds the absolute layout information for the views along one axis. The
  98:    * indices are absolute[axis][index], where axis is either X_AXIS (columns)
  99:    * or Y_AXIS (rows). Rows or columns that don't have absolute layout have
 100:    * a -1 in this array.
 101:    */
 102:   int[][] absolute;
 103: 
 104:   /**
 105:    * Holds the relative (*) layout information for the views along one axis.
 106:    * The indices are relative[axis][index], where axis is either X_AXIS
 107:    * (columns) or Y_AXIS (rows). Rows or columns that don't have relative
 108:    * layout have a Float.NaN in this array.
 109:    */
 110:   int[][] relative;
 111: 
 112:   /**
 113:    * Holds the relative (%) layout information for the views along one axis.
 114:    * The indices are relative[axis][index], where axis is either X_AXIS
 115:    * (columns) or Y_AXIS (rows). Rows or columns that don't have relative
 116:    * layout have a Float.NaN in this array.
 117:    *
 118:    * The percentage is divided by 100 so that we hold the actual fraction here.
 119:    */
 120:   int[][] percent;
 121: 
 122:   /**
 123:    * The number of children in each direction.
 124:    */
 125:   int[] numViews;
 126: 
 127:   FrameSetView(Element el)
 128:   {
 129:     super(el, Y_AXIS);
 130:     numViews = new int[2];
 131:     absolute = new int[2][];
 132:     relative = new int[2][];
 133:     percent = new int[2][];
 134:   }
 135: 
 136:   /**
 137:    * Loads the children and places them inside the grid.
 138:    */
 139:   protected void loadChildren(ViewFactory f)
 140:   {
 141:     parseRowsCols();
 142:     // Set up the rows.
 143:     View[] rows = new View[numViews[Y_AXIS]];
 144:     for (int r = 0; r < numViews[Y_AXIS]; r++)
 145:       {
 146:         rows[r] = new FrameSetRow(getElement(), r);
 147:       }
 148:     replace(0, 0, rows);
 149:   }
 150: 
 151:   /**
 152:    * Parses the rows and cols attributes and sets up the layout info.
 153:    */
 154:   private void parseRowsCols()
 155:   {
 156:     Element el = getElement();
 157:     AttributeSet atts = el.getAttributes();
 158:     String cols = (String) atts.getAttribute(HTML.Attribute.COLS);
 159:     if (cols == null) // Defaults to '100%' when not specified.
 160:       cols = "100%";
 161:     parseLayout(cols, X_AXIS);
 162:     String rows = (String) atts.getAttribute(HTML.Attribute.ROWS);
 163:     if (rows == null) // Defaults to '100%' when not specified.
 164:       rows = "100%";
 165:     parseLayout(rows, Y_AXIS);
 166:   }
 167: 
 168:   /**
 169:    * Parses the cols or rows attribute and places the layout info in the
 170:    * appropriate arrays.
 171:    *
 172:    * @param att the attributes to parse
 173:    * @param axis the axis
 174:    */
 175:   private void parseLayout(String att, int axis)
 176:   {
 177:     StringTokenizer tokens = new StringTokenizer(att, ",");
 178:     numViews[axis] = tokens.countTokens();
 179:     absolute[axis] = new int[numViews[axis]];
 180:     relative[axis] = new int[numViews[axis]];
 181:     percent[axis] = new int[numViews[axis]];
 182:     for (int index = 0; tokens.hasMoreTokens(); index++)
 183:       {
 184:         String token = tokens.nextToken();
 185:         int p = token.indexOf('%');
 186:         int s = token.indexOf('*');
 187:         if (p != -1)
 188:           {
 189:             // Percent value.
 190:             String number = token.substring(0, p);
 191:             try
 192:               {
 193:                 percent[axis][index] = Integer.parseInt(number);
 194:               }
 195:             catch (NumberFormatException ex)
 196:               {
 197:                 // Leave value as 0 then.
 198:               }
 199:           }
 200:         else if (s != -1)
 201:           {
 202:             // Star relative value.
 203:             String number = token.substring(0, s);
 204:             try
 205:               {
 206:                 relative[axis][index] = Integer.parseInt(number);
 207:               }
 208:             catch (NumberFormatException ex)
 209:               {
 210:                 // Leave value as 0 then.
 211:               }
 212:           }
 213:         else
 214:           {
 215:             // Absolute value.
 216:             try
 217:               {
 218:                 absolute[axis][index] = Integer.parseInt(token);
 219:               }
 220:             catch (NumberFormatException ex)
 221:               {
 222:                 // Leave value as 0 then.
 223:               }
 224:           }
 225:       }
 226:   }
 227: 
 228:   protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
 229:                                  int[] spans)
 230:   {
 231:     int numRows = numViews[Y_AXIS];
 232:     int[] abs = absolute[Y_AXIS];
 233:     int[] rel = relative[Y_AXIS];
 234:     int[] perc = percent[Y_AXIS];
 235:     layoutViews(targetSpan, axis, offsets, spans, numRows, abs, rel, perc);
 236:   }
 237: 
 238:   void layoutViews(int targetSpan, int axis, int[] offsets, int[] spans,
 239:                    int numViews, int[] abs, int[] rel, int[] perc)
 240:   {
 241:     // We need two passes. In the first pass we layout the absolute and
 242:     // percent values and accumulate the needed space. In the second pass
 243:     // the relative values are distributed and the offsets are set.
 244:     int total = 0;
 245:     int relTotal = 0;
 246:     for (int i = 0; i < numViews; i++)
 247:       {
 248:         if (abs[i] > 0)
 249:           {
 250:             spans[i] = abs[i];
 251:             total += spans[i];
 252:           }
 253:         else if (perc[i] > 0)
 254:           {
 255:             spans[i] = (targetSpan * perc[i]) / 100;
 256:             total += spans[i];
 257:           }
 258:         else if (rel[i] > 0)
 259:           {
 260:             relTotal += rel[i];
 261:           }
 262:       }
 263:     int offs = 0;
 264:     for (int i = 0; i < numViews; i++)
 265:       {
 266:         if (relTotal > 0 && rel[i] > 0)
 267:           {
 268:             spans[i] = targetSpan * (rel[i] / relTotal);
 269:           }
 270:         offsets[i] = offs;
 271:         offs += spans[i];
 272:       }
 273:   }
 274: }