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

eu.hansolo.steelseries.gauges.RadialCounter Maven / Gradle / Ivy

package eu.hansolo.steelseries.gauges;

/**
 *
 * @author hansolo
 */
public final class RadialCounter extends AbstractRadial
{
    private boolean rotateTickmarks;
    private double oldValue;
    private double rotationAngle;
    private final java.awt.geom.Point2D CENTER;
    private final java.awt.GraphicsConfiguration GFX_CONF;
    private java.awt.image.BufferedImage frameImage;
    private java.awt.image.BufferedImage backgroundImage;
    private java.awt.image.BufferedImage postsImage;
    private java.awt.image.BufferedImage tickmarksImage;
    private java.awt.image.BufferedImage pointerImage;
    private java.awt.image.BufferedImage foregroundImage;
    private java.awt.image.BufferedImage disabledImage;
    private final org.pushingpixels.trident.Timeline TIMELINE;

    
    public RadialCounter()
    {
        super();
        rotateTickmarks = true;
        oldValue = 0;
        rotationAngle = 0;
        CENTER = new java.awt.geom.Point2D.Double();
        GFX_CONF = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        TIMELINE = new org.pushingpixels.trident.Timeline(this);
        createInitialImages();        
    }

    @Override
    public final AbstractGauge init(int WIDTH, int HEIGHT)
    {
        for(eu.hansolo.steelseries.tools.ImageType imageType : IMAGES_TO_UPDATE)
        {
            switch(imageType)
            {
                case FRAME:
                    if (frameImage != null)
                    {
                        frameImage.flush();
                    }
                    frameImage = create_FRAME_Image(WIDTH);
                    break;
                case BACKGROUND:
                    if (backgroundImage != null)
                    {
                        backgroundImage.flush();
                    }
                    backgroundImage = create_BACKGROUND_Image(WIDTH);
                    break;
                case POSTS:
                    if (postsImage != null)
                    {
                        postsImage.flush();
                    }                    
                    postsImage = create_POSTS_Image(WIDTH, eu.hansolo.steelseries.tools.PostPosition.CENTER);                                                
                    break;    
                case TICKMARKS:
                    if (tickmarksImage != null)
                    {
                        tickmarksImage.flush();
                    }
                    tickmarksImage = create_TICKMARKS_Image(WIDTH);
                    break;
                case POINTER:
                    if (pointerImage != null)
                    {
                        pointerImage.flush();
                    }
                    pointerImage = create_POINTER_Image(WIDTH);
                    break;
                case FOREGROUND:
                    if (foregroundImage != null)
                    {
                        foregroundImage.flush();
                    }
                    foregroundImage = create_FOREGROUND_Image(WIDTH, false, getForegroundType());
                    break;
                case DISABLED:
                    if (disabledImage != null)
                    {
                        disabledImage.flush();
                    }
                    disabledImage = create_DISABLED_Image(WIDTH);
                    break;
            }
        }

        IMAGES_TO_UPDATE.clear();

        return this;
    }

    @Override
    protected void paintComponent(java.awt.Graphics g)
    {
        if (!isInitialized())
        {            
            return;
        }
        
        final java.awt.Graphics2D G2 = (java.awt.Graphics2D) g.create();

        CENTER.setLocation(getGaugeBounds().getCenterX(), getGaugeBounds().getCenterY());

        G2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_RENDERING, java.awt.RenderingHints.VALUE_RENDER_QUALITY);
        //G2.setRenderingHint(java.awt.RenderingHints.KEY_DITHERING, java.awt.RenderingHints.VALUE_DITHER_ENABLE);
        //G2.setRenderingHint(java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        //G2.setRenderingHint(java.awt.RenderingHints.KEY_COLOR_RENDERING, java.awt.RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_STROKE_CONTROL, java.awt.RenderingHints.VALUE_STROKE_PURE);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // Translate the coordinate system related to insets
        G2.translate(getInnerBounds().x, getInnerBounds().y);

        final java.awt.geom.AffineTransform OLD_TRANSFORM = G2.getTransform();

