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

com.alee.laf.scroll.WebScrollPaneUI Maven / Gradle / Ivy

There is a newer version: 1.2.14
Show newest version
/*
 * This file is part of WebLookAndFeel library.
 *
 * WebLookAndFeel library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * WebLookAndFeel library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with WebLookAndFeel library.  If not, see .
 */

package com.alee.laf.scroll;

import com.alee.global.StyleConstants;
import com.alee.laf.WebLookAndFeel;
import com.alee.managers.focus.DefaultFocusTracker;
import com.alee.managers.focus.FocusManager;
import com.alee.managers.focus.FocusTracker;
import com.alee.utils.LafUtils;
import com.alee.utils.SwingUtils;
import com.alee.utils.laf.ShapeProvider;

import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ScrollBarUI;
import javax.swing.plaf.basic.BasicScrollPaneUI;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

/**
 * User: mgarin Date: 29.04.11 Time: 15:34
 */

public class WebScrollPaneUI extends BasicScrollPaneUI implements ShapeProvider
{
    /**
     * todo 1. Implement optional shade layer
     */

    private boolean drawBorder = WebScrollPaneStyle.drawBorder;
    private Color borderColor = WebScrollPaneStyle.borderColor;
    private Color darkBorder = WebScrollPaneStyle.darkBorder;

    private int round = WebScrollPaneStyle.round;
    private int shadeWidth = WebScrollPaneStyle.shadeWidth;
    private Insets margin = WebScrollPaneStyle.margin;

    private boolean drawFocus = WebScrollPaneStyle.drawFocus;
    private boolean drawBackground = WebScrollPaneStyle.drawBackground;

    private WebScrollPaneCorner lowerTrailing;
    private WebScrollPaneCorner lowerLeading;
    private WebScrollPaneCorner upperTrailing;
    private PropertyChangeListener propertyChangeListener;

    /**
     * Scroll pane focus tracker.
     */
    protected FocusTracker focusTracker;

    private boolean focused = false;

    @SuppressWarnings ("UnusedParameters")
    public static ComponentUI createUI ( final JComponent c )
    {
        return new WebScrollPaneUI ();
    }

    @Override
    public void installUI ( final JComponent c )
    {
        super.installUI ( c );

        // Default settings
        SwingUtils.setOrientation ( scrollpane );
        LookAndFeel.installProperty ( scrollpane, WebLookAndFeel.OPAQUE_PROPERTY, Boolean.FALSE );
        scrollpane.setBackground ( StyleConstants.backgroundColor );

        // Updating scroll bars
        // todo Remove these when scroll pane painter will be completed
        final ScrollBarUI vui = scrollpane.getVerticalScrollBar ().getUI ();
        if ( vui instanceof WebScrollBarUI )
        {
            final WebScrollBarUI ui = ( WebScrollBarUI ) vui;
            ui.setPaintTrack ( drawBorder );
        }
        final ScrollBarUI hui = scrollpane.getHorizontalScrollBar ().getUI ();
        if ( hui instanceof WebScrollBarUI )
        {
            final WebScrollBarUI ui = ( WebScrollBarUI ) hui;
            ui.setPaintTrack ( drawBorder );
        }

        // Special
        LafUtils.setScrollBarStyleId ( scrollpane, "scroll-pane" );

        //        // Shade layer
        //        final WebPanel shadeLayer = new WebPanel ( new AbstractPainter ()
        //        {
        //            final int shadeWidth = 15;
        //            final float transparency = 0.7f;
        //
        //            @Override
        //            public void paint ( final Graphics2D g2d, final Rectangle bounds, final Component c )
        //            {
        //                final JViewport viewport = scrollpane.getViewport ();
        //                final Component vc = viewport.getView ();
        //                if ( vc != null && vc instanceof JComponent )
        //                {
        //                    final JComponent view = ( JComponent ) vc;
        //                    final Rectangle vr = view.getVisibleRect ();
        //
        //                    final int topY = vr.y;
        //                    if ( topY > 0 )
        //                    {
        //                        final float max = topY / 2;
        //                        final float opacity = ( shadeWidth < max ? 1f : ( 1f - ( shadeWidth - max ) / shadeWidth ) ) * transparency;
        //                        final NinePatchIcon npi = NinePatchUtils.getShadeIcon ( shadeWidth, 0, opacity );
        //                        final Dimension ps = npi.getPreferredSize ();
        //                        npi.paintIcon ( g2d, -shadeWidth * 2, shadeWidth - ps.height, vr.width + shadeWidth * 4, ps.height );
        //                    }
        //
        //                    final int bottomY = vr.y + vr.height;
        //                    final int height = view.getHeight ();
        //                    if ( bottomY < height )
        //                    {
        //                        final float max = ( height - bottomY ) / 2;
        //                        final float opacity = ( shadeWidth < max ? 1f : ( 1f - ( shadeWidth - max ) / shadeWidth ) ) * transparency;
        //                        final NinePatchIcon npi = NinePatchUtils.getShadeIcon ( shadeWidth, 0, opacity );
        //                        final Dimension ps = npi.getPreferredSize ();
        //                        npi.paintIcon ( g2d, -shadeWidth * 2, vr.height - shadeWidth, vr.width + shadeWidth * 4, ps.height );
        //                    }
        //                }
        //            }
        //        } );
        //        scrollpane.add ( shadeLayer, scrollpane.getComponentCount () );
        //        scrollpane.setLayout ( new WebScrollPaneLayout.UIResource ( shadeLayer ) );

        // Border
        updateBorder ();

        // Styled scroll pane corner
        scrollpane.setCorner ( JScrollPane.LOWER_LEADING_CORNER, getLowerLeadingCorner () );
        scrollpane.setCorner ( JScrollPane.LOWER_TRAILING_CORNER, getLowerTrailingCorner () );
        scrollpane.setCorner ( JScrollPane.UPPER_TRAILING_CORNER, getUpperTrailing () );
        propertyChangeListener = new PropertyChangeListener ()
        {
            @Override
            public void propertyChange ( final PropertyChangeEvent evt )
            {
                scrollpane.setCorner ( JScrollPane.LOWER_LEADING_CORNER, getLowerLeadingCorner () );
                scrollpane.setCorner ( JScrollPane.LOWER_TRAILING_CORNER, getLowerTrailingCorner () );
                scrollpane.setCorner ( JScrollPane.UPPER_TRAILING_CORNER, getUpperTrailing () );
            }
        };
        scrollpane.addPropertyChangeListener ( WebLookAndFeel.ORIENTATION_PROPERTY, propertyChangeListener );

        // Focus tracker for the scroll pane content
        focusTracker = new DefaultFocusTracker ()
        {
            @Override
            public boolean isTrackingEnabled ()
            {
                return drawBorder && drawFocus;
            }

            @Override
            public void focusChanged ( final boolean focused )
            {
                WebScrollPaneUI.this.focused = focused;
                scrollpane.repaint ();
            }
        };
        FocusManager.addFocusTracker ( scrollpane, focusTracker );
    }

