001: /*
002: #IFNDEF ALT_LICENSE
003: ThinWire(R) RIA Ajax Framework
004: Copyright (C) 2003-2007 Custom Credit Systems
005:
006: This library is free software; you can redistribute it and/or modify it under
007: the terms of the GNU Lesser General Public License as published by the Free
008: Software Foundation; either version 2.1 of the License, or (at your option) any
009: later version.
010:
011: This library is distributed in the hope that it will be useful, but WITHOUT ANY
012: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
013: PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
014:
015: You should have received a copy of the GNU Lesser General Public License along
016: with this library; if not, write to the Free Software Foundation, Inc., 59
017: Temple Place, Suite 330, Boston, MA 02111-1307 USA
018:
019: Users who would rather have a commercial license, warranty or support should
020: contact the following company who invented, built and supports the technology:
021:
022: Custom Credit Systems, Richardson, TX 75081, USA.
023: email: info@thinwire.com ph: +1 (888) 644-6405
024: http://www.thinwire.com
025: #ENDIF
026: [ v1.2_RC2 ]
027: */
028: package thinwire.ui;
029:
030: import thinwire.ui.event.ItemChangeEvent;
031: import thinwire.ui.event.ItemChangeListener;
032: import thinwire.ui.event.PropertyChangeEvent;
033: import thinwire.ui.event.PropertyChangeListener;
034: import thinwire.ui.event.ItemChangeEvent.Type;
035: import thinwire.ui.layout.Layout;
036: import thinwire.ui.style.Font;
037: import thinwire.ui.style.Background;
038: import thinwire.ui.style.Style;
039:
040: /**
041: * A container for Tab Sheets. A Tab folder could sit in a dialog and have
042: * multiple tabs.
043: * <p>
044: * <b>Example:</b> <br>
045: * <img src="doc-files/TabFolder-1.png"> <br>
046: *
047: * <pre>
048: * Dialog dlg = new Dialog("TabFolder Test");
049: * dlg.setBounds(25, 25, 600, 400);
050: *
051: * TabSheet tSheet1 = new TabSheet("Sheet 1");
052: * TabSheet tSheet2 = new TabSheet("Sheet 2");
053: *
054: * TabFolder tFolder = new TabFolder();
055: * tFolder.setBounds(50, 25, 500, 300);
056: * tFolder.getChildren().add(tSheet1);
057: * tFolder.getChildren().add(tSheet2);
058: *
059: * TextField tf = new TextField();
060: * tf.setBounds(25, 25, 150, 20);
061: * tSheet2.getChildren().add(tf);
062: *
063: * Button firstButton = new Button("Change Tab Title 1");
064: * firstButton.setBounds(50, 50, 150, 30);
065: * firstButton.addActionListener(Button.ACTION_CLICK, new ActionListener() {
066: * public void actionPerformed(ActionEvent ev) {
067: * ((TabSheet) ((Button) ev.getSource()).getParent()).setText("New Title 1");
068: * }
069: * });
070: * tSheet1.getChildren().add(firstButton);
071: * dlg.getChildren().add(tFolder);
072: * dlg.setVisible(true);
073: * </pre>
074: *
075: * </p>
076: * <p>
077: * <b>Keyboard Navigation:</b><br>
078: * <table border="1">
079: * <tr>
080: * <td>KEY</td>
081: * <td>RESPONSE</td>
082: * <td>NOTE</td>
083: * </tr>
084: * </table>
085: * </p>
086: *
087: * @author Joshua J. Gertzen
088: */
089: public class TabFolder extends AbstractContainer<TabSheet> {
090: public static final String PROPERTY_CURRENT_INDEX = "currentIndex";
091: static final int TABS_HEIGHT = 20;
092: private static final String[] BOUNDS_PROPERTIES = new String[] {
093: Component.PROPERTY_X, Component.PROPERTY_Y,
094: Component.PROPERTY_WIDTH, Component.PROPERTY_HEIGHT };
095:
096: private static final String[] STYLE_PROPERTIES = {
097: Font.PROPERTY_FONT_BOLD, Font.PROPERTY_FONT_COLOR,
098: Font.PROPERTY_FONT_FAMILY, Font.PROPERTY_FONT_ITALIC,
099: Font.PROPERTY_FONT_SIZE, Font.PROPERTY_FONT_UNDERLINE,
100: Font.PROPERTY_FONT_STRIKE,
101: Background.PROPERTY_BACKGROUND_COLOR,
102: Background.PROPERTY_BACKGROUND_IMAGE,
103: Background.PROPERTY_BACKGROUND_POSITION,
104: Background.PROPERTY_BACKGROUND_REPEAT };
105:
106: private int currentIndex = -1;
107: private TabSheet currentSheet;
108:
109: public TabFolder() {
110: addItemChangeListener(new ItemChangeListener() {
111: public void itemChange(ItemChangeEvent ev) {
112: Type type = ev.getType();
113: TabSheet oSheet = (TabSheet) ev.getOldValue();
114: TabSheet nSheet = (TabSheet) ev.getNewValue();
115:
116: if (type == Type.REMOVE || type == Type.SET) {
117: oSheet.boundsChanged(0, 0, 0, 0);
118: if (getChildren().size() == 0) {
119: setCurrentIndex(-1);
120: } else if (oSheet.equals(currentSheet)) {
121: setCurrentIndex(currentIndex - 1);
122: }
123: }
124:
125: if (type == Type.ADD || type == Type.SET) {
126: nSheet.boundsChanged(getX(), getY(), getWidth(),
127: getHeight());
128: Style ss = nSheet.getStyle();
129: Style s = getStyle();
130: ss.getBorder().copy(s.getBorder(), false);
131: ss.getBackground().copy(s.getBackground(), true);
132: ss.getFont().copy(s.getFont(), true);
133: ss.getFX().copy(s.getFX(), true);
134: if (getChildren().size() == 1)
135: setCurrentIndex(0);
136: }
137: }
138: });
139:
140: addPropertyChangeListener(BOUNDS_PROPERTIES,
141: new PropertyChangeListener() {
142: public void propertyChange(PropertyChangeEvent ev) {
143: int x = getX(), y = getY(), width = getWidth(), height = getHeight();
144:
145: for (TabSheet ts : getChildren()) {
146: ts.boundsChanged(x, y, width, height);
147: }
148: }
149: });
150:
151: addPropertyChangeListener(STYLE_PROPERTIES,
152: new PropertyChangeListener() {
153: public void propertyChange(PropertyChangeEvent ev) {
154: String propertyName = ev.getPropertyName();
155: Object o = ev.getNewValue();
156:
157: for (TabSheet ts : getChildren()) {
158: Style s = ts.getStyle();
159: s.setProperty(propertyName, o);
160: }
161: }
162: });
163: }
164:
165: /**
166: * Sets the current tab sheet.
167: * @param currentIndex (Default = 0)
168: */
169: public void setCurrentIndex(int currentIndex) {
170: if (currentIndex < -1 || currentIndex >= getChildren().size())
171: throw new IllegalArgumentException(
172: "currentIndex < 0 || currentIndex >= getChildren().size()");
173: int oldCurrentIndex = this .currentIndex;
174: this .currentIndex = currentIndex;
175: currentSheet = this .currentIndex > -1 ? getChildren().get(
176: this .currentIndex) : null;
177: firePropertyChange(this , PROPERTY_CURRENT_INDEX,
178: oldCurrentIndex, this .currentIndex);
179: }
180:
181: public int getCurrentIndex() {
182: return currentIndex;
183: }
184:
185: public int getInnerHeight() {
186: int innerHeight = super .getInnerHeight() - TABS_HEIGHT;
187: return innerHeight < 0 ? 0 : innerHeight;
188: }
189:
190: /**
191: * This property is unsupported by the TabFolder component.
192: * @throws UnsupportedOperationException indicating this property is not supported by TabFolder.
193: */
194: public ScrollType getScrollType() {
195: throw new UnsupportedOperationException(
196: getStandardPropertyUnsupportedMsg(PROPERTY_SCROLL_TYPE,
197: true));
198: }
199:
200: /**
201: * This property is unsupported by the TabFolder component.
202: * @throws UnsupportedOperationException indicating this property is not supported by TabFolder.
203: */
204: public void setScrollType(ScrollType scrollType) {
205: throw new UnsupportedOperationException(
206: getStandardPropertyUnsupportedMsg(PROPERTY_SCROLL_TYPE,
207: false));
208: }
209:
210: /**
211: * This property is unsupported by the TabFolder component.
212: * @throws UnsupportedOperationException indicating this property is not supported by TabFolder.
213: */
214: public Layout getLayout() {
215: throw new UnsupportedOperationException(
216: getStandardPropertyUnsupportedMsg(PROPERTY_LAYOUT, true));
217: }
218:
219: /**
220: * This property is unsupported by the TabFolder component.
221: * @throws UnsupportedOperationException indicating this property is not supported by TabFolder.
222: */
223: public void setLayout(Layout layout) {
224: throw new UnsupportedOperationException(
225: getStandardPropertyUnsupportedMsg(PROPERTY_LAYOUT,
226: false));
227: }
228: }
|