001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.uml.ui.support.wizard;
043:
044: import java.awt.Component;
045: import java.awt.Container;
046: import java.awt.Dimension;
047: import java.awt.Insets;
048: import java.awt.LayoutManager;
049: import java.awt.Rectangle;
050:
051: import javax.swing.JPanel;
052:
053: /**
054: * A simpler alternative to a JPanel with a CardLayout. The AWT CardLayout
055: * layout manager can be inconvenient to use because the special "stack of
056: * cards" operations it supports require a cast to use. For example to show
057: * the card named "myCard" given a JPanel with a CardLayout one would write:
058: * <pre>
059: * ((CardLayout)(myJPanel.getLayout())).show(myJPanel, "myCard");
060: * </pre>
061: * This doesn't work well with Swing - all of the CardLayout display operations,
062: * like <code>show</code> call validate directly. Swing supports automatic
063: * validation (see JComponent.revalidate()); this direct call to validate is
064: * inefficient.
065: * <p>
066: * The CardPane JPanel subclass is intended to support a layout with a modest number
067: * of cards, on the order of 100 or less. A cards name is it's component
068: * name, as in java.awt.Component.getName(), which is set when the component
069: * is added to the CardPanel:
070: * <pre>
071: * myCardPanel.add(myChild, "MyChildName");
072: * myChild.getName() <i>=> "MyChildName"</i>
073: * </pre>
074: * As with CardLayout, the first child added to a CardPanel is made visible
075: * and there's only one child visible at a time. The <code>showCard</code>
076: * method accepts either a childs name or the child itself:
077: * <pre>
078: * myCardPanel.show("MyChildName");
079: * myCardPanel.show(myChild);
080: * </pre>
081: * <p>
082: * The CardPanel class doesn't support the vgap/hgap CardLayout properties since
083: * one can add a Border, see JComponent.setBorder().
084: */
085:
086: public class CardPanel extends JPanel {
087:
088: private IWizardSheet m_ParentSheet = null;
089:
090: private static class Layout implements LayoutManager {
091: /**
092: * Set the childs name (if non-null) and and make it visible
093: * iff it's the only CardPanel child.
094: * @see java.awt.Component#setName
095: */
096: public void addLayoutComponent(String name, Component child) {
097: if (name != null) {
098: child.setName(name);
099: }
100: child
101: .setVisible(child.getParent().getComponentCount() == 1);
102: }
103:
104: /**
105: * If this child was visible, then make the first remaining
106: * child visible.
107: */
108: public void removeLayoutComponent(Component child) {
109: if (child.isVisible()) {
110: Container parent = child.getParent();
111: if (parent.getComponentCount() > 0) {
112: parent.getComponent(0).setVisible(true);
113: }
114: }
115: }
116:
117: /**
118: * @return the maximum preferred width/height + the parents insets
119: */
120: public Dimension preferredLayoutSize(Container parent) {
121: int nChildren = parent.getComponentCount();
122: Insets insets = parent.getInsets();
123: int width = insets.left + insets.right;
124: int height = insets.top + insets.bottom;
125:
126: for (int i = 0; i < nChildren; i++) {
127: Dimension d = parent.getComponent(i).getPreferredSize();
128: if (d.width > width) {
129: width = d.width;
130: }
131: if (d.height > height) {
132: height = d.height;
133: }
134: }
135: return new Dimension(width, height);
136: }
137:
138: /**
139: * @return the maximum minimum width/height + the parents insets
140: */
141: public Dimension minimumLayoutSize(Container parent) {
142: int nChildren = parent.getComponentCount();
143: Insets insets = parent.getInsets();
144: int width = insets.left + insets.right;
145: int height = insets.top + insets.bottom;
146:
147: for (int i = 0; i < nChildren; i++) {
148: Dimension d = parent.getComponent(i).getMinimumSize();
149: if (d.width > width) {
150: width = d.width;
151: }
152: if (d.height > height) {
153: height = d.height;
154: }
155: }
156: return new Dimension(width, height);
157: }
158:
159: public void layoutContainer(Container parent) {
160: int nChildren = parent.getComponentCount();
161: Insets insets = parent.getInsets();
162: for (int i = 0; i < nChildren; i++) {
163: Component child = parent.getComponent(i);
164: if (child.isVisible()) {
165: Rectangle r = parent.getBounds();
166: int width = r.width - insets.left + insets.right;
167: int height = r.height - insets.top + insets.bottom;
168: child.setBounds(insets.left, insets.top, width,
169: height);
170: break;
171: }
172: }
173: }
174: }
175:
176: /**
177: * Creates a CardPanel. Children, called "cards" in this API, should be added
178: * with add(). The first child we be made visible, subsequent children will
179: * be hidden. To show a card, use one of the show*Card methods.
180: */
181: public CardPanel() {
182: super (new Layout());
183: }
184:
185: public CardPanel(IWizardSheet pParentSheet) {
186: this ();
187: this .m_ParentSheet = pParentSheet;
188: }
189:
190: /**
191: * Return the index of the first (and one would hope - only)
192: * visible child. If a visible child can't be found,
193: * perhaps the caller has inexlicably hidden all of the
194: * children, then return -1.
195: */
196: private int getVisibleChildIndex() {
197: int nChildren = getComponentCount();
198: for (int i = 0; i < nChildren; i++) {
199: Component child = getComponent(i);
200: if (child.isVisible()) {
201: return i;
202: }
203: }
204: return -1;
205: }
206:
207: public Component getCurrentCard() {
208: Component retValue = null;
209: int nChildren = getComponentCount();
210: for (int i = 0; i < nChildren; i++) {
211: Component child = getComponent(i);
212: if (child.isVisible()) {
213: retValue = child;
214: }
215: }
216: return retValue;
217: }
218:
219: public String getCurrentCardName() {
220: String retValue = "";
221: int nChildren = getComponentCount();
222: for (int i = 0; i < nChildren; i++) {
223: Component child = getComponent(i);
224: if (child.isVisible()) {
225: retValue = child.getName();
226: }
227: }
228: return retValue;
229: }
230:
231: public int getCurrentCardIndex() {
232: int nChildren = getComponentCount();
233: for (int i = 0; i < nChildren; i++) {
234: Component child = getComponent(i);
235: if (child.isVisible()) {
236: return i;
237: }
238: }
239: return -1;
240: }
241:
242: public int getCardCount() {
243: return getComponentCount();
244: }
245:
246: /**
247: * Hide the currently visible child "card" and show the
248: * specified card. If the specified card isn't a child
249: * of the CardPanel then we add it here.
250: */
251: public void showCard(Component card) {
252:
253: if (card.getParent() != this ) {
254: add(card);
255: }
256:
257: int index = getVisibleChildIndex();
258:
259: if (index != -1) {
260: getComponent(index).setVisible(false);
261: }
262:
263: card.setVisible(true);
264: revalidate();
265: repaint();
266:
267: if (m_ParentSheet != null) {
268: m_ParentSheet.onPageChange();
269: }
270: }
271:
272: /**
273: * Show the card with the specified name.
274: * @see java.awt.Component#getName
275: */
276: public void showCard(String name) {
277: int nChildren = getComponentCount();
278: for (int i = 0; i < nChildren; i++) {
279: Component child = getComponent(i);
280: if (child.getName().equals(name)) {
281: showCard(child);
282: break;
283: }
284: }
285: }
286:
287: public void showCard(int pIndex) {
288: if (pIndex >= 0 && pIndex < getComponentCount()) {
289: showCard(getComponent(pIndex));
290: }
291: }
292:
293: /**
294: * Show the card that was added to this CardPanel after the currently
295: * visible card. If the currently visible card was added last, then
296: * show the first card.
297: */
298: public void showNextCard() {
299: if (getComponentCount() <= 0) {
300: return;
301: }
302: int index = getVisibleChildIndex();
303: if (index == -1) {
304: showCard(getComponent(0));
305: } else if (index == (getComponentCount() - 1)) {
306: showCard(getComponent(0));
307: } else {
308: showCard(getComponent(index + 1));
309: }
310: }
311:
312: /**
313: * Show the card that was added to this CardPanel before the currently
314: * visible card. If the currently visible card was added first, then
315: * show the last card.
316: */
317: public void showPreviousCard() {
318: if (getComponentCount() <= 0) {
319: return;
320: }
321: int index = getVisibleChildIndex();
322: if (index == -1) {
323: showCard(getComponent(0));
324: } else if (index == 0) {
325: showCard(getComponent(getComponentCount() - 1));
326: } else {
327: showCard(getComponent(index - 1));
328: }
329: }
330:
331: /**
332: * Show the first card that was added to this CardPanel.
333: */
334: public void showFirstCard() {
335: if (getComponentCount() <= 0) {
336: return;
337: }
338: showCard(getComponent(0));
339: }
340:
341: /**
342: * Show the last card that was added to this CardPanel.
343: */
344: public void showLastCard() {
345: if (getComponentCount() <= 0) {
346: return;
347: }
348: showCard(getComponent(getComponentCount() - 1));
349: }
350: }
|