pcgen.gui2.plaf.LookAndFeelManager.java Source code

Java tutorial

Introduction

Here is the source code for pcgen.gui2.plaf.LookAndFeelManager.java

Source

/*
 * 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);
        }

    }

}