/* * UIFactory.java * Copyright 2001 (C) Bryan McRoberts <merton_monk@yahoo.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on xxxx xx, xxxx, xx:xx PM */ package pcgen.gui2.plaf; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.beans.PropertyChangeListener; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.LookAndFeel; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import org.apache.commons.lang3.SystemUtils; import pcgen.system.ConfigurationSettings; import pcgen.util.Logging; import pcgen.util.SkinLFResourceChecker; /** * {@code UIFactory}. * * @author Thomas Behr */ public final class LookAndFeelManager { public static final boolean HAS_SKIN_LAF = SkinLFResourceChecker.getMissingResourceCount() == 0; private static final String SYSTEM_LAF_CLASS = UIManager.getSystemLookAndFeelClassName(); private static final String CROSS_LAF_CLASS = UIManager.getCrossPlatformLookAndFeelClassName(); private static final LookAndFeelHandler[] lafHandlers; private static final Map<String, LookAndFeelHandler> lafMap = new HashMap<>(); private static final LookAndFeelManager instance = new LookAndFeelManager(); static { try { // Add the Kunststoff L&F before asking the UIManager. Class.forName("com.incors.plaf.kunststoff.KunststoffLookAndFeel"); UIManager.installLookAndFeel("Kunststoff", "com.incors.plaf.kunststoff.KunststoffLookAndFeel"); } catch (ClassNotFoundException ex) { //not much we can do can do about this } Comparator<LookAndFeelInfo> lafcomp = new Comparator<LookAndFeelInfo>() { @Override public int compare(LookAndFeelInfo o1, LookAndFeelInfo o2) { //System laf goes first if (o1.getClassName().equals(SYSTEM_LAF_CLASS)) { return -1; } if (o2.getClassName().equals(SYSTEM_LAF_CLASS)) { return 1; } //Cross Platfrom laf goes second if (o1.getClassName().equals(CROSS_LAF_CLASS)) { return -1; } if (o2.getClassName().equals(CROSS_LAF_CLASS)) { return 1; } //the rest don't matter return 0; } }; LookAndFeelInfo[] lafInfo = UIManager.getInstalledLookAndFeels(); //Sort them so that they are in a UI friendly order Arrays.sort(lafInfo, lafcomp); if (!SystemUtils.IS_OS_WINDOWS) { // Replace the broken Windows L&F which will // only run on M$ platforms with one that will // run everywhere. No difference otherwise. for (int i = 0; i < lafInfo.length; ++i) { if (lafInfo[i].getClassName().endsWith("WindowsLookAndFeel")) //$NON-NLS-1$ { lafInfo[i] = new UIManager.LookAndFeelInfo(lafInfo[i].getName(), "pcgen.gui2.plaf.FakeWindowsLookAndFeel"); //$NON-NLS-1$ break; } } } int length = lafInfo.length; if (HAS_SKIN_LAF) { length++; } lafHandlers = new LookAndFeelHandler[length]; for (int i = 0; i < lafInfo.length; i++) { LookAndFeelInfo info = lafInfo[i]; String name; String tooltip; if (info.getClassName().equals(SYSTEM_LAF_CLASS)) { name = "System"; //TODO: internationalize this tooltip = "Sets the look to that of the System you are using"; } else if (info.getClassName().equals(CROSS_LAF_CLASS)) { name = "Java"; //TODO: internationalize this tooltip = "Sets the look to that of Java's cross platform look"; } else { name = info.getName(); //TODO: internationalize this tooltip = "Sets the look to " + name + " look"; } LookAndFeelHandler handler = new LookAndFeelHandler(name, info.getClassName(), tooltip); lafHandlers[i] = handler; lafMap.put(name, handler); } if (HAS_SKIN_LAF) { String name = "Skinned"; String tooltip = "Sets the look to skinned"; LookAndFeelHandler skinhandler = new LookAndFeelHandler(name, null, tooltip); //the Skin LAF always goes last lafHandlers[lafInfo.length] = skinhandler; lafMap.put(name, skinhandler); } UIManager.setInstalledLookAndFeels(lafInfo); } private static String selectedLookAndFeel = null; private static String selectedTheme = null; private static String currentTheme = null; private static String currentLAF = null; private String oldThemePack = null; private LookAndFeelManager() { } // // public static LookAndFeelManager getInstance() // { // if (instance == null) // { // instance = new LookAndFeelManager(); // } // return instance; // } /** * Initialise the look and feel to be used for this session. The look and * feel used will be the one saved in the preferences, or if none is * selected, nimbus will be used if present and the screen is a decent * size, otherwise Java will be used. Nimbus doesn't work so well on small * screens, hence the test for screen size. */ public static void initLookAndFeel() { //set Java as the fallback look and feel currentLAF = "Java"; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); LookAndFeelInfo nimbus = getNimbusLaf(); if (screenSize.height > 800 && nimbus != null) { currentLAF = nimbus.getName(); } String laf = ConfigurationSettings.initSystemProperty("lookAndFeel", currentLAF); selectedTheme = ConfigurationSettings.getSystemProperty("selectedThemePack"); setLookAndFeel(laf); } private static LookAndFeelInfo getNimbusLaf() { LookAndFeelInfo[] lafInfo = UIManager.getInstalledLookAndFeels(); for (LookAndFeelInfo lookAndFeelInfo : lafInfo) { if ("nimbus".equalsIgnoreCase(lookAndFeelInfo.getName())) { return lookAndFeelInfo; } } return null; } public static Action[] getActions() { return lafHandlers; } public static void addThemePackListener(PropertyChangeListener listener) { ConfigurationSettings.getInstance().addPropertyChangeListener("selectedThemePack", listener); } public static String getCurrentThemePack() { return ConfigurationSettings.getSystemProperty("selectedThemePack"); } public static String getCurrentLAF() { return ConfigurationSettings.getSystemProperty("lookAndFeel"); } public static void setSelectedThemePack(String themePack) { selectedTheme = themePack; ConfigurationSettings.setSystemProperty("selectedThemePack", selectedTheme); } private static void setSkinLAF() { try { //path += File.separator + selectedTheme; LookAndFeel laf = SkinManager.createSkinLAF(selectedTheme); UIManager.setLookAndFeel(laf); ConfigurationSettings.setSystemProperty("lookAndFeel", "Skinned"); ConfigurationSettings.setSystemProperty("selectedThemePack", selectedTheme); currentTheme = selectedTheme; currentLAF = "Skinned"; } catch (Exception ex) { if ("Skinned".equals(currentLAF)) { try { //fall back to old theme //path += File.separator + currentTheme; LookAndFeel laf = SkinManager.createSkinLAF(currentTheme); UIManager.setLookAndFeel(laf); } catch (Exception ex1) { setLookAndFeel("Java"); } } else { setLookAndFeel(currentLAF); } } } public static void setLookAndFeel(String name) { LookAndFeelHandler handler = lafMap.get(name); if (handler == null) { Logging.errorPrint("Look and Feel " + name + " cannot be found"); return; } String className = handler.getClassName(); if (className != null) { try { UIManager.setLookAndFeel(className); // Fix colors; themes which inherit from // MetalTheme change the colors because it's a // static member of MetalTheme (!), so when you // change back & forth, colors get wonked. // final LookAndFeel laf = UIManager.getLookAndFeel(); // if (laf instanceof MetalLookAndFeel) // { // MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme()); // } ConfigurationSettings.setSystemProperty("lookAndFeel", name); currentLAF = name; } catch (Exception ex) { setLookAndFeel(currentLAF); } } else if (HAS_SKIN_LAF) { setSkinLAF(); } else { Logging.errorPrint("Skin LAF library is missing! Setting to default LAF"); setLookAndFeel("Java"); } } public static class LookAndFeelHandler extends AbstractAction { private String className; public LookAndFeelHandler(String name, String className, String tooltip) { super(name); this.className = className; putValue(SHORT_DESCRIPTION, tooltip); } public String getClassName() { return className; } @Override public void actionPerformed(ActionEvent e) { //This is the default operation String name = (String) getValue(NAME); ConfigurationSettings.setSystemProperty("lookAndFeel", name); } } }