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

mdlaf.utils.MaterialFontFactory Maven / Gradle / Ivy

There is a newer version: 1.1.4
Show newest version
/*
 * MIT License
 *
 * Copyright (c) 2018-2020 Vincenzo Palazzo [email protected]
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package mdlaf.utils;

import java.awt.*;
import java.awt.font.TextAttribute;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.swing.plaf.FontUIResource;

/**
 * This class managed the font inside the library and inside the Look and Feel, in fact
 * this class use a flaywait patter to minimized the font instance created from the library.
 * In fact on a lot of component you have only 4 instance of font in a normal use case.
 *
 * @author https://github.com/vincenzopalazzo
 */
public class MaterialFontFactory {

    private static final Map fontSettings = new HashMap<>();

    public static final MaterialTypeFont REGULAR = MaterialTypeFont.REGULAR;
    public static final MaterialTypeFont BOLD = MaterialTypeFont.BOLD;
    public static final MaterialTypeFont ITALIC = MaterialTypeFont.ITALIC;
    public static final MaterialTypeFont MEDIUM = MaterialTypeFont.MEDIUM;

    private static MaterialFontFactory SINGLETON;

    public static MaterialFontFactory getInstance() {
        if (SINGLETON == null) {
            SINGLETON = new MaterialFontFactory();
        }
        return SINGLETON;
    }

    /**
     * @deprecated this method will be removed in the version 1.2, this method is not really util fot the library.
     */
    @Deprecated
    public static Font fontUtilsDisplayable(String textDisplayable, Font withFont) {
        if (textDisplayable == null || withFont == null) {
            throw new IllegalArgumentException("Argument at the fontUtilsDisplayable function are/is null");
        }

        if (withFont.canDisplayUpTo(textDisplayable) < 0) {
            return withFont;
        }

        return new FontUIResource(Font.SANS_SERIF, withFont.getStyle(), withFont.getSize());
    }

    /**
     * The path font was load from a proprieties file.
     * This can permit the user to change the font also with a proprieties file
     * see The file inside resources/config/font-all-language.properties
     */
    protected Properties properties = new Properties();
    protected Map cacheFont = new HashMap<>();
    protected float defaultSize = 14f;
    protected boolean withPersonalSettings = true;


    private MaterialFontFactory() {
        try {
            loadOsProprieties();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * This method load the font from a String path, in common this method should be use to load the
     * personal font in a personal location.
     **/
    public FontUIResource getFontWithPath(String path) {
        return this.getFontWithPath(path, this.withPersonalSettings);
    }

    /**
     * This method load the font from a input resource, in common this method should be use to load the
     * personal font in a personal resource.
     **/
    public FontUIResource getFontWithStream(InputStream stream) {
        return this.getFontWithStream(stream, this.withPersonalSettings);
    }

    /**
     * This method load the library default font, at this moment this is a Noto Sans font, you can
     * load 4 different dimension of font, @see MaterialTypeFont
     **/
    public FontUIResource getFont(MaterialTypeFont typeFont) {
        return this.getFont(typeFont, this.withPersonalSettings);
    }

    /**
     * This method load the library default font, at this moment this is a Noto Sans font, you can
     * load 4 different dimension of font, @see MaterialTypeFont
     * 

* In addition, this method have the boolean (by default this propriety is true) called withPersonalSettings * to jump the personal font setting. * This is util when you have other library that work with font and you want take the control on your code */ public FontUIResource getFont(MaterialTypeFont typeFont, boolean withPersonalSettings) { if (typeFont == null) { throw new IllegalArgumentException("\n- Parameter type font null.\n"); } String typeFontString = typeFont.toString(); if (cacheFont.containsKey(typeFontString)) { return cacheFont.get(typeFontString); } String propieties = properties.getProperty(typeFontString); FontUIResource font = getFontWithPath(propieties); cacheFont.put(typeFontString, font); return font; } /** * This method load the font from a String path, in common this method should be use to load the * personal font in a personal location. *

* In addition, this method have the boolean (by default this propriety is true) called withPersonalSettings * to jump the personal font setting. * This is util when you have other library that work with font and you want take the control on your code */ public FontUIResource getFontWithPath(String path, boolean withPersonalSettings) { if (path == null || path.isEmpty()) { throw new IllegalArgumentException("\n- The path to load personal fort is null or empty"); } InputStream stream = getClass().getResourceAsStream(path); return loadFont(stream, withPersonalSettings); } /** * This method load the font from a input resource, in common this method should be use to load the * personal font in a personal resource. * In addition, this method have the boolean (by default this propriety is true) called withPersonalSettings * to jump the personal font setting. * This is util when you have other library that work with font and you want take the control on your code */ public FontUIResource getFontWithStream(InputStream stream, boolean withPersonalSettings) { if (stream == null) { throw new IllegalArgumentException("\n- The stream to load personal fort is null"); } return loadFont(stream, withPersonalSettings); } /** * The JDK 8 paint with fin with pixel, this effect is not present in JDK version > 9 * But this library try to support the all JDK version and with the calculate dimension form * resolution screen resolve in part the pixelated effect. * This is the resource that report the optimizing font * https://stackoverflow.com/questions/5829703/java-getting-a-font-with-a-specific-height-in-pixels */ private FontUIResource loadFont(InputStream inputStream, boolean withPersonalSettings) { float size = this.doOptimizingDimensionFont(this.defaultSize); if (withPersonalSettings && fontSettings.isEmpty()) { fontSettings.put(TextAttribute.SIZE, size); fontSettings.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); } try { Font font; if (withPersonalSettings) { font = Font.createFont(Font.TRUETYPE_FONT, inputStream).deriveFont(fontSettings); return new FontUIResource(font); } font = Font.createFont(Font.TRUETYPE_FONT, inputStream).deriveFont(size); return new FontUIResource(font); } catch (IOException | FontFormatException e) { e.printStackTrace(); throw new RuntimeException("Font " + inputStream.toString() + " wasn't loaded"); } } /** * In this method optimizing the font dimension with the display resolution * This method to calculate the font dimension is bad, We now but the JDK 8 display the font very bad * and at the moment with the JDK 8 the dimension of the font is calculate with the screen resolution * and with the JDK9+ the font set with the defaultSize @see defaultSize * @param dimension is the dimension font that you want optimizing */ public float doOptimizingDimensionFont(float dimension) { if (defaultSize <= 0) { throw new IllegalArgumentException("\n- The dimension should be positive (>= 0)"); } if (Utils.isJavaVersionUnderJava9()) { return 11f * Math.min(Toolkit.getDefaultToolkit().getScreenResolution(), 96) / 72; } return dimension; } /** * This method was to change the font based on the operating system because there * was a bug for the well-known font, it was tinted pixeled, * but now this problem has been solved and therefore there is no need to carry around * Many dependencies, native fonts are removed from the project but this method remains for furious purposes * * @throws IOException */ private void loadOsProprieties() throws IOException { properties.load(getClass().getResourceAsStream("/config/font-all-language.properties")); } /** * Enum class that. This constant is to set the library font inside the material type * as, REGULAR, BOLD, ITALIC, MEDIUM */ protected enum MaterialTypeFont { REGULAR("REGULAR"), BOLD("BOLD"), ITALIC("ITALIC"), MEDIUM("MEDIUM"); private String type; MaterialTypeFont(String type) { this.type = type; } @Override public String toString() { return type; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy