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 }