Source code: com/virtuosotechnologies/lib/platform/PlatformUtils.java
1 /*
2 ================================================================================
3
4 FILE: PlatformUtils.java
5
6 PROJECT:
7
8 Virtuoso Utilities
9
10 CONTENTS:
11
12 Utilities for dealing with cross-platform issues
13
14 PROGRAMMERS:
15
16 Daniel Azuma (DA) <dazuma@kagi.com>
17
18 COPYRIGHT:
19
20 Copyright (C) 2003 Daniel Azuma (dazuma@kagi.com)
21
22 This program is free software; you can redistribute it and/or
23 modify it under the terms of the GNU General Public License as
24 published by the Free Software Foundation; either version 2
25 of the License, or (at your option) any later version.
26
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public
33 License along with this program; if not, write to
34 Free Software Foundation, Inc.
35 59 Temple Place, Suite 330
36 Boston, MA 02111-1307 USA
37
38 ================================================================================
39 */
40
41
42 package com.virtuosotechnologies.lib.platform;
43
44
45 import java.awt.event.InputEvent;
46 import java.util.Map;
47 import java.util.HashMap;
48 import javax.swing.UIManager;
49
50 import com.virtuosotechnologies.lib.util.EventBroadcastHelper;
51
52
53 /**
54 * Utilities for dealing with cross-platform issues.
55 */
56 public final class PlatformUtils
57 {
58 private static PlatformID platform_ = null;
59
60 private static EventBroadcastHelper broadcaster_ =
61 new EventBroadcastHelper(PlatformListener.class);
62
63 private static boolean providersInitialized_ = false;
64 private static Map providersByName_ = new HashMap();
65
66 private static final Object lock_ = new Object();
67
68
69 public static final PlatformEvent.Type OPEN_ABOUTBOX_EVENT =
70 new PlatformEvent.Type("open_aboutbox");
71
72 public static final PlatformEvent.Type QUIT_EVENT =
73 new PlatformEvent.Type("quit");
74
75 public static final PlatformEvent.Type OPEN_PREFERENCES_EVENT =
76 new PlatformEvent.Type("open_preferences");
77
78
79 public static final PlatformID JAVA_COMPATIBLE_PLATFORM =
80 new PlatformID("java_compatible");
81
82 public static final PlatformID UNIX_PLATFORM =
83 new PlatformID("unix", JAVA_COMPATIBLE_PLATFORM);
84
85 public static final PlatformID MAC_OS_PLATFORM =
86 new PlatformID("mac_os", JAVA_COMPATIBLE_PLATFORM);
87
88 public static final PlatformID WINDOWS_PLATFORM =
89 new PlatformID("windows", JAVA_COMPATIBLE_PLATFORM);
90
91 public static final PlatformID MAC_OS_X_PLATFORM =
92 new PlatformID("mac_os_x", UNIX_PLATFORM, MAC_OS_PLATFORM);
93
94 public static final PlatformID LINUX_PLATFORM =
95 new PlatformID("linux", UNIX_PLATFORM);
96
97
98 public static final String MAC_OS_X_PROVIDERNAME =
99 "com.virtuosotechnologies.lib.platform.MacOSXPlatformProvider";
100
101
102 /**
103 * Prevent instantiation
104 */
105 private PlatformUtils()
106 {
107 throw new RuntimeException();
108 }
109
110
111 /**
112 * Returns a PlatformID describing the current platform
113 *
114 * @return a PlatformID
115 */
116 public static PlatformID getCurrentPlatformID()
117 {
118 synchronized(lock_)
119 {
120 if (platform_ == null)
121 {
122 String osname = System.getProperty("os.name");
123 if (osname.equals("Mac OS X"))
124 {
125 platform_ = MAC_OS_X_PLATFORM;
126 }
127 else if (osname.equals("Linux"))
128 {
129 platform_ = LINUX_PLATFORM;
130 }
131 else
132 {
133 platform_ = JAVA_COMPATIBLE_PLATFORM;
134 }
135 }
136 }
137 return platform_;
138 }
139
140
141 /**
142 * Add a listener for platform events
143 *
144 * @param listener listener to add
145 */
146 public static void addPlatformListener(
147 PlatformListener listener)
148 {
149 initPlatformProviders();
150 broadcaster_.addListenerWeak(listener);
151 }
152
153
154 /**
155 * Remove a listener for platform events
156 *
157 * @param listener listener to remove
158 */
159 public static void removePlatformListener(
160 PlatformListener listener)
161 {
162 broadcaster_.removeListener(listener);
163 }
164
165
166 /**
167 * Fire a platform event
168 *
169 * @param event the event to fire
170 */
171 public static void firePlatformEvent(
172 PlatformEvent event)
173 {
174 broadcaster_.fireEvent(PlatformListener.PLATFORM_EVENT_HAPPENED_METHOD, event);
175 }
176
177
178 private static void initPlatformProviders()
179 {
180 synchronized(lock_)
181 {
182 if (!providersInitialized_)
183 {
184 providersInitialized_ = true;
185 try
186 {
187 Class cls = Class.forName(MAC_OS_X_PROVIDERNAME);
188 PlatformProvider provider = (PlatformProvider)cls.newInstance();
189 if (provider.initialize())
190 {
191 providersByName_.put(MAC_OS_X_PROVIDERNAME, provider);
192 }
193 }
194 catch (LinkageError ex)
195 {
196 }
197 catch (ClassNotFoundException ex)
198 {
199 }
200 catch (InstantiationException ex)
201 {
202 }
203 catch (IllegalAccessException ex)
204 {
205 }
206 }
207 }
208 }
209
210
211 /**
212 * Returns the platform provider with the given name if it is available, or
213 * null if it is not.
214 * Note that even if we're running on that platform, this may still return null
215 * if the platform provider wasn't compiled in by whoever built this program--
216 * in such a case, functionality specific to that platform will still not be
217 * available.
218 *
219 * @return a PlatformProvider
220 */
221 public static PlatformProvider getNamedPlatformProvider(
222 String name)
223 {
224 initPlatformProviders();
225 return (PlatformProvider)providersByName_.get(name);
226 }
227
228
229 /**
230 * Returns true if swing menu bars are currently being merged into the Mac OS X
231 * screen-wide menu bar. If this is the case, a system menu is present that
232 * automatically provides "About", "Preferences" and "Quit" items, among others.
233 * In this case, the program should generally not provide those facilities itself.
234 *
235 * @return true if using the screen menu bar
236 */
237 public static boolean isUsingMacOSXScreenMenuBar()
238 {
239 PlatformProvider provider = getNamedPlatformProvider(MAC_OS_X_PROVIDERNAME);
240 return provider != null &&
241 UIManager.getLookAndFeel().isNativeLookAndFeel() &&
242 System.getProperty("apple.laf.useScreenMenuBar").toLowerCase().equals("true");
243 }
244
245
246 /**
247 * Returns true if there is a system-provided "Preferences" menu item
248 * and it is enabled.
249 *
250 * @return true if system-provided "Preferences" is enabled
251 */
252 public static boolean isSystemPreferencesMenuItemEnabled()
253 {
254 if (!isUsingMacOSXScreenMenuBar())
255 {
256 return false;
257 }
258 PlatformProvider provider = getNamedPlatformProvider(MAC_OS_X_PROVIDERNAME);
259 return Boolean.TRUE.equals(provider.performOperation(
260 "isSystemPreferencesMenuItemEnabled", null));
261 }
262
263
264 /**
265 * Enable or disable the system-provided "Preferences" menu item.
266 *
267 * @param enabled true to enable
268 * @return true if successful, or false if there is no system-provided
269 * "Preferences" menu item.
270 */
271 public static boolean setSystemPreferencesMenuItemEnabled(
272 boolean enabled)
273 {
274 if (!isUsingMacOSXScreenMenuBar())
275 {
276 return false;
277 }
278 PlatformProvider provider = getNamedPlatformProvider(MAC_OS_X_PROVIDERNAME);
279 provider.performOperation("setSystemPreferencesMenuItemEnabled",
280 enabled ? Boolean.TRUE : Boolean.FALSE);
281 return true;
282 }
283 }