Ptidej-v5.2-master/POM Tests/data/ArgoUML_0.28/src/org/argouml/ui/LookAndFeelMgr.java
// $Id: LookAndFeelMgr.java 12546 2007-05-05 16:54:40Z linus $
// Copyright (c) 1996-2007 The Regents of the University of California. All
// Rights Reserved. Permission to use, copy, modify, and distribute this
// software and its documentation without fee, and without a written
// agreement is hereby granted, provided that the above copyright notice
// and this paragraph appear in all copies.  This software program and
// documentation are copyrighted by The Regents of the University of
// California. The software program and documentation are supplied "AS
// IS", without any accompanying services from The Regents. The Regents
// does not warrant that the operation of the program will be
// uninterrupted or error-free. The end-user understands that the program
// was developed for research purposes and is advised not to rely
// exclusively on the program for any reason.  IN NO EVENT SHALL THE
// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

/*
 * LookAndFeelMgr.java
 *
 * Created on 12 October 2002, 22:25
 */

package org.argouml.ui;

import java.awt.Font;

import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.metal.DefaultMetalTheme;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.MetalTheme;

import org.apache.log4j.Logger;
import org.argouml.application.api.Argo;
import org.argouml.configuration.Configuration;

/**
 * Controls the look and feel and theme of ArgoUML. LookAndFeelMgr has a
 * "Look and Feel" property which represents the Swing Pluggable Look-and-feel.
 * It also has a "Theme" property which represents a MetalTheme when the
 * Metal look-and-feel is selected
 * (for other LAFs, a theme is not supported). <p>
 *
 * Themes have 2 kinds of names:
 * 1. The "display name" shown in the UI,
 * which is retrieved by theme.getName(), and
 * 2. the "class name",
 * which is the name of the theme class,
 * and is retrieved by theme.getClass().getName().
 *
 * @author Bob Tarling
 * @author Jeremy Jones
 */
public final class LookAndFeelMgr {
    /**
     * Logger.
     */
    private static final Logger LOG = Logger.getLogger(LookAndFeelMgr.class);

    /**
     * The instance.
     */
    private static final LookAndFeelMgr	SINGLETON = new LookAndFeelMgr();

    /**
     * The Metal look and feel class name.
     */
    private static final String                 METAL_LAF_CLASS_NAME =
	"javax.swing.plaf.metal.MetalLookAndFeel";

    /**
     * Display name and configuration key for default look and feel and theme.
     */
    private static final String			DEFAULT_KEY = "Default";

    // JasonsThemes
    private static final MetalTheme		DEFAULT_THEME =
	new JasonsTheme();
    private static final MetalTheme		BIG_THEME =
	new JasonsBigTheme();
    private static final MetalTheme		HUGE_THEME =
	new JasonsHugeTheme();

    /**
     * The list of supported MetalThemes.
     */
    private static final MetalTheme[] THEMES = {
        DEFAULT_THEME,
        BIG_THEME,
        HUGE_THEME,
        new DefaultMetalTheme(),
    };

    /**
     * The class name of Swing's default look and feel (will be used if
     * the LookAndFeel property is null).
     */
    private String				defaultLafClass;

    /**
     * Get the single instance of the LookAndFeelMgr.
     *
     * @return the single instance of the LookAndFeelMgr
     */
    public static LookAndFeelMgr getInstance() {
        return SINGLETON;
    }

    /**
     * Creates a new instance of LookAndFeelMgr.
     */
    private LookAndFeelMgr() {
        LookAndFeel laf = UIManager.getLookAndFeel();
        if (laf != null) {
            defaultLafClass = laf.getClass().getName();
        } else {
            defaultLafClass = null;
        }
    }

    /**
     * Sets the appearance of the UI using the current values of
     * the LookAndFeel and Theme properties.
     */
    public void initializeLookAndFeel() {
        String n = getCurrentLookAndFeel();
        setLookAndFeel(n);
        if (isThemeCompatibleLookAndFeel(n)) {
            setTheme(getMetalTheme(getCurrentThemeClassName()));
        }
    }

    /**
     * Detecting the theme from the command line.
     *
     * @param arg the argument from the command line
     * @return the theme
     */
    public String getThemeClassNameFromArg(String arg) {
        if (arg.equalsIgnoreCase("-big")) {
            return BIG_THEME.getClass().getName();
        } else if (arg.equalsIgnoreCase("-huge")) {
            return HUGE_THEME.getClass().getName();
        }
        return null;
    }

    /**
     * Outputs command-line arguments supported by this class.
     */
    public void printThemeArgs() {
        System.err.println("  -big            use big fonts");
        System.err.println("  -huge           use huge fonts");
    }

    /**
     * Returns the display names of the available look and feel choices.
     * This may be used to fill a combobox to allow the user
     * to select the LAF.
     *
     * @return	look and feel display names
     */
    public String[] getAvailableLookAndFeelNames() {
        UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();

        String[] names = new String[lafs.length + 1];
        names[0] = DEFAULT_KEY;
        for (int i = 0; i < lafs.length; ++i) {
            names[i + 1] = lafs[i].getName();
        }

        return names;
    }

    /**
     * Returns the display names of the available theme choices.
     * This may be used to fill a combobox to allow the user
     * to select the theme.
     *
     * @return	theme display names
     */
    public String[] getAvailableThemeNames() {
        String[] names = new String[LookAndFeelMgr.THEMES.length];
        for (int i = 0; i < THEMES.length; ++i) {
            names[i] = THEMES[i].getName();
        }

        return names;
    }

    /**
     * Returns the Look and Feel class name identifier for the specified
     * display name, or null if no such Look and Feel is found.
     *
     * @param	name	display name of desired look and feel
     * @return			class name for desired look and feel
     */
    public String getLookAndFeelFromName(String name) {
        if (name == null || DEFAULT_KEY.equals(name)) {
            return null;
        }

        String className = null;

        UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();
        for (int i = 0; i < lafs.length; ++i) {
            if (lafs[i].getName().equals(name)) {
                className = lafs[i].getClassName();
            }
        }

        return className;
    }

    /**
     * Returns the theme class name identifier for the specified
     * display name, or null if no such theme is found.
     *
     * @param	name	display name of desired theme
     * @return			class name for desired theme
     */
    public String getThemeFromName(String name) {
        if (name == null) {
            return null;
        }

        String className = null;

        for (int i = 0; i < THEMES.length; ++i) {
            if (THEMES[i].getName().equals(name)) {
                className = THEMES[i].getClass().getName();
            }
        }

        return className;
    }

    /**
     * Returns true if the specified look and feel class
     * supports setting different themes.
     *
     * @param	lafClass	look and feel class name
     * @return				true if supports themes
     */
    public boolean isThemeCompatibleLookAndFeel(String lafClass) {
        if (lafClass == null) {
            return false;
        }
        return (/*lafClass == null ||*/ lafClass.equals(METAL_LAF_CLASS_NAME));
    }

    /**
     * Returns the string identifier for the current look and feel.
     * This is the class name of the LookAndFeel class for the look and feel.
     * Returns null if no look and feel has been specified, in which case
     * Swing's default look and feel should be used.
     *
     * @return	current look and feel class name
     */
    public String getCurrentLookAndFeel() {
        String value =
	    Configuration.getString(Argo.KEY_LOOK_AND_FEEL_CLASS, null);
        if (DEFAULT_KEY.equals(value)) {
            value = null;
        }
        return value;
    }

    /**
     * Returns the display name of the current look and feel.
     *
     * @return	look and feel display name
     */
    public String getCurrentLookAndFeelName() {
        String currentLookAndFeel = getCurrentLookAndFeel();

        if (currentLookAndFeel == null) {
            return DEFAULT_KEY;
        }
        String name = null;

        UIManager.LookAndFeelInfo[] lafs =
            UIManager.getInstalledLookAndFeels();
        for (int i = 0; i < lafs.length; ++i) {
            if (lafs[i].getClassName().equals(currentLookAndFeel)) {
                name = lafs[i].getName();
            }
        }

        return name;
    }

    /**
     * Sets the current look and feel, storing the new value in
     * Configuration.  If argument is null, indicates that Swing's default
     * look and feel should be used.
     *
     * @param lafName	the name of desired look and feel
     * @param themeName the name of the theme
     */
    public void setCurrentLAFAndThemeByName(String lafName, String themeName) {
        String lafClass = getLookAndFeelFromName(lafName);
        String currentLookAndFeel = getCurrentLookAndFeel();

        if (lafClass == null && currentLookAndFeel == null) {
            return;
        }
        /* Disabled since it gives various problems: e.g. the toolbar icons
         * get too wide. Also the default does not give the new java 5.0 looks.
        if (!(lafClass != null && !lafClass.equals(currentLookAndFeel))) {
            setLookAndFeel(lafClass);
            Component tree = ProjectBrowser.getInstance();
            SwingUtilities.updateComponentTreeUI(
                    SwingUtilities.getRootPane(tree));
        }
        */

        if (lafClass == null) {
            lafClass = DEFAULT_KEY;
        }
        Configuration.setString(Argo.KEY_LOOK_AND_FEEL_CLASS, lafClass);

        setCurrentTheme(getThemeFromName(themeName));
    }

    /**
     * Returns the string identifier for the current theme.
     * This is the class name of the MetalTheme class for the theme.
     * This method returns null when the configuration
     * does not return a valid metaltheme.
     *
     * @return	current theme class name or null
     */
    public String getCurrentThemeClassName() {
	String value = Configuration.getString(Argo.KEY_THEME_CLASS, null);
	if (DEFAULT_KEY.equals(value)) {
	    value = null;
	}
	return value;
    }

    /**
     * Returns the display name of the current theme.
     * Guaranteed to return the display name
     * of one of the themes in the THEMES list.
     *
     * @return	theme display name
     */
    public String getCurrentThemeName() {
        String currentThemeClassName = getCurrentThemeClassName();

        if (currentThemeClassName == null) {
            /* Make up a default */
            return THEMES[0].getName();
        }

        for (int i = 0; i < THEMES.length; ++i) {
            if (THEMES[i].getClass().getName().equals(currentThemeClassName)) {
                return THEMES[i].getName();
            }
        }
        return THEMES[0].getName();
    }

    /**
     * Sets the current theme, storing the new value in
     * Configuration. Argument should not be null, and argument class
     * should be an instance of MetalTheme.
     *
     * @param	themeClass	class name of desired theme
     */
    public void setCurrentTheme(String themeClass) {
        MetalTheme theme = getMetalTheme(themeClass);

        if (theme.getClass().getName().equals(getCurrentThemeClassName())) {
            return;
        }

        setTheme(theme);

        /* Disabled since it gives various problems: e.g. the toolbar icons
         * get too wide. Also the default does not give the new java 5.0 looks.
        Component tree = ProjectBrowser.getInstance();
        SwingUtilities.updateComponentTreeUI(SwingUtilities.getRootPane(tree));
        */

        String themeValue = themeClass;
        if (themeValue == null) {
            themeValue = DEFAULT_KEY;
        }
        Configuration.setString(Argo.KEY_THEME_CLASS, themeValue);
    }

    /**
     * @return the standard textfield font
     */
    public Font getStandardFont() {
        Font font = UIManager.getDefaults().getFont("TextField.font");
        if (font == null) {
            font = (new javax.swing.JTextField()).getFont();
        }
        return font;
    }

    /**
     * @return the small font
     */
    public Font getSmallFont() {
        Font font = getStandardFont();
        if (font.getSize2D() >= 12f) {
            return font.deriveFont(font.getSize2D() - 2f);
        }
        return font;
    }

    /**
     * Sets the look and feel in the GUI by calling UIManager.setLookAndFeel().
     *
     * @param	lafClass	class name of look and feel
     */
    private void setLookAndFeel(String lafClass) {
        try {
            if (lafClass == null && defaultLafClass != null) {
                // Set to the default LAF
                UIManager.setLookAndFeel(defaultLafClass);
            } else {
                // Set a custom LAF
                UIManager.setLookAndFeel(lafClass);
            }
        } catch (UnsupportedLookAndFeelException e) {
            LOG.error(e);
        } catch (ClassNotFoundException e) {
            LOG.error(e);
        } catch (InstantiationException e) {
            LOG.error(e);
        } catch (IllegalAccessException e) {
            LOG.error(e);
        }
    }

    /**
     * Sets the metal theme in the GUI by calling
     * MetalLookAndFeel.setCurrentTheme().
     *
     * @param	theme	new MetalTheme to set
     */
    private void setTheme(MetalTheme theme) {
        String currentLookAndFeel = getCurrentLookAndFeel();

        // If LAF is Metal (either set explicitly, or as the default)
        if ((currentLookAndFeel != null
                && currentLookAndFeel.equals(METAL_LAF_CLASS_NAME))
	    || (currentLookAndFeel == null
	        && defaultLafClass.equals(METAL_LAF_CLASS_NAME))) {
            try {
                MetalLookAndFeel.setCurrentTheme(theme);
                UIManager.setLookAndFeel(METAL_LAF_CLASS_NAME);
            } catch (UnsupportedLookAndFeelException e) {
                LOG.error(e);
            } catch (ClassNotFoundException e) {
                LOG.error(e);
            } catch (InstantiationException e) {
                LOG.error(e);
            } catch (IllegalAccessException e) {
                LOG.error(e);
            }
        }
    }

    /**
     * Returns the MetalTheme for the specified class name.
     * Returns the default theme if a corresponding MetalTheme class
     * can not be found.
     *
     * @param	themeClass	MetalTheme class name
     * @return				MetalTheme object for class name
     */
    private MetalTheme getMetalTheme(String themeClass) {
        MetalTheme theme = null;

        for (int i = 0; i < THEMES.length; ++i) {
            if (THEMES[i].getClass().getName().equals(themeClass)) {
                theme = THEMES[i];
            }
        }

        if (theme == null) {
            theme = DEFAULT_THEME;
        }

        return theme;
    }
}
