1 /* 2 * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package javax.swing.plaf.basic; 26 27 import java.lang.reflect.*; 28 import javax.swing.*; 29 import javax.swing.plaf.*; 30 31 /** 32 * An ActionMap that populates its contents as necessary. The 33 * contents are populated by invoking the <code>loadActionMap</code> 34 * method on the passed in Object. 35 * 36 * @author Scott Violet 37 */ 38 class LazyActionMap extends ActionMapUIResource { 39 private static final long serialVersionUID = -7235747077122712304L; 40 41 /** 42 * Object to invoke <code>loadActionMap</code> on. This may be 43 * a Class object. 44 */ 45 private transient Object _loader; 46 47 /** 48 * Installs an ActionMap that will be populated by invoking the 49 * <code>loadActionMap</code> method on the specified Class 50 * when necessary. 51 * <p> 52 * This should be used if the ActionMap can be shared. 53 * 54 * @param c JComponent to install the ActionMap on. 55 * @param loaderClass Class object that gets loadActionMap invoked 56 * on. 57 * @param defaultsKey Key to use to defaults table to check for 58 * existing map and what resulting Map will be registered on. 59 */ 60 static void installLazyActionMap(JComponent c, Class loaderClass, 61 String defaultsKey) { 62 ActionMap map = (ActionMap)UIManager.get(defaultsKey); 63 if (map == null) { 64 map = new LazyActionMap(loaderClass); 65 UIManager.getLookAndFeelDefaults().put(defaultsKey, map); 66 } 67 SwingUtilities.replaceUIActionMap(c, map); 68 } 69 70 /** 71 * Returns an ActionMap that will be populated by invoking the 72 * <code>loadActionMap</code> method on the specified Class 73 * when necessary. 74 * <p> 75 * This should be used if the ActionMap can be shared. 76 * 77 * @param c JComponent to install the ActionMap on. 78 * @param loaderClass Class object that gets loadActionMap invoked 79 * on. 80 * @param defaultsKey Key to use to defaults table to check for 81 * existing map and what resulting Map will be registered on. 82 */ 83 static ActionMap getActionMap(Class loaderClass, 84 String defaultsKey) { 85 ActionMap map = (ActionMap)UIManager.get(defaultsKey); 86 if (map == null) { 87 map = new LazyActionMap(loaderClass); 88 UIManager.getLookAndFeelDefaults().put(defaultsKey, map); 89 } 90 return map; 91 } 92 93 94 private LazyActionMap(Class loader) { 95 _loader = loader; 96 } 97 98 public void put(Action action) { 99 put(action.getValue(Action.NAME), action); 100 } 101 102 public void put(Object key, Action action) { 103 loadIfNecessary(); 104 super.put(key, action); 105 } 106 107 public Action get(Object key) { 108 loadIfNecessary(); 109 return super.get(key); 110 } 111 112 public void remove(Object key) { 113 loadIfNecessary(); 114 super.remove(key); 115 } 116 117 public void clear() { 118 loadIfNecessary(); 119 super.clear(); 120 } 121 122 public Object[] keys() { 123 loadIfNecessary(); 124 return super.keys(); 125 } 126 127 public int size() { 128 loadIfNecessary(); 129 return super.size(); 130 } 131 132 public Object[] allKeys() { 133 loadIfNecessary(); 134 return super.allKeys(); 135 } 136 137 public void setParent(ActionMap map) { 138 loadIfNecessary(); 139 super.setParent(map); 140 } 141 142 private void loadIfNecessary() { 143 if (_loader != null) { 144 Object loader = _loader; 145 146 _loader = null; 147 Class<?> klass = (Class<?>)loader; 148 try { 149 Method method = klass.getDeclaredMethod("loadActionMap", 150 new Class[] { LazyActionMap.class }); 151 method.invoke(klass, new Object[] { this }); 152 } catch (NoSuchMethodException nsme) { 153 assert false : "LazyActionMap unable to load actions " + 154 klass; 155 } catch (IllegalAccessException iae) { 156 assert false : "LazyActionMap unable to load actions " + 157 iae; 158 } catch (InvocationTargetException ite) { 159 assert false : "LazyActionMap unable to load actions " + 160 ite; 161 } catch (IllegalArgumentException iae) { 162 assert false : "LazyActionMap unable to load actions " + 163 iae; 164 } 165 } 166 } 167 }