    @Override
    public void uninstallUI ( final JComponent c )
    {
        scrollpane.removePropertyChangeListener ( WebLookAndFeel.ORIENTATION_PROPERTY, propertyChangeListener );
        scrollpane.remove ( getLowerLeadingCorner () );
        scrollpane.remove ( getLowerTrailingCorner () );
        scrollpane.remove ( getUpperTrailing () );

        FocusManager.removeFocusTracker ( focusTracker );

        super.uninstallUI ( c );
    }

    private WebScrollPaneCorner getLowerLeadingCorner ()
    {
        if ( lowerLeading == null )
        {
            lowerLeading = new WebScrollPaneCorner ( JScrollPane.LOWER_LEADING_CORNER );
        }
        return lowerLeading;
    }

    private WebScrollPaneCorner getLowerTrailingCorner ()
    {
        if ( lowerTrailing == null )
        {
            lowerTrailing = new WebScrollPaneCorner ( JScrollPane.LOWER_TRAILING_CORNER );
        }
        return lowerTrailing;
    }

    private WebScrollPaneCorner getUpperTrailing ()
    {
        if ( upperTrailing == null )
        {
            upperTrailing = new WebScrollPaneCorner ( JScrollPane.UPPER_TRAILING_CORNER );
        }
        return upperTrailing;
    }

    @Override
    public Shape provideShape ()
    {
        return LafUtils.getWebBorderShape ( scrollpane, getShadeWidth (), getRound () );
    }

    private void updateBorder ()
    {
        if ( scrollpane != null )
        {
            // Preserve old borders
            if ( SwingUtils.isPreserveBorders ( scrollpane ) )
            {
                return;
            }

            final Insets insets;
            if ( drawBorder )
            {
                insets = new Insets ( shadeWidth + 1 + margin.top, shadeWidth + 1 + margin.left, shadeWidth + 1 + margin.bottom,
                        shadeWidth + 1 + margin.right );
            }
            else
            {
                insets = new Insets ( margin.top, margin.left, margin.bottom, margin.right );
            }
            scrollpane.setBorder ( LafUtils.createWebBorder ( insets ) );
        }
    }

    public boolean isDrawBorder ()
    {
        return drawBorder;
    }

    public void setDrawBorder ( final boolean drawBorder )
    {
        this.drawBorder = drawBorder;
        updateBorder ();
    }

    public int getRound ()
    {
        return round;
    }

    public void setRound ( final int round )
    {
        this.round = round;
    }

    public int getShadeWidth ()
    {
        return shadeWidth;
    }

    public void setShadeWidth ( final int shadeWidth )
    {
        this.shadeWidth = shadeWidth;
        updateBorder ();
    }

    public Insets getMargin ()
    {
        return margin;
    }

    public void setMargin ( final Insets margin )
    {
        this.margin = margin;
        updateBorder ();
    }

    public boolean isDrawFocus ()
    {
        return drawFocus;
    }

    public void setDrawFocus ( final boolean drawFocus )
    {
        this.drawFocus = drawFocus;
    }

    public boolean isDrawBackground ()
    {
        return drawBackground;
    }

    public void setDrawBackground ( final boolean drawBackground )
    {
        this.drawBackground = drawBackground;
    }

    public Color getBorderColor ()
    {
        return borderColor;
    }

    public void setBorderColor ( final Color borderColor )
    {
        this.borderColor = borderColor;
    }

    public Color getDarkBorder ()
    {
        return darkBorder;
    }

    public void setDarkBorder ( final Color darkBorder )
    {
        this.darkBorder = darkBorder;
    }

    @Override
    public void paint ( final Graphics g, final JComponent c )
    {
        if ( drawBorder )
        {
            // Border, background and shade
            LafUtils.drawWebStyle ( ( Graphics2D ) g, c, drawFocus && focused ? StyleConstants.fieldFocusColor : StyleConstants.shadeColor,
                    shadeWidth, round, drawBackground, false );
        }

        super.paint ( g, c );
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy