Frames | No Frames |
1: /* BasicRootPaneUI.java -- 2: Copyright (C) 2002, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing.plaf.basic; 40: 41: import java.awt.event.ActionEvent; 42: import java.beans.PropertyChangeEvent; 43: import java.beans.PropertyChangeListener; 44: 45: import javax.swing.AbstractAction; 46: import javax.swing.ButtonModel; 47: import javax.swing.InputMap; 48: import javax.swing.JButton; 49: import javax.swing.JComponent; 50: import javax.swing.JRootPane; 51: import javax.swing.LookAndFeel; 52: import javax.swing.SwingUtilities; 53: import javax.swing.UIManager; 54: import javax.swing.plaf.ActionMapUIResource; 55: import javax.swing.plaf.ComponentInputMapUIResource; 56: import javax.swing.plaf.ComponentUI; 57: import javax.swing.plaf.RootPaneUI; 58: 59: public class BasicRootPaneUI extends RootPaneUI 60: implements PropertyChangeListener 61: { 62: 63: /** 64: * Performed when the user activates the default button inside the JRootPane, 65: * usually by pressing 'ENTER'. 66: */ 67: private class DefaultPressAction 68: extends AbstractAction 69: { 70: /** 71: * The JRootPane for which this action should be installed. 72: */ 73: private JRootPane rootPane; 74: 75: /** 76: * Creates a new DefaultPressAction for the specified JRootPane. 77: */ 78: DefaultPressAction(JRootPane rp) 79: { 80: rootPane = rp; 81: } 82: 83: /** 84: * Performes the action. 85: */ 86: public void actionPerformed(ActionEvent ev) 87: { 88: JButton b = rootPane.getDefaultButton(); 89: if (b != null) 90: { 91: ButtonModel m = b.getModel(); 92: m.setArmed(true); 93: m.setPressed(true); 94: } 95: } 96: } 97: 98: /** 99: * Performed when the user activates the default button inside the JRootPane, 100: * usually by releasing 'ENTER'. 101: */ 102: private class DefaultReleaseAction 103: extends AbstractAction 104: { 105: /** 106: * The JRootPane for which this action should be installed. 107: */ 108: private JRootPane rootPane; 109: 110: /** 111: * Creates a new DefaultReleaseAction for the specified JRootPane. 112: */ 113: DefaultReleaseAction(JRootPane rp) 114: { 115: rootPane = rp; 116: } 117: 118: /** 119: * Performes the action. 120: */ 121: public void actionPerformed(ActionEvent ev) 122: { 123: JButton b = rootPane.getDefaultButton(); 124: if (b != null) 125: { 126: ButtonModel m = b.getModel(); 127: m.setPressed(false); 128: m.setArmed(false); 129: } 130: } 131: } 132: 133: public static ComponentUI createUI(JComponent x) 134: { 135: return new BasicRootPaneUI(); 136: } 137: 138: public void installUI(JComponent c) 139: { 140: super.installUI(c); 141: if (c instanceof JRootPane) 142: { 143: JRootPane rp = (JRootPane) c; 144: installDefaults(rp); 145: installComponents(rp); 146: installListeners(rp); 147: installKeyboardActions(rp); 148: } 149: } 150: 151: /** 152: * Installs the look and feel defaults for JRootPane. 153: * 154: * @param rp the root pane to install the defaults to 155: */ 156: protected void installDefaults(JRootPane rp) 157: { 158: // TODO: What to do here, if anything? (might be a hook method) 159: } 160: 161: /** 162: * Installs additional look and feel components to the root pane. 163: * 164: * @param rp the root pane to install the components to 165: */ 166: protected void installComponents(JRootPane rp) 167: { 168: // All components are initialized in the JRootPane constructor, and since 169: // the createXXXPane methods are protected, I see no reasonable way, 170: // and no need to initialize them here. This method is here anyway 171: // for compatibility and to provide the necessary hooks to subclasses. 172: } 173: 174: /** 175: * Installs any look and feel specific listeners on the root pane. 176: * 177: * @param rp the root pane to install the listeners to 178: */ 179: protected void installListeners(JRootPane rp) 180: { 181: rp.addPropertyChangeListener(this); 182: } 183: 184: /** 185: * Installs look and feel keyboard actions on the root pane. 186: * 187: * @param rp the root pane to install the keyboard actions to 188: */ 189: protected void installKeyboardActions(JRootPane rp) 190: { 191: // Install the keyboard actions. 192: ActionMapUIResource am = new ActionMapUIResource(); 193: am.put("press", new DefaultPressAction(rp)); 194: am.put("release", new DefaultReleaseAction(rp)); 195: SwingUtilities.replaceUIActionMap(rp, am); 196: 197: // Install the input map from the UIManager. It seems like the actual 198: // bindings are installed in the JRootPane only when the defaultButton 199: // property receives a value. So we also only install an empty 200: // input map here, and fill it in propertyChange. 201: ComponentInputMapUIResource im = new ComponentInputMapUIResource(rp); 202: SwingUtilities.replaceUIInputMap(rp, JComponent.WHEN_IN_FOCUSED_WINDOW, 203: im); 204: } 205: 206: public void propertyChange(PropertyChangeEvent event) 207: { 208: JRootPane source = (JRootPane) event.getSource(); 209: String propertyName = event.getPropertyName(); 210: if (propertyName.equals("defaultButton")) 211: { 212: Object newValue = event.getNewValue(); 213: InputMap im = 214: SwingUtilities.getUIInputMap(source, 215: JComponent.WHEN_IN_FOCUSED_WINDOW); 216: if (newValue != null) 217: { 218: Object[] keybindings = (Object[]) UIManager.get( 219: "RootPane.defaultButtonWindowKeyBindings"); 220: LookAndFeel.loadKeyBindings(im, keybindings); 221: } 222: else 223: { 224: im.clear(); 225: } 226: } 227: } 228: 229: /** 230: * Uninstalls this UI from the root pane. This calls 231: * {@link #uninstallDefaults}, {@link #uninstallComponents}, 232: * {@link #uninstallListeners}, {@link #uninstallKeyboardActions} 233: * in this order. 234: * 235: * @param c the root pane to uninstall the UI from 236: */ 237: public void uninstallUI(JComponent c) 238: { 239: super.uninstallUI(c); 240: if (c instanceof JRootPane) 241: { 242: JRootPane rp = (JRootPane) c; 243: uninstallDefaults(rp); 244: uninstallComponents(rp); 245: uninstallListeners(rp); 246: uninstallKeyboardActions(rp); 247: } 248: } 249: 250: /** 251: * Uninstalls the look and feel defaults that have been installed in 252: * {@link #installDefaults}. 253: * 254: * @param rp the root pane to uninstall the defaults from 255: */ 256: protected void uninstallDefaults(JRootPane rp) 257: { 258: // We do nothing here. 259: } 260: 261: /** 262: * Uninstalls look and feel components from the root pane. 263: * 264: * @param rp the root pane to uninstall the components from 265: */ 266: protected void uninstallComponents(JRootPane rp) 267: { 268: // We do nothing here. 269: } 270: 271: /** 272: * Uninstalls any look and feel specific listeners from the root pane. 273: * 274: * @param rp the root pane to uninstall the listeners from 275: */ 276: protected void uninstallListeners(JRootPane rp) 277: { 278: rp.removePropertyChangeListener(this); 279: } 280: 281: /** 282: * Uninstalls look and feel keyboard actions from the root pane. 283: * 284: * @param rp the root pane to uninstall the keyboard actions from 285: */ 286: protected void uninstallKeyboardActions(JRootPane rp) 287: { 288: SwingUtilities.replaceUIActionMap(rp, null); 289: SwingUtilities.replaceUIInputMap(rp, JComponent.WHEN_IN_FOCUSED_WINDOW, 290: null); 291: } 292: }