        // Draw the frame
        if (isFrameVisible())
        {
            G2.drawImage(frameImage, 0, 0, null);
        }

        // Draw the background
        if (isBackgroundVisible())
        {
            G2.drawImage(backgroundImage, 0, 0, null);
        }

        // Draw the tickmarks
        if (rotateTickmarks)
        {
            G2.rotate(-rotationAngle, CENTER.getX(), CENTER.getY());
            G2.drawImage(tickmarksImage, 0, 0, null);
            G2.setTransform(OLD_TRANSFORM);
        }
        else
        {
            G2.drawImage(tickmarksImage, 0, 0, null);
        }

        // Draw pointer
        if (!rotateTickmarks)
        {
            G2.rotate(rotationAngle, CENTER.getX(), CENTER.getY());
            G2.drawImage(pointerImage, 0, 0, null);
            G2.setTransform(OLD_TRANSFORM);
        }
        else
        {
            G2.drawImage(pointerImage, 0, 0, null);
        }

        // Draw posts
        G2.drawImage(postsImage, 0, 0, null);
        
        // Draw foreground
        if (isForegroundVisible())
        {
            G2.drawImage(foregroundImage, 0, 0, null);
        }

        if (!isEnabled())
        {
            G2.drawImage(disabledImage, 0, 0, null);
        }
                    
        // Translate coordinate system back to original
        G2.translate(-getInnerBounds().x, -getInnerBounds().y);

