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.util.SStringBuilder;
017: import org.wings.io.Device;
018: import org.wings.plaf.css.script.LayoutFillScript;
019: import org.wings.session.Browser;
020: import org.wings.session.BrowserType;
021: import org.wings.session.ScriptManager;
022:
023: import javax.swing.*;
024: import java.awt.event.ActionEvent;
025: import java.awt.event.KeyEvent;
026: import java.io.IOException;
027: import java.util.HashMap;
028: import java.util.Map;
029:
030: public class TabbedPaneCG extends AbstractComponentCG {
031: private static final long serialVersionUID = 1L;
032: private static final Map<Integer, String> placements = new HashMap<Integer, String>();
033:
034: static {
035: placements.put(SConstants.TOP, "top");
036: placements.put(SConstants.BOTTOM, "bottom");
037: placements.put(SConstants.LEFT, "left");
038: placements.put(SConstants.RIGHT, "right");
039: }
040:
041: public void installCG(SComponent component) {
042: super .installCG(component);
043:
044: final STabbedPane tab = (STabbedPane) component;
045: InputMap inputMap = new InputMap();
046: inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
047: KeyEvent.ALT_DOWN_MASK, false), "previous");
048: inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
049: KeyEvent.ALT_DOWN_MASK, false), "next");
050: tab
051: .setInputMap(
052: SComponent.WHEN_FOCUSED_OR_ANCESTOR_OF_FOCUSED_COMPONENT,
053: inputMap);
054:
055: Action action = new AbstractAction() {
056: public void actionPerformed(ActionEvent e) {
057: if (tab.getSelectedIndex() > 0
058: && "previous".equals(e.getActionCommand())) {
059: int index = tab.getSelectedIndex() - 1;
060: if (tab.isEnabledAt(index))
061: tab.setSelectedIndex(index);
062: } else if (tab.getSelectedIndex() < tab.getTabCount() - 1
063: && "next".equals(e.getActionCommand())) {
064: int index = tab.getSelectedIndex() + 1;
065: if (tab.isEnabledAt(index))
066: tab.setSelectedIndex(index);
067: }
068: tab.requestFocus();
069: }
070: };
071: ActionMap actionMap = new ActionMap();
072: actionMap.put("previous", action);
073: actionMap.put("next", action);
074: tab.setActionMap(actionMap);
075: }
076:
077: public void writeInternal(final Device device,
078: final SComponent component) throws java.io.IOException {
079:
080: final STabbedPane tabbedPane = (STabbedPane) component;
081: if (tabbedPane.getTabCount() > 0) {
082: final int placement = tabbedPane.getTabPlacement();
083:
084: SStringBuilder tabArea = Utils.inlineStyles(component
085: .getDynamicStyle(STabbedPane.SELECTOR_TABS));
086: SStringBuilder contentArea = Utils.inlineStyles(component
087: .getDynamicStyle(STabbedPane.SELECTOR_CONTENT));
088:
089: SDimension preferredSize = component.getPreferredSize();
090: String height = preferredSize != null ? preferredSize
091: .getHeight() : null;
092: boolean clientLayout = isMSIE(component)
093: && height != null
094: && !"auto".equals(height)
095: && (placement == SConstants.TOP || placement == SConstants.BOTTOM);
096:
097: device.print("<table");
098:
099: if (clientLayout) {
100: Utils.optAttribute(device, "layoutHeight", height);
101: preferredSize.setHeight(null);
102: }
103:
104: Utils.writeAllAttributes(device, component);
105: Utils.writeEvents(device, tabbedPane, null);
106:
107: if (clientLayout) {
108: preferredSize.setHeight(height);
109: ScriptManager.getInstance().addScriptListener(
110: new LayoutFillScript(component.getName()));
111: }
112:
113: device.print(">");
114:
115: if (placement == SConstants.TOP) {
116: device.print("<tr><th");
117: } else if (placement == SConstants.LEFT) {
118: device.print("<tr><th");
119: } else if (placement == SConstants.RIGHT) {
120: device.print("<tr><td");
121: Utils.printTableCellAlignment(device, tabbedPane
122: .getSelectedComponent(), SConstants.LEFT,
123: SConstants.TOP);
124: } else if (placement == SConstants.BOTTOM) {
125: device.print("<tr yweight=\"100\" oversize=\"2\"");
126: device.print("><td");
127: Utils.printTableCellAlignment(device, tabbedPane
128: .getSelectedComponent(), SConstants.LEFT,
129: SConstants.TOP);
130: }
131:
132: if (placement == SConstants.TOP) {
133: Utils.optAttribute(device, "class", "STabbedPane_top");
134: Utils.optAttribute(device, "style", tabArea);
135: } else if (placement == SConstants.LEFT) {
136: Utils.optAttribute(device, "class", "STabbedPane_left");
137: Utils.optAttribute(device, "style", tabArea);
138: } else {
139: Utils.optAttribute(device, "class", "STabbedPane_pane");
140: Utils.optAttribute(device, "style", contentArea);
141: }
142: device.print(">");
143:
144: if (placement == SConstants.TOP
145: || placement == SConstants.LEFT) {
146: writeTabs(device, tabbedPane);
147: } else {
148: writeSelectedPaneContent(device, tabbedPane);
149: }
150:
151: if (placement == SConstants.TOP) {
152: device
153: .print("</th></tr>\n<tr yweight=\"100\" oversize=\"2\"><td");
154: Utils.printTableCellAlignment(device, tabbedPane
155: .getSelectedComponent(), SConstants.LEFT,
156: SConstants.TOP);
157: Utils.optAttribute(device, "style", contentArea);
158: } else if (placement == SConstants.LEFT) {
159: device.print("</th><td");
160: Utils.printTableCellAlignment(device, tabbedPane
161: .getSelectedComponent(), SConstants.LEFT,
162: SConstants.TOP);
163: Utils.optAttribute(device, "style", contentArea);
164: } else if (placement == SConstants.RIGHT) {
165: device.print("</td><th");
166: Utils.optAttribute(device, "style", tabArea);
167: } else if (placement == SConstants.BOTTOM) {
168: device.print("</td></tr>\n<tr><th");
169: Utils.optAttribute(device, "style", tabArea);
170: }
171:
172: if (placement == SConstants.RIGHT) {
173: Utils
174: .optAttribute(device, "class",
175: "STabbedPane_right");
176: } else if (placement == SConstants.BOTTOM) {
177: Utils.optAttribute(device, "class",
178: "STabbedPane_bottom");
179: } else {
180: Utils.optAttribute(device, "class", "STabbedPane_pane");
181: }
182: device.print(">");
183:
184: if (placement == SConstants.TOP
185: || placement == SConstants.LEFT) {
186: writeSelectedPaneContent(device, tabbedPane);
187: device.print("</td></tr></table>");
188: } else {
189: writeTabs(device, tabbedPane);
190: device.print("</th></tr></table>");
191: }
192: } else {
193: Utils
194: .printDebug(device,
195: "<!-- tabbed pane has no tabs -->");
196: }
197: }
198:
199: /**
200: * Renders the currently selected pane of the tabbed Pane.
201: */
202: protected void writeSelectedPaneContent(Device device,
203: STabbedPane tabbedPane) throws IOException {
204: SComponent selected = tabbedPane.getSelectedComponent();
205: if (selected != null) {
206: selected.write(device);
207: }
208: }
209:
210: protected void writeTabs(Device device, STabbedPane tabbedPane)
211: throws IOException {
212: final Browser browser = tabbedPane.getSession().getUserAgent();
213: // substitute whitespaces for konqueror and ie5.0x
214: final boolean nbspWorkaround = browser.getBrowserType().equals(
215: BrowserType.KONQUEROR);
216:
217: SStringBuilder selectedTab = Utils.inlineStyles(tabbedPane
218: .getDynamicStyle(STabbedPane.SELECTOR_SELECTED_TAB));
219: SStringBuilder unselectedTab = Utils.inlineStyles(tabbedPane
220: .getDynamicStyle(STabbedPane.SELECTOR_UNSELECTED_TAB));
221: SStringBuilder disabledTab = Utils.inlineStyles(tabbedPane
222: .getDynamicStyle(STabbedPane.SELECTOR_DISABLED_TAB));
223:
224: for (int i = 0; i < tabbedPane.getTabCount(); i++) {
225: final SIcon icon = tabbedPane.getIconAt(i);
226: final String tooltip = tabbedPane.getToolTipText();
227: final String title = nbspWorkaround ? Utils
228: .nonBreakingSpaces(tabbedPane.getTitleAt(i))
229: : tabbedPane.getTitleAt(i);
230: final boolean enabledTab = tabbedPane.isEnabledAt(i);
231: final String eventValue = String.valueOf(i);
232:
233: /*
234: * needed here so that the tabs can be wrapped. else they are in
235: * one long line. noticed in firefox and konqueror.
236: */
237: Utils.printNewline(device, tabbedPane);
238:
239: Utils.printButtonStart(device, tabbedPane, eventValue,
240: enabledTab, tabbedPane.getShowAsFormComponent());
241:
242: if (tooltip != null) {
243: Utils.optAttribute(device, "title", tooltip);
244: }
245:
246: if (i == tabbedPane.getSelectedIndex()
247: && tabbedPane.isFocusOwner()) {
248: Utils.optAttribute(device, "foc", tabbedPane.getName());
249: }
250:
251: final SStringBuilder cssClassName = new SStringBuilder(
252: "STabbedPane_Tab_");
253: cssClassName.append(placements.get(tabbedPane
254: .getTabPlacement()));
255: if (i == tabbedPane.getSelectedIndex()) {
256: cssClassName.append(" STabbedPane_Tab_selected");
257: } else if (!enabledTab) {
258: cssClassName.append(" STabbedPane_Tab_disabled");
259: } else {
260: cssClassName.append(" STabbedPane_Tab_unselected");
261: }
262: if (i == tabbedPane.getSelectedIndex()) {
263: Utils.optAttribute(device, "style", selectedTab);
264: } else if (!enabledTab) {
265: Utils.optAttribute(device, "style", disabledTab);
266: } else {
267: Utils.optAttribute(device, "style", unselectedTab);
268: }
269: Utils.optAttribute(device, "class", cssClassName);
270:
271: device.print(">");
272:
273: if (icon != null
274: && tabbedPane.getTabPlacement() != SConstants.RIGHT) {
275: device.print("<img");
276: Utils.optAttribute(device, "src", icon.getURL());
277: Utils
278: .optAttribute(device, "width", icon
279: .getIconWidth());
280: Utils.optAttribute(device, "height", icon
281: .getIconHeight());
282: Utils.attribute(device, "alt", icon.getIconTitle());
283: device.print("/>");
284: }
285:
286: if (title != null) {
287: device.print(" ");
288: Utils.write(device, title);
289: device.print(" ");
290: }
291:
292: if (icon != null
293: && tabbedPane.getTabPlacement() == SConstants.RIGHT) {
294: device.print("<img");
295: Utils.optAttribute(device, "src", icon.getURL());
296: Utils
297: .optAttribute(device, "width", icon
298: .getIconWidth());
299: Utils.optAttribute(device, "height", icon
300: .getIconHeight());
301: Utils.attribute(device, "alt", icon.getIconTitle());
302: device.print("/>");
303: }
304:
305: Utils.printButtonEnd(device, enabledTab);
306: }
307: }
308: }
|