summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/text/TableView.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/text/TableView.java')
-rw-r--r--libjava/classpath/javax/swing/text/TableView.java491
1 files changed, 491 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/text/TableView.java b/libjava/classpath/javax/swing/text/TableView.java
new file mode 100644
index 000000000..bdf5004a9
--- /dev/null
+++ b/libjava/classpath/javax/swing/text/TableView.java
@@ -0,0 +1,491 @@
+/* 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 &lt;= 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));
+ }
+ }
+ }
+}