001: /*
002: * Copyright 2000,2005 wingS development team.
003: *
004: * This file is part of wingS (http://wingsframework.org).
005: *
006: * wingS is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * Please see COPYING for the complete licence.
012: */
013: package org.wings.plaf.css;
014:
015: import org.wings.*;
016: import org.wings.plaf.css.PaddingVoodoo;
017: import org.wings.io.Device;
018:
019: import java.awt.*;
020: import java.io.IOException;
021:
022: public class GridBagLayoutCG extends AbstractLayoutCG {
023: private static final long serialVersionUID = 1L;
024:
025: /**
026: * Renders a gridbag layout using invisible layouter tables.
027: *
028: * @param d the device to write the code to
029: * @param l the layout manager
030: */
031: public void write(Device d, SLayoutManager l) throws IOException {
032: final SGridBagLayout layout = (SGridBagLayout) l;
033: final SContainer container = layout.getContainer();
034: final boolean header = layout.getHeader();
035: final boolean useCellInsets = layout.getVgap() == -1
036: && layout.getHgap() == -1;
037: final SGridBagLayout.Grid grid = layout.getGrid();
038: final TableCellStyle cellStyle = cellLayoutStyle(layout);
039:
040: SDimension preferredSize = container.getPreferredSize();
041: String height = preferredSize != null ? preferredSize
042: .getHeight() : null;
043: boolean clientLayout = isMSIE(container) && height != null
044: && !"auto".equals(height);
045: int vertivalOversize = layoutOversize(layout);
046:
047: if (grid.cols == 0) {
048: return;
049: }
050:
051: openLayouterBody(d, layout);
052:
053: for (int row = grid.firstRow; row < grid.rows; row++) {
054: Utils.printNewline(d, container);
055: if (clientLayout) {
056: d.print("<tr");
057: Utils.optAttribute(d, "yweight", determineRowHeight(
058: layout, row));
059: if (useCellInsets) {
060: vertivalOversize = 0;
061: for (int col = grid.firstCol; col < grid.cols; col++) {
062: final SComponent comp = grid.grid[col][row];
063: if (comp != null) {
064: GridBagConstraints c = layout
065: .getConstraints(comp);
066: Insets insets = c.insets;
067: if (insets != null)
068: vertivalOversize = Math.max(
069: vertivalOversize, cellOversize(
070: layout, insets));
071: }
072: }
073: }
074: Utils.optAttribute(d, "oversize", vertivalOversize);
075: d.print(">");
076: } else {
077: openLayouterRow(d, determineRowHeight(layout, row)
078: + "%");
079: }
080: for (int col = grid.firstCol; col < grid.cols; col++) {
081: final SComponent comp = grid.grid[col][row];
082: Utils.printNewline(d, container);
083:
084: cellStyle.renderAsTH = row == grid.firstRow && header;
085: cellStyle.defaultLayoutCellHAlignment = SConstants.CENTER;
086: cellStyle.defaultLayoutCellVAlignment = SConstants.CENTER;
087:
088: if (comp == null) {
089: cellStyle.colspan = -1;
090: cellStyle.rowspan = -1;
091: cellStyle.width = null;
092:
093: openLayouterCell(d, null, cellStyle);
094: closeLayouterCell(d, null, cellStyle.renderAsTH);
095: } else {
096: GridBagConstraints c = layout.getConstraints(comp);
097:
098: if ((c.gridx == SGridBagLayout.LAST_CELL || c.gridx == col)
099: && (c.gridy == SGridBagLayout.LAST_CELL || c.gridy == row)) {
100:
101: int gridwidth = c.gridwidth;
102: if (gridwidth == GridBagConstraints.RELATIVE) {
103: gridwidth = grid.cols - col - 1;
104: } else if (gridwidth == GridBagConstraints.REMAINDER) {
105: gridwidth = grid.cols - col;
106: }
107: if (gridwidth < 2) {
108: gridwidth = -1;
109: }
110:
111: int gridheight = c.gridheight;
112: if (gridheight == GridBagConstraints.RELATIVE) {
113: gridheight = grid.cols - col - 1;
114: } else if (gridheight == GridBagConstraints.REMAINDER) {
115: gridheight = grid.cols - col;
116: }
117: if (gridheight < 2) {
118: gridheight = -1;
119: }
120:
121: cellStyle.width = null;
122: if (c.weightx > 0 && grid.colweight[row] > 0) {
123: cellStyle.width = (int) (100 * c.weightx / grid.colweight[row])
124: + "%";
125: }
126:
127: if (useCellInsets) {
128: cellStyle.setInsets((Insets) c.insets
129: .clone());
130: }
131: cellStyle.colspan = gridwidth;
132: cellStyle.rowspan = gridheight;
133:
134: if (PaddingVoodoo.hasPaddingInsets(container)) {
135: final Insets patchedInsets = (Insets) cellStyle
136: .getInsets().clone();
137: final boolean isFirstRow = row == grid.firstRow;
138: final boolean isLastRow = row == grid.rows - 1;
139: final boolean isFirstCol = col == grid.firstCol;
140: final boolean isLastCol = col == grid.cols - 1;
141: PaddingVoodoo.doBorderPaddingsWorkaround(
142: container.getBorder(),
143: patchedInsets, isFirstRow,
144: isFirstCol, isLastCol, isLastRow);
145: cellStyle.setInsets(patchedInsets);
146: }
147:
148: openLayouterCell(d, comp, cellStyle);
149:
150: Utils.printNewline(d, comp);
151: comp.write(d); // Render component
152:
153: closeLayouterCell(d, comp, cellStyle.renderAsTH);
154: }
155: }
156: }
157: Utils.printNewline(d, container);
158: closeLayouterRow(d);
159: }
160: closeLayouterBody(d, layout);
161: }
162:
163: /**
164: * Copy and paste extracted method to determine an optional row height of the passed row.
165: * Was necessary to avoid a rendering bug with Gecko engines leading to a messed up layout.
166: * Refer to http://jira.j-wings.org/browse/WGS-120
167: *
168: * @param layout The gridbaglayout
169: * @param row The row
170: * @return Row height percentage as int or 0
171: */
172: protected int determineRowHeight(SGridBagLayout layout, int row) {
173: final SGridBagLayout.Grid grid = layout.getGrid();
174: int rowHeight = 0;
175:
176: for (int col = grid.firstCol; col < grid.cols; col++) {
177: SComponent comp = grid.grid[col][row];
178: if (comp != null) {
179: GridBagConstraints c = layout.getConstraints(comp);
180: if ((c.gridx == SGridBagLayout.LAST_CELL || c.gridx == col)
181: && (c.gridy == SGridBagLayout.LAST_CELL || c.gridy == row)) {
182: if (c.weighty > 0 && grid.rowweight[col] > 0) {
183: int cellHeight = (int) (100 * c.weighty / grid.rowweight[col]);
184: if (cellHeight > rowHeight) {
185: rowHeight = cellHeight;
186: }
187: }
188: }
189: }
190: }
191: return rowHeight;
192: }
193:
194: protected int getLayoutHGap(SLayoutManager layout) {
195: return ((SGridBagLayout) layout).getHgap();
196: }
197:
198: protected int getLayoutVGap(SLayoutManager layout) {
199: return ((SGridBagLayout) layout).getVgap();
200: }
201:
202: protected int getLayoutBorder(SLayoutManager layout) {
203: return layout.getBorder();
204: }
205:
206: protected int layoutOversize(SLayoutManager layout) {
207: return ((SGridBagLayout) layout).getVgap() + layout.getBorder();
208: }
209:
210: public int getDefaultLayoutCellHAlignment() {
211: return SConstants.NO_ALIGN; // Don't knoff.
212: }
213:
214: public int getDefaultLayoutCellVAlignment() {
215: return SConstants.NO_ALIGN; // Don't knoff.
216: }
217:
218: }
|