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));
 | |
|           }
 | |
|       }
 | |
|   }
 | |
| }
 |