Source Code Cross Referenced for TableWrapLayout.java in  » IDE-Eclipse » ui » org » eclipse » ui » forms » widgets » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui » org.eclipse.ui.forms.widgets 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.ui.forms.widgets;
011:
012:        import java.util.Enumeration;
013:        import java.util.Hashtable;
014:        import java.util.Vector;
015:
016:        import org.eclipse.swt.SWT;
017:        import org.eclipse.swt.graphics.*;
018:        import org.eclipse.swt.widgets.*;
019:
020:        /**
021:         * This implementation of the layout algorithm attempts to position controls in
022:         * the composite using a two-pass autolayout HTML table altorithm recommeded by
023:         * HTML 4.01 W3C specification (see
024:         * http://www.w3.org/TR/html4/appendix/notes.html#h-B.5.2.2). The main
025:         * differences with GridLayout is that it has two passes and that width and
026:         * height are not calculated in the same pass.
027:         * <p>
028:         * The advantage of the algorithm over GridLayout is that it is capable of
029:         * flowing text controls capable of line wrap. These controls do not have
030:         * natural 'preferred size'. Instead, they are capable of providing the required
031:         * height if the width is set. Consequently, this algorithm first calculates the
032:         * widths that will be assigned to columns, and then passes those widths to the
033:         * controls to calculate the height. When a composite with this layout is a
034:         * child of the scrolling composite, they should interact in such a way that
035:         * reduction in the scrolling composite width results in the reflow and increase
036:         * of the overall height.
037:         * <p>
038:         * If none of the columns contain expandable and wrappable controls, the
039:         * end-result will be similar to the one provided by GridLayout. The difference
040:         * will show up for layouts that contain controls whose minimum and maximum
041:         * widths are not the same.
042:         * 
043:         * @see TableWrapData
044:         * @since 3.0
045:         */
046:        public final class TableWrapLayout extends Layout implements 
047:                ILayoutExtension {
048:            /**
049:             * Number of columns to use when positioning children (default is 1).
050:             */
051:            public int numColumns = 1;
052:
053:            /**
054:             * Left margin variable (default is 5).
055:             */
056:            public int leftMargin = 5;
057:
058:            /**
059:             * Right margin variable (default is 5).
060:             */
061:            public int rightMargin = 5;
062:
063:            /**
064:             * Top margin variable (default is 5).
065:             */
066:            public int topMargin = 5;
067:
068:            /**
069:             * Botom margin variable (default is 5).
070:             */
071:            public int bottomMargin = 5;
072:
073:            /**
074:             * Horizontal spacing (default is 5).
075:             */
076:            public int horizontalSpacing = 5;
077:
078:            /**
079:             * Vertical spacing (default is 5).
080:             */
081:            public int verticalSpacing = 5;
082:
083:            /**
084:             * If set to <code>true</code>, all the columns will have the same width.
085:             * Otherwise, column widths will be computed based on controls in them and
086:             * their layout data (default is <code>false</code>).
087:             */
088:            public boolean makeColumnsEqualWidth = false;
089:
090:            private boolean initialLayout = true;
091:
092:            private Vector grid = null;
093:
094:            private Hashtable rowspans;
095:
096:            private int[] minColumnWidths, maxColumnWidths;
097:
098:            private int widestColumnWidth;
099:
100:            private int[] growingColumns;
101:
102:            private int[] growingRows;
103:
104:            private LayoutCache cache = new LayoutCache();
105:
106:            private class RowSpan {
107:                Control child;
108:
109:                int row;
110:
111:                int column;
112:
113:                int height;
114:
115:                int totalHeight;
116:
117:                public RowSpan(Control child, int column, int row) {
118:                    this .child = child;
119:                    this .column = column;
120:                    this .row = row;
121:                }
122:
123:                /*
124:                 * Updates this row span's height with the given one if it is within
125:                 * this span.
126:                 */
127:                public void update(int currentRow, int rowHeight) {
128:                    TableWrapData td = (TableWrapData) child.getLayoutData();
129:                    // is currentRow within this span?
130:                    if (currentRow >= row && currentRow < row + td.rowspan) {
131:                        totalHeight += rowHeight;
132:                        if (currentRow > row)
133:                            totalHeight += verticalSpacing;
134:                    }
135:                }
136:
137:                public int getRequiredHeightIncrease() {
138:                    if (totalHeight < height)
139:                        return height - totalHeight;
140:                    return 0;
141:                }
142:            }
143:
144:            /**
145:             * Implements ILayoutExtension. Should not be called directly.
146:             * 
147:             * @see ILayoutExtension
148:             */
149:            public int computeMinimumWidth(Composite parent, boolean changed) {
150:
151:                Control[] children = parent.getChildren();
152:                if (changed) {
153:                    cache.flush();
154:                }
155:
156:                cache.setControls(children);
157:
158:                changed = true;
159:                initializeIfNeeded(parent, changed);
160:                if (initialLayout) {
161:                    changed = true;
162:                    initialLayout = false;
163:                }
164:                if (grid == null || changed) {
165:                    changed = true;
166:                    grid = new Vector();
167:                    createGrid(parent);
168:                }
169:                if (minColumnWidths == null)
170:                    minColumnWidths = new int[numColumns];
171:                for (int i = 0; i < numColumns; i++) {
172:                    minColumnWidths[i] = 0;
173:                }
174:                return internalGetMinimumWidth(parent, changed);
175:            }
176:
177:            /**
178:             * Implements ILayoutExtension. Should not be called directly.
179:             * 
180:             * @see ILayoutExtension
181:             */
182:            public int computeMaximumWidth(Composite parent, boolean changed) {
183:                Control[] children = parent.getChildren();
184:                if (changed) {
185:                    cache.flush();
186:                }
187:
188:                cache.setControls(children);
189:
190:                changed = true;
191:                initializeIfNeeded(parent, changed);
192:                if (initialLayout) {
193:                    changed = true;
194:                    initialLayout = false;
195:                }
196:                if (grid == null || changed) {
197:                    changed = true;
198:                    grid = new Vector();
199:                    createGrid(parent);
200:                }
201:                if (maxColumnWidths == null)
202:                    maxColumnWidths = new int[numColumns];
203:                for (int i = 0; i < numColumns; i++) {
204:                    maxColumnWidths[i] = 0;
205:                }
206:                return internalGetMaximumWidth(parent, changed);
207:            }
208:
209:            /**
210:             * @see Layout#layout(Composite, boolean)
211:             */
212:            protected void layout(Composite parent, boolean changed) {
213:
214:                Rectangle clientArea = parent.getClientArea();
215:                Control[] children = parent.getChildren();
216:                if (changed) {
217:                    cache.flush();
218:                }
219:
220:                if (children.length == 0)
221:                    return;
222:
223:                cache.setControls(children);
224:
225:                int parentWidth = clientArea.width;
226:                changed = true;
227:                initializeIfNeeded(parent, changed);
228:                if (initialLayout) {
229:                    changed = true;
230:                    initialLayout = false;
231:                }
232:                if (grid == null || changed) {
233:                    changed = true;
234:                    grid = new Vector();
235:                    createGrid(parent);
236:                }
237:                resetColumnWidths();
238:                int minWidth = internalGetMinimumWidth(parent, changed);
239:                int maxWidth = internalGetMaximumWidth(parent, changed);
240:                int tableWidth = parentWidth;
241:                int[] columnWidths;
242:                if (parentWidth <= minWidth) {
243:                    tableWidth = minWidth;
244:                    if (makeColumnsEqualWidth) {
245:                        columnWidths = new int[numColumns];
246:                        for (int i = 0; i < numColumns; i++) {
247:                            columnWidths[i] = widestColumnWidth;
248:                        }
249:                    } else
250:                        columnWidths = minColumnWidths;
251:                } else if (parentWidth > maxWidth) {
252:                    if (growingColumns.length == 0) {
253:                        tableWidth = maxWidth;
254:                        columnWidths = maxColumnWidths;
255:                    } else {
256:                        columnWidths = new int[numColumns];
257:                        int colSpace = tableWidth - leftMargin - rightMargin;
258:                        colSpace -= (numColumns - 1) * horizontalSpacing;
259:                        int extra = parentWidth - maxWidth;
260:                        int colExtra = extra / growingColumns.length;
261:                        for (int i = 0; i < numColumns; i++) {
262:                            columnWidths[i] = maxColumnWidths[i];
263:                            if (isGrowingColumn(i)) {
264:                                columnWidths[i] += colExtra;
265:                            }
266:                        }
267:                    }
268:                } else {
269:                    columnWidths = new int[numColumns];
270:                    if (makeColumnsEqualWidth) {
271:                        int colSpace = tableWidth - leftMargin - rightMargin;
272:                        colSpace -= (numColumns - 1) * horizontalSpacing;
273:                        int col = colSpace / numColumns;
274:                        for (int i = 0; i < numColumns; i++) {
275:                            columnWidths[i] = col;
276:                        }
277:                    } else {
278:                        columnWidths = assignExtraSpace(tableWidth, maxWidth,
279:                                minWidth);
280:                    }
281:                }
282:                int y = topMargin + clientArea.y;
283:                int[] rowHeights = computeRowHeights(children, columnWidths,
284:                        changed);
285:                for (int i = 0; i < grid.size(); i++) {
286:                    int rowHeight = rowHeights[i];
287:                    int x = leftMargin + clientArea.x;
288:                    TableWrapData[] row = (TableWrapData[]) grid.elementAt(i);
289:                    for (int j = 0; j < numColumns; j++) {
290:                        TableWrapData td = row[j];
291:                        if (td.isItemData) {
292:                            Control child = children[td.childIndex];
293:                            placeControl(child, td, x, y, rowHeights, i);
294:                        }
295:                        x += columnWidths[j];
296:                        if (j < numColumns - 1)
297:                            x += horizontalSpacing;
298:                    }
299:                    y += rowHeight + verticalSpacing;
300:                }
301:            }
302:
303:            int[] computeRowHeights(Control[] children, int[] columnWidths,
304:                    boolean changed) {
305:                int[] rowHeights = new int[grid.size()];
306:                for (int i = 0; i < grid.size(); i++) {
307:                    TableWrapData[] row = (TableWrapData[]) grid.elementAt(i);
308:                    rowHeights[i] = 0;
309:                    for (int j = 0; j < numColumns; j++) {
310:                        TableWrapData td = row[j];
311:                        if (td.isItemData == false) {
312:                            continue;
313:                        }
314:                        Control child = children[td.childIndex];
315:                        int span = td.colspan;
316:                        int cwidth = 0;
317:                        for (int k = j; k < j + span; k++) {
318:                            cwidth += columnWidths[k];
319:                            if (k < j + span - 1)
320:                                cwidth += horizontalSpacing;
321:                        }
322:                        Point size = computeSize(td.childIndex, cwidth,
323:                                td.indent, td.maxWidth, td.maxHeight);
324:                        td.compWidth = cwidth;
325:                        if (td.heightHint != SWT.DEFAULT) {
326:                            size = new Point(size.x, td.heightHint);
327:                        }
328:                        td.compSize = size;
329:                        RowSpan rowspan = (RowSpan) rowspans.get(child);
330:                        if (rowspan == null) {
331:                            rowHeights[i] = Math.max(rowHeights[i], size.y);
332:                        } else
333:                            rowspan.height = size.y;
334:                    }
335:                    updateRowSpans(i, rowHeights[i]);
336:                }
337:                for (Enumeration enm = rowspans.elements(); enm
338:                        .hasMoreElements();) {
339:                    RowSpan rowspan = (RowSpan) enm.nextElement();
340:                    int increase = rowspan.getRequiredHeightIncrease();
341:                    if (increase == 0)
342:                        continue;
343:                    TableWrapData td = (TableWrapData) rowspan.child
344:                            .getLayoutData();
345:                    int ngrowing = 0;
346:                    int[] affectedRows = new int[grid.size()];
347:                    for (int i = 0; i < growingRows.length; i++) {
348:                        int growingRow = growingRows[i];
349:                        if (growingRow >= rowspan.row
350:                                && growingRow < rowspan.row + td.rowspan) {
351:                            affectedRows[ngrowing++] = growingRow;
352:                        }
353:                    }
354:                    if (ngrowing == 0) {
355:                        ngrowing = 1;
356:                        affectedRows[0] = rowspan.row + td.rowspan - 1;
357:                    }
358:                    increase += increase % ngrowing;
359:                    int perRowIncrease = increase / ngrowing;
360:                    for (int i = 0; i < ngrowing; i++) {
361:                        int growingRow = affectedRows[i];
362:                        rowHeights[growingRow] += perRowIncrease;
363:                    }
364:                }
365:                return rowHeights;
366:            }
367:
368:            boolean isGrowingColumn(int col) {
369:                if (growingColumns == null)
370:                    return false;
371:                for (int i = 0; i < growingColumns.length; i++) {
372:                    if (col == growingColumns[i])
373:                        return true;
374:                }
375:                return false;
376:            }
377:
378:            int[] assignExtraSpace(int tableWidth, int maxWidth, int minWidth) {
379:                int fixedPart = leftMargin + rightMargin + (numColumns - 1)
380:                        * horizontalSpacing;
381:                int D = maxWidth - minWidth;
382:                int W = tableWidth - fixedPart - minWidth;
383:                int widths[] = new int[numColumns];
384:                int rem = 0;
385:                for (int i = 0; i < numColumns; i++) {
386:                    int cmin = minColumnWidths[i];
387:                    int cmax = maxColumnWidths[i];
388:                    int d = cmax - cmin;
389:                    int extra = D != 0 ? (d * W) / D : 0;
390:                    if (i < numColumns - 1) {
391:                        widths[i] = cmin + extra;
392:                        rem += widths[i];
393:                    } else {
394:                        widths[i] = tableWidth - fixedPart - rem;
395:                    }
396:                }
397:                return widths;
398:            }
399:
400:            Point computeSize(int childIndex, int width, int indent,
401:                    int maxWidth, int maxHeight) {
402:                int widthArg = width - indent;
403:                SizeCache controlCache = cache.getCache(childIndex);
404:                if (!isWrap(controlCache.getControl()))
405:                    widthArg = SWT.DEFAULT;
406:                Point size = controlCache.computeSize(widthArg, SWT.DEFAULT);
407:                if (maxWidth != SWT.DEFAULT)
408:                    size.x = Math.min(size.x, maxWidth);
409:                if (maxHeight != SWT.DEFAULT)
410:                    size.y = Math.min(size.y, maxHeight);
411:                size.x += indent;
412:                return size;
413:            }
414:
415:            void placeControl(Control control, TableWrapData td, int x, int y,
416:                    int[] rowHeights, int row) {
417:                int xloc = x + td.indent;
418:                int yloc = y;
419:                int height = td.compSize.y;
420:                int colWidth = td.compWidth - td.indent;
421:                int width = td.compSize.x - td.indent;
422:                width = Math.min(width, colWidth);
423:                int slotHeight = rowHeights[row];
424:                RowSpan rowspan = (RowSpan) rowspans.get(control);
425:                if (rowspan != null) {
426:                    slotHeight = 0;
427:                    for (int i = row; i < row + td.rowspan; i++) {
428:                        if (i > row)
429:                            slotHeight += verticalSpacing;
430:                        slotHeight += rowHeights[i];
431:                    }
432:                }
433:                // align horizontally
434:                if (td.align == TableWrapData.CENTER) {
435:                    xloc = x + colWidth / 2 - width / 2;
436:                } else if (td.align == TableWrapData.RIGHT) {
437:                    xloc = x + colWidth - width;
438:                } else if (td.align == TableWrapData.FILL) {
439:                    width = colWidth;
440:                }
441:                // align vertically
442:                if (td.valign == TableWrapData.MIDDLE) {
443:                    yloc = y + slotHeight / 2 - height / 2;
444:                } else if (td.valign == TableWrapData.BOTTOM) {
445:                    yloc = y + slotHeight - height;
446:                } else if (td.valign == TableWrapData.FILL) {
447:                    height = slotHeight;
448:                }
449:                control.setBounds(xloc, yloc, width, height);
450:            }
451:
452:            void createGrid(Composite composite) {
453:                int row, column, rowFill, columnFill;
454:                Control[] children;
455:                TableWrapData spacerSpec;
456:                Vector growingCols = new Vector();
457:                Vector growingRows = new Vector();
458:                rowspans = new Hashtable();
459:                // 
460:                children = composite.getChildren();
461:                if (children.length == 0)
462:                    return;
463:                // 
464:                grid.addElement(createEmptyRow());
465:                row = 0;
466:                column = 0;
467:                // Loop through the children and place their associated layout specs in
468:                // the
469:                // grid. Placement occurs left to right, top to bottom (i.e., by row).
470:                for (int i = 0; i < children.length; i++) {
471:                    // Find the first available spot in the grid.
472:                    Control child = children[i];
473:                    TableWrapData spec = (TableWrapData) child.getLayoutData();
474:                    while (((TableWrapData[]) grid.elementAt(row))[column] != null) {
475:                        column = column + 1;
476:                        if (column >= numColumns) {
477:                            row = row + 1;
478:                            column = 0;
479:                            if (row >= grid.size()) {
480:                                grid.addElement(createEmptyRow());
481:                            }
482:                        }
483:                    }
484:                    // See if the place will support the widget's horizontal span. If
485:                    // not, go to the
486:                    // next row.
487:                    if (column + spec.colspan - 1 >= numColumns) {
488:                        grid.addElement(createEmptyRow());
489:                        row = row + 1;
490:                        column = 0;
491:                    }
492:                    // The vertical span for the item will be at least 1. If it is > 1,
493:                    // add other rows to the grid.
494:                    if (spec.rowspan > 1) {
495:                        rowspans.put(child, new RowSpan(child, column, row));
496:                    }
497:                    for (int j = 2; j <= spec.rowspan; j++) {
498:                        if (row + j > grid.size()) {
499:                            grid.addElement(createEmptyRow());
500:                        }
501:                    }
502:                    // Store the layout spec. Also cache the childIndex. NOTE: That we
503:                    // assume the children of a
504:                    // composite are maintained in the order in which they are created
505:                    // and added to the composite.
506:                    ((TableWrapData[]) grid.elementAt(row))[column] = spec;
507:                    spec.childIndex = i;
508:                    if (spec.grabHorizontal) {
509:                        updateGrowingColumns(growingCols, spec, column);
510:                    }
511:                    if (spec.grabVertical) {
512:                        updateGrowingRows(growingRows, spec, row);
513:                    }
514:                    // Put spacers in the grid to account for the item's vertical and
515:                    // horizontal
516:                    // span.
517:                    rowFill = spec.rowspan - 1;
518:                    columnFill = spec.colspan - 1;
519:                    for (int r = 1; r <= rowFill; r++) {
520:                        for (int c = 0; c < spec.colspan; c++) {
521:                            spacerSpec = new TableWrapData();
522:                            spacerSpec.isItemData = false;
523:                            ((TableWrapData[]) grid.elementAt(row + r))[column
524:                                    + c] = spacerSpec;
525:                        }
526:                    }
527:                    for (int c = 1; c <= columnFill; c++) {
528:                        for (int r = 0; r < spec.rowspan; r++) {
529:                            spacerSpec = new TableWrapData();
530:                            spacerSpec.isItemData = false;
531:                            ((TableWrapData[]) grid.elementAt(row + r))[column
532:                                    + c] = spacerSpec;
533:                        }
534:                    }
535:                    column = column + spec.colspan - 1;
536:                }
537:                // Fill out empty grid cells with spacers.
538:                for (int k = column + 1; k < numColumns; k++) {
539:                    spacerSpec = new TableWrapData();
540:                    spacerSpec.isItemData = false;
541:                    ((TableWrapData[]) grid.elementAt(row))[k] = spacerSpec;
542:                }
543:                for (int k = row + 1; k < grid.size(); k++) {
544:                    spacerSpec = new TableWrapData();
545:                    spacerSpec.isItemData = false;
546:                    ((TableWrapData[]) grid.elementAt(k))[column] = spacerSpec;
547:                }
548:                growingColumns = new int[growingCols.size()];
549:                for (int i = 0; i < growingCols.size(); i++) {
550:                    growingColumns[i] = ((Integer) growingCols.get(i))
551:                            .intValue();
552:                }
553:                this .growingRows = new int[growingRows.size()];
554:                for (int i = 0; i < growingRows.size(); i++) {
555:                    this .growingRows[i] = ((Integer) growingRows.get(i))
556:                            .intValue();
557:                }
558:            }
559:
560:            private void updateGrowingColumns(Vector growingColumns,
561:                    TableWrapData spec, int column) {
562:                int affectedColumn = column + spec.colspan - 1;
563:                for (int i = 0; i < growingColumns.size(); i++) {
564:                    Integer col = (Integer) growingColumns.get(i);
565:                    if (col.intValue() == affectedColumn)
566:                        return;
567:                }
568:                growingColumns.add(new Integer(affectedColumn));
569:            }
570:
571:            private void updateGrowingRows(Vector growingRows,
572:                    TableWrapData spec, int row) {
573:                int affectedRow = row + spec.rowspan - 1;
574:                for (int i = 0; i < growingRows.size(); i++) {
575:                    Integer irow = (Integer) growingRows.get(i);
576:                    if (irow.intValue() == affectedRow)
577:                        return;
578:                }
579:                growingRows.add(new Integer(affectedRow));
580:            }
581:
582:            private TableWrapData[] createEmptyRow() {
583:                TableWrapData[] row = new TableWrapData[numColumns];
584:                for (int i = 0; i < numColumns; i++)
585:                    row[i] = null;
586:                return row;
587:            }
588:
589:            /**
590:             * @see Layout#computeSize(Composite, int, int, boolean)
591:             */
592:            protected Point computeSize(Composite parent, int wHint, int hHint,
593:                    boolean changed) {
594:                Control[] children = parent.getChildren();
595:                if (changed) {
596:                    cache.flush();
597:                }
598:                if (children.length == 0) {
599:                    return new Point(0, 0);
600:                }
601:                cache.setControls(children);
602:
603:                int parentWidth = wHint;
604:                changed = true;
605:                initializeIfNeeded(parent, changed);
606:                if (initialLayout) {
607:                    changed = true;
608:                    initialLayout = false;
609:                }
610:                if (grid == null || changed) {
611:                    changed = true;
612:                    grid = new Vector();
613:                    createGrid(parent);
614:                }
615:                resetColumnWidths();
616:                int minWidth = internalGetMinimumWidth(parent, changed);
617:                int maxWidth = internalGetMaximumWidth(parent, changed);
618:
619:                if (wHint == SWT.DEFAULT)
620:                    parentWidth = maxWidth;
621:
622:                int tableWidth = parentWidth;
623:                int[] columnWidths;
624:                if (parentWidth <= minWidth) {
625:                    tableWidth = minWidth;
626:                    if (makeColumnsEqualWidth) {
627:                        columnWidths = new int[numColumns];
628:                        for (int i = 0; i < numColumns; i++) {
629:                            columnWidths[i] = widestColumnWidth;
630:                        }
631:                    } else
632:                        columnWidths = minColumnWidths;
633:                } else if (parentWidth >= maxWidth) {
634:                    if (makeColumnsEqualWidth) {
635:                        columnWidths = new int[numColumns];
636:                        int colSpace = parentWidth - leftMargin - rightMargin;
637:                        colSpace -= (numColumns - 1) * horizontalSpacing;
638:                        int col = colSpace / numColumns;
639:                        for (int i = 0; i < numColumns; i++) {
640:                            columnWidths[i] = col;
641:                        }
642:                    } else {
643:                        tableWidth = maxWidth;
644:                        columnWidths = maxColumnWidths;
645:                    }
646:                } else {
647:                    columnWidths = new int[numColumns];
648:                    if (makeColumnsEqualWidth) {
649:                        int colSpace = tableWidth - leftMargin - rightMargin;
650:                        colSpace -= (numColumns - 1) * horizontalSpacing;
651:                        int col = colSpace / numColumns;
652:                        for (int i = 0; i < numColumns; i++) {
653:                            columnWidths[i] = col;
654:                        }
655:                    } else {
656:                        columnWidths = assignExtraSpace(tableWidth, maxWidth,
657:                                minWidth);
658:                    }
659:                }
660:                int totalHeight = 0;
661:                int innerHeight = 0;
662:                // compute widths
663:                for (int i = 0; i < grid.size(); i++) {
664:                    TableWrapData[] row = (TableWrapData[]) grid.elementAt(i);
665:                    // assign widths, calculate heights
666:                    int rowHeight = 0;
667:                    for (int j = 0; j < numColumns; j++) {
668:                        TableWrapData td = row[j];
669:                        if (td.isItemData == false) {
670:                            continue;
671:                        }
672:                        Control child = children[td.childIndex];
673:                        int span = td.colspan;
674:                        int cwidth = 0;
675:                        for (int k = j; k < j + span; k++) {
676:                            if (k > j)
677:                                cwidth += horizontalSpacing;
678:                            cwidth += columnWidths[k];
679:                        }
680:                        int cy = td.heightHint;
681:                        if (cy == SWT.DEFAULT) {
682:                            Point size = computeSize(td.childIndex, cwidth,
683:                                    td.indent, td.maxWidth, td.maxHeight);
684:                            cy = size.y;
685:                        }
686:                        RowSpan rowspan = (RowSpan) rowspans.get(child);
687:                        if (rowspan != null) {
688:                            // don't take the height of this child into acount
689:                            // because it spans multiple rows
690:                            rowspan.height = cy;
691:                        } else {
692:                            rowHeight = Math.max(rowHeight, cy);
693:                        }
694:                    }
695:                    updateRowSpans(i, rowHeight);
696:                    if (i > 0)
697:                        innerHeight += verticalSpacing;
698:                    innerHeight += rowHeight;
699:                }
700:                if (!rowspans.isEmpty())
701:                    innerHeight = compensateForRowSpans(innerHeight);
702:                totalHeight = topMargin + innerHeight + bottomMargin;
703:                return new Point(tableWidth, totalHeight);
704:            }
705:
706:            private void updateRowSpans(int row, int rowHeight) {
707:                if (rowspans == null || rowspans.size() == 0)
708:                    return;
709:                for (Enumeration enm = rowspans.elements(); enm
710:                        .hasMoreElements();) {
711:                    RowSpan rowspan = (RowSpan) enm.nextElement();
712:                    rowspan.update(row, rowHeight);
713:                }
714:            }
715:
716:            private int compensateForRowSpans(int totalHeight) {
717:                for (Enumeration enm = rowspans.elements(); enm
718:                        .hasMoreElements();) {
719:                    RowSpan rowspan = (RowSpan) enm.nextElement();
720:                    totalHeight += rowspan.getRequiredHeightIncrease();
721:                }
722:                return totalHeight;
723:            }
724:
725:            int internalGetMinimumWidth(Composite parent, boolean changed) {
726:                if (changed)
727:                    //calculateMinimumColumnWidths(parent, true);
728:                    calculateColumnWidths(parent, minColumnWidths, false, true);
729:                int minimumWidth = 0;
730:                widestColumnWidth = 0;
731:                if (makeColumnsEqualWidth) {
732:                    for (int i = 0; i < numColumns; i++) {
733:                        widestColumnWidth = Math.max(widestColumnWidth,
734:                                minColumnWidths[i]);
735:                    }
736:                }
737:                for (int i = 0; i < numColumns; i++) {
738:                    if (i > 0)
739:                        minimumWidth += horizontalSpacing;
740:                    if (makeColumnsEqualWidth)
741:                        minimumWidth += widestColumnWidth;
742:                    else
743:                        minimumWidth += minColumnWidths[i];
744:                }
745:                // add margins
746:                minimumWidth += leftMargin + rightMargin;
747:                return minimumWidth;
748:            }
749:
750:            int internalGetMaximumWidth(Composite parent, boolean changed) {
751:                if (changed)
752:                    //calculateMaximumColumnWidths(parent, true);
753:                    calculateColumnWidths(parent, maxColumnWidths, true, true);
754:                int maximumWidth = 0;
755:                for (int i = 0; i < numColumns; i++) {
756:                    if (i > 0)
757:                        maximumWidth += horizontalSpacing;
758:                    maximumWidth += maxColumnWidths[i];
759:                }
760:                // add margins
761:                maximumWidth += leftMargin + rightMargin;
762:                return maximumWidth;
763:            }
764:
765:            void resetColumnWidths() {
766:                if (minColumnWidths == null)
767:                    minColumnWidths = new int[numColumns];
768:                if (maxColumnWidths == null)
769:                    maxColumnWidths = new int[numColumns];
770:                for (int i = 0; i < numColumns; i++) {
771:                    minColumnWidths[i] = 0;
772:                }
773:                for (int i = 0; i < numColumns; i++) {
774:                    maxColumnWidths[i] = 0;
775:                }
776:            }
777:
778:            void calculateColumnWidths(Composite parent, int[] columnWidths,
779:                    boolean max, boolean changed) {
780:                boolean secondPassNeeded = false;
781:                for (int i = 0; i < grid.size(); i++) {
782:                    TableWrapData[] row = (TableWrapData[]) grid.elementAt(i);
783:                    for (int j = 0; j < numColumns; j++) {
784:                        TableWrapData td = row[j];
785:                        if (td.isItemData == false)
786:                            continue;
787:
788:                        if (td.colspan > 1) {
789:                            // we will not do controls with multiple column span
790:                            // here - increment and continue
791:                            secondPassNeeded = true;
792:                            j += td.colspan - 1;
793:                            continue;
794:                        }
795:
796:                        SizeCache childCache = cache.getCache(td.childIndex);
797:                        // !!
798:                        int width = max ? childCache.computeMaximumWidth()
799:                                : childCache.computeMinimumWidth();
800:                        if (td.maxWidth != SWT.DEFAULT)
801:                            width = Math.min(width, td.maxWidth);
802:
803:                        width += td.indent;
804:                        columnWidths[j] = Math.max(columnWidths[j], width);
805:                    }
806:                }
807:                if (!secondPassNeeded)
808:                    return;
809:
810:                // Second pass for controls with multi-column horizontal span
811:                for (int i = 0; i < grid.size(); i++) {
812:                    TableWrapData[] row = (TableWrapData[]) grid.elementAt(i);
813:                    for (int j = 0; j < numColumns; j++) {
814:                        TableWrapData td = row[j];
815:                        if (td.isItemData == false || td.colspan == 1)
816:                            continue;
817:
818:                        SizeCache childCache = cache.getCache(td.childIndex);
819:                        int width = max ? childCache.computeMaximumWidth()
820:                                : childCache.computeMinimumWidth();
821:                        if (td.maxWidth != SWT.DEFAULT)
822:                            width = Math.min(width, td.maxWidth);
823:
824:                        width += td.indent;
825:                        // check if the current width is enough to
826:                        // support the control; if not, add the delta to
827:                        // the last column or to all the growing columns, if present
828:                        int current = 0;
829:                        for (int k = j; k < j + td.colspan; k++) {
830:                            if (k > j)
831:                                current += horizontalSpacing;
832:                            current += columnWidths[k];
833:                        }
834:                        if (width <= current) {
835:                            // we are ok - nothing to do here
836:                        } else {
837:                            int ndiv = 0;
838:                            if (growingColumns != null) {
839:                                for (int k = j; k < j + td.colspan; k++) {
840:                                    if (isGrowingColumn(k)) {
841:                                        ndiv++;
842:                                    }
843:                                }
844:                            }
845:                            if (ndiv == 0) {
846:                                // add the delta to the last column
847:                                columnWidths[j + td.colspan - 1] += width
848:                                        - current;
849:                            } else {
850:                                // distribute the delta to the growing
851:                                // columns
852:                                int percolumn = (width - current) / ndiv;
853:                                if ((width - current) % ndiv > 0)
854:                                    percolumn++;
855:                                for (int k = j; k < j + td.colspan; k++) {
856:                                    if (isGrowingColumn(k))
857:                                        columnWidths[k] += percolumn;
858:                                }
859:                            }
860:                        }
861:                    }
862:                }
863:            }
864:
865:            boolean isWrap(Control control) {
866:                if (control instanceof  Composite
867:                        && ((Composite) control).getLayout() instanceof  ILayoutExtension)
868:                    return true;
869:                return (control.getStyle() & SWT.WRAP) != 0;
870:            }
871:
872:            private void initializeIfNeeded(Composite parent, boolean changed) {
873:                if (changed)
874:                    initialLayout = true;
875:                if (initialLayout) {
876:                    initializeLayoutData(parent);
877:                    initialLayout = false;
878:                }
879:            }
880:
881:            void initializeLayoutData(Composite composite) {
882:                Control[] children = composite.getChildren();
883:                for (int i = 0; i < children.length; i++) {
884:                    Control child = children[i];
885:                    if (child.getLayoutData() == null) {
886:                        child.setLayoutData(new TableWrapData());
887:                    }
888:                }
889:            }
890:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.