All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ch.randelshofer.quaqua.QuaquaManager Maven / Gradle / Ivy

Go to download

A Mavenisation of the Quaqua Mac OSX Swing Look and Feel (Java library) Quaqua Look and Feel (C) 2003-2017, Werner Randelshofer. Mavenisation by Matt Gumbley, DevZendo.org - for problems with Mavenisation, see Matt; for issues with Quaqua, see the Quaqua home page. For full license details, see http://randelshofer.ch/quaqua/license.html

The newest version!
/*
 * @(#)QuaquaManager.java 
 *
 * Copyright (c) 2003-2013 Werner Randelshofer, Switzerland.
 * You may not use, copy or modify this file, except in compliance with the
 * accompanying license terms.
 */
package ch.randelshofer.quaqua;

import ch.randelshofer.quaqua.osx.OSXFile;
import javax.swing.*;
import javax.swing.border.*;
import java.util.*;
import java.io.*;

/**
 * The QuaquaManager provides bug fixes and enhancements for the Mac Look and
 * Feel and for the Aqua Look and Feel on Mac OS X. 

Usage for Java * Applications: *

 * UIManager.setLookAndFeel(QuaquaManager.getLookAndFeelClassName());
 * 

Usage for Java Applets: *

 * UIManager.put("ClassLoader", getClass().getClassLoader());
 * UIManager.setLookAndFeel(QuaquaManager.getLookAndFeel());
 * 

System Properties for Java Applications:
You can * customize the Quaqua Look and Feel using the following system properties: *

  • {@code Quaqua.design=jaguar} Enforces Jaguar design.
  • *
  • {@code Quaqua.design=panther} Enforces Panther design.
  • *
  • {@code Quaqua.design=tiger} Enforces Tiger design.
  • *
  • Quaqua.design=auto Chooses design automatically. This * is the default value.
  • *
*
    *
  • {@code Quaqua.TabbedPane.design=jaguar} Enforces Jaguar design for * tabbed panes.
  • {@code Quaqua.TabbedPane.design=panther} Enforces * Panther design for tabbed panes.
  • *
  • Quaqua.TabbedPane.design=auto Chooses design * automatically. This is the default value.
  • *
*
    *
  • {@code Quaqua.FileChooser.autovalidate=false} FileChoosers do not * refresh their contents automatically. Users have to close and reopen a file * chooser to see changes in the file system.
  • *
  • Quaqua.FileChooser.autovalidate=true FileChoosers * refresh their contents periodically. This is the default value.
*
  • {@code Quaqua.Debug.crossPlatform=true} Enforces cross platform * support. This is a hack, useful only for testing an application with the * Quaqua Look and Feel on non-Mac OS X platforms.
  • *
  • Quaqua.Debug.crossPlatform=false Chooses native * support. This is the default value.
Example: *
 * System.setProperty("Quaqua.design", "panther");
 * System.setProperty("Quaqua.TabbedPane.design", "jaguar");
 * System.setProperty("Quaqua.FileChooser.autovalidate", "true");
 * 

System Properties for Java Applets:
In a secure * environment, you are not allowed to change system properties. Use * {@code QuaquaManager.setProperty} to specify (or override) system * properties that are used by Quaqua (that is, for all system properties listed * above).

Example: *

 * QuaquaManager.setProperty("Quaqua.design", "panther");
 * QuaquaManager.setProperty("Quaqua.TabbedPane.design", "jaguar");
 * QuaquaManager.setProperty("Quaqua.FileChooser.autovalidate", "true");
 * 

Client Properties:
You can customize some of the * components by specifying client properties.

  • JTable: * {@code Quaqua.Table.style=striped} displays rows with alternating * colors.
Specifying class loader (Java Applets):
If your * code runs as an Applet in a Java 1.3 VM, Swing attempts to load the UI * classes from the system class loader instead of from the class loader which * loads the applet classes. To have Swing load the UI classes using the same * class loader as your code, use the following code to set the Quaqua look and * feel on Swing's UIManager. *
 * UIManager.put("ClassLoader", getClass().getClassLoader());
 * UIManager.setLookAndFeel(QuaquaManager.getLookAndFeel());
 * 
* * * @author Werner Randelshofer * @version $Id: QuaquaManager.java 464 2014-03-22 12:32:00Z wrandelshofer $ */ public class QuaquaManager { private static Properties properties; /** * Set of included Quaqua UI's. If this variable is null, all UI's * of the QuaquaLookAndFeel are included. */ private static Set includedUIs; /** * Set of excluded Quaqua UI's. If this variable is null, all UI's * of the QuaquaLookAndFeel are excluded. */ private static Set excludedUIs = Collections.EMPTY_SET; private final static String version; static { String v = null; try { InputStream s = QuaquaManager.class.getResourceAsStream("version.txt"); if (s != null) { BufferedReader r = new BufferedReader(new InputStreamReader(s, "UTF8")); v = r.readLine(); r.close(); } } catch (IOException e) { } version = (v == null) ? "unknown" : v; } /** * Mac OS X 10.0 Cheetah. */ public final static int CHEETAH = 0; /** * Mac OS X 10.1 Puma. */ public final static int PUMA = 1; /** * Mac OS X 10.2 Jaguar. */ public final static int JAGUAR = 2; /** * Mac OS X 10.3 Panther. */ public final static int PANTHER = 3; /** * Mac OS X 10.4 Tiger. */ public final static int TIGER = 4; /** * Mac OS X 10.5 Leopard or Darwin 9.1.0. */ public final static int LEOPARD = 5; /** * Mac OS X 10.6 Snow Leopard. */ public final static int SNOW_LEOPARD = 6; /** * Mac OS X 10.7 Lion. */ public final static int LION = 7; /** * Mac OS X 10.8 Mountain Lion. */ public final static int MOUNTAIN_LION = 8; /** * Mac OS X 10.9 Maverick. */ public final static int MAVERICKS = 9; /** * Mac OS X 10.x Always points to next OSX X release. */ public final static int X = 100; /** * Generic Linux. */ public final static int LINUX = -4; /** * Darwin. */ public final static int DARWIN = -3; /** * Windows. */ public final static int WINDOWS = -2; /** * Unknown. */ public final static int UNKNOWN = -1; /** * Current operating system. */ private static int OS; /** * True if Mac OS X. */ private static boolean isOSX; /** * Current design. May differ from the operating system, by setting a value * in the "Quaqua.design" property. */ private static int design; static { updateAvailableLAFs(); updateDesignAndOS(); } private static void updateDesignAndOS() { String osName = getProperty("os.name"); String osVersion = getProperty("os.version"); isOSX = osName.equals("Mac OS X"); if (isOSX) { int p = osVersion.indexOf('.'); p = osVersion.indexOf('.', p + 1); if (p != -1) { osVersion = osVersion.substring(0, p); } if (osVersion.equals("10.0")) { OS = CHEETAH; } else if (osVersion.equals("10.1")) { OS = PUMA; } else if (osVersion.equals("10.2")) { OS = JAGUAR; } else if (osVersion.equals("10.3")) { OS = PANTHER; } else if (osVersion.equals("10.4")) { OS = TIGER; } else if (osVersion.equals("10.5")) { OS = LEOPARD; } else if (osVersion.equals("10.6")) { OS = SNOW_LEOPARD; } else if (osVersion.equals("10.7")) { OS = LION; } else if (osVersion.equals("10.8")) { OS = MOUNTAIN_LION; } else if (osVersion.equals("10.9")) { OS = MAVERICKS; } else if (osVersion.startsWith("10.")) { OS = X; } else { // Note: We must fall back to Snow Leopard here, because this // is the last OS X version for which we provide our own artwork. // For later OS X versions, we retrieve the artwork from // the system using native API's. OS = SNOW_LEOPARD; } } else if (osName.startsWith("Darwin")) { OS = DARWIN; } else if (osName.startsWith("Linux")) { OS = LINUX; } else if (osName.startsWith("Windows")) { OS = WINDOWS; } else { OS = UNKNOWN; } String osDesign = getProperty("Quaqua.design", "auto").toLowerCase(); if (osDesign.equals("cheetah")) { design = JAGUAR; } else if (osDesign.equals("puma")) { design = JAGUAR; } else if (osDesign.equals("jaguar")) { design = JAGUAR; } else if (osDesign.equals("panther")) { design = PANTHER; } else if (osDesign.equals("tiger")) { design = TIGER; } else if (osDesign.equals("leopard")) { design = LEOPARD; } else if (osDesign.equals("snowleopard")) { design = SNOW_LEOPARD; } else if (osDesign.equals("lion")) { design = LION; } else if (osDesign.equals("mountainlion")) { design = MOUNTAIN_LION; } else if (osDesign.equals("maverick")) { design = MAVERICKS; } else { if (OS <= UNKNOWN) { // Note: We must fall back to Snow Leopard here, because this // is the last OS X version for which we provide our own artwork. // For later OS X versions, we retrieve the artwork from // the system using native API's. design = SNOW_LEOPARD; } else { design = OS; } } } /** * Map of Quaqua Look and Feels. * * key lafKey. value Look and Feel class name. */ private static HashMap lafs; /** * Updates the map of available Quaqua Look and Feels. The list may vary * depending on the deployment chosen for the Quaqua Look and Feel. * * The list of look and feels is contained in a file named "laf.txt" in the * package "ch.randelshofer.quaqua". The file contains a semicolon separated * mapping according to the following EBNF production: *
     * mapping ::= {design}"."{version}"="{class}";"
     * 
* */ private static void updateAvailableLAFs() { lafs = new HashMap(); try { InputStream s = QuaquaManager.class.getResourceAsStream("laf.txt"); if (s != null) { BufferedReader r = new BufferedReader(new InputStreamReader(s, "UTF8")); StreamTokenizer tt = new StreamTokenizer(r); tt.wordChars('_', '_'); tt.ordinaryChar('='); tt.ordinaryChar(';'); while (tt.nextToken() != StreamTokenizer.TT_EOF) { if (tt.ttype != StreamTokenizer.TT_WORD) { throw new IOException("Illegal token for 'design.version' in line " + tt.lineno() + " of laf.txt File"); } String lafKey = tt.sval; if (tt.nextToken() != '=') { throw new IOException("Illegal token for '=' in line " + tt.lineno() + " of laf.txt File"); } if (tt.nextToken() != StreamTokenizer.TT_WORD) { throw new IOException("Illegal token for 'class' in line " + tt.lineno() + " of laf.txt File at key '" + lafKey + "'"); } String className = tt.sval; if (tt.nextToken() != ';') { throw new IOException("Illegal token " + (tt.ttype > 32 ? "'" + (char) tt.ttype + "'" : "" + tt.ttype) + " for ';' in line " + tt.lineno() + " of laf.txt File"); } lafs.put(lafKey, className); } r.close(); } else { throw new IOException("File laf.txt not found"); } } catch (IOException e) { System.err.println("Warning: " + QuaquaManager.class + ".updateAvailableLAFs() couldn't access resource file \"laf.txt\"."); // e.printStackTrace(); // Fall back to default values lafs.put("Jaguar.15", "ch.randelshofer.quaqua.jaguar.Quaqua15JaguarLookAndFeel"); lafs.put("Jaguar.16", "ch.randelshofer.quaqua.jaguar.Quaqua15JaguarLookAndFeel"); lafs.put("Panther.15", "ch.randelshofer.quaqua.panther.Quaqua15PantherLookAndFeel"); lafs.put("Panther.16", "ch.randelshofer.quaqua.panther.Quaqua15PantherLookAndFeel"); lafs.put("Tiger.15", "ch.randelshofer.quaqua.tiger.Quaqua15TigerLookAndFeel"); lafs.put("Tiger.16", "ch.randelshofer.quaqua.tiger.Quaqua15TigerLookAndFeel"); lafs.put("Leopard.15", "ch.randelshofer.quaqua.leopard.Quaqua15LeopardLookAndFeel"); lafs.put("Leopard.16", "ch.randelshofer.quaqua.leopard.Quaqua16LeopardLookAndFeel"); lafs.put("SnowLeopard.15", "ch.randelshofer.quaqua.leopard.Quaqua15LeopardLookAndFeel"); lafs.put("SnowLeopard.16", "ch.randelshofer.quaqua.snowleopard.Quaqua16SnowLeopardLookAndFeel"); lafs.put("Lion.16", "ch.randelshofer.quaqua.lion.Quaqua16LionLookAndFeel"); lafs.put("MountainLion.16", "ch.randelshofer.quaqua.mountainlion.Quaqua16MountainLionLookAndFeel"); lafs.put("CrossTiger.15", "ch.randelshofer.quaqua.tiger.Quaqua15TigerCrossPlatformLookAndFeel"); lafs.put("CrossTiger.16", "ch.randelshofer.quaqua.tiger.Quaqua15TigerCrossPlatformLookAndFeel"); lafs.put("CrossLeopard.15", "ch.randelshofer.quaqua.leopard.Quaqua15LeopardCrossPlatformLookAndFeel"); lafs.put("CrossLeopard.16", "ch.randelshofer.quaqua.leopard.Quaqua15LeopardCrossPlatformLookAndFeel"); } } /** * Prevent instance creation. */ private QuaquaManager() { } /** * Returns the current operating system. * * @return one of the OS constants: CHEETAH..SNOW_LEOPARD, DARWIN, WINDOWS * or UNKNOWN. */ public static int getOS() { return OS; } /** * Returns true if the current operating system is known to be Mac OS X. */ public static boolean isOSX() { return OS >= CHEETAH; } /** * Returns the current design of Mac OS X. * * @return one of the OS constants: CHEETAH..TIGER or UNKNOWN. */ public static int getDesign() { return design; } /** * Returns the class name of a Quaqua look and feel. The class name depends * on the JVM, Quaqua is running on, and on the visual design of the * operating system. */ public static String getLookAndFeelClassName() { updateDesignAndOS(); if (getProperty("Quaqua.noQuaqua", "false").equals("true")) { return UIManager.getCrossPlatformLookAndFeelClassName(); } String lafKey = null; String className; className = "apple.laf.AquaLookAndFeel"; try { Class.forName(className); } catch (ClassNotFoundException e1) { className = "com.apple.mrj.swing.MacLookAndFeel"; try { Class.forName(className); } catch (ClassNotFoundException e2) { className = UIManager.getCrossPlatformLookAndFeelClassName(); } } String javaVersion = getProperty("java.version", ""); if (className.equals("apple.laf.AquaLookAndFeel")) { if (javaVersion.startsWith("1.5")) { switch (design) { case JAGUAR: lafKey = "Jaguar.15"; break; case PANTHER: lafKey = "Panther.15"; break; case TIGER: lafKey = "Tiger.15"; break; case LEOPARD: lafKey = "Leopard.15"; break; case SNOW_LEOPARD: lafKey = "SnowLeopard.16"; break; case LION: lafKey = "Lion.16"; break; case MOUNTAIN_LION: case MAVERICKS: case X: lafKey = "MountainLion.16"; break; default: lafKey = "SnowLeopard.16"; break; } } else { switch (design) { case JAGUAR: lafKey = "Jaguar.16"; break; case PANTHER: lafKey = "Panther.16"; break; case TIGER: lafKey = "Tiger.16"; break; case LEOPARD: lafKey = "Leopard.16"; break; case SNOW_LEOPARD: lafKey = "SnowLeopard.16"; break; case LION: lafKey = "Lion.16"; break; case MOUNTAIN_LION: case MAVERICKS: case X: lafKey = "MountainLion.16"; break; default: lafKey = "SnowLeopard.16"; break; } } } else { lafKey = "CrossPlatform.15"; switch (design) { case JAGUAR: lafKey = "CrossTiger.15"; break; case PANTHER: lafKey = "CrossTiger.15"; break; case TIGER: lafKey = "CrossTiger.15"; break; case LEOPARD: lafKey = "CrossLeopard.15"; break; case SNOW_LEOPARD: lafKey = "CrossSnowLeopard.15"; break; default: lafKey = "CrossSnowLeopard.15"; break; } } if (lafs.containsKey(lafKey)) { className = (String) lafs.get(lafKey); } return className; } /** * Returns a Quaqua look and feel, if workarounds for the system look and * feel are available. Returns a UIManager.getSystemLookAndFeelClassName() * instance if no workaround is available. */ public static LookAndFeel getLookAndFeel() { try { return (LookAndFeel) Class.forName(getLookAndFeelClassName()).newInstance(); } catch (Exception e) { InternalError ie = new InternalError(e.toString()); /* FIXME - This needs JDK 1.4 to work. ie.initCause(e); */ throw ie; } } /** * This method returns a locally specified property, if it has been set * using method * {@code setProperty}. If no local property has been found, a system * property using method * {@code java.lang.System.getProperty(String,String} is returned.

* This method is used to specify properties for Quaqua, when, due to * security reasons, system properties can not be used, e.g. in a secure * Applet environment. * * @see #setProperty */ public static String getProperty(String key) { try { if (properties == null || !properties.containsKey(key)) { return System.getProperty(key); } else { return properties.getProperty(key); } } catch (SecurityException e) { return null; } } /** * This method returns a locally specified property, if it has been set * using method * {@code setProperty}. If no local property has been found, a system * property using method * {@code java.lang.System.getProperty(String,String} is returned.

* This method is used to specify properties for Quaqua, when, due to * security reasons, system properties can not be used, e.g. in a secure * Applet environment. * * @see #setProperty */ public static String getProperty(String key, String def) { try { if (properties == null || !properties.containsKey(key)) { return System.getProperty(key, def); } else { return properties.getProperty(key, def); } } catch (SecurityException e) { return def; } } /** * This method returns a locally specified property, if it has been set * using method * {@code setProperty}. If no local property has been found, a system * property using method * {@code java.lang.System.getProperty(String,String} is returned.

* This method is used to specify properties for Quaqua, when, due to * security reasons, system properties can not be used, e.g. in a secure * Applet environment. * * @see #setProperty */ public static int[] getProperty(String key, int[] def) { String value; try { if (properties == null || !properties.containsKey(key)) { value = System.getProperty(key, null); } else { value = properties.getProperty(key, null); } } catch (SecurityException e) { value = null; } if (value != null) { StringTokenizer tt = new StringTokenizer(value, ","); if (tt.countTokens() == def.length) { int[] result = new int[def.length]; try { for (int i = 0; i < result.length; i++) { result[i] = Integer.decode(tt.nextToken()).intValue(); } return result; } catch (NumberFormatException e) { // continue (we return def below) } } } return def; } /** * Locally defines a property.

Use method * {@code clearProperty} to clear a local property.

This method is * used to specify properties for Quaqua, when, due to security reasons, * system properties can not be used, e.g. in a secure Applet * environment.

* * @see #getProperty */ public static String setProperty(String key, String value) { if (properties == null) { properties = new Properties(); } return (String) properties.setProperty(key, value); } /** * Removes a locally defined property.

This method is used to specify * properties for Quaqua, when, due to security reasons, system properties * can not be used, e.g. in a secure Applet environment. * * @see #setProperty */ public static void removeProperty(String key) { if (properties != null) { properties.remove(key); } } /** * Returns the version string of Quaqua. The version string is a sequence of * numbers separated by full stops, followed by a blank character and a * release date in ISO-format. e.g. "3.6.1 2006-03-12" */ public static String getVersion() { return version; } public static void main(String[] args) { try { UIManager.setLookAndFeel(QuaquaManager.getLookAndFeelClassName()); } catch (Exception e) { // empty } SwingUtilities.invokeLater(new Runnable() { public void run() { try { JFrame f = new JFrame("Quaqua Look and Feel"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel label = new JLabel( "" + "

Quaqua Look and Feel " + version + "

" + "Copyright 2003-2013 Werner Randelshofer
" + "All Rights Reserved.
" + "
" + "This is a software library.
" + "Please read the accompanying documentation
for additional information."); label.setBorder(new EmptyBorder(12, 20, 20, 20)); f.getContentPane().add(label); f.pack(); f.setVisible(true); } catch (Throwable t) { t.printStackTrace(); } } }); } /** * Returns true, if Quaqua uses native code for some of its functionality. */ public static boolean isNativeCodeAvailable() { return OSXFile.canWorkWithAliases(); } /** * Include only UI delegates with the specified names. This method must be * called, before setting the QuaquaLookAndFeel to the UIManager.

Usage: *

     * HashSet includes = new HashSet();
     * includes.add("Button");
     * QuaquaManager.setIncludeUIs(includes);
     * 
* * @param includes Set<String> Only include UI delegates, which are in this * list. Specify null to include all UIs. */ public static void setIncludedUIs(Set includes) { includedUIs = includes; } /** * Excludes UI delegates with the specified names. This method must be * called, before setting the QuaquaLookAndFeel to the UIManager.

Usage: *

     * HashSet excludes = new HashSet();
     * excludes.add("TextField");
     * QuaquaManager.setExcludeUIs(excludes);
     * 
* * @param excludes Set<String> Exclude UI delegates, which are in this list. * Specify null to exclude all UIs. */ public static void setExcludedUIs(Set excludes) { excludedUIs = excludes; } /** * Gets the included UI delegates, or null, if all Quaqua UI delegates shall * be included into the QuaquaLookAndFeel. * * @return Set<String>. */ public static Set getIncludedUIs() { return includedUIs; } /** * Gets the excluded UI delegates, or null, if all Quaqua UI delegates shall * be excluded from the QuaquaLookAndFeel. * * @return Set<String>. */ public static Set getExcludedUIs() { return excludedUIs; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy