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

org.apache.pivot.wtk.Theme Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.pivot.wtk;

import java.awt.Font;

import org.apache.pivot.collections.Dictionary;
import org.apache.pivot.collections.HashMap;
import org.apache.pivot.util.Service;
import org.apache.pivot.wtk.skin.BorderSkin;
import org.apache.pivot.wtk.skin.BoxPaneSkin;
import org.apache.pivot.wtk.skin.CardPaneSkin;
import org.apache.pivot.wtk.skin.ColorChooserButtonSkin;
import org.apache.pivot.wtk.skin.FillPaneSkin;
import org.apache.pivot.wtk.skin.FlowPaneSkin;
import org.apache.pivot.wtk.skin.GridPaneFillerSkin;
import org.apache.pivot.wtk.skin.GridPaneSkin;
import org.apache.pivot.wtk.skin.ImageViewSkin;
import org.apache.pivot.wtk.skin.LabelSkin;
import org.apache.pivot.wtk.skin.MovieViewSkin;
import org.apache.pivot.wtk.skin.PanelSkin;
import org.apache.pivot.wtk.skin.ScrollPaneSkin;
import org.apache.pivot.wtk.skin.SeparatorSkin;
import org.apache.pivot.wtk.skin.StackPaneSkin;
import org.apache.pivot.wtk.skin.TablePaneFillerSkin;
import org.apache.pivot.wtk.skin.TablePaneSkin;
import org.apache.pivot.wtk.skin.TextAreaSkin;
import org.apache.pivot.wtk.skin.TextPaneSkin;
import org.apache.pivot.wtk.skin.WindowSkin;

/**
 * Base class for Pivot themes. A theme defines a complete "look and feel"
 * for a Pivot application.
 * 

* Note that concrete Theme implementations should be declared as final. If * multiple third-party libraries attempted to extend a theme, it would cause a * conflict, as only one could be used in any given application. *

* IMPORTANT All skin mappings must be added to the map, even non-static inner * classes. Otherwise, the component's base class will attempt to install its * own skin, which will result in the addition of duplicate listeners. */ public abstract class Theme { protected HashMap, Class> componentSkinMap = new HashMap, Class>(); private static Theme theme = null; public static final String NAME_KEY = "name"; public static final String SIZE_KEY = "size"; public static final String BOLD_KEY = "bold"; public static final String ITALIC_KEY = "italic"; /** * The service provider name (see {@link Service#getProvider(String)}). */ public static final String PROVIDER_NAME = "org.apache.pivot.wtk.Theme"; static { theme = (Theme)Service.getProvider(PROVIDER_NAME); if (theme == null) { throw new ThemeNotFoundException(); } } public Theme() { componentSkinMap.put(Border.class, BorderSkin.class); componentSkinMap.put(BoxPane.class, BoxPaneSkin.class); componentSkinMap.put(CardPane.class, CardPaneSkin.class); componentSkinMap.put(ColorChooserButtonSkin.ColorChooserPopup.class, ColorChooserButtonSkin.ColorChooserPopupSkin.class); componentSkinMap.put(FillPane.class, FillPaneSkin.class); componentSkinMap.put(FlowPane.class, FlowPaneSkin.class); componentSkinMap.put(GridPane.class, GridPaneSkin.class); componentSkinMap.put(GridPane.Filler.class, GridPaneFillerSkin.class); componentSkinMap.put(ImageView.class, ImageViewSkin.class); componentSkinMap.put(Label.class, LabelSkin.class); componentSkinMap.put(MovieView.class, MovieViewSkin.class); componentSkinMap.put(Panel.class, PanelSkin.class); componentSkinMap.put(ScrollPane.class, ScrollPaneSkin.class); componentSkinMap.put(Separator.class, SeparatorSkin.class); componentSkinMap.put(StackPane.class, StackPaneSkin.class); componentSkinMap.put(TablePane.class, TablePaneSkin.class); componentSkinMap.put(TablePane.Filler.class, TablePaneFillerSkin.class); componentSkinMap.put(TextArea.class, TextAreaSkin.class); componentSkinMap.put(TextPane.class, TextPaneSkin.class); componentSkinMap.put(Window.class, WindowSkin.class); } public final Class getSkinClass(Class componentClass) { return componentSkinMap.get(componentClass); } public abstract Font getFont(); public abstract void setFont(Font font); /** * Returns the skin class responsible for skinning the specified component * class. * * @param componentClass * The component class. * * @return * The skin class, or null if no skin mapping exists for the * component class. */ public Class get(Class componentClass) { if (componentClass == null) { throw new IllegalArgumentException("Component class is null."); } return componentSkinMap.get(componentClass); } /** * Sets the skin class responsible for skinning the specified component * class. * * @param componentClass * The component class. * * @param skinClass * The skin class. */ public void set(Class componentClass, Class skinClass) { if (componentClass == null) { throw new IllegalArgumentException("Component class is null."); } if (skinClass == null) { throw new IllegalArgumentException("Skin class is null."); } componentSkinMap.put(componentClass, skinClass); } /** * Gets the current theme, as determined by the {@linkplain #PROVIDER_NAME * theme provider}. * * @throws IllegalStateException * If a theme has not been installed. */ public static Theme getTheme() { if (theme == null) { throw new IllegalStateException("No installed theme."); } return theme; } /** * Produce a font by describing it relative to the current theme's font * @param dictionary A dictionary with any of the following keys: *

    *
  • {@value #NAME_KEY} - the family name of the font
  • *
  • {@value #SIZE_KEY} - the font size as an integer, or a string "x%" for a relative size
  • *
  • {@value #BOLD_KEY} - true/false
  • *
  • {@value #ITALIC_KEY} - true/false
  • *
* Omitted values are taken from the theme's font. */ public static Font deriveFont(Dictionary dictionary) { Font font = theme.getFont(); String name = font.getName(); if (dictionary.containsKey(NAME_KEY)) { name = (String)dictionary.get(NAME_KEY); } int size = font.getSize(); if (dictionary.containsKey(SIZE_KEY)) { Object value = dictionary.get(SIZE_KEY); if (value instanceof String) { String string = (String)value; if (string.endsWith("%")) { float percentage = Float.parseFloat(string.substring(0, string.length() - 1)) / 100f; size = Math.round(font.getSize() * percentage); } else { throw new IllegalArgumentException(value + " is not a valid font size."); } } else { size = (Integer)value; } } int style = font.getStyle(); if (dictionary.containsKey(BOLD_KEY)) { boolean bold = (Boolean)dictionary.get(BOLD_KEY); if (bold) { style |= Font.BOLD; } else { style &= ~Font.BOLD; } } if (dictionary.containsKey(ITALIC_KEY)) { boolean italic = (Boolean)dictionary.get(ITALIC_KEY); if (italic) { style |= Font.ITALIC; } else { style &= ~Font.ITALIC; } } return new Font(name, style, size); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy