com.googlecode.blaisemath.style.Styles.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.blaisemath.style.Styles.java

Source

/*
 * Styles.java
 * Created May 9, 2013
 */
package com.googlecode.blaisemath.style;

/*
 * #%L
 * BlaiseGraphics
 * --
 * Copyright (C) 2009 - 2015 Elisha Peterson
 * --
 * Licensed 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.
 * #L%
 */

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Floats;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Stroke;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;

/**
 * Factory class providing convenience methods for easily creating styles.
 * 
 * @author Elisha
 */
public final class Styles {

    //<editor-fold defaultstate="collapsed" desc="STYLE ATTRIBUTE CONSTANTS">

    public static final String ID = "id";

    @SVGAttribute
    public static final String OPACITY = "opacity";

    @SVGAttribute
    public static final String FILL = "fill";
    @SVGAttribute
    public static final String FILL_OPACITY = "fill-opacity";

    @SVGAttribute
    public static final String STROKE = "stroke";
    @SVGAttribute
    public static final String STROKE_WIDTH = "stroke-width";
    @SVGAttribute
    public static final String STROKE_DASHES = "stroke-dasharray";
    @SVGAttribute
    public static final String STROKE_OPACITY = "stroke-opacity";

    public static final String MARKER = "marker";
    public static final String MARKER_RADIUS = "marker-radius";

    public static final String MARKER_ORIENT = "orient";

    @SVGAttribute
    public static final String FONT = "font-family";
    @SVGAttribute
    public static final String FONT_SIZE = "font-size";

    /** Denotes anchor of text relative to a point */
    public static final String TEXT_ANCHOR = "text-anchor";
    /** Denotes offset from a point */
    public static final String OFFSET = "offset";

    /** Tooltip text */
    // TODO - check whether this is an existing SVG attribute, and if so, change it
    public static final String TOOLTIP = "tooltip";

    //</editor-fold>

    public static final AttributeSet DEFAULT_SHAPE_STYLE = AttributeSet.with(FILL, Color.white)
            .and(STROKE, Color.black).and(STROKE_WIDTH, 1f).immutable();

    public static final AttributeSet DEFAULT_PATH_STYLE = AttributeSet.with(STROKE, Color.black)
            .and(STROKE_WIDTH, 1f).immutable();

    public static final AttributeSet DEFAULT_POINT_STYLE = AttributeSet.with(FILL, Color.white)
            .and(STROKE, Color.black).and(STROKE_WIDTH, 1f).and(MARKER, Markers.CIRCLE).and(MARKER_RADIUS, 4)
            .immutable();

    public static final AttributeSet DEFAULT_TEXT_STYLE = AttributeSet.with(FILL, Color.black).and(FONT, "Dialog")
            .and(FONT_SIZE, 12f).and(TEXT_ANCHOR, Anchor.SOUTHWEST).immutable();

    // utility class
    private Styles() {
    }

    /**
     * Create a partial copy of the attribute set, with only those values matching
     * the given keys.
     * @param sty style to copy from
     * @param keys keys to copy
     * @return copied style
     */
    public static AttributeSet partialCopy(AttributeSet sty, String... keys) {
        AttributeSet res = new AttributeSet();
        for (String k : keys) {
            if (sty.contains(k)) {
                res.put(k, sty.get(k));
            }
        }
        return res;
    }

    //<editor-fold defaultstate="collapsed" desc="UTILITY STYLE/JAVA TRANSLATORS">

    /**
     * Get font from the provided style.
     * @param style style object
     * @return font
     */
    public static Font getFont(AttributeSet style) {
        String fontFace = style.getString(Styles.FONT, "Dialog");
        Integer pointSize = style.getInteger(Styles.FONT_SIZE, 12);
        return new Font(fontFace, Font.PLAIN, pointSize);
    }

    public static void setFont(AttributeSet style, Font font) {
        style.put(Styles.FONT, font.getFontName());
        style.put(Styles.FONT_SIZE, font.getSize());
    }

    public static Stroke getStroke(AttributeSet style) {
        float strokeWidth = style.getFloat(Styles.STROKE_WIDTH, 1f);
        String dashes = style.getString(Styles.STROKE_DASHES, null);
        if (!Strings.isNullOrEmpty(dashes)) {
            Iterable<String> sDashes = Splitter.on(",").trimResults().split(dashes);
            try {
                Iterable<Float> fDashes = Floats.stringConverter().convertAll(sDashes);
                float[] fArr = new float[Iterables.size(fDashes)];
                int i = 0;
                for (Float f : fDashes) {
                    fArr[i] = f == null ? 0f : f;
                    i++;
                }
                return new BasicStroke(strokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, fArr,
                        0.0f);
            } catch (NumberFormatException x) {
                Logger.getLogger(Styles.class.getName()).log(Level.WARNING, "Invalid dash pattern: " + dashes, x);
            }
        }
        return new BasicStroke(strokeWidth);
    }

    /**
     * Retrieve text anchor from style. Permits the anchor to be either a string
     * or an instance of {@link Anchor}.
     * @param style the style to get anchor from
     * @param def default anchor if there is none set
     * @return anchor
     */
    public static Anchor getAnchor(AttributeSet style, Anchor def) {
        Object styleAnchor = style.get(Styles.TEXT_ANCHOR);
        if (styleAnchor == null) {
            return def;
        } else if (styleAnchor instanceof String) {
            String styleAnchorText = (String) styleAnchor;
            try {
                return Anchor.valueOf(styleAnchorText);
            } catch (IllegalArgumentException x) {
                throw new IllegalStateException("A text anchor string must match"
                        + " a value of the Anchor enum, but was " + styleAnchorText, x);
            }
        } else if (styleAnchor instanceof Anchor) {
            return (Anchor) styleAnchor;
        } else {
            throw new IllegalStateException("The style " + Styles.TEXT_ANCHOR
                    + " should either be a string or an Anchor, but was " + styleAnchor);
        }
    }

    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="STYLE SET FACTORY METHODS">

    public static AttributeSet defaultShapeStyle() {
        return DEFAULT_SHAPE_STYLE;
    }

    public static AttributeSet defaultPathStyle() {
        return DEFAULT_PATH_STYLE;
    }

    public static AttributeSet defaultPointStyle() {
        return DEFAULT_POINT_STYLE;
    }

    public static AttributeSet defaultTextStyle() {
        return DEFAULT_TEXT_STYLE;
    }

    /**
     * Create a basic shape style with given fill and stroke
     * @param fill fill color
     * @param stroke stroke color
     * @return shape style
     */
    public static AttributeSet fillStroke(@Nullable Color fill, @Nullable Color stroke) {
        return AttributeSet.with(FILL, fill).and(STROKE, stroke);
    }

    /**
     * Create a basic shape style with given fill and stroke
     * @param fill fill color
     * @param stroke stroke color
     * @param width stroke width
     * @return shape style
     */
    public static AttributeSet fillStroke(@Nullable Color fill, @Nullable Color stroke, float width) {
        return AttributeSet.with(FILL, fill).and(STROKE, stroke).and(STROKE_WIDTH, width);
    }

    /**
     * Create a path style with a stroke color and width
     * @param stroke stroke color
     * @param width stroke width
     * @return path style
     */
    public static AttributeSet strokeWidth(Color stroke, float width) {
        return AttributeSet.with(STROKE, stroke).and(STROKE_WIDTH, width);
    }

    /**
     * Create a style with given fill, size, and anchor
     * @param col fill color of text
     * @param sz font size
     * @param anchor anchor of text
     * @return text style
     */
    public static AttributeSet text(Color col, float sz, Anchor anchor) {
        return AttributeSet.with(FILL, col).and(FONT_SIZE, sz).and(TEXT_ANCHOR, anchor);
    }

    /**
     * Create style for a marker with given radius
     * @param marker the marker shape
     * @param rad the radius
     * @return style
     */
    public static AttributeSet marker(Marker marker, float rad) {
        return AttributeSet.with(MARKER, marker).and(MARKER_RADIUS, rad);
    }

    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="MODIFIER & CONTEXT FACTORY METHODS">

    /**
     * Modifies colors in a style set.
     * @return color modifier
     */
    public static StyleModifier defaultColorModifier() {
        return new ColorModifier();
    }

    /**
     * Modifies stroke widths in a style set.
     * @return color modifier
     */
    public static StyleModifier defaultStrokeModifier() {
        return new StrokeWidthModifier();
    }

    /**
     * Create default style context.
     * @return a default style context w/ no parent, but with a standard set of styles
     */
    public static StyleContext defaultStyleContext() {
        StyleContext res = new StyleContext();
        res.addModifier(defaultColorModifier());
        res.addModifier(defaultStrokeModifier());
        return res;
    }

    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="MODIFIER UTILITIES">

    /**
     * Return highlight-modified version of the style set.
     * @param style style to modify
     * @return default modified style for highlighting
     */
    public static AttributeSet withHighlight(AttributeSet style) {
        return defaultStyleContext().applyModifiers(style, AttributeSet.with(StyleHints.HILITE_HINT, true));
    }

    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="INNER CLASSES">

    /** Modifier that adjusts fill/stroke attributes to preset colors. */
    public static class PresetColorModifier implements StyleModifier {
        private Color highlightFill = null;
        private Color highlightStroke = null;
        private Color selectFill = null;
        private Color selectStroke = null;

        public AttributeSet apply(AttributeSet style, AttributeSet hints) {
            AttributeSet res = style;
            if (hints.contains(StyleHints.HILITE_HINT)) {
                res = new AttributeSet(res);
                res.put(Styles.FILL, highlightFill);
                res.put(Styles.STROKE, highlightStroke);
            }
            if (hints.contains(StyleHints.SELECTED_HINT)) {
                res = new AttributeSet(res);
                res.put(Styles.FILL, selectFill);
                res.put(Styles.STROKE, selectStroke);
            }
            return res;
        }

        //<editor-fold defaultstate="collapsed" desc="PROPERTY PATTERNS">
        //
        // PROPERTY PATTERNS
        //

        public Color getHighlightFill() {
            return highlightFill;
        }

        public void setHighlightFill(Color highlightFill) {
            this.highlightFill = highlightFill;
        }

        public Color getHighlightStroke() {
            return highlightStroke;
        }

        public void setHighlightStroke(Color highlightStroke) {
            this.highlightStroke = highlightStroke;
        }

        public Color getSelectFill() {
            return selectFill;
        }

        public void setSelectFill(Color selectFill) {
            this.selectFill = selectFill;
        }

        public Color getSelectStroke() {
            return selectStroke;
        }

        public void setSelectStroke(Color selectStroke) {
            this.selectStroke = selectStroke;
        }

        //</editor-fold>

    }

    /** Modifier that overrides all colors in the source style using the supplied hints. */
    public static class ColorModifier implements StyleModifier {
        public AttributeSet apply(AttributeSet style, AttributeSet hints) {
            AttributeSet res = new AttributeSet(style);
            for (String key : style.getAllAttributes(Color.class)) {
                res.put(key, StyleHints.modifyColorsDefault(style.getColor(key), hints));
            }
            return res;
        }
    }

    /** Modifier that modifies stroke-width in the supplied style using the supplied hints. */
    public static class StrokeWidthModifier implements StyleModifier {
        public AttributeSet apply(AttributeSet style, AttributeSet hints) {
            return new AttributeSet(style).and(STROKE_WIDTH,
                    StyleHints.modifyStrokeWidthDefault(style.getFloat(STROKE_WIDTH), hints));
        }
    }

    //</editor-fold>

}