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;
014:
015: import org.apache.commons.logging.Log;
016: import org.apache.commons.logging.LogFactory;
017: import org.wings.plaf.RootContainerCG;
018: import org.wings.style.Selector;
019:
020: /**
021: * A root container. The classes derived from this class ({@link SFrame} and {@link SInternalFrame}) render in the content pane of this
022: * RootContainer.
023: * <p/>
024: * <p>The RootContainer has a stack of components. Ususally, the stack contains only <em>one</em> element, the content pane; this is the
025: * bottom-most component. When dialogs are added to the RootContainer, then these dialogs are stacked on top of this content pane and only
026: * <em>that</em> dialog is visible then. This emulates the behaviour of modal dialogs in a windowing system.
027: *
028: * @author Holger Engels
029: * @author <a href="mailto:H.Zeller@acm.org">Henner Zeller</a>
030: * @author <a href="mailto:Haaf@mercatis.de">Armin Haaf</a>
031: */
032: public abstract class SRootContainer extends SContainer {
033: private final static Log LOG = LogFactory
034: .getLog(SRootContainer.class);
035:
036: /**
037: * The container for the contentPane.
038: */
039: protected SContainer contentPane;
040:
041: /**
042: * Contains all windows linked to this root container.
043: */
044: protected SContainer windowsPane;
045:
046: /**
047: * default constructor initializes the stack layout system of this SRootContainer.
048: */
049: public SRootContainer() {
050: super (new SRootLayout());
051: initializeContentPane();
052: initializeWindowsPane();
053: }
054:
055: protected void initializeContentPane() {
056: setContentPane(new SPanel(new SBorderLayout()));
057: }
058:
059: protected void initializeWindowsPane() {
060: SContainer windowsPane = new SContainer(new SFlowDownLayout());
061: windowsPane.setStyle("SWindowsPane");
062: setWindowsPane(windowsPane);
063: }
064:
065: public void setCG(RootContainerCG cg) {
066: super .setCG(cg);
067: }
068:
069: /**
070: * Push a new window on top of the stack.
071: *
072: * @param window the SDialog that is to be shown on top.
073: */
074: public void pushWindow(SWindow window) {
075:
076: getSession().getReloadManager().setSuppressMode(true);
077: windowsPane.addComponent(window);
078: getSession().getReloadManager().setSuppressMode(false);
079:
080: if (isUpdatePossible()
081: && SRootContainer.class.isAssignableFrom(getClass())) {
082: update(((RootContainerCG) getCG()).getAddWindowUpdate(
083: windowsPane, window));
084: } else {
085: windowsPane.reload();
086: }
087:
088: LOG.debug("push window = " + window.getName());
089: }
090:
091: /**
092: * remove the dialog, that is on top of the stack.
093: *
094: * @return the dialog, that is popped from the stack.
095: */
096: public SWindow popWindow() {
097:
098: int count = windowsPane.getComponentCount();
099: if (count < 1) {
100: throw new IllegalStateException("there's no window left!");
101: }
102:
103: SWindow window = (SWindow) windowsPane.getComponent(count - 1);
104: removeWindow(window);
105:
106: LOG.debug("pop window = " + window.getName());
107: return window;
108: }
109:
110: public void removeWindow(SWindow window) {
111:
112: getSession().getReloadManager().setSuppressMode(true);
113: windowsPane.remove(window);
114: getSession().getReloadManager().setSuppressMode(false);
115:
116: if (isUpdatePossible()
117: && SRootContainer.class.isAssignableFrom(getClass())) {
118: update(((RootContainerCG) getCG()).getRemoveWindowUpdate(
119: windowsPane, window));
120: } else {
121: windowsPane.reload();
122: }
123: }
124:
125: /**
126: * @return the number of dialogs that are on the stack currently.
127: */
128: public int getWindowCount() {
129: return windowsPane.getComponentCount();
130: }
131:
132: /**
133: * returns the content pane of this RootContainer.
134: */
135: public SContainer getContentPane() {
136: return contentPane;
137: }
138:
139: /**
140: * Returns the container that contains the windows linked to this root container.
141: *
142: * @return The container that contains the windows linked to this root container.
143: */
144: public SContainer getWindowsPane() {
145: return windowsPane;
146: }
147:
148: /**
149: * Sets the container for the contentPane.
150: *
151: * @param container the container for the contentPane.
152: */
153: public void setContentPane(SContainer container) {
154: if (this .contentPane != null) {
155: super .remove(contentPane);
156: }
157: this .contentPane = container;
158: super .addComponent(this .contentPane, null, 0);
159: }
160:
161: /**
162: * Sets the container for the windowsPane. ! This is not like in swing. Each window object is bound to its frame or internal frame.
163: *
164: * @param windowsPane The container for the windowsPane.
165: */
166: protected void setWindowsPane(SContainer windowsPane) {
167: if (this .windowsPane != null) {
168: super .remove(this .windowsPane);
169: }
170: this .windowsPane = windowsPane;
171: super .addComponent(this .windowsPane, null, 1);
172: }
173:
174: /**
175: * Adds the component to the content pane of the root container.
176: */
177: public SComponent addComponent(SComponent c, Object constraint,
178: int index) {
179: return contentPane.addComponent(c, constraint, index);
180: }
181:
182: /**
183: * Removes the component from the content pane.
184: */
185: public void remove(SComponent c) {
186: contentPane.addComponent(c);
187: }
188:
189: // allow frame.setBackground(Color.yellow);
190: // public void setAttribute(Selector selector, CSSProperty property, String propertyValue) {
191: // throw new IllegalArgumentException("use getContentPane().setAttribute()");
192: // }
193: }
|