Package com.alee.laf.tabbedpane

Source Code of com.alee.laf.tabbedpane.WebTabbedPaneUI

/*
* 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 <http://www.gnu.org/licenses/>.
*/

package com.alee.laf.tabbedpane;

import com.alee.extended.painter.Painter;
import com.alee.extended.painter.PainterSupport;
import com.alee.global.StyleConstants;
import com.alee.utils.GraphicsUtils;
import com.alee.utils.LafUtils;
import com.alee.utils.SwingUtils;
import com.alee.utils.laf.ShapeProvider;
import com.alee.utils.swing.BorderMethods;

import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import javax.swing.text.View;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.util.HashMap;
import java.util.Map;

/**
* User: mgarin Date: 27.04.11 Time: 18:39
*/

public class WebTabbedPaneUI extends BasicTabbedPaneUI implements ShapeProvider, BorderMethods
{
    private TabbedPaneStyle tabbedPaneStyle = WebTabbedPaneStyle.tabbedPaneStyle;

    private Color selectedTopBg = WebTabbedPaneStyle.selectedTopBg;
    private Color selectedBottomBg = WebTabbedPaneStyle.selectedBottomBg;
    private Color topBg = WebTabbedPaneStyle.topBg;
    private Color bottomBg = WebTabbedPaneStyle.bottomBg;
    private int round = WebTabbedPaneStyle.round;
    private int shadeWidth = WebTabbedPaneStyle.shadeWidth;
    private boolean rotateTabInsets = WebTabbedPaneStyle.rotateTabInsets;
    private Insets contentInsets = WebTabbedPaneStyle.contentInsets;
    private Insets tabInsets = WebTabbedPaneStyle.tabInsets;
    private Painter painter = WebTabbedPaneStyle.painter;
    private int tabRunIndent = WebTabbedPaneStyle.tabRunIndent;
    private int tabOverlay = WebTabbedPaneStyle.tabOverlay;
    private TabStretchType tabStretchType = WebTabbedPaneStyle.tabStretchType;

    private final Map<Integer, Color> selectedForegroundAt = new HashMap<Integer, Color> ();
    private final Map<Integer, Painter> backgroundPainterAt = new HashMap<Integer, Painter> ();

    private FocusAdapter focusAdapter;
    //    private MouseAdapter mouseAdapter;
    //    private int rolloverTab = -1;

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

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

        // Default settings
        SwingUtils.setOrientation ( tabPane );
        tabPane.setBackground ( StyleConstants.backgroundColor );
        PainterSupport.installPainter ( tabPane, this.painter );

        // Updating border
        updateBorder ();

        // Focus updater
        focusAdapter = new FocusAdapter ()
        {
            @Override
            public void focusGained ( final FocusEvent e )
            {
                tabPane.repaint ();
            }

            @Override
            public void focusLost ( final FocusEvent e )
            {
                tabPane.repaint ();
            }
        };
        tabPane.addFocusListener ( focusAdapter );

