001: package com.opensymphony.workflow.designer.swing;
002:
003: /*
004: * Copyright (c) Sun Microsystems.
005: */
006:
007: import java.awt.*;
008:
009: import javax.swing.*;
010:
011: /**
012: * A simpler alternative to a JPanel with a CardLayout. The AWT CardLayout
013: * layout manager can be inconvenient to use because the special "stack of
014: * cards" operations it supports require a cast to use. For example to show
015: * the card named "myCard" given a JPanel with a CardLayout one would write:
016: * <pre>
017: * ((CardLayout)(myJPanel.getLayout())).show(myJPanel, "myCard");
018: * </pre>
019: * This doesn't work well with Swing - all of the CardLayout display
020: * operations, like <code>show</code> call validate directly. Swing supports
021: * automatic validation (see JComponent.revalidate()); this direct call to
022: * validate is inefficient.
023: * <p>
024: * The CardPane JPanel subclass is intended to support a layout with a modest
025: * number of cards, on the order of 100 or less. A cards name is it's
026: * component name, as in java.awt.Component.getName(), which is set when the
027: * component is added to the CardPanel:
028: * <pre>
029: * myCardPanel.add(myChild, "MyChildName");
030: * myChild.getName() <i>=> "MyChildName"</i>
031: * </pre>
032: * As with CardLayout, the first child added to a CardPanel is made visible
033: * and there's only one child visible at a time. The <code>showCard</code>
034: * method accepts either a childs name or the child itself:
035: * <pre>
036: * myCardPanel.show("MyChildName");
037: * myCardPanel.show(myChild);
038: * </pre>
039: * <p>
040: * The CardPanel class doesn't support the vgap/hgap CardLayout properties
041: * since one can add a Border, see JComponent.setBorder().
042: *
043: * @author Sun Microsystems
044: */
045:
046: public class CardPanel extends JPanel {
047:
048: private static class Layout implements LayoutManager {
049: /**
050: * Set the childs name (if non-null) and and make it visible
051: * iff it's the only CardPanel child.
052: * @see java.awt.Component#setName
053: */
054: public void addLayoutComponent(String name, Component child) {
055: if (name != null) {
056: child.setName(name);
057: }
058: child
059: .setVisible(child.getParent().getComponentCount() == 1);
060: }
061:
062: /**
063: * If this child was visible, then make the first remaining
064: * child visible.
065: */
066: public void removeLayoutComponent(Component child) {
067: if (child.isVisible()) {
068: Container parent = child.getParent();
069: if (parent.getComponentCount() > 0) {
070: parent.getComponent(0).setVisible(true);
071: }
072: }
073: }
074:
075: /**
076: * @return the maximum preferred width/height + the parents insets
077: */
078: public Dimension preferredLayoutSize(Container parent) {
079: int nChildren = parent.getComponentCount();
080: Insets insets = parent.getInsets();
081: int width = insets.left + insets.right;
082: int height = insets.top + insets.bottom;
083: for (int i = 0; i < nChildren; i++) {
084: Dimension d = parent.getComponent(i).getPreferredSize();
085: if (d.width > width) {
086: width = d.width;
087: }
088: if (d.height > height) {
089: height = d.height;
090: }
091: }
092: return new Dimension(width, height);
093: }
094:
095: /**
096: * @return the maximum minimum width/height + the parents insets
097: */
098: public Dimension minimumLayoutSize(Container parent) {
099: int nChildren = parent.getComponentCount();
100: Insets insets = parent.getInsets();
101: int width = insets.left + insets.right;
102: int height = insets.top + insets.bottom;
103: for (int i = 0; i < nChildren; i++) {
104: if (!parent.getComponent(i).isVisible())
105: continue;
106: Dimension d = parent.getComponent(i).getMinimumSize();
107: if (d.width > width) {
108: width = d.width;
109: }
110: if (d.height > height) {
111: height = d.height;
112: }
113: }
114: //return new Dimension(width, height);
115: return new Dimension(100, height);
116: }
117:
118: public void layoutContainer(Container parent) {
119: int nChildren = parent.getComponentCount();
120: Insets insets = parent.getInsets();
121: for (int i = 0; i < nChildren; i++) {
122: Component child = parent.getComponent(i);
123: if (child.isVisible()) {
124: Rectangle r = parent.getBounds();
125: int width = r.width - insets.left + insets.right;
126: int height = r.height - insets.top + insets.bottom;
127: child.setBounds(insets.left, insets.top, width,
128: height);
129: break;
130: }
131: }
132: }
133: }
134:
135: /**
136: * Creates a CardPanel. Children, called "cards" in this API, should be
137: * added with add(). The first child we be made visible, subsequent
138: * children will be hidden. To show a card, use one of the show*Card
139: * methods.
140: */
141: public CardPanel() {
142: super (new Layout());
143: }
144:
145: /**
146: * Hide the currently visible child "card" and show the
147: * specified card. If the specified card isn't a child
148: * of the CardPanel then we add it here.
149: */
150: public Component getVisibleCard() {
151: int index = getVisibleChildIndex();
152: return index != -1 ? getComponent(index) : null;
153: }
154:
155: /**
156: * Return the index of the first (and one would hope - only)
157: * visible child. If a visible child can't be found,
158: * perhaps the caller has inexlicably hidden all of the
159: * children, then return -1.
160: */
161: public int getVisibleChildIndex() {
162: int nChildren = getComponentCount();
163: for (int i = 0; i < nChildren; i++) {
164: Component child = getComponent(i);
165: if (child.isVisible()) {
166: return i;
167: }
168: }
169: return -1;
170: }
171:
172: /**
173: * Return the name of the visible child.
174: */
175: public String getVisibleChildName() {
176: int i = getVisibleChildIndex();
177: return -1 == i ? null : getComponent(i).getName();
178: }
179:
180: /**
181: * Hide the currently visible child "card" and show the
182: * specified card. If the specified card isn't a child
183: * of the CardPanel then we add it here.
184: */
185: public void showCard(Component card) {
186: if (card.getParent() != this ) {
187: add(card);
188: }
189: Component visibleComponent = getVisibleCard();
190: if (visibleComponent == card)
191: return;
192: visibleComponent.setVisible(false);
193: card.setVisible(true);
194: revalidate();
195: repaint();
196: }
197:
198: /**
199: * Show the card with the specified name.
200: * @see java.awt.Component#getName
201: */
202: public Component showCard(String name) {
203: if (getVisibleCard() != null
204: && name.equals(getVisibleCard().getName()))
205: return getVisibleCard();
206: int nChildren = getComponentCount();
207: for (int i = 0; i < nChildren; i++) {
208: Component child = getComponent(i);
209: if (child.getName().equals(name) && !child.isVisible()) {
210: showCard(child);
211: return child;
212: }
213: }
214: return null;
215: }
216:
217: /**
218: * Show the first card that was added to this CardPanel.
219: */
220: public void showFirstCard() {
221: if (getComponentCount() <= 0) {
222: return;
223: }
224: showCard(getComponent(0));
225: }
226:
227: /**
228: * Show the last card that was added to this CardPanel.
229: */
230: public void showLastCard() {
231: if (getComponentCount() <= 0) {
232: return;
233: }
234: showCard(getComponent(getComponentCount() - 1));
235: }
236:
237: /**
238: * Show the card that was added to this CardPanel after the currently
239: * visible card. If the currently visible card was added last, then
240: * show the first card.
241: */
242: public void showNextCard() {
243: if (getComponentCount() <= 0) {
244: return;
245: }
246: int index = getVisibleChildIndex();
247: if (index == -1) {
248: showCard(getComponent(0));
249: } else if (index == (getComponentCount() - 1)) {
250: showCard(getComponent(0));
251: } else {
252: showCard(getComponent(index + 1));
253: }
254: }
255:
256: /**
257: * Show the card that was added to this CardPanel before the currently
258: * visible card. If the currently visible card was added first, then
259: * show the last card.
260: */
261: public void showPreviousCard() {
262: if (getComponentCount() <= 0) {
263: return;
264: }
265: int index = getVisibleChildIndex();
266: if (index == -1) {
267: showCard(getComponent(0));
268: } else if (index == 0) {
269: showCard(getComponent(getComponentCount() - 1));
270: } else {
271: showCard(getComponent(index - 1));
272: }
273: }
274:
275: }
|