View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program 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.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui.theme;
21  
22  import javax.swing.UIDefaults;
23  import javax.swing.UIManager;
24  import javax.swing.plaf.basic.BasicBorders;
25  
26  import java.lang.reflect.Method;
27  import java.util.Arrays;
28  import java.util.Comparator;
29  import java.util.Enumeration;
30  import java.util.HashSet;
31  import java.util.Iterator;
32  import java.util.LinkedList;
33  import java.util.List;
34  
35  import org.xnap.loader.XNapClassLoader;
36  
37  /***
38   * This class manages the available themes and installs additional Look & Feels
39   * if available.
40   */
41  public class ThemeManager {
42  
43      //--- Constant(s) ---
44  
45      //--- Data field(s) ---
46  
47      private static Object[] savedDefaults = getDefaults();
48  	private static List themes = new LinkedList();
49  
50      //--- Constructor(s) ---
51  
52      private ThemeManager()
53      {
54  		// never invoked
55      }
56  
57      //--- Method(s) ---
58  
59  	public static void addTheme(Theme theme)
60  	{
61  		themes.add(theme);
62  	}
63  
64  	/*** 
65  	 * Makes the default themes available.  */
66  	public static void initialize()
67  	{
68  		UIManager.put("ClassLoader", XNapClassLoader.getInstance());
69  		// remove ugly looking border around split pane divider
70  		UIManager.put("SplitPaneDivider.border", 
71  					  new BasicBorders.MarginBorder());
72  
73  		addTheme(new DefaultTheme());
74  		addTheme(new DefaultIconTheme());
75  
76  		UIManager.installLookAndFeel
77  			("Kunststoff",
78  			 "com.incors.plaf.kunststoff.KunststoffLookAndFeel");
79  
80  		//  UIManager.installLookAndFeel("Napkin", "napkin.NapkinLookAndFeel");
81  		
82  //  		addTheme(new MetalThemeWrapper(new KunststoffDesktopTheme()));
83  //  		addTheme(new MetalThemeWrapper(new KunststoffNotebookTheme()));
84  //  		addTheme(new MetalThemeWrapper(new KunststoffPresentationTheme()));
85  	}
86  
87  	/***
88  	 * Returns true, if a plugin with className is installed.  */
89  	public static boolean isInstalled(String className)
90  	{
91  		UIManager.LookAndFeelInfo[] info
92  			= UIManager.getInstalledLookAndFeels();
93  		if (info != null) {
94  			for (int i = 0; i < info.length; i++) {
95  				if (info[i].getClassName().equals(className)) {
96  					return true;
97  				}
98  			}
99  		}
100 		return false;
101 	}
102 
103 	/***
104 	 * Returns the ui defaults that were saved when the ThemeManager
105 	 * was instanciated, meaning before any other theme was loaded.
106 	 */
107     public static Object[] getDefaults()
108     {
109 		UIDefaults defaults = UIManager.getDefaults();
110 		Object[] array = new Object[defaults.size() * 2];
111 		int i = 0;
112 		for (Enumeration e = defaults.keys(); e.hasMoreElements()
113 			 && i + 1 < array.length; i += 2) {
114 			Object key = e.nextElement();
115 			array[i] = key;
116 			array[i + 1] = defaults.get(key);
117 		}
118 		return array;
119     }
120 
121     /***
122      * Returns an array of all installed and supported look and feels.
123      */
124     public static UIManager.LookAndFeelInfo[] getInstalledLookAndFeels()
125     {
126 		HashSet classNames = new HashSet();
127 
128 		LinkedList lafs = new LinkedList();
129 		UIManager.LookAndFeelInfo[] info 
130 			= UIManager.getInstalledLookAndFeels();
131 		if (info != null) {
132 			for (int i = 0; i < info.length; i++) {
133 				if (classNames.contains(info[i].getClassName())) {
134 					// work around for lafs that were installed twice
135 					continue;
136 				}
137 
138 				try {
139 					Class c = XNapClassLoader.getInstance().loadClass
140 						(info[i].getClassName());
141 					Object laf = c.newInstance();
142 					Method m = c.getMethod("isSupportedLookAndFeel", null);
143 					Object supported = m.invoke(laf, null);
144 					if (((Boolean)supported).booleanValue()) {
145 						lafs.add(info[i]);
146 						classNames.add(info[i].getClassName());
147 					}
148 				}
149 				catch (Exception e) {
150 				}
151 			}
152 		}
153 
154 		return (UIManager.LookAndFeelInfo[])lafs.toArray
155 			(new UIManager.LookAndFeelInfo[0]);
156     }
157 
158     /***
159      * Returns a sorted array of all available themes.
160      */
161     public static Theme[] getThemes()
162     {
163 		Theme[] array = (Theme[])themes.toArray(new Theme[0]);
164 		Arrays.sort(array, new ThemeComparator());
165 		return array;
166     }
167 
168     /***
169      * Returns the defaults that were saved when this class was instanciated.
170      */
171     public static Object[] getSavedDefaults()
172     {
173 		return savedDefaults;
174     }
175 
176 	public static void removeTheme(Theme theme)
177 	{
178 		themes.remove(theme);
179 	}
180 
181     public static void setDefaults(Object[] defaults)
182     {
183 		UIManager.getDefaults().putDefaults(defaults);
184     }
185 
186     /***
187      * Looks up the by <code>className</code> and sets the current
188      * theme, if found.
189      *
190      * @return true, if theme was set; false, otherwise */
191     public static boolean setTheme(String className)
192     {
193 		for (Iterator it = themes.iterator(); it.hasNext();) {
194 			Theme theme = (Theme)it.next();
195 			if (theme.getClassName().equals(className)) {
196 				setTheme(theme);
197 				return true;
198 			}
199 		}
200 
201 		return false;
202     }
203 
204     /***
205      * Sets the current theme to <code>theme</code>.
206      */
207     public static void setTheme(Theme theme)
208     {
209 		theme.install();
210     }
211 
212 	//--- Inner Classes ---
213 
214 	/***
215      * Compares {@link Theme} objects by name.
216      */
217 	public static class ThemeComparator implements Comparator {
218 
219 		public int compare(Object o1, Object o2) 
220 		{
221 			return ((Theme)o1).getName().compareToIgnoreCase
222 				(((Theme)o2).getName());
223 		}
224 
225 	}
226 
227 }
228