        //        mouseAdapter = new MouseAdapter ()
        //        {
        //            public void mouseEntered ( MouseEvent e )
        //            {
        //                updateRolloverTab ( e );
        //            }
        //
        //            public void mouseExited ( MouseEvent e )
        //            {
        //                updateRolloverTab ( e );
        //            }
        //
        //            public void mouseMoved ( MouseEvent e )
        //            {
        //                updateRolloverTab ( e );
        //            }
        //
        //            public void mouseDragged ( MouseEvent e )
        //            {
        //                updateRolloverTab ( e );
        //            }
        //        };
        //        c.addMouseListener ( mouseAdapter );
        //        c.addMouseMotionListener ( mouseAdapter );
    }

    @Override
    public void uninstallUI ( final JComponent c )
    {
        PainterSupport.uninstallPainter ( tabPane, this.painter );

        if ( focusAdapter != null )
        {
            c.removeFocusListener ( focusAdapter );
        }
        //        if ( mouseAdapter != null )
        //        {
        //            c.removeMouseListener ( mouseAdapter );
        //            c.removeMouseMotionListener ( mouseAdapter );
        //        }

        super.uninstallUI ( c );
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateBorder ()
    {
        if ( tabPane != null )
        {
            // Preserve old borders
            if ( SwingUtils.isPreserveBorders ( tabPane ) )
            {
                return;
            }

            final Insets bgInsets = getBackgroundInsets ( tabPane );
            if ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) )
            {
                // Standalone style border
                tabPane.setBorder ( LafUtils.createWebBorder (
                        SwingUtils.max ( bgInsets, new Insets ( shadeWidth, shadeWidth, shadeWidth, shadeWidth ) ) ) );
            }
            else
            {
                // Attached style border
                tabPane.setBorder ( LafUtils.createWebBorder ( bgInsets ) );
            }
        }
    }

    private Insets getBackgroundInsets ( final JComponent c )
    {
        return painter != null ? painter.getMargin ( c ) : new Insets ( 0, 0, 0, 0 );
    }

    public int getShadeWidth ()
    {
        return shadeWidth;
    }

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

    public boolean isRotateTabInsets ()
    {
        return rotateTabInsets;
    }

    public void setRotateTabInsets ( final boolean rotateTabInsets )
    {
        this.rotateTabInsets = rotateTabInsets;
    }

    public int getRound ()
    {
        return round;
    }

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

    public Insets getContentInsets ()
    {
        return contentInsets;
    }

    public void setContentInsets ( final Insets contentInsets )
    {
        this.contentInsets = contentInsets;
    }

    public Insets getTabInsets ()
    {
        return tabInsets;
    }

    public void setTabInsets ( final Insets tabInsets )
    {
        this.tabInsets = tabInsets;
    }

    public Color getSelectedTopBg ()
    {
        return selectedTopBg;
    }

    public void setSelectedTopBg ( final Color selectedTopBg )
    {
        this.selectedTopBg = selectedTopBg;
    }

    public Color getSelectedBottomBg ()
    {
        return selectedBottomBg;
    }

    public void setSelectedBottomBg ( final Color selectedBottomBg )
    {
        this.selectedBottomBg = selectedBottomBg;
    }

    public Color getTopBg ()
    {
        return topBg;
    }

    public void setTopBg ( final Color topBg )
    {
        this.topBg = topBg;
    }

    public Color getBottomBg ()
    {
        return bottomBg;
    }

    public void setBottomBg ( final Color bottomBg )
    {
        this.bottomBg = bottomBg;
    }

    public void setSelectedForegroundAt ( final int tabIndex, final Color foreground )
    {
        selectedForegroundAt.put ( tabIndex, foreground );
    }

    public Color getSelectedForegroundAt ( final int tabIndex )
    {
        return selectedForegroundAt.get ( tabIndex );
    }

    public void setBackgroundPainterAt ( final int tabIndex, final Painter painter )
    {
        backgroundPainterAt.put ( tabIndex, painter );
    }

    public Painter getBackgroundPainterAt ( final int tabIndex )
    {
        return backgroundPainterAt.get ( tabIndex );
    }

    public TabbedPaneStyle getTabbedPaneStyle ()
    {
        return tabbedPaneStyle;
    }

    public void setTabbedPaneStyle ( final TabbedPaneStyle tabbedPaneStyle )
    {
        this.tabbedPaneStyle = tabbedPaneStyle;
        updateBorder ();
    }

    //    private void updateRolloverTab ( MouseEvent e )
    //    {
    //        if ( tabPane != null )
    //        {
    //            int old = rolloverTab;
    //            rolloverTab = tabForCoordinate ( tabPane, e.getX (), e.getY () );
    //            if ( old != rolloverTab )
    //            {
    //                tabPane.repaint ();
    //            }
    //        }
    //    }

    public Painter getPainter ()
    {
        return painter;
    }

    public void setPainter ( final Painter painter )
    {
        PainterSupport.uninstallPainter ( tabPane, this.painter );

        this.painter = painter;
        PainterSupport.installPainter ( tabPane, this.painter );
        updateBorder ();
    }

    public int getTabRunIndent ()
    {
        return tabRunIndent;
    }

    public void setTabRunIndent ( final int tabRunIndent )
    {
        this.tabRunIndent = tabRunIndent;
    }

    public int getTabOverlay ()
    {
        return tabOverlay;
    }

    public void setTabOverlay ( final int tabOverlay )
    {
        this.tabOverlay = tabOverlay;
    }

    public TabStretchType getTabStretchType ()
    {
        return tabStretchType;
    }

    public void setTabStretchType ( final TabStretchType tabStretchType )
    {
        this.tabStretchType = tabStretchType;
    }

    @Override
    protected int getTabRunIndent ( final int tabPlacement, final int run )
    {
        return tabRunIndent;
    }

    @Override
    protected int getTabRunOverlay ( final int tabPlacement )
    {
        return tabOverlay;
    }

    @Override
    protected boolean shouldPadTabRun ( final int tabPlacement, final int run )
    {
        return !tabStretchType.equals ( TabStretchType.never ) &&
                ( tabStretchType.equals ( TabStretchType.always ) || tabStretchType.equals ( TabStretchType.multiline ) && runCount > 1 );
    }

    @Override
    protected boolean shouldRotateTabRuns ( final int tabPlacement )
    {
        // todo Requires style changes
        return true;
    }

    @Override
    protected Insets getContentBorderInsets ( final int tabPlacement )
    {
        if ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) )
        {
            final Insets insets;
            if ( tabPlacement == JTabbedPane.TOP )
            {
                insets = new Insets ( 1, 2, 1, 2 );
            }
            else if ( tabPlacement == JTabbedPane.BOTTOM )
            {
                insets = new Insets ( 2, 2, 0, 2 );
            }
            else if ( tabPlacement == JTabbedPane.LEFT )
            {
                insets = new Insets ( 2, 1, 2, 1 );
            }
            else if ( tabPlacement == JTabbedPane.RIGHT )
            {
                insets = new Insets ( 2, 2, 2, 0 );
            }
            else
            {
                insets = new Insets ( 0, 0, 0, 0 );
            }
            insets.top += contentInsets.top - 1;
            insets.left += contentInsets.left - 1;
            insets.bottom += contentInsets.bottom - 1;
            insets.right += contentInsets.right - 1;
            return insets;
        }
        else
        {
            return new Insets ( 0, 0, 0, 0 );
        }
    }

    @Override
    protected Insets getTabAreaInsets ( final int tabPlacement )
    {
        final Insets targetInsets = new Insets ( 0, 0, 0, 0 );
        rotateInsets ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) ? new Insets ( tabPlacement == RIGHT ? 1 : 0, 1, 0, 2 ) :
                new Insets ( -1, -1, 0, 0 ), targetInsets, tabPlacement );
        return targetInsets;
    }

    @Override
    protected Insets getTabInsets ( final int tabPlacement, final int tabIndex )
    {
        final Insets insets = SwingUtils.copy ( tabInsets );
        if ( tabIndex == 0 && tabPane.getSelectedIndex () == 0 )
        {
            // Fix for 1st element
            insets.left -= 1;
            insets.right += 1;
        }
        if ( rotateTabInsets )
        {
            final Insets targetInsets = new Insets ( 0, 0, 0, 0 );
            rotateInsets ( insets, targetInsets, tabPlacement );
            return targetInsets;
        }
        else
        {
            return insets;
        }
    }

    @Override
    protected Insets getSelectedTabPadInsets ( final int tabPlacement )
    {
        final Insets targetInsets = new Insets ( 0, 0, 0, 0 );
        rotateInsets ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) ? new Insets ( 2, 2, 2, 1 ) : new Insets ( 0, 0, 0, 0 ),
                targetInsets, tabPlacement );
        return targetInsets;
    }

    @Override
    protected int getTabLabelShiftX ( final int tabPlacement, final int tabIndex, final boolean isSelected )
    {
        if ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) )
        {
            return super.getTabLabelShiftX ( tabPlacement, tabIndex, isSelected );
        }
        else
        {
            return 0;
        }
    }

    @Override
    protected int getTabLabelShiftY ( final int tabPlacement, final int tabIndex, final boolean isSelected )
    {
        if ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) )
        {
            return super.getTabLabelShiftY ( tabPlacement, tabIndex, isSelected );
        }
        else
        {
            return 0;
        }
    }

    @Override
    protected void paintTabBorder ( final Graphics g, final int tabPlacement, final int tabIndex, final int x, final int y, final int w,
                                    final int h, final boolean isSelected )
    {
        // We don't need this one
    }

    @Override
    protected void paintTabBackground ( final Graphics g, final int tabPlacement, final int tabIndex, final int x, final int y, final int w,
                                        final int h, final boolean isSelected )
    {
        final Graphics2D g2d = ( Graphics2D ) g;
        final Object aa = GraphicsUtils.setupAntialias ( g2d );

        // Border shape
        final GeneralPath borderShape = createTabShape ( TabShapeType.border, tabPlacement, x, y, w, h, isSelected );

        // Tab shade
        if ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) )
        {
            final GeneralPath shadeShape = createTabShape ( TabShapeType.shade, tabPlacement, x, y, w, h, isSelected );
            GraphicsUtils.drawShade ( g2d, shadeShape, StyleConstants.shadeColor, shadeWidth,
                    new Rectangle2D.Double ( 0, 0, tabPane.getWidth (), y + h ), round > 0 );
        }

        // Tab background
        final GeneralPath bgShape = createTabShape ( TabShapeType.background, tabPlacement, x, y, w, h, isSelected );
        if ( backgroundPainterAt.containsKey ( tabIndex ) && isSelected )
        {
            final Shape old = GraphicsUtils.intersectClip ( g2d, bgShape );
            final Painter bp = backgroundPainterAt.get ( tabIndex );
            bp.paint ( g2d, new Rectangle ( x, y, w, h ), tabPane );
            GraphicsUtils.restoreClip ( g2d, old );
        }
        else
        {
            final Point topPoint = getTopTabBgPoint ( tabPlacement, x, y, w, h );
            final Point bottomPoint = getBottomTabBgPoint ( tabPlacement, x, y, w, h );
            if ( isSelected )
            {
                Color bg = tabPane.getBackgroundAt ( tabIndex );
                bg = bg != null ? bg : tabPane.getBackground ();
                g2d.setPaint ( new GradientPaint ( topPoint.x, topPoint.y, selectedTopBg, bottomPoint.x, bottomPoint.y, bg ) );
            }
            else
            {
                g2d.setPaint ( new GradientPaint ( topPoint.x, topPoint.y, topBg, bottomPoint.x, bottomPoint.y, bottomBg ) );
            }
            g2d.fill ( isSelected ? borderShape : bgShape );
        }

        // Tab border
        g2d.setPaint ( StyleConstants.darkBorderColor );
        g2d.draw ( borderShape );

        // Tab focus
        final boolean drawFocus = isSelected && tabPane.isFocusOwner ();
        if ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) )
        {
            LafUtils.drawCustomWebFocus ( g2d, null, StyleConstants.focusType, borderShape, null, drawFocus );
        }
        //        else if ( drawFocus )
        //        {
        //            g2d.setPaint ( StyleConstants.fieldFocusColor );
        //            g2d.drawLine ( x, y + 1, x + w, y + 1 );
        //        }

        //todo Paint selected tab together with area

        GraphicsUtils.restoreAntialias ( g2d, aa );
    }

    @Override
    protected void paintText ( final Graphics g, final int tabPlacement, final Font font, final FontMetrics metrics, final int tabIndex,
                               final String title, final Rectangle textRect, final boolean isSelected )
    {
        g.setFont ( font );
        final View v = getTextViewForTab ( tabIndex );
        if ( v != null )
        {
            // html
            v.paint ( g, textRect );
        }
        else
        {
            // plain text
            final int mnemIndex = tabPane.getDisplayedMnemonicIndexAt ( tabIndex );

            if ( tabPane.isEnabled () && tabPane.isEnabledAt ( tabIndex ) )
            {
                Color fg = tabPane.getForegroundAt ( tabIndex );
                if ( isSelected && ( fg instanceof UIResource ) )
                {
                    if ( selectedForegroundAt.containsKey ( tabIndex ) )
                    {
                        fg = selectedForegroundAt.get ( tabIndex );
                    }
                    else
                    {
                        final Color selectedFG = UIManager.getColor ( "TabbedPane.selectedForeground" );
                        if ( selectedFG != null )
                        {
                            fg = selectedFG;
                        }
                    }
                }
                g.setColor ( fg );
                SwingUtils.drawStringUnderlineCharAt ( g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent () );

            }
            else
            {
                // tab disabled
                g.setColor ( tabPane.getBackgroundAt ( tabIndex ).brighter () );
                SwingUtils.drawStringUnderlineCharAt ( g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent () );
                g.setColor ( tabPane.getBackgroundAt ( tabIndex ).darker () );
                SwingUtils.drawStringUnderlineCharAt ( g, title, mnemIndex, textRect.x - 1, textRect.y + metrics.getAscent () - 1 );
            }
        }
    }

    private GeneralPath createTabShape ( final TabShapeType tabShapeType, final int tabPlacement, int x, final int y, int w, final int h,
                                         final boolean isSelected )
    {
        // Fix for basic layouting of selected left-sided tab x coordinate
        final Insets insets = tabPane.getInsets ();
        if ( tabbedPaneStyle.equals ( TabbedPaneStyle.attached ) && isSelected )
        {
            // todo fix for other tabPlacement values aswell
            if ( tabPlacement == TOP && x == insets.left )
            {
                x = x - 1;
                w = w + 1;
            }
        }

        final int actualRound = tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) ? round : 0;
        final GeneralPath bgShape = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
        if ( tabPlacement == JTabbedPane.TOP )
        {
            bgShape.moveTo ( x, y + h + getChange ( tabShapeType ) );
            bgShape.lineTo ( x, y + actualRound );
            bgShape.quadTo ( x, y, x + actualRound, y );
            bgShape.lineTo ( x + w - actualRound, y );
            bgShape.quadTo ( x + w, y, x + w, y + actualRound );
            bgShape.lineTo ( x + w, y + h + getChange ( tabShapeType ) );
        }
        else if ( tabPlacement == JTabbedPane.BOTTOM )
        {
            bgShape.moveTo ( x, y - getChange ( tabShapeType ) );
            bgShape.lineTo ( x, y + h - actualRound );
            bgShape.quadTo ( x, y + h, x + actualRound, y + h );
            bgShape.lineTo ( x + w - actualRound, y + h );
            bgShape.quadTo ( x + w, y + h, x + w, y + h - actualRound );
            bgShape.lineTo ( x + w, y - getChange ( tabShapeType ) );
        }
        else if ( tabPlacement == JTabbedPane.LEFT )
        {
            bgShape.moveTo ( x + w + getChange ( tabShapeType ), y );
            bgShape.lineTo ( x + actualRound, y );
            bgShape.quadTo ( x, y, x, y + actualRound );
            bgShape.lineTo ( x, y + h - actualRound );
            bgShape.quadTo ( x, y + h, x + actualRound, y + h );
            bgShape.lineTo ( x + w + getChange ( tabShapeType ), y + h );
        }
        else
        {
            bgShape.moveTo ( x - getChange ( tabShapeType ), y );
            bgShape.lineTo ( x + w - actualRound, y );
            bgShape.quadTo ( x + w, y, x + w, y + actualRound );
            bgShape.lineTo ( x + w, y + h - actualRound );
            bgShape.quadTo ( x + w, y + h, x + w - actualRound, y + h );
            bgShape.lineTo ( x - getChange ( tabShapeType ), y + h );
        }
        return bgShape;
    }

    private int getChange ( final TabShapeType tabShapeType )
    {
        if ( tabShapeType.equals ( TabShapeType.shade ) )
        {
            return -( round > 0 ? round : 1 );
        }
        else if ( tabShapeType.equals ( TabShapeType.border ) )
        {
            return -1;
        }
        else if ( tabShapeType.equals ( TabShapeType.backgroundPainter ) )
        {
            return 2;
        }
        else
        {
            return 0;
        }
    }

    private enum TabShapeType
    {
        shade,
        background,
        backgroundPainter,
        border
    }

    private Point getTopTabBgPoint ( final int tabPlacement, final int x, final int y, final int w, final int h )
    {
        if ( tabPlacement == JTabbedPane.TOP )
        {
            return new Point ( x, y );
        }
        else if ( tabPlacement == JTabbedPane.BOTTOM )
        {
            return new Point ( x, y + h );
        }
        else if ( tabPlacement == JTabbedPane.LEFT )
        {
            return new Point ( x, y );
        }
        else
        {
            return new Point ( x + w, y );
        }
    }

    private Point getBottomTabBgPoint ( final int tabPlacement, final int x, final int y, final int w, final int h )
    {
        if ( tabPlacement == JTabbedPane.TOP )
        {
            return new Point ( x, y + h - 4 );
        }
        else if ( tabPlacement == JTabbedPane.BOTTOM )
        {
            return new Point ( x, y + 4 );
        }
        else if ( tabPlacement == JTabbedPane.LEFT )
        {
            return new Point ( x + w - 4, y );
        }
        else
        {
            return new Point ( x + 4, y );
        }
    }

    @Override
    protected void paintContentBorder ( final Graphics g, final int tabPlacement, final int selectedIndex )
    {
        final Graphics2D g2d = ( Graphics2D ) g;
        final Object aa = GraphicsUtils.setupAntialias ( g2d );

        final int tabAreaSize = getTabAreaLength ( tabPlacement );

        final Insets bi = tabPane.getInsets ();
        if ( tabPlacement == JTabbedPane.TOP || tabPlacement == JTabbedPane.BOTTOM )
        {
            bi.right += 1;
        }
        else
        {
            bi.bottom += 1;
        }

        // Selected tab bounds
        final Rectangle selected = selectedIndex != -1 ? getTabBounds ( tabPane, selectedIndex ) : null;

        // Background shape
        final Shape bs = createBackgroundShape ( tabPlacement, tabAreaSize, bi, selected );

        if ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) )
        {
            // Proper clip
            final GeneralPath clip = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
            clip.append ( new Rectangle2D.Double ( 0, 0, tabPane.getWidth (), tabPane.getHeight () ), false );
            clip.append ( bs, false );
            GraphicsUtils.drawShade ( g2d, bs, StyleConstants.shadeColor, shadeWidth, clip, round > 0 );

            //            // Corners covering for large round
            //            if ( round > 2 )
            //            {
            //                Insets tai = getTabAreaInsets ( tabPlacement );
            //                if ( tabPlacement == TOP )
            //                {
            //                    if ( selected.x > bi.left )
            //                    {
            //                        g2d.setPaint ( bottomBg );
            //                        g2d.fillRect ( bi.left + tai.left, bi.top + tabAreaSize, round, round );
            //
            //                        g2d.setPaint ( StyleConstants.darkBorderColor );
            //                        g2d.drawLine ( bi.left + tai.left, bi.top + tabAreaSize, bi.left + tai.left,
            //                                bi.top + tabAreaSize + round );
            //                    }
            ////                    if ( selected.x + selected.width < tabPane.getWidth () - bi.right )
            ////                    {
            ////                        g2d.setPaint ( bottomBg );
            ////                        g2d.fillRect ( bi.rightbi.left + tai.left, bi.top + tabAreaSize, round, round );
            ////
            ////                        g2d.setPaint ( StyleConstants.darkBorderColor );
            ////                        g2d.drawLine ( bi.left + tai.left, bi.top + tabAreaSize, bi.left + tai.left,
            ////                                bi.top + tabAreaSize + round );
            ////                    }
            //                }
            //            }

            // Area background
            if ( backgroundPainterAt.containsKey ( selectedIndex ) )
            {
                final Shape old = GraphicsUtils.intersectClip ( g2d, bs );
                backgroundPainterAt.get ( selectedIndex ).paint ( g2d, bs.getBounds (), tabPane );
                GraphicsUtils.restoreClip ( g2d, old );
            }
            else
            {
                final Color bg = selectedIndex != -1 ? tabPane.getBackgroundAt ( selectedIndex ) : null;
                g2d.setPaint ( bg != null ? bg : tabPane.getBackground () );
                g2d.fill ( bs );
            }

            // Area border
            g2d.setPaint ( StyleConstants.darkBorderColor );
            g2d.draw ( bs );

            // Area focus
            LafUtils.drawCustomWebFocus ( g2d, null, StyleConstants.focusType, bs, null, tabPane.isFocusOwner () );
        }
        else
        {
            // Area background
            if ( backgroundPainterAt.containsKey ( selectedIndex ) )
            {
                backgroundPainterAt.get ( selectedIndex ).paint ( g2d, bs.getBounds (), tabPane );
            }
            else
            {
                final Color bg = selectedIndex != -1 ? tabPane.getBackgroundAt ( selectedIndex ) : null;
                g2d.setPaint ( bg != null ? bg : tabPane.getBackground () );
                g2d.fill ( bs );
            }

            // todo draw for other tabPlacement values aswell
            // Area border
            g2d.setPaint ( Color.GRAY );
            if ( tabPlacement == JTabbedPane.TOP )
            {
                if ( selected != null )
                {
                    if ( bi.left < selected.x )
                    {
                        g2d.drawLine ( bi.left, bi.top + tabAreaSize, selected.x, bi.top + tabAreaSize );
                    }
                    if ( selected.x + selected.width < tabPane.getWidth () - bi.right )
                    {
                        g2d.drawLine ( selected.x + selected.width, bi.top + tabAreaSize, tabPane.getWidth () - bi.right,
                                bi.top + tabAreaSize );
                    }
                }
                else
                {
                    g2d.drawLine ( bi.left, bi.top + tabAreaSize, tabPane.getWidth () - bi.right, bi.top + tabAreaSize );
                }
            }
            //            else if ( tabPlacement == JTabbedPane.BOTTOM )
            //            {
            //                //
            //            }
            //            else if ( tabPlacement == JTabbedPane.LEFT )
            //            {
            //                //
            //            }
            //            else if ( tabPlacement == JTabbedPane.RIGHT )
            //            {
            //                //
            //            }
        }

        GraphicsUtils.restoreAntialias ( g2d, aa );
    }

    public int getTabAreaLength ( final int tabPlacement )
    {
        return tabPlacement == JTabbedPane.TOP || tabPlacement == JTabbedPane.BOTTOM ?
                calculateTabAreaHeight ( tabPlacement, runCount, maxTabHeight ) - 1 :
                calculateTabAreaWidth ( tabPlacement, runCount, maxTabWidth ) - 1;
    }

    private Shape createBackgroundShape ( final int tabPlacement, final int tabAreaSize, final Insets bi, final Rectangle selected )
    {
        if ( tabbedPaneStyle.equals ( TabbedPaneStyle.standalone ) )
        {
            if ( selected != null )
            {
                final GeneralPath gp = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
                if ( tabPlacement == JTabbedPane.TOP )
                {
                    final int topY = bi.top + tabAreaSize;
                    gp.moveTo ( selected.x, topY );
                    if ( selected.x > bi.left + round && round > 0 )
                    {
                        gp.lineTo ( bi.left + round, topY );
                        gp.quadTo ( bi.left, topY, bi.left, topY + round );
                    }
                    else
                    {
                        gp.lineTo ( bi.left, topY );
                    }
                    if ( round > 0 )
                    {
                        gp.lineTo ( bi.left, tabPane.getHeight () - bi.bottom - round );
                        gp.quadTo ( bi.left, tabPane.getHeight () - bi.bottom, bi.left + round, tabPane.getHeight () - bi.bottom );
                        gp.lineTo ( tabPane.getWidth () - bi.right - round, tabPane.getHeight () - bi.bottom );
                        gp.quadTo ( tabPane.getWidth () - bi.right, tabPane.getHeight () - bi.bottom, tabPane.getWidth () - bi.right,
                                tabPane.getHeight () - bi.bottom - round );
                    }
                    else
                    {
                        gp.lineTo ( bi.left, tabPane.getHeight () - bi.bottom );
                        gp.lineTo ( tabPane.getWidth () - bi.right, tabPane.getHeight () - bi.bottom );
                    }
                    if ( selected.x + selected.width < tabPane.getWidth () - bi.right - round && round > 0 )
                    {
                        gp.lineTo ( tabPane.getWidth () - bi.right, topY + round );
                        gp.quadTo ( tabPane.getWidth () - bi.right, topY, tabPane.getWidth () - bi.right - round, topY );
                    }
                    else
                    {
                        gp.lineTo ( tabPane.getWidth () - bi.right, topY );
                    }
                    gp.lineTo ( selected.x + selected.width, topY );
                }
                else if ( tabPlacement == JTabbedPane.BOTTOM )
                {
                    final int bottomY = tabPane.getHeight () - bi.bottom - tabAreaSize;
                    gp.moveTo ( selected.x, bottomY );
                    if ( selected.x > bi.left + round && round > 0 )
                    {
                        gp.lineTo ( bi.left + round, bottomY );
                        gp.quadTo ( bi.left, bottomY, bi.left, bottomY - round );
                    }
                    else
                    {
                        gp.lineTo ( bi.left, bottomY );
                    }
                    if ( round > 0 )
                    {
                        gp.lineTo ( bi.left, bi.top + round );
                        gp.quadTo ( bi.left, bi.top, bi.left + round, bi.top );
                        gp.lineTo ( tabPane.getWidth () - bi.right - round, bi.top );
                        gp.quadTo ( tabPane.getWidth () - bi.right, bi.top, tabPane.getWidth () - bi.right, bi.top + round );
                    }
                    else
                    {
                        gp.lineTo ( bi.left, bi.top );
                        gp.lineTo ( tabPane.getWidth () - bi.right, bi.top );
                    }
                    if ( selected.x + selected.width < tabPane.getWidth () - bi.right - round && round > 0 )
                    {
                        gp.lineTo ( tabPane.getWidth () - bi.right, bottomY - round );
                        gp.quadTo ( tabPane.getWidth () - bi.right, bottomY, tabPane.getWidth () - bi.right - round, bottomY );
                    }
                    else
                    {
                        gp.lineTo ( tabPane.getWidth () - bi.right, bottomY );
                    }
                    gp.lineTo ( selected.x + selected.width, bottomY );
                }
                else if ( tabPlacement == JTabbedPane.LEFT )
                {
                    final int leftX = bi.left + tabAreaSize;
                    gp.moveTo ( leftX, selected.y );
                    if ( selected.y > bi.top + round && round > 0 )
                    {
                        gp.lineTo ( leftX, bi.top + round );
                        gp.quadTo ( leftX, bi.top, leftX + round, bi.top );
                    }
                    else
                    {
                        gp.lineTo ( leftX, bi.top );
                    }
                    if ( round > 0 )
                    {
                        gp.lineTo ( tabPane.getWidth () - bi.right - round, bi.top );
                        gp.quadTo ( tabPane.getWidth () - bi.right, bi.top, tabPane.getWidth () - bi.right, bi.top + round );
                        gp.lineTo ( tabPane.getWidth () - bi.right, tabPane.getHeight () - bi.bottom - round );
                        gp.quadTo ( tabPane.getWidth () - bi.right, tabPane.getHeight () - bi.bottom,
                                tabPane.getWidth () - bi.right - round, tabPane.getHeight () - bi.bottom );
                    }
                    else
                    {
                        gp.lineTo ( tabPane.getWidth () - bi.right, bi.top );
                        gp.lineTo ( tabPane.getWidth () - bi.right, tabPane.getHeight () - bi.bottom );
                    }
                    if ( selected.y + selected.height < tabPane.getHeight () - bi.bottom - round && round > 0 )
                    {
                        gp.lineTo ( leftX + round, tabPane.getHeight () - bi.bottom );
                        gp.quadTo ( leftX, tabPane.getHeight () - bi.bottom, leftX, tabPane.getHeight () - bi.bottom - round );
                    }
                    else
                    {
                        gp.lineTo ( leftX, tabPane.getHeight () - bi.bottom );
                    }
                    gp.lineTo ( leftX, selected.y + selected.height );
                }
                else
                {
                    final int rightX = tabPane.getWidth () - bi.right - tabAreaSize;
                    gp.moveTo ( rightX, selected.y );
                    if ( selected.y > bi.top + round && round > 0 )
                    {
                        gp.lineTo ( rightX, bi.top + round );
                        gp.quadTo ( rightX, bi.top, rightX - round, bi.top );
                    }
                    else
                    {
                        gp.lineTo ( rightX, bi.top );
                    }
                    if ( round > 0 )
                    {
                        gp.lineTo ( bi.left + round, bi.top );
                        gp.quadTo ( bi.left, bi.top, bi.left, bi.top + round );
                        gp.lineTo ( bi.left, tabPane.getHeight () - bi.bottom - round );
                        gp.quadTo ( bi.left, tabPane.getHeight () - bi.bottom, bi.left + round, tabPane.getHeight () - bi.bottom );
                    }
                    else
                    {
                        gp.lineTo ( bi.left, bi.top );
                        gp.lineTo ( bi.left, tabPane.getHeight () - bi.bottom );
                    }
                    if ( selected.y + selected.height < tabPane.getHeight () - bi.bottom - round && round > 0 )
                    {
                        gp.lineTo ( rightX - round, tabPane.getHeight () - bi.bottom );
                        gp.quadTo ( rightX, tabPane.getHeight () - bi.bottom, rightX, tabPane.getHeight () - bi.bottom - round );
                    }
                    else
                    {
                        gp.lineTo ( rightX, tabPane.getHeight () - bi.bottom );
                    }
                    gp.lineTo ( rightX, selected.y + selected.height );
                }
                return gp;
            }
            else
            {
                final boolean top = tabPlacement == JTabbedPane.TOP;
                final boolean bottom = tabPlacement == JTabbedPane.BOTTOM;
                final boolean left = tabPlacement == JTabbedPane.LEFT;
                final boolean right = tabPlacement == JTabbedPane.RIGHT;
                return new RoundRectangle2D.Double ( bi.left + ( left ? tabAreaSize : 0 ), bi.top + ( top ? tabAreaSize : 0 ),
                        tabPane.getWidth () - bi.left - bi.right -
                                ( left || right ? tabAreaSize : 0 ), tabPane.getHeight () - bi.top - bi.bottom -
                        ( top || bottom ? tabAreaSize : 0 ), round * 2, round * 2
                );
            }
        }
        else
        {
            final int x = bi.left + ( tabPlacement == JTabbedPane.LEFT ? tabAreaSize : 0 );
            final int y = bi.top + ( tabPlacement == JTabbedPane.TOP ? tabAreaSize : 0 );
            final int width = tabPane.getWidth () - bi.left - bi.right -
                    ( tabPlacement == JTabbedPane.LEFT || tabPlacement == JTabbedPane.RIGHT ? tabAreaSize : 0 );
            final int height = tabPane.getHeight () - bi.top - bi.bottom -
                    ( tabPlacement == JTabbedPane.TOP || tabPlacement == JTabbedPane.BOTTOM ? tabAreaSize : 0 );
            return new Rectangle ( x, y, width + 1, height );
        }
    }

    public Shape getContentClip ()
    {
        Shape clip = null;

        final int tabPlacement = tabPane.getTabPlacement ();
        final int tabAreaLength = getTabAreaLength ( tabPlacement );
        final Insets insets = tabPane.getInsets ();

        if ( tabPlacement == JTabbedPane.TOP )
        {
            clip = new RoundRectangle2D.Double ( insets.left, insets.top + tabAreaLength, tabPane.getWidth () - insets.left - insets.right,
                    tabPane.getHeight () - insets.top - tabAreaLength - insets.bottom, round * 2, round * 2 );
        }
        else if ( tabPlacement == JTabbedPane.BOTTOM )
        {
            clip = new RoundRectangle2D.Double ( insets.left, insets.top, tabPane.getWidth () - insets.left - insets.right,
                    tabPane.getHeight () - insets.top - tabAreaLength - insets.bottom, round * 2, round * 2 );
        }
        else if ( tabPlacement == JTabbedPane.LEFT )
        {
            clip = new RoundRectangle2D.Double ( insets.left + tabAreaLength, insets.top,
                    tabPane.getWidth () - insets.left - tabAreaLength - insets.right, tabPane.getHeight () - insets.top - insets.bottom,
                    round * 2, round * 2 );
        }
        else if ( tabPlacement == JTabbedPane.RIGHT )
        {
            clip = new RoundRectangle2D.Double ( insets.left, insets.top, tabPane.getWidth () - insets.left - tabAreaLength - insets.right,
                    tabPane.getHeight () - insets.top - insets.bottom, round * 2, round * 2 );
        }

        return clip;
    }

    @Override
    protected void paintFocusIndicator ( final Graphics g, final int tabPlacement, final Rectangle[] rects, final int tabIndex,
                                         final Rectangle iconRect, final Rectangle textRect, final boolean isSelected )
    {
        // We don't need this one
    }

    @Override
    public void paint ( final Graphics g, final JComponent c )
    {
        // Background painter
        if ( painter != null )
        {
            painter.paint ( ( Graphics2D ) g, SwingUtils.size ( c ), c );
        }

        // Basic paintings
        final Map hints = SwingUtils.setupTextAntialias ( g );
        super.paint ( g, c );
        SwingUtils.restoreTextAntialias ( g, hints );
    }

    //    protected void setRolloverTab ( int index )
    //    {
    //        super.setRolloverTab ( index );
    //
    //        // todo Animate rollover
    //    }

    //    public Dimension getPreferredSize ( JComponent c )
    //    {
    //        if ( tabPane.getTabPlacement () == JTabbedPane.TOP ||
    //                tabPane.getTabPlacement () == JTabbedPane.BOTTOM )
    //        {
    //            getTab
    //        }else {
    //
    //        }
    //    }

    //    protected LayoutManager createLayoutManager ()
    //    {
    //        return new TabbedPaneLayout ();
    //    }
    //
    //    public class TabbedPaneLayout extends BasicTabbedPaneUI.TabbedPaneLayout
    //    {
    //
    //        public TabbedPaneLayout ()
    //        {
    //            WebTabbedPaneUI.this.super ();
    //        }
    //
    //        protected void normalizeTabRuns ( int tabPlacement, int tabCount, int start, int max )
    //        {
    //            // Only normalize the runs for top & bottom;  normalizing
    //            // doesn't look right for Metal's vertical tabs
    //            // because the last run isn't padded and it looks odd to have
    //            // fat tabs in the first vertical runs, but slimmer ones in the
    //            // last (this effect isn't noticeable for horizontal tabs).
    //            if ( tabPlacement == TOP || tabPlacement == BOTTOM )
    //            {
    //                super.normalizeTabRuns ( tabPlacement, tabCount, start, max );
    //            }
    //        }
    //
    //        // Don't rotate runs!
    //        protected void rotateTabRuns ( int tabPlacement, int selectedRun )
    //        {
    //        }
    //
    //        // Don't pad selected tab
    //        protected void padSelectedTab ( int tabPlacement, int selectedIndex )
    //        {
    //        }
    //    }

    //    public static void main ( String[] args )
    //    {
    //        new TestFrame ( new WebTabbedPane (  ){
    //            {
    //                getWebUI ().setTabbedPaneStyle ( TabbedPaneStyle.attached );
    //                addTab ( "Tab 1", new WebTabbedPane (  ){
    //                    {
    //                        setTabPlacement ( LEFT );
    //                        getWebUI ().setTabbedPaneStyle ( TabbedPaneStyle.attached );
    //                        addTab ( "Tab 1", new JLabel (  ) );
    //                        addTab ( "Tab 2", new JLabel (  ) );
    //                        addTab ( "Tab 3", new JLabel (  ) );
    //                        addTab ( "Tab 4", new JLabel (  ) );
    //                    }
    //                } );
    //                addTab ( "Tab 2",  new WebTabbedPane (  ){
    //                    {
    //                        setTabPlacement ( RIGHT );
    //                        getWebUI ().setTabbedPaneStyle ( TabbedPaneStyle.attached );
    //                        addTab ( "Tab 1", new JLabel (  ) );
    //                        addTab ( "Tab 2", new JLabel (  ) );
    //                        addTab ( "Tab 3", new JLabel (  ) );
    //                        addTab ( "Tab 4", new JLabel (  ) );
    //                    }
    //                } );
    //                addTab ( "Tab 3",  new WebTabbedPane (  ){
    //                    {
    //                        setTabPlacement ( BOTTOM );
    //                        getWebUI ().setTabbedPaneStyle ( TabbedPaneStyle.attached );
    //                        addTab ( "Tab 1", new JLabel (  ) );
    //                        addTab ( "Tab 2", new JLabel (  ) );
    //                        addTab ( "Tab 3", new JLabel (  ) );
    //                        addTab ( "Tab 4", new JLabel (  ) );
    //                    }
    //                } );
    //                addTab ( "Tab 4", new JLabel (  ) );
    //            }
    //        });
    //    }
}
TOP

Related Classes of com.alee.laf.tabbedpane.WebTabbedPaneUI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.