001 /* 002 * Copyright 2002-2004 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package org.springframework.richclient.application; 017 018 import java.awt.Window; 019 import java.util.ArrayList; 020 import java.util.Iterator; 021 import java.util.List; 022 import java.util.Observable; 023 import java.beans.PropertyChangeSupport; 024 import java.beans.PropertyChangeListener; 025 026 import org.springframework.util.Assert; 027 import org.springframework.binding.value.PropertyChangePublisher; 028 029 /** 030 * A manager for a group of windows. Window managers are needed in applications 031 * which create many different windows in addition to a main window. A window 032 * manager can be used to remember all the windows that an application has 033 * created (independent of whether they are presently open or closed). There can 034 * be several window managers, and they can be arranged into a tree. This kind 035 * of organization makes it simple to close whole subgroupings of windows. 036 * <p> 037 * Associating a window with a window manager is done with 038 * <code>WindowManager.add(Window)</code>. A window is automatically removed 039 * from its window manager as a side effect of closing the window. 040 * 041 * @see Window 042 */ 043 public class WindowManager extends Observable implements PropertyChangePublisher { 044 045 /** 046 * List of windows managed by this window manager (element type: 047 * <code>Window</code>). 048 */ 049 private List windows = new ArrayList(); 050 051 /** 052 * Parent window manager, or <code>null</code> if none. 053 */ 054 private WindowManager parentManager; 055 056 /** 057 * List of window managers who have this window manager as their parent 058 * (element type: <code>WindowManager</code>). 059 */ 060 private List subManagers; 061 062 /** 063 * Holds the currently active window. 064 */ 065 private ApplicationWindow activeWindow; 066 067 private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); 068 069 /** 070 * Creates an empty window manager without a parent window manager (that is, 071 * a root window manager). 072 */ 073 public WindowManager() { 074 } 075 076 /** 077 * Creates an empty window manager with the given window manager as parent. 078 * 079 * @param parent 080 * the parent window manager 081 */ 082 public WindowManager(WindowManager parent) { 083 Assert.notNull(parent); 084 parent.addWindowManager(this); 085 } 086 087 /** 088 * Adds the given window to the set of windows managed by this window 089 * manager. Does nothing is this window is already managed by this window 090 * manager. 091 * 092 * @param window 093 * the window 094 */ 095 public void add(ApplicationWindow window) { 096 if (activeWindow == null) // first window will be set as activeWindow 097 setActiveWindow(window); 098 099 if (!windows.contains(window)) { 100 windows.add(window); 101 window.setWindowManager(this); 102 setChanged(); 103 notifyObservers(); 104 } 105 } 106 107 /** 108 * Adds the given window manager to the list of window managers that have 109 * this one as a parent. 110 * 111 * @param wm 112 * the child window manager 113 */ 114 private void addWindowManager(WindowManager wm) { 115 if (subManagers == null) { 116 subManagers = new ArrayList(); 117 } 118 if (!subManagers.contains(wm)) { 119 subManagers.add(wm); 120 wm.parentManager = this; 121 } 122 } 123 124 /** 125 * Attempts to close all windows managed by this window manager, as well as 126 * windows managed by any descendent window managers. 127 * 128 * @return <code>true</code> if all windows were sucessfully closed, and 129 * <code>false</code> if any window refused to close 130 */ 131 public boolean close() { 132 List t = (List)((ArrayList)windows).clone(); 133 Iterator e = t.iterator(); 134 while (e.hasNext()) { 135 ApplicationWindow window = (ApplicationWindow)e.next(); 136 if (!window.close()) { return false; } 137 } 138 if (subManagers != null) { 139 e = subManagers.iterator(); 140 while (e.hasNext()) { 141 WindowManager wm = (WindowManager)e.next(); 142 if (!wm.close()) { return false; } 143 } 144 } 145 return true; 146 } 147 148 /** 149 * Returns this window manager's set of windows. 150 * 151 * @return a possibly empty list of window 152 */ 153 public ApplicationWindow[] getWindows() { 154 ApplicationWindow managed[] = new ApplicationWindow[windows.size()]; 155 windows.toArray(managed); 156 return managed; 157 } 158 159 /** 160 * @return the parent of this WindowManager 161 */ 162 public WindowManager getParent() { 163 return parentManager; 164 } 165 166 /** 167 * Removes the given window from the set of windows managed by this window 168 * manager. Does nothing is this window is not managed by this window 169 * manager. 170 * 171 * @param window 172 * the window 173 */ 174 public final void remove(ApplicationWindow window) { 175 if (windows.contains(window)) { 176 windows.remove(window); 177 window.setWindowManager(null); 178 setChanged(); 179 notifyObservers(); 180 } 181 } 182 183 /** 184 * Set the currently active window. When a window gets focus, it will set itself 185 * as the current window of it's manager. 186 * 187 * @param window 188 */ 189 public final void setActiveWindow(ApplicationWindow window) 190 { 191 final ApplicationWindow old = this.activeWindow; 192 this.activeWindow = window; 193 if (getParent() != null) // let things ripple up 194 getParent().setActiveWindow(window); 195 getChangeSupport().firePropertyChange("activeWindow", old, window); 196 } 197 198 /** 199 * @return the active window. 200 */ 201 public final ApplicationWindow getActiveWindow() 202 { 203 return this.activeWindow; 204 } 205 206 /** 207 * @return Number of windows managed by this instance. 208 */ 209 public int size() { 210 return windows.size(); 211 } 212 213 214 protected PropertyChangeSupport getChangeSupport() { 215 return changeSupport; 216 } 217 218 219 220 221 // 222 // METHODS FROM INTERFACE PropertyChangePublisher 223 // 224 225 226 public void addPropertyChangeListener(PropertyChangeListener listener) { 227 getChangeSupport().addPropertyChangeListener(listener); 228 } 229 230 public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { 231 getChangeSupport().addPropertyChangeListener(propertyName, listener); 232 } 233 234 public void removePropertyChangeListener(PropertyChangeListener listener) { 235 getChangeSupport().removePropertyChangeListener(listener); 236 } 237 238 public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { 239 getChangeSupport().removePropertyChangeListener(propertyName, listener); 240 } 241 }