001 /*
002 * $Id: JXRootPane.java,v 1.5 2006/03/11 23:56:51 rbair Exp $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021
022 package org.jdesktop.swingx;
023
024 import java.awt.BorderLayout;
025 import java.awt.Component;
026 import java.awt.Container;
027
028 import javax.swing.BoxLayout;
029 import javax.swing.JMenuBar;
030 import javax.swing.JPanel;
031 import javax.swing.JRootPane;
032 import javax.swing.JToolBar;
033
034 import org.jdesktop.swingx.event.MessageSource;
035 import org.jdesktop.swingx.event.ProgressSource;
036
037 /**
038 * Extends the JRootPane by supporting specific placements for a toolbar and a
039 * status bar. If a status bar exists, then toolbars, menus and any
040 * MessageSource components will be registered with the status bar.
041 * <p>
042 * Components should be added using the <code>addComponent</code> method. This
043 * method will walk the containment hierarchy of the added component and will
044 * register all <code>MessageSource</code> or <code>ProgressSource</code>
045 * components.
046 *
047 * @see JXStatusBar
048 * @see org.jdesktop.swingx.event.MessageEvent
049 * @see org.jdesktop.swingx.event.MessageSource
050 * @see org.jdesktop.swingx.event.ProgressSource
051 * @author Mark Davidson
052 */
053 public class JXRootPane extends JRootPane {
054
055 private JXStatusBar statusBar;
056
057 private JToolBar toolBar;
058
059 private JPanel contentPanel;
060
061 public JXRootPane() {
062 contentPanel = new JPanel();
063 contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
064
065 getContentPane().add(contentPanel, BorderLayout.CENTER);
066 }
067
068 /**
069 * Adds a component to the root pane. If this component and/or it's children
070 * is a <code>MessageSource</code> then it will be registered with the
071 * status bar.
072 */
073 public void addComponent(Component comp) {
074 contentPanel.add(comp);
075 registerStatusBar(comp);
076 }
077
078 /**
079 * Removes a component from the center panel.
080 */
081 public void removeComponent(Component comp) {
082 contentPanel.remove(comp);
083 unregisterStatusBar(statusBar, comp);
084 }
085
086 /**
087 * Return an array of components that were added to the content panel with
088 * addComponent.
089 */
090 public Component[] getContentComponents() {
091 return contentPanel.getComponents();
092 }
093
094 private void registerStatusBar(Component comp) {
095 if (statusBar == null || comp == null) {
096 return;
097 }
098 if (comp instanceof MessageSource) {
099 MessageSource source = (MessageSource) comp;
100 // source.addMessageListener(statusBar);
101 }
102 if (comp instanceof ProgressSource) {
103 ProgressSource source = (ProgressSource) comp;
104 // source.addProgressListener(statusBar);
105 }
106 if (comp instanceof Container) {
107 Component[] comps = ((Container) comp).getComponents();
108 for (int i = 0; i < comps.length; i++) {
109 registerStatusBar(comps[i]);
110 }
111 }
112 }
113
114 private void unregisterStatusBar(JXStatusBar statusBar, Component comp) {
115 if (statusBar == null || comp == null) {
116 return;
117 }
118 if (comp instanceof MessageSource) {
119 MessageSource source = (MessageSource) comp;
120 // source.removeMessageListener(statusBar);
121 }
122 if (comp instanceof ProgressSource) {
123 ProgressSource source = (ProgressSource) comp;
124 // source.removeProgressListener(statusBar);
125 }
126 if (comp instanceof Container) {
127 Component[] comps = ((Container) comp).getComponents();
128 for (int i = 0; i < comps.length; i++) {
129 unregisterStatusBar(statusBar, comps[i]);
130 }
131 }
132 }
133
134 /**
135 * Set the status bar for this root pane. Any components held by this root
136 * pane will be registered. If this is replacing an existing status bar then
137 * the existing component will be unregistered from the old status bar.
138 *
139 * @param statusBar
140 * the status bar to use
141 */
142 public void setStatusBar(JXStatusBar statusBar) {
143 JXStatusBar oldStatusBar = this.statusBar;
144 this.statusBar = statusBar;
145
146 if (statusBar != null) {
147 if (handler == null) {
148 // Create the new mouse handler and register the toolbar
149 // and menu components.
150 // handler = new MouseMessagingHandler(this, statusBar);
151 if (toolBar != null) {
152 // handler.registerListeners(toolBar.getComponents());
153 }
154 if (menuBar != null) {
155 // handler.registerListeners(menuBar.getSubElements());
156 }
157 } else {
158 // handler.setMessageListener(statusBar);
159 }
160 }
161
162 Component[] comps = contentPanel.getComponents();
163 for (int i = 0; i < comps.length; i++) {
164 // Unregister the old status bar.
165 unregisterStatusBar(oldStatusBar, comps[i]);
166
167 // register the new status bar.
168 registerStatusBar(comps[i]);
169 }
170 if (oldStatusBar != null) {
171 getContentPane().remove(oldStatusBar);
172 }
173 if (statusBar != null) {
174 getContentPane().add(BorderLayout.SOUTH, statusBar);
175 }
176 }
177
178 public JXStatusBar getStatusBar() {
179 return statusBar;
180 }
181
182 private MouseMessagingHandler handler;
183
184 /**
185 * Set the toolbar bar for this root pane. If the status bar exists, then
186 * all components will be registered with a
187 * <code>MouseMessagingHandler</code> so that mouse over messages will be
188 * sent to the status bar.
189 *
190 * @param toolBar
191 * the toolbar to register
192 * @see MouseMessagingHandler
193 */
194 public void setToolBar(JToolBar toolBar) {
195 JToolBar oldToolBar = this.toolBar;
196 this.toolBar = toolBar;
197
198 if (handler != null && oldToolBar != null) {
199 handler.unregisterListeners(oldToolBar.getComponents());
200 }
201
202 if (handler != null && toolBar != null) {
203 handler.registerListeners(toolBar.getComponents());
204 }
205
206 getContentPane().add(BorderLayout.NORTH, toolBar);
207 }
208
209 public JToolBar getToolBar() {
210 return toolBar;
211 }
212
213 /**
214 * Set the menu bar for this root pane. If the status bar exists, then all
215 * components will be registered with a <code>MouseMessagingHandler</code>
216 * so that mouse over messages will be sent to the status bar.
217 *
218 * @param menuBar
219 * the menu bar to register
220 * @see MouseMessagingHandler
221 */
222 public void setJMenuBar(JMenuBar menuBar) {
223 JMenuBar oldMenuBar = this.menuBar;
224
225 super.setJMenuBar(menuBar);
226
227 if (handler != null && oldMenuBar != null) {
228 handler.unregisterListeners(oldMenuBar.getSubElements());
229 }
230
231 if (handler != null && menuBar != null) {
232 handler.registerListeners(menuBar.getSubElements());
233 }
234 }
235
236 }