mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			492 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			492 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Java
		
	
	
	
/* TableView.java -- A view impl for tables inside styled text
 | 
						|
   Copyright (C) 2006 Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
 | 
						|
package javax.swing.text;
 | 
						|
 | 
						|
import java.awt.Rectangle;
 | 
						|
import java.awt.Shape;
 | 
						|
 | 
						|
import javax.swing.SizeRequirements;
 | 
						|
import javax.swing.event.DocumentEvent;
 | 
						|
 | 
						|
/**
 | 
						|
 * A {@link View} implementation for rendering tables inside styled text.
 | 
						|
 * Tables are rendered as vertical boxes (see {@link BoxView}). These boxes
 | 
						|
 * have a number of child views, which are the rows of the table. These are
 | 
						|
 * horizontal boxes containing the actuall cells of the table. These cells
 | 
						|
 * can be arbitrary view implementations and are fetched via the
 | 
						|
 * {@link ViewFactory} returned by {@link View#getViewFactory}.
 | 
						|
 *
 | 
						|
 * @author Roman Kennke (kennke@aicas.com)
 | 
						|
 */
 | 
						|
public abstract class TableView
 | 
						|
  extends BoxView
 | 
						|
{
 | 
						|
 | 
						|
  /**
 | 
						|
   * A view implementation that renders a row of a <code>TableView</code>.
 | 
						|
   * This is implemented as a horizontal box that contains the actual cells
 | 
						|
   * of the table.
 | 
						|
   *
 | 
						|
   * @author Roman Kennke (kennke@aicas.com)
 | 
						|
   */
 | 
						|
  public class TableRow
 | 
						|
    extends BoxView
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Creates a new instance of <code>TableRow</code>.
 | 
						|
     *
 | 
						|
     * @param el the element for which to create a row view
 | 
						|
     */
 | 
						|
    public TableRow(Element el)
 | 
						|
    {
 | 
						|
      super(el, X_AXIS);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Replaces some child views with a new set of child views. This is
 | 
						|
     * implemented to call the superclass behaviour and invalidates the row
 | 
						|
     * grid so that rows and columns will be recalculated.
 | 
						|
     *
 | 
						|
     * @param offset the start offset at which to replace views
 | 
						|
     * @param length the number of views to remove
 | 
						|
     * @param views the new set of views
 | 
						|
     */
 | 
						|
    public void replace(int offset, int length, View[] views)
 | 
						|
    {
 | 
						|
      super.replace(offset, length, views);
 | 
						|
      int viewCount = getViewCount();
 | 
						|
      if (columnRequirements == null
 | 
						|
          || viewCount > columnRequirements.length)
 | 
						|
        {
 | 
						|
          columnRequirements = new SizeRequirements[viewCount];
 | 
						|
          for (int i = 0; i < columnRequirements.length; i++)
 | 
						|
            columnRequirements[i] = new SizeRequirements();
 | 
						|
        }
 | 
						|
      if (columnOffsets == null || columnOffsets.length < viewCount)
 | 
						|
        columnOffsets = new int[viewCount];
 | 
						|
      if (columnSpans == null || columnSpans.length < viewCount)
 | 
						|
        columnSpans = new int[viewCount];
 | 
						|
      layoutChanged(X_AXIS);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Lays out the box's child views along the major axis. This is
 | 
						|
     * reimplemented so that the child views all have the width of their
 | 
						|
     * column.
 | 
						|
     *
 | 
						|
     * @param targetSpan the total span of the view
 | 
						|
     * @param axis the axis that is laid out
 | 
						|
     * @param offsets an array that holds the offsets of the child views after
 | 
						|
     *        this method returned
 | 
						|
     * @param spans an array that holds the spans of the child views after this
 | 
						|
     *        method returned
 | 
						|
     */
 | 
						|
    protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
 | 
						|
                                   int[] spans)
 | 
						|
    {
 | 
						|
      // Some sanity checks. If these preconditions are not met, then the
 | 
						|
      // following code will not work. Also, there must be something
 | 
						|
      // seriously wrong then.
 | 
						|
      assert(offsets.length == columnOffsets.length);
 | 
						|
      assert(spans.length == columnSpans.length);
 | 
						|
      assert(offsets.length == spans.length);
 | 
						|
      for (int i = 0; i < offsets.length; ++i)
 | 
						|
        {
 | 
						|
          offsets[i] = columnOffsets[i];
 | 
						|
          spans[i] = columnSpans[i];
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Lays out the box's child views along the minor axis (the orthogonal axis
 | 
						|
     * to the major axis). This is reimplemented to call the super behaviour
 | 
						|
     * and then adjust the span of the child views that span multiple rows.
 | 
						|
     *
 | 
						|
     * @param targetSpan the total span of the view
 | 
						|
     * @param axis the axis that is laid out
 | 
						|
     * @param offsets an array that holds the offsets of the child views after
 | 
						|
     *        this method returned
 | 
						|
     * @param spans an array that holds the spans of the child views after this
 | 
						|
     *        method returned
 | 
						|
     */
 | 
						|
    protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets,
 | 
						|
                                   int[] spans)
 | 
						|
    {
 | 
						|
      // FIXME: Figure out how to fetch the row heights from the TableView's
 | 
						|
      // element.
 | 
						|
      super.layoutMinorAxis(targetSpan, axis, offsets, spans);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Determines the resizeability of this view along the specified axis.
 | 
						|
     *
 | 
						|
     * @param axis the axis of which to fetch the resizability
 | 
						|
     *
 | 
						|
     * @return the resize weight or <= 0 if this view is not resizable
 | 
						|
     *
 | 
						|
     * @throws IllegalArgumentException when an illegal axis is specified
 | 
						|
     */
 | 
						|
    public int getResizeWeight(int axis)
 | 
						|
    {
 | 
						|
      // TODO: Figure out if this is ok. I would think so, but better test
 | 
						|
      // this.
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the child view that represents the specified position in the
 | 
						|
     * model. This is reimplemented because in this view we do not necessarily
 | 
						|
     * have a one to one mapping of child elements to child views.
 | 
						|
     *
 | 
						|
     * @param pos the model position for which to query the view
 | 
						|
     * @param a the allocation of this view
 | 
						|
     *
 | 
						|
     * @return the view that corresponds to the specified model position or
 | 
						|
     *         <code>null</code> if there is none
 | 
						|
     */
 | 
						|
    protected View getViewAtPosition(int pos, Rectangle a)
 | 
						|
    {
 | 
						|
      // FIXME: Do not call super here. Instead walk through the child views
 | 
						|
      // and look for a range that contains the given position.
 | 
						|
      return super.getViewAtPosition(pos, a);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This class is deprecated and not used anymore. Table cells are
 | 
						|
   * rendered by an arbitrary <code>View</code> implementation.
 | 
						|
   *
 | 
						|
   * @author Roman Kennke (kennke@aicas.com)
 | 
						|
   *
 | 
						|
   * @deprecated Table cells are now rendered by an arbitrary <code>View</code>
 | 
						|
   *             implementation.
 | 
						|
   */
 | 
						|
  public class TableCell
 | 
						|
    extends BoxView
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * The row number of this cell.
 | 
						|
     */
 | 
						|
    private int row;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The column number of this cell.
 | 
						|
     */
 | 
						|
    private int column;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Creates a new instance.
 | 
						|
     *
 | 
						|
     * @param el the element
 | 
						|
     *
 | 
						|
     * @deprecated Table cells are now rendered by an arbitrary
 | 
						|
     *             <code>View</code> implementation.
 | 
						|
     */
 | 
						|
    public TableCell(Element el)
 | 
						|
    {
 | 
						|
      super(el, X_AXIS);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of columns that this cell spans.
 | 
						|
     *
 | 
						|
     * @return the number of columns that this cell spans
 | 
						|
     *
 | 
						|
     * @deprecated Table cells are now rendered by an arbitrary
 | 
						|
     *             <code>View</code> implementation.
 | 
						|
     */
 | 
						|
    public int getColumnCount()
 | 
						|
    {
 | 
						|
      // TODO: Figure out if this is right. However, this is not so important
 | 
						|
      // since this class isn't used anyway (except maybe be application code
 | 
						|
      // that still uses this deprecated class).
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of rows that this cell spans.
 | 
						|
     *
 | 
						|
     * @return the number of rows that this cell spans
 | 
						|
     *
 | 
						|
     * @deprecated Table cells are now rendered by an arbitrary
 | 
						|
     *             <code>View</code> implementation.
 | 
						|
     */
 | 
						|
    public int getRowCount()
 | 
						|
    {
 | 
						|
      // TODO: Figure out if this is right. However, this is not so important
 | 
						|
      // since this class isn't used anyway (except maybe be application code
 | 
						|
      // that still uses this deprecated class).
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the grid location of this table cell.
 | 
						|
     *
 | 
						|
     * @param r the row of this cell
 | 
						|
     * @param c the column of this cell
 | 
						|
     *
 | 
						|
     * @deprecated Table cells are now rendered by an arbitrary
 | 
						|
     *             <code>View</code> implementation.
 | 
						|
     */
 | 
						|
    public void setGridLocation(int r, int c)
 | 
						|
    {
 | 
						|
      row = r;
 | 
						|
      column = c;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the row number of this cell.
 | 
						|
     *
 | 
						|
     * @return the row number of this cell
 | 
						|
     *
 | 
						|
     * @deprecated Table cells are now rendered by an arbitrary
 | 
						|
     *             <code>View</code> implementation.
 | 
						|
     */
 | 
						|
    public int getGridRow()
 | 
						|
    {
 | 
						|
      return row;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the column number of this cell.
 | 
						|
     *
 | 
						|
     * @return the column number of this cell
 | 
						|
     *
 | 
						|
     * @deprecated Table cells are now rendered by an arbitrary
 | 
						|
     *             <code>View</code> implementation.
 | 
						|
     */
 | 
						|
    public int getGridColumn()
 | 
						|
    {
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The offsets of the columns of this table. Package private to avoid
 | 
						|
   * synthetic accessor methods.
 | 
						|
   */
 | 
						|
  int[] columnOffsets;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The spans of the columns of this table. Package private to avoid
 | 
						|
   * synthetic accessor methods.
 | 
						|
   */
 | 
						|
  int[] columnSpans;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The size requirements of the columns.
 | 
						|
   */
 | 
						|
  SizeRequirements[] columnRequirements = new SizeRequirements[0];
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a new instance of <code>TableView</code>.
 | 
						|
   *
 | 
						|
   * @param el the element for which to create a table view
 | 
						|
   */
 | 
						|
  public TableView(Element el)
 | 
						|
  {
 | 
						|
    super(el, Y_AXIS);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Replaces a number of child views with a set of new child views. This is
 | 
						|
   * implemented to call the superclass behaviour and invalidate the layout.
 | 
						|
   *
 | 
						|
   * @param offset the offset at which to replace child views
 | 
						|
   * @param length the number of child views to remove
 | 
						|
   * @param views the new set of views
 | 
						|
   */
 | 
						|
  public void replace(int offset, int length, View[] views)
 | 
						|
  {
 | 
						|
    super.replace(offset, length, views);
 | 
						|
    layoutChanged(Y_AXIS);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a view for a table row.
 | 
						|
   *
 | 
						|
   * @param el the element that represents the table row
 | 
						|
   *
 | 
						|
   * @return a view for rendering the table row
 | 
						|
   */
 | 
						|
  protected TableRow createTableRow(Element el)
 | 
						|
  {
 | 
						|
    return new TableRow(el);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a view for a table cell. This method is deprecated and not used
 | 
						|
   * anymore.
 | 
						|
   *
 | 
						|
   * @param el the element that represents the table cell
 | 
						|
   *
 | 
						|
   * @return a view for rendering the table cell
 | 
						|
   *
 | 
						|
   * @deprecated Table cells are now rendered by an arbitrary
 | 
						|
   *             <code>View</code> implementation.
 | 
						|
   */
 | 
						|
  protected TableCell createTableCell(Element el)
 | 
						|
  {
 | 
						|
    return new TableCell(el);
 | 
						|
  }
 | 
						|
 | 
						|
  protected void forwardUpdate(DocumentEvent.ElementChange ec, DocumentEvent e,
 | 
						|
                               Shape a, ViewFactory vf)
 | 
						|
  {
 | 
						|
    // TODO: Figure out what to do here.
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Lays out the columns to fit within the specified target span.
 | 
						|
   *
 | 
						|
   * @param targetSpan the total span for the columns
 | 
						|
   * @param offsets an array that holds the offsets of the columns when this
 | 
						|
   *        method returns
 | 
						|
   * @param spans an array that holds the spans of the columns when this method
 | 
						|
   *        returns
 | 
						|
   * @param reqs the size requirements for each column
 | 
						|
   */
 | 
						|
  protected void layoutColumns(int targetSpan, int[] offsets, int spans[],
 | 
						|
                               SizeRequirements[] reqs)
 | 
						|
  {
 | 
						|
    updateColumnRequirements();
 | 
						|
    SizeRequirements r = calculateMinorAxisRequirements(X_AXIS, null);
 | 
						|
    SizeRequirements.calculateTiledPositions(targetSpan, r, columnRequirements,
 | 
						|
                                             offsets, spans);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Lays out the child views along the minor axis of the table (that is the
 | 
						|
   * horizontal axis). This is implemented to call {@link #layoutColumns} to
 | 
						|
   * layout the column layout of this table, and then forward to the superclass
 | 
						|
   * to actually lay out the rows.
 | 
						|
   *
 | 
						|
   * @param targetSpan the available span along the minor (horizontal) axis
 | 
						|
   * @param axis the axis
 | 
						|
   * @param offsets an array that holds the offsets of the columns when this
 | 
						|
   *        method returns
 | 
						|
   * @param spans an array that holds the spans of the columns when this method
 | 
						|
   *        returns
 | 
						|
   */
 | 
						|
  protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets,
 | 
						|
                                 int[] spans)
 | 
						|
  {
 | 
						|
    // TODO: Prepare size requirements for the columns.
 | 
						|
    layoutColumns(targetSpan, columnOffsets, columnSpans, columnRequirements);
 | 
						|
    super.layoutMinorAxis(targetSpan, axis, offsets, spans);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Calculates the requirements of this view for the minor (== horizontal)
 | 
						|
   * axis.
 | 
						|
   *
 | 
						|
   * This is reimplemented to calculate the requirements as the sum of the
 | 
						|
   * size requirements of the columns.
 | 
						|
   *
 | 
						|
   * @param axis the axis
 | 
						|
   * @param req the size requirements object to use, if <code>null</code> a new
 | 
						|
   *        one will be created
 | 
						|
   */
 | 
						|
  protected SizeRequirements calculateMinorAxisRequirements(int axis,
 | 
						|
                                                            SizeRequirements req)
 | 
						|
  {
 | 
						|
    // TODO: Maybe prepare columnRequirements.
 | 
						|
    SizeRequirements res = req;
 | 
						|
    if (res == null)
 | 
						|
      res = new SizeRequirements();
 | 
						|
    else
 | 
						|
      {
 | 
						|
        res.alignment = 0.5f;
 | 
						|
        res.maximum = 0;
 | 
						|
        res.minimum = 0;
 | 
						|
        res.preferred = 0;
 | 
						|
      }
 | 
						|
 | 
						|
    for (int i = 0; i < columnRequirements.length; ++i)
 | 
						|
      {
 | 
						|
        res.minimum += columnRequirements[i].minimum;
 | 
						|
        res.preferred += columnRequirements[i].preferred;
 | 
						|
        res.maximum += columnRequirements[i].maximum;
 | 
						|
        // TODO: Do we have to handle alignment somehow?
 | 
						|
      }
 | 
						|
    return res;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the child view that represents the specified position in the
 | 
						|
   * model. This is reimplemented because in this view we do not necessarily
 | 
						|
   * have a one to one mapping of child elements to child views.
 | 
						|
   *
 | 
						|
   * @param pos the model position for which to query the view
 | 
						|
   * @param a the allocation of this view
 | 
						|
   *
 | 
						|
   * @return the view that corresponds to the specified model position or
 | 
						|
   *         <code>null</code> if there is none
 | 
						|
   */
 | 
						|
  protected View getViewAtPosition(int pos, Rectangle a)
 | 
						|
  {
 | 
						|
    // FIXME: Do not call super here. Instead walk through the child views
 | 
						|
    // and look for a range that contains the given position.
 | 
						|
    return super.getViewAtPosition(pos, a);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Updates the column requirements.
 | 
						|
   */
 | 
						|
  private void updateColumnRequirements()
 | 
						|
  {
 | 
						|
    int rowCount = getViewCount();
 | 
						|
    for (int r = 0; r < rowCount; ++r)
 | 
						|
      {
 | 
						|
        TableRow row = (TableRow) getView(r);
 | 
						|
        int columnCount = row.getViewCount();
 | 
						|
        for (int c = 0; c < columnCount; ++c)
 | 
						|
          {
 | 
						|
            View cell = row.getView(c);
 | 
						|
            SizeRequirements cr = columnRequirements[c];
 | 
						|
            cr.minimum = Math.max(cr.minimum, (int) cell.getMinimumSpan(X_AXIS));
 | 
						|
            cr.preferred = Math.max(cr.preferred,
 | 
						|
                                    (int) cell.getPreferredSpan(X_AXIS));
 | 
						|
            cr.maximum = Math.max(cr.maximum, (int) cell.getMaximumSpan(X_AXIS));
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
}
 |