KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > layoutmgr > table > ColumnSetup


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: ColumnSetup.java 471725 2006-11-06 13:33:12Z jeremias $ */
19
20 package org.apache.fop.layoutmgr.table;
21
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.ListIterator JavaDoc;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.fop.datatypes.PercentBaseContext;
29 import org.apache.fop.datatypes.Length;
30
31 import org.apache.fop.fo.FONode;
32 import org.apache.fop.fo.flow.Table;
33 import org.apache.fop.fo.flow.TableColumn;
34 import org.apache.fop.fo.properties.TableColLength;
35
36 /**
37  * Class holding a number of columns making up the column setup of a row.
38  */

39 public class ColumnSetup {
40
41     /** Logger **/
42     private static Log log = LogFactory.getLog(ColumnSetup.class);
43
44     private Table table;
45     private List JavaDoc columns = new java.util.ArrayList JavaDoc();
46     private List JavaDoc colWidths = new java.util.ArrayList JavaDoc();
47     
48     private int maxColIndexReferenced = 0;
49     
50     /**
51      * Main Constructor.
52      * @param table the table to construct this column setup for
53      */

54     public ColumnSetup(Table table) {
55         this.table = table;
56         prepareColumns();
57         initializeColumnWidths();
58     }
59     
60     private void prepareColumns() {
61         List JavaDoc rawCols = table.getColumns();
62         if (rawCols != null) {
63             int colnum = 1;
64             ListIterator JavaDoc iter = rawCols.listIterator();
65             while (iter.hasNext()) {
66                 TableColumn col = (TableColumn)iter.next();
67                 if (col == null) {
68                     continue;
69                 }
70                 colnum = col.getColumnNumber();
71                 for (int i = 0; i < col.getNumberColumnsRepeated(); i++) {
72                     while (colnum > columns.size()) {
73                         columns.add(null);
74                     }
75                     columns.set(colnum - 1, col);
76                     colnum++;
77                 }
78             }
79             //Post-processing the list (looking for gaps)
80
int pos = 1;
81             ListIterator JavaDoc ppIter = columns.listIterator();
82             while (ppIter.hasNext()) {
83                 TableColumn col = (TableColumn)ppIter.next();
84                 if (col == null) {
85                     log.error("Found a gap in the table-columns at position " + pos);
86                 }
87                 pos++;
88             }
89         }
90     }
91
92     /**
93      * Returns a column. If the index of the column is bigger than the number of explicitly
94      * defined columns the last column is returned.
95      * @param index index of the column (1 is the first column)
96      * @return the requested column
97      */

98     public TableColumn getColumn(int index) {
99         int size = columns.size();
100         if (index > size) {
101             if (index > maxColIndexReferenced) {
102                 maxColIndexReferenced = index;
103                 if (!(size == 1 && getColumn(1).isDefaultColumn())) {
104                     log.warn(FONode.decorateWithContextInfo(
105                             "There are fewer table-columns than are needed. "
106                             + "Column " + index + " was accessed, but only "
107                             + size + " columns have been defined. "
108                             + "The last defined column will be reused."
109                         , table));
110                     if (!table.isAutoLayout()) {
111                         log.warn("Please note that according XSL-FO 1.0 (7.26.9) says that "
112                                 + "the 'column-width' property must be specified for every "
113                                 + "column, unless the automatic table layout is used.");
114                     }
115                 }
116             }
117             return (TableColumn) columns.get(size - 1);
118         } else {
119             return (TableColumn) columns.get(index - 1);
120         }
121     }
122  
123     /** @see java.lang.Object#toString() */
124     public String JavaDoc toString() {
125         return columns.toString();
126     }
127
128     /** @return the number of columns in the setup. */
129     public int getColumnCount() {
130         if (maxColIndexReferenced > columns.size()) {
131             return maxColIndexReferenced;
132         } else {
133             return columns.size();
134         }
135    }
136     
137     /** @return an Iterator over all columns */
138     public Iterator JavaDoc iterator() {
139         return this.columns.iterator();
140     }
141     
142     /*
143     private void createColumnsFromFirstRow() {
144         //TODO Create oldColumns from first row here
145         //--> rule 2 in "fixed table layout", see CSS2, 17.5.2
146         //Alternative: extend oldColumns on-the-fly, but in this case we need the
147         //new property evaluation context so proportional-column-width() works
148         //correctly.
149         if (columns.size() == 0) {
150             this.columns.add(table.getDefaultColumn());
151         }
152     }
153     */

154
155     /**
156      * Initializes the column's widths
157      *
158      */

159     private void initializeColumnWidths() {
160         
161         TableColumn col;
162         Length colWidth;
163         
164         for (int i = columns.size(); --i >= 0;) {
165             if (columns.get(i) != null) {
166                 col = (TableColumn) columns.get(i);
167                 colWidth = col.getColumnWidth();
168                 colWidths.add(0, colWidth);
169             }
170         }
171         colWidths.add(0, null);
172     }
173     
174     /**
175      * Works out the base unit for resolving proportional-column-width()
176      * [p-c-w(x) = x * base_unit_ipd]
177      *
178      * @param tlm the TableLayoutManager
179      * @return the computed base unit (in millipoint)
180      */

181     protected double computeTableUnit(TableLayoutManager tlm) {
182         
183         int sumCols = 0;
184         float factors = 0;
185         double unit = 0;
186         
187         /* calculate the total width (specified absolute/percentages),
188          * and work out the total number of factors to use to distribute
189          * the remaining space (if any)
190          */

191         for (Iterator JavaDoc i = colWidths.iterator(); i.hasNext();) {
192             Length colWidth = (Length) i.next();
193             if (colWidth != null) {
194                 sumCols += colWidth.getValue(tlm);
195                 if (colWidth instanceof TableColLength) {
196                     factors +=
197                         ((TableColLength) colWidth).getTableUnits();
198                 }
199             }
200         }
201         
202         /* distribute the remaining space over the accumulated
203          * factors (if any)
204          */

205         if (factors > 0) {
206             if (sumCols < tlm.getContentAreaIPD()) {
207                 unit = (tlm.getContentAreaIPD() - sumCols) / factors;
208             } else {
209                 log.warn("No space remaining to distribute over columns.");
210             }
211         }
212         
213         return unit;
214     }
215     
216     /**
217      * @param col column index (1 is first column)
218      * @param context the context for percentage based calculations
219      * @return the X offset of the requested column
220      */

221     public int getXOffset(int col, PercentBaseContext context) {
222         int xoffset = 0;
223         for (int i = col; --i >= 0;) {
224             if (colWidths.get(i) != null) {
225                 xoffset += ((Length) colWidths.get(i)).getValue(context);
226             }
227         }
228         return xoffset;
229     }
230
231     /**
232      * Calculates the sum of all column widths.
233      * @param context the context for percentage based calculations
234      * @return the requested sum in millipoints
235      */

236     public int getSumOfColumnWidths(PercentBaseContext context) {
237         int sum = 0;
238         for (int i = 1, c = getColumnCount(); i <= c; i++) {
239             int effIndex = i;
240             if (i >= colWidths.size()) {
241                 effIndex = colWidths.size() - 1;
242             }
243             if (colWidths.get(effIndex) != null) {
244                 sum += ((Length) colWidths.get(effIndex)).getValue(context);
245             }
246         }
247         return sum;
248     }
249     
250 }
251
Popular Tags