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

org.controlsfx.glyphfont.Glyph Maven / Gradle / Ivy

Go to download

High quality UI controls and other tools to complement the core JavaFX distribution

There is a newer version: 11.2.1
Show newest version
/**
 * Copyright (c) 2013, 2015 ControlsFX
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *     * Neither the name of ControlsFX, any associated website, nor the
 * names of its contributors may be used to endorse or promote products
 * derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL CONTROLSFX BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.controlsfx.glyphfont;

import java.util.Optional;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.paint.*;
import javafx.scene.text.Font;

import org.controlsfx.control.action.Action;
import org.controlsfx.tools.Duplicatable;

/**
 * Represents one glyph from the font.
 * The glyph is actually a label showing one character from the specified font. It can be used as 'graphic' on any UI
 * control or {@link Action}. It can also directly be used in FXML.
 *
 * Examples:
 *
 * 
{@code
 * new Button("", new Glyph("FontAwesome", "BEER"))
 * }
* *
{@code
 * new Button("", new Glyph("FontAwesome", FontAwesome.Glyph.BEER))
 * }
* * Thy Glyph-Class also offers a fluent API to customize the look of the Glyph. * For example, you can set the color {@link #color(javafx.scene.paint.Color)} or * also add effects such as {@link #useHoverEffect()} * *

An ability to retrieve glyph node by combination of font name and glyph name * extends to the {@link org.controlsfx.control.action.ActionProxy} graphic attribute, where the "font>" * prefix should be used. For more information see {@link org.controlsfx.control.action.ActionProxy}. * */ public class Glyph extends Label implements Duplicatable { /*************************************************************************** * * * Static creators * * * **************************************************************************/ /** * Retrieve glyph by font name and glyph name using one string * where font name an glyph name are separated by pipe. * * @param fontAndGlyph The font and glyph separated by a pipe. Example: "FontAwesome|STAR" * @return A instance of a Glyph node */ public static Glyph create(String fontAndGlyph) { String[] args = fontAndGlyph.split("\\|"); //$NON-NLS-1$ return new Glyph(args[0], args[1]); } /*************************************************************************** * * * Private fields * * * **************************************************************************/ public final static String DEFAULT_CSS_CLASS = "glyph-font"; //$NON-NLS-1$ public final static String STYLE_GRADIENT = "gradient"; //$NON-NLS-1$ public final static String STYLE_HOVER_EFFECT = "hover-effect"; //$NON-NLS-1$ private final ObjectProperty icon = new SimpleObjectProperty<>(); /*************************************************************************** * * * Constructors * * * **************************************************************************/ /** * Empty Constructor (used by FXML) */ public Glyph(){ getStyleClass().add(DEFAULT_CSS_CLASS); icon.addListener(x -> updateIcon()); fontProperty().addListener(x -> updateIcon()); } /** * Creates a new Glyph * @param fontFamily The family name of the font. Example: "FontAwesome" * @param unicode The Unicode character of the glyph */ public Glyph(String fontFamily, char unicode) { this(); setFontFamily(fontFamily); setTextUnicode(unicode); } /** * Creates a new Glyph * @param fontFamily The family name of the font. Example: "FontAwesome" * @param icon The icon - which can be the name (String) or Enum value. * Example: FontAwesome.Glyph.BEER */ public Glyph(String fontFamily, Object icon) { this(); setFontFamily(fontFamily); setIcon(icon); } /*************************************************************************** * * * Public API * * * **************************************************************************/ /** * Sets the glyph icon font family * @param fontFamily A font family name * @return Returns this instance for fluent API */ public Glyph fontFamily(String fontFamily){ setFontFamily(fontFamily); return this; } /** * Sets the glyph color * @param color * @return Returns this instance for fluent API */ public Glyph color(Color color){ setColor(color); return this; } /** * Sets glyph size * @param size * @return Returns this instance for fluent API */ public Glyph size(double size) { setFontSize(size); return this; } /** * Sets glyph size using size factor based on default font size * @param factor * @return Returns this instance for fluent API */ public Glyph sizeFactor(int factor) { Optional.ofNullable(GlyphFontRegistry.font(getFont().getFamily())).ifPresent( glyphFont ->{ setFontSize(glyphFont.getDefaultSize()* (factor < 1? 1: factor)); }); return this; } /** * Adds the hover effect style * @return Returns this instance for fluent API */ public Glyph useHoverEffect(){ this.getStyleClass().add(Glyph.STYLE_HOVER_EFFECT); return this; } /** * Adds the gradient effect style * @return Returns this instance for fluent API */ public Glyph useGradientEffect(){ if(getTextFill() instanceof Color){ Color currentColor = (Color)getTextFill(); /* TODO Do this in code: -fx-text-fill: linear-gradient(to bottom, derive(-fx-text-fill,20%) 10%, derive(-fx-text-fill,-40%) 80%); */ Stop[] stops = new Stop[] { new Stop(0, Color.BLACK), new Stop(1, currentColor)}; LinearGradient lg1 = new LinearGradient(0, 0, 1, 0, true, CycleMethod.NO_CYCLE, stops); setTextFill(lg1); } this.getStyleClass().add(Glyph.STYLE_GRADIENT); return this; } /** * Allows glyph duplication. Since in the JavaFX scenegraph it is not possible to insert the same * {@link Node} in multiple locations at the same time, this method allows for glyph reuse in several places */ @Override public Glyph duplicate() { Paint color = getTextFill(); Object icon = getIcon(); ObservableList classes = getStyleClass(); return new Glyph(){{ setIcon(icon); setTextFill(color); getStyleClass().addAll(classes); }} .fontFamily(getFontFamily()) .size(getFontSize()); } /*************************************************************************** * * * Properties * * * **************************************************************************/ /** * Sets the font family of this glyph * Font size is reset to default glyph font size */ public void setFontFamily(String family){ if( !getFont().getFamily().equals(family)){ Optional.ofNullable(GlyphFontRegistry.font(family)).ifPresent( glyphFont -> { glyphFont.ensureFontIsLoaded(); // Make sure font is loaded Font newFont = Font.font(family, glyphFont.getDefaultSize()); // Reset to default font size setFont(newFont); }); } } /** * Gets the font family of this glyph */ public String getFontFamily(){ return getFont().getFamily(); } /** * Sets the font size of this glyph */ public void setFontSize(double size){ Font newFont = Font.font(getFont().getFamily(), size); setFont(newFont); } /** * Gets the font size of this glyph */ public double getFontSize(){ return getFont().getSize(); } /** * Set the Color of this Glyph */ public void setColor(Color color){ setTextFill(color); } /** * The icon name property. * * This must either be a Glyph-Name (either string or enum value) known by the GlyphFontRegistry. * Alternatively, you can directly submit a unicode character here. */ public ObjectProperty iconProperty(){ return icon; } /** * Set the icon to display. * @param iconValue This can either be the Glyph-Name, Glyph-Enum Value or a unicode character representing the sign. */ public void setIcon(Object iconValue){ icon.set(iconValue); } public Object getIcon(){ return icon.get(); } /*************************************************************************** * * * Private methods * * * **************************************************************************/ /** * This updates the text with the correct unicode value * so that the desired icon is displayed. */ private void updateIcon(){ Object iconValue = getIcon(); if(iconValue != null) { if(iconValue instanceof Character){ setTextUnicode((Character)iconValue); }else { GlyphFont glyphFont = GlyphFontRegistry.font(getFontFamily()); if (glyphFont != null) { String name = iconValue.toString(); Character unicode = glyphFont.getCharacter(name); if (unicode != null) { setTextUnicode(unicode); } else { // Could not find a icon with this name setText(name); } } } } } /** * Sets the given char as text * @param unicode */ private void setTextUnicode(char unicode){ setText(String.valueOf(unicode)); } }