1 /* TableView.java -- A view impl for tables inside styled text
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
39 package javax
.swing
.text
;
41 import java
.awt
.Rectangle
;
42 import java
.awt
.Shape
;
44 import javax
.swing
.SizeRequirements
;
45 import javax
.swing
.event
.DocumentEvent
;
48 * A {@link View} implementation for rendering tables inside styled text.
49 * Tables are rendered as vertical boxes (see {@link BoxView}). These boxes
50 * have a number of child views, which are the rows of the table. These are
51 * horizontal boxes containing the actuall cells of the table. These cells
52 * can be arbitrary view implementations and are fetched via the
53 * {@link ViewFactory} returned by {@link View#getViewFactory}.
55 * @author Roman Kennke (kennke@aicas.com)
57 public class TableView
62 * A view implementation that renders a row of a <code>TableView</code>.
63 * This is implemented as a horizontal box that contains the actual cells
66 * @author Roman Kennke (kennke@aicas.com)
72 * Creates a new instance of <code>TableRow</code>.
74 * @param el the element for which to create a row view
76 public TableRow(Element el
)
82 * Replaces some child views with a new set of child views. This is
83 * implemented to call the superclass behaviour and invalidates the row
84 * grid so that rows and columns will be recalculated.
86 * @param offset the start offset at which to replace views
87 * @param length the number of views to remove
88 * @param views the new set of views
90 public void replace(int offset
, int length
, View
[] views
)
92 super.replace(offset
, length
, views
);
93 layoutChanged(X_AXIS
);
97 * Lays out the box's child views along the major axis. This is
98 * reimplemented so that the child views all have the width of their
101 * @param targetSpan the total span of the view
102 * @param axis the axis that is laid out
103 * @param offsets an array that holds the offsets of the child views after
104 * this method returned
105 * @param spans an array that holds the spans of the child views after this
108 protected void layoutMajorAxis(int targetSpan
, int axis
, int[] offsets
,
111 // TODO: Maybe prepare columnSpans and columnOffsets.
113 // Some sanity checks. If these preconditions are not met, then the
114 // following code will not work. Also, there must be something
115 // seriously wrong then.
116 assert(offsets
.length
== columnOffsets
.length
);
117 assert(spans
.length
== columnSpans
.length
);
118 assert(offsets
.length
== spans
.length
);
119 for (int i
= 0; i
< offsets
.length
; ++i
)
121 offsets
[i
] = columnOffsets
[i
];
122 spans
[i
] = columnSpans
[i
];
127 * Lays out the box's child views along the minor axis (the orthogonal axis
128 * to the major axis). This is reimplemented to call the super behaviour
129 * and then adjust the span of the child views that span multiple rows.
131 * @param targetSpan the total span of the view
132 * @param axis the axis that is laid out
133 * @param offsets an array that holds the offsets of the child views after
134 * this method returned
135 * @param spans an array that holds the spans of the child views after this
138 protected void layoutMinorAxis(int targetSpan
, int axis
, int[] offsets
,
141 // FIXME: Figure out how to fetch the row heights from the TableView's
143 super.layoutMajorAxis(targetSpan
, axis
, offsets
, spans
);
147 * Determines the resizeability of this view along the specified axis.
149 * @param axis the axis of which to fetch the resizability
151 * @return the resize weight or <= 0 if this view is not resizable
153 * @throws IllegalArgumentException when an illegal axis is specified
155 public int getResizeWeight(int axis
)
157 // TODO: Figure out if this is ok. I would think so, but better test
163 * Returns the child view that represents the specified position in the
164 * model. This is reimplemented because in this view we do not necessarily
165 * have a one to one mapping of child elements to child views.
167 * @param pos the model position for which to query the view
168 * @param a the allocation of this view
170 * @return the view that corresponds to the specified model position or
171 * <code>null</code> if there is none
173 protected View
getViewAtPosition(int pos
, Rectangle a
)
175 // FIXME: Do not call super here. Instead walk through the child views
176 // and look for a range that contains the given position.
177 return super.getViewAtPosition(pos
, a
);
182 * This class is deprecated and not used anymore. Table cells are
183 * rendered by an arbitrary <code>View</code> implementation.
185 * @author Roman Kennke (kennke@aicas.com)
187 * @deprecated Table cells are now rendered by an arbitrary <code>View</code>
190 public class TableCell
195 * The row number of this cell.
200 * The column number of this cell.
205 * Creates a new instance.
207 * @param el the element
209 * @deprecated Table cells are now rendered by an arbitrary
210 * <code>View</code> implementation.
212 public TableCell(Element el
)
218 * Returns the number of columns that this cell spans.
220 * @return the number of columns that this cell spans
222 * @deprecated Table cells are now rendered by an arbitrary
223 * <code>View</code> implementation.
225 public int getColumnCount()
227 // TODO: Figure out if this is right. However, this is not so important
228 // since this class isn't used anyway (except maybe be application code
229 // that still uses this deprecated class).
234 * Returns the number of rows that this cell spans.
236 * @return the number of rows that this cell spans
238 * @deprecated Table cells are now rendered by an arbitrary
239 * <code>View</code> implementation.
241 public int getRowCount()
243 // TODO: Figure out if this is right. However, this is not so important
244 // since this class isn't used anyway (except maybe be application code
245 // that still uses this deprecated class).
250 * Sets the grid location of this table cell.
252 * @param r the row of this cell
253 * @param c the column of this cell
255 * @deprecated Table cells are now rendered by an arbitrary
256 * <code>View</code> implementation.
258 public void setGridLocation(int r
, int c
)
265 * Returns the row number of this cell.
267 * @return the row number of this cell
269 * @deprecated Table cells are now rendered by an arbitrary
270 * <code>View</code> implementation.
272 public int getGridRow()
278 * Returns the column number of this cell.
280 * @return the column number of this cell
282 * @deprecated Table cells are now rendered by an arbitrary
283 * <code>View</code> implementation.
285 public int getGridColumn()
292 * The offsets of the columns of this table. Package private to avoid
293 * synthetic accessor methods.
298 * The spans of the columns of this table. Package private to avoid
299 * synthetic accessor methods.
304 * The size requirements of the columns.
306 private SizeRequirements
[] columnRequirements
;
309 * Creates a new instance of <code>TableView</code>.
311 * @param el the element for which to create a table view
313 public TableView(Element el
)
316 int numChildren
= el
.getElementCount();
317 View
[] rows
= new View
[numChildren
];
318 for (int i
= 0; i
< numChildren
; ++i
)
320 Element rowEl
= el
.getElement(i
);
321 TableRow rowView
= createTableRow(rowEl
);
328 * Replaces a number of child views with a set of new child views. This is
329 * implemented to call the superclass behaviour and invalidate the layout.
331 * @param offset the offset at which to replace child views
332 * @param length the number of child views to remove
333 * @param views the new set of views
335 public void replace(int offset
, int length
, View
[] views
)
337 super.replace(offset
, length
, views
);
338 layoutChanged(Y_AXIS
);
342 * Creates a view for a table row.
344 * @param el the element that represents the table row
346 * @return a view for rendering the table row
348 protected TableRow
createTableRow(Element el
)
350 return new TableRow(el
);
354 * Creates a view for a table cell. This method is deprecated and not used
357 * @param el the element that represents the table cell
359 * @return a view for rendering the table cell
361 * @deprecated Table cells are now rendered by an arbitrary
362 * <code>View</code> implementation.
364 protected TableCell
createTableCell(Element el
)
366 return new TableCell(el
);
369 protected void forwardUpdate(DocumentEvent
.ElementChange ec
, DocumentEvent e
,
370 Shape a
, ViewFactory vf
)
372 // TODO: Figure out what to do here.
376 * Lays out the columns to fit within the specified target span.
378 * @param targetSpan the total span for the columns
379 * @param offsets an array that holds the offsets of the columns when this
381 * @param spans an array that holds the spans of the columns when this method
383 * @param reqs the size requirements for each column
385 protected void layoutColumns(int targetSpan
, int[] offsets
, int spans
[],
386 SizeRequirements
[] reqs
)
388 // TODO: Figure out what exactly to do here.
392 * Lays out the child views along the minor axis of the table (that is the
393 * horizontal axis). This is implemented to call {@link #layoutColumns} to
394 * layout the column layout of this table, and then forward to the superclass
395 * to actually lay out the rows.
397 * @param targetSpan the available span along the minor (horizontal) axis
398 * @param axis the axis
399 * @param offsets an array that holds the offsets of the columns when this
401 * @param spans an array that holds the spans of the columns when this method
404 protected void layoutMinorAxis(int targetSpan
, int axis
, int[] offsets
,
407 // TODO: Prepare size requirements for the columns.
408 layoutColumns(targetSpan
, columnOffsets
, columnSpans
, columnRequirements
);
409 super.layoutMinorAxis(targetSpan
, axis
, offsets
, spans
);
413 * Calculates the requirements of this view for the minor (== horizontal)
416 * This is reimplemented to calculate the requirements as the sum of the
417 * size requirements of the columns.
419 * @param axis the axis
420 * @param req the size requirements object to use, if <code>null</code> a new
421 * one will be created
423 protected SizeRequirements
calculateMinorAxisRequirements(int axis
,
424 SizeRequirements req
)
426 // TODO: Maybe prepare columnRequirements.
427 SizeRequirements res
= req
;
429 res
= new SizeRequirements();
432 res
.alignment
= 0.5f
;
438 for (int i
= 0; i
< columnRequirements
.length
; ++i
)
440 res
.minimum
+= columnRequirements
[i
].minimum
;
441 res
.preferred
+= columnRequirements
[i
].preferred
;
442 res
.maximum
+= columnRequirements
[i
].maximum
;
443 // TODO: Do we have to handle alignment somehow?
449 * Returns the child view that represents the specified position in the
450 * model. This is reimplemented because in this view we do not necessarily
451 * have a one to one mapping of child elements to child views.
453 * @param pos the model position for which to query the view
454 * @param a the allocation of this view
456 * @return the view that corresponds to the specified model position or
457 * <code>null</code> if there is none
459 protected View
getViewAtPosition(int pos
, Rectangle a
)
461 // FIXME: Do not call super here. Instead walk through the child views
462 // and look for a range that contains the given position.
463 return super.getViewAtPosition(pos
, a
);