        G2.dispose();
    }

    @Override
    public void setValue(final double VALUE)
    {
        if (VALUE < -10 || VALUE > 10)
        {
            throw new java.lang.IllegalArgumentException("Value (" + VALUE + ")out of range (" + getMinValue() + " - " + getMaxValue() +").");
        }
        rotationAngle = (2.0 * Math.PI / 10.0) * VALUE;
        fireStateChanged();
        this.oldValue = VALUE;
        repaint(getInnerBounds());
    }

    @Override
    public void setValueAnimated(final double VALUE)
    {
        if (TIMELINE.getState() == org.pushingpixels.trident.Timeline.TimelineState.PLAYING_FORWARD || TIMELINE.getState() == org.pushingpixels.trident.Timeline.TimelineState.PLAYING_REVERSE)
        {
            TIMELINE.abort();
        }

        final double OVERALL_RANGE = getMaxValue() - getMinValue();
        final double RANGE = Math.abs(getValue() - VALUE);
        final double FRACTION = RANGE / OVERALL_RANGE;

        TIMELINE.addPropertyToInterpolate("value", this.oldValue, VALUE);
        TIMELINE.setEase(new org.pushingpixels.trident.ease.Spline(0.5f));

        TIMELINE.setDuration((long) (3000 * FRACTION));
        TIMELINE.play();
    }

    @Override
    public double getMinValue()
    {
        return -10;
    }

    @Override
    public double getMaxValue()
    {
        return 10;
    }

    public boolean isRotateTickmarks()
    {
        return this.rotateTickmarks;
    }

    public void setRotateTickmarks(final boolean ROTATE_TICKMARKS)
    {
        this.rotateTickmarks = ROTATE_TICKMARKS;
        setValue(0);
        repaint(getInnerBounds());
    }

    @Override
    public java.awt.geom.Point2D getCenter()
    {
        return new java.awt.geom.Point2D.Double(getInnerBounds().getCenterX() + getInnerBounds().x, getInnerBounds().getCenterX() + getInnerBounds().y);
    }

    @Override
    public java.awt.geom.Rectangle2D getBounds2D()
    {
        return getInnerBounds();
    }

    private java.awt.image.BufferedImage create_TICKMARKS_Image(final int WIDTH)
    {
        if (WIDTH <= 0)
        {
            return null;
        }
        
        final java.awt.image.BufferedImage IMAGE = GFX_CONF.createCompatibleImage(WIDTH, WIDTH, java.awt.Transparency.TRANSLUCENT);
        final java.awt.Graphics2D G2 = IMAGE.createGraphics();
        G2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_FRACTIONALMETRICS, java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_RENDERING, java.awt.RenderingHints.VALUE_RENDER_QUALITY);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_STROKE_CONTROL, java.awt.RenderingHints.VALUE_STROKE_PURE);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_INTERPOLATION, java.awt.RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        final int IMAGE_WIDTH = IMAGE.getWidth();

        final java.awt.geom.AffineTransform OLD_TRANSFORM = G2.getTransform();

        final java.awt.BasicStroke THIN_STROKE = new java.awt.BasicStroke(0.01f * IMAGE_WIDTH, java.awt.BasicStroke.CAP_ROUND, java.awt.BasicStroke.JOIN_BEVEL);
        final java.awt.Font SMALL_FONT = new java.awt.Font("Verdana", 0, (int) (0.1f * IMAGE_WIDTH));
        final float TEXT_DISTANCE = 0.11f * IMAGE_WIDTH;
        final float MIN_LENGTH = 0.015f * IMAGE_WIDTH;
        final float MED_LENGTH = 0.035f * IMAGE_WIDTH;

        // Create the watch itself
        final float RADIUS = IMAGE_WIDTH * 0.35f;
        final java.awt.geom.Point2D CENTER = new java.awt.geom.Point2D.Double(IMAGE_WIDTH / 2.0f, IMAGE_WIDTH / 2.0f);

        // Draw ticks
        java.awt.geom.Point2D innerPoint;
        java.awt.geom.Point2D outerPoint;
        java.awt.geom.Point2D textPoint = null;
        java.awt.geom.Line2D tick;
        int tickCounterFull = 0;
        int tickCounterHalf = 0;
        int counter = 0;

        double sinValue = 0;
        double cosValue = 0;

        final double STEP = (2.0 * Math.PI) / (20.0);
        
        if (isTickmarkColorFromThemeEnabled())
        {
            G2.setColor(getBackgroundColor().LABEL_COLOR);
        }
        else
        {
            G2.setColor(getTickmarkColor());
        }

        for (double alpha = 2.0 * Math.PI; alpha >= 0; alpha -= STEP)
        {
            G2.setStroke(THIN_STROKE);
            sinValue = Math.sin(alpha);
            cosValue = Math.cos(alpha);
           
            if (tickCounterHalf == 1)
            {
                G2.setStroke(THIN_STROKE);
                innerPoint = new java.awt.geom.Point2D.Double(CENTER.getX() + (RADIUS - MIN_LENGTH) * sinValue, CENTER.getY() + (RADIUS - MIN_LENGTH) * cosValue);
                outerPoint = new java.awt.geom.Point2D.Double(CENTER.getX() + RADIUS * sinValue, CENTER.getY() + RADIUS * cosValue);
                // Draw ticks
                tick = new java.awt.geom.Line2D.Double(innerPoint.getX(), innerPoint.getY(), outerPoint.getX(), outerPoint.getY());
                G2.draw(tick);

                tickCounterHalf = 0;
            }

            // Different tickmark every 15 units
            if (tickCounterFull == 2)
            {
                G2.setStroke(THIN_STROKE);
                innerPoint = new java.awt.geom.Point2D.Double(CENTER.getX() + (RADIUS - MED_LENGTH) * sinValue, CENTER.getY() + (RADIUS - MED_LENGTH) * cosValue);
                outerPoint = new java.awt.geom.Point2D.Double(CENTER.getX() + RADIUS * sinValue, CENTER.getY() + RADIUS * cosValue);

                // Draw ticks
                tick = new java.awt.geom.Line2D.Double(innerPoint.getX(), innerPoint.getY(), outerPoint.getX(), outerPoint.getY());
                G2.draw(tick);

                tickCounterFull = 0;
            }

            // Draw text
            G2.setFont(SMALL_FONT);
            textPoint = new java.awt.geom.Point2D.Double(CENTER.getX() + (RADIUS - TEXT_DISTANCE) * sinValue, CENTER.getY() + (RADIUS - TEXT_DISTANCE) * cosValue);
            if (counter != 20 && counter % 2 == 0)
            {
                G2.rotate(Math.toRadians(0), CENTER.getX(), CENTER.getY());
                G2.fill(UTIL.rotateTextAroundCenter(G2, String.valueOf(counter/2), (int) textPoint.getX(), (int) textPoint.getY(), Math.toDegrees(2*Math.PI - alpha)));
            }

            G2.setTransform(OLD_TRANSFORM);

            tickCounterHalf++;
            tickCounterFull++;

            counter ++;
        }

        G2.dispose();

        return IMAGE;
    }

    @Override
    protected java.awt.image.BufferedImage create_POINTER_Image(final int WIDTH)
    {
        if (WIDTH <= 0)
        {
            return null;
        }

        final java.awt.image.BufferedImage IMAGE = GFX_CONF.createCompatibleImage(WIDTH, WIDTH, java.awt.Transparency.TRANSLUCENT);
        final java.awt.Graphics2D G2 = IMAGE.createGraphics();
        G2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_RENDERING, java.awt.RenderingHints.VALUE_RENDER_QUALITY);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_DITHERING, java.awt.RenderingHints.VALUE_DITHER_ENABLE);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_COLOR_RENDERING, java.awt.RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        G2.setRenderingHint(java.awt.RenderingHints.KEY_STROKE_CONTROL, java.awt.RenderingHints.VALUE_STROKE_PURE);

        final int IMAGE_WIDTH = IMAGE.getWidth();
        final int IMAGE_HEIGHT = IMAGE.getHeight();

        final java.awt.geom.GeneralPath POINTER = new java.awt.geom.GeneralPath();
        POINTER.setWindingRule(java.awt.geom.GeneralPath.WIND_EVEN_ODD);
        POINTER.moveTo(IMAGE_WIDTH * 0.5, IMAGE_HEIGHT * 0.8317757009345794);
        POINTER.lineTo(IMAGE_WIDTH * 0.46261682242990654, IMAGE_HEIGHT * 0.9065420560747663);
        POINTER.lineTo(IMAGE_WIDTH * 0.5420560747663551, IMAGE_HEIGHT * 0.9065420560747663);
        POINTER.lineTo(IMAGE_WIDTH * 0.5, IMAGE_HEIGHT * 0.8317757009345794);
        POINTER.closePath();
        final java.awt.geom.Point2D POINTER_START = new java.awt.geom.Point2D.Double(0, POINTER.getBounds2D().getMinY() );
        final java.awt.geom.Point2D POINTER_STOP = new java.awt.geom.Point2D.Double(0, POINTER.getBounds2D().getMaxY() );
        final float[] POINTER_FRACTIONS =
        {
            0.0f,
            0.3f,
            0.59f,
            1.0f
        };
        final java.awt.Color[] POINTER_COLORS;
        if (getPointerColor() != eu.hansolo.steelseries.tools.ColorDef.CUSTOM)
        {
            POINTER_COLORS = new java.awt.Color[]
            {
                getPointerColor().DARK,
                getPointerColor().LIGHT,
                getPointerColor().LIGHT,
                getPointerColor().DARK
            };
        }
        else
        {
            POINTER_COLORS = new java.awt.Color[]
            {
                getCustomPointerColorObject().DARK,
                getCustomPointerColorObject().LIGHT,
                getCustomPointerColorObject().LIGHT,
                getCustomPointerColorObject().DARK
            };
        }
        final java.awt.LinearGradientPaint POINTER_GRADIENT = new java.awt.LinearGradientPaint(POINTER_START, POINTER_STOP, POINTER_FRACTIONS, POINTER_COLORS);
        G2.setPaint(POINTER_GRADIENT);
        G2.fill(POINTER);

        if (getPointerColor() != eu.hansolo.steelseries.tools.ColorDef.CUSTOM)
        {
            G2.setColor(getPointerColor().LIGHT);
        }
        else
        {
            G2.setColor(getCustomPointerColorObject().LIGHT);
        }
        G2.setStroke(new java.awt.BasicStroke(1.0f, java.awt.BasicStroke.CAP_BUTT, java.awt.BasicStroke.JOIN_MITER));
        G2.draw(POINTER);

        G2.dispose();

        return IMAGE;
    }
        
    @Override
    public String toString()
    {
        return "RadialCounter";
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy