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

com.alee.laf.progressbar.ProgressBarPainter Maven / Gradle / Ivy

There is a newer version: 1.2.14
Show newest version
package com.alee.laf.progressbar;

import com.alee.api.annotations.NotNull;
import com.alee.api.annotations.Nullable;
import com.alee.api.jdk.Objects;
import com.alee.laf.WebLookAndFeel;
import com.alee.managers.style.BoundsType;
import com.alee.painter.DefaultPainter;
import com.alee.painter.SectionPainter;
import com.alee.painter.decoration.AbstractDecorationPainter;
import com.alee.painter.decoration.DecorationState;
import com.alee.painter.decoration.IDecoration;
import com.alee.utils.SwingUtils;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.List;

/**
 * Basic painter for {@link JProgressBar} component.
 * It is used as {@link WProgressBarUI} default painter.
 *
 * @param  component type
 * @param  component UI type
 * @param  decoration type
 * @author Alexandr Zernov
 * @author Mikle Garin
 */
public class ProgressBarPainter>
        extends AbstractDecorationPainter implements IProgressBarPainter, ChangeListener
{
    /**
     * Style settings.
     * todo Replace with general getMinimumSize method in painters
     */
    protected Dimension minimumContentSize;

    /**
     * Progress line painter.
     */
    @DefaultPainter ( ProgressPainter.class )
    protected IProgressPainter progressPainter;

    /**
     * Progress text painter.
     */
    @DefaultPainter ( ProgressTextPainter.class )
    protected IProgressTextPainter progressTextPainter;

    /**
     * Cached last progress bar value.
     */
    protected transient int value;

    @Nullable
    @Override
    protected List> getSectionPainters ()
    {
        return asList ( progressPainter, progressTextPainter );
    }

    @Override
    protected void installPropertiesAndListeners ()
    {
        super.installPropertiesAndListeners ();
        installProgressBarValueListeners ();
    }

    @Override
    protected void uninstallPropertiesAndListeners ()
    {
        uninstallProgressBarValueListeners ();
        super.uninstallPropertiesAndListeners ();
    }

    @Override
    protected void propertyChanged ( @NotNull final String property, @Nullable final Object oldValue, @Nullable final Object newValue )
    {
        // Perform basic actions on property changes
        super.propertyChanged ( property, oldValue, newValue );

        // Update animator on progress state changes
        if ( Objects.equals ( property, WebProgressBar.INDETERMINATE_PROPERTY, WebLookAndFeel.ORIENTATION_PROPERTY ) )
        {
            updateDecorationState ();
        }
    }

    /**
     * Installs custom {@link JProgressBar} value listeners which will perform decoration state updates when needed.
     */
    protected void installProgressBarValueListeners ()
    {
        value = component.getValue ();
        component.addChangeListener ( this );
    }

    /**
     * Uninstalls custom {@link JProgressBar} value listeners.
     */
    protected void uninstallProgressBarValueListeners ()
    {
        component.removeChangeListener ( this );
        value = -1;
    }

    @Override
    public void stateChanged ( @NotNull final ChangeEvent e )
    {
        // Ensure component is still available
        // This might happen if painter is replaced from another ChangeListener
        if ( component != null )
        {
            // Check value change
            final int newValue = component.getValue ();
            if ( newValue != value )
            {
                // Perform states update only for non-indeterminate progress bar
                if ( !component.isIndeterminate () )
                {
                    // Update decoration on border value changes
                    final int min = component.getMinimum ();
                    final int max = component.getMaximum ();
                    if ( value == min || value == max || newValue == min || newValue == max )
                    {
                        updateDecorationState ();
                    }
                }

                // Save current value
                value = newValue;
            }
        }
    }

    @NotNull
    @Override
    public List getDecorationStates ()
    {
        final List states = super.getDecorationStates ();
        states.add ( isHorizontal () ? DecorationState.horizontal : DecorationState.vertical );
        states.add ( component.isIndeterminate () ? DecorationState.indeterminate : DecorationState.progress );
        if ( !component.isIndeterminate () )
        {
            final boolean min = component.getValue () == component.getMinimum ();
            final boolean max = component.getValue () == component.getMaximum ();
            if ( min )
            {
                states.add ( DecorationState.minimum );
            }
            if ( max )
            {
                states.add ( DecorationState.maximum );
            }
            if ( !min && !max )
            {
                states.add ( DecorationState.intermediate );
            }
        }
        return states;
    }

    @Override
    protected void paintContent ( @NotNull final Graphics2D g2d, @NotNull final C c, @NotNull final U ui, @NotNull final Rectangle bounds )
    {
        // Painting progress line
        paintProgress ( g2d, BoundsType.border.bounds ( c ) );

        // Painting text
        paintText ( g2d, BoundsType.padding.bounds ( c ) );
    }

    /**
     * Paints progress line.
     *
     * @param g2d    graphics context
     * @param bounds painting bounds
     */
    protected void paintProgress ( @NotNull final Graphics2D g2d, @NotNull final Rectangle bounds )
    {
        if ( progressPainter != null )
        {
            paintSection ( progressPainter, g2d, bounds );
        }
    }

    /**
     * Paints progress bar text.
     *
     * @param g2d    graphics context
     * @param bounds painting bounds
     */
    protected void paintText ( @NotNull final Graphics2D g2d, @NotNull final Rectangle bounds )
    {
        if ( progressTextPainter != null && component.isStringPainted () )
        {
            // Painting progress text
            paintSection ( progressTextPainter, g2d, bounds );
        }
    }

    /**
     * Returns minimum content area size.
     *
     * @return minimum content area size
     */
    @NotNull
    protected Dimension getMinimumContentSize ()
    {
        final Dimension ms;
        if ( component != null && this.minimumContentSize != null )
        {
            final boolean hor = isHorizontal ();
            ms = new Dimension (
                    hor ? this.minimumContentSize.width : this.minimumContentSize.height,
                    hor ? this.minimumContentSize.height : this.minimumContentSize.width
            );
        }
        else
        {
            ms = new Dimension ();
        }
        return ms;
    }

    /**
     * Returns whether or not progress bar is horizontal.
     *
     * @return true if progress bar is horizontal, false otherwise
     */
    protected boolean isHorizontal ()
    {
        return component.getOrientation () == SwingConstants.HORIZONTAL;
    }

    @NotNull
    @Override
    public Dimension getPreferredSize ()
    {
        // Minimum size
        final Dimension min = getMinimumContentSize ();
        int w = min.width;
        int h = min.height;

        // Text size
        // todo Retrieve size from painter
        if ( component.isStringPainted () )
        {
            final boolean hor = isHorizontal ();
            final FontMetrics fontSizer = component.getFontMetrics ( component.getFont () );
            final String progString = component.getString ();
            final int stringWidth = SwingUtils.stringWidth ( fontSizer, progString );
            final int stringHeight = fontSizer.getHeight () + fontSizer.getDescent ();
            w = Math.max ( w, hor ? stringWidth : stringHeight );
            h = Math.max ( h, hor ? stringHeight : stringWidth );
        }

        // Final size
        final Insets border = component.getInsets ();
        return new Dimension ( border.left + w + border.right, border.top + h + border.bottom );
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy