/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * muCommander 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.mucommander.ui.theme; import javax.swing.*; import javax.swing.text.JTextComponent; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; /** * {@link DefaultColor} implementation that maps to a system value. * <p> * The purpose of this class is to create default colors that map, for example, to the default text area foreground * color for the current look and feel. * </p> * <p> * The mechanism used to identify the default color goes through three different stages: * <ul> * <li>Look for a specific property in {@link UIManager}.</li> * <li> * If this isn't found, rely on a {@link ComponentMapper} to get an instance of the target and retrieve the relevant * color. * </li> * <li> * If this is <code>null</code>, return a hard-coded default value. * </li> * </ul> * </p> * @author Nicolas Rinaudo */ public class SystemDefaultColor extends DefaultColor implements PropertyChangeListener { // - Fallbacks ----------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------- /** Foreground color used in case no system default could be identified. */ public static Color DEFAULT_FOREGROUND = Color.BLACK; /** Background color used in case no system default could be identified. */ public static Color DEFAULT_BACKGROUND = Color.WHITE; /** Selection foreground color used in case no system default could be identified. */ public static Color DEFAULT_SELECTION_FOREGROUND = Color.WHITE; /** Selection background color used in case no system default could be identified. */ public static Color DEFAULT_SELECTION_BACKGROUND = Color.BLUE; // - Color types --------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------- /** Identifies a foreground color (linked to {@link JComponent#getForeground()}). */ public static final int FOREGROUND = 1; /** Identifies a background color (linked to {@link JComponent#getBackground()}). */ public static final int BACKGROUND = 2; /** Identifies a selection foreground color (linked to {@link JTextComponent#getSelectedTextColor()}). */ public static final int SELECTION_FOREGROUND = 3; /** Identifies a selection background color (linked to {@link JTextComponent#getSelectionColor()}). */ public static final int SELECTION_BACKGROUND = 4; // - Instance fields ----------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------- /** {@link UIManager} property to look for. */ private String property; /** * Type of the default color (can be one of {@link #FOREGROUND}, {@link #BACKGROUND}, {@link #SELECTION_FOREGROUND} * or {@link #SELECTION_BACKGROUND}). */ private int type; /** Current default color value. */ private Color color; /** Used to create instance of the component whose color will be retrieved (in case {@link #property} isn't set). */ private ComponentMapper mapper; // - Initialisation ------------------------------------------------------------------------------------------------ // ----------------------------------------------------------------------------------------------------------------- /** * Creates a new instance of {@link SystemDefaultColor}. * @param type type of the color being described (can be one of {@link #FOREGROUND}, {@link #BACKGROUND}, * {@link #SELECTION_FOREGROUND} or {@link #SELECTION_BACKGROUND}). * @param property name of the {@link UIManager} property to look for. * @param mapper component mapper to use when the {@link UIManager} property isn't set. */ public SystemDefaultColor(int type, String property, ComponentMapper mapper) { UIManager.addPropertyChangeListener(this); this.property = property; this.mapper = mapper; this.type = type; } // - DefaultColor implementation ----------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------- /** * Returns the color of the right {@link #type type} used by the specified component. * @param component component to analyse. * @return the color of the right {@link #type type} used by the specified component. */ private Color getColor(JComponent component) { // Foreground color. if(type == FOREGROUND) return component.getForeground(); // Background color. else if(type == BACKGROUND) return component.getBackground(); // Text component specific colors. else if(component instanceof JTextComponent) { JTextComponent comp; comp = (JTextComponent)component; // Selection foreground color. if(type == SELECTION_FOREGROUND) return comp.getSelectedTextColor(); // Selection background color. else if(type == SELECTION_BACKGROUND) return comp.getSelectionColor(); } return null; } /** * Returns the fallback color of the right {@link #type type}. * @return the fallback color of the right {@link #type type}. */ private Color getColor() { switch(type) { case FOREGROUND: return DEFAULT_FOREGROUND; case SELECTION_FOREGROUND: return DEFAULT_SELECTION_FOREGROUND; case SELECTION_BACKGROUND: return DEFAULT_SELECTION_BACKGROUND; case BACKGROUND: default: return DEFAULT_BACKGROUND; } } @Override public Color getColor(ThemeData data) { if(color == null) { if((color = UIManager.getColor(property)) == null) if((color = getColor(mapper.getComponent())) == null) color = getColor(); color = new Color(color.getRGB(), (color.getRGB() & 0xFF000000) != 0xFF000000); } return color; } // - PropertyChangeListener implementation ------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------- public void propertyChange(PropertyChangeEvent evt) { String name; name = evt.getPropertyName().toLowerCase(); if(name.equals("lookandfeel") || name.equalsIgnoreCase(property)) { Color oldColor; color = null; oldColor = color; color = getColor((ThemeData)null); if(!color.equals(oldColor)) notifyChange(color); } } }