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

com.alee.managers.popup.ShadeLayer Maven / Gradle / Ivy

The 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.managers.popup;

import com.alee.extended.layout.AlignLayout;
import com.alee.utils.GraphicsUtils;
import com.alee.utils.SwingUtils;
import com.alee.utils.swing.WebTimer;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * This special popup layer is used to place modal-like popups atop of it.
 * It basically provides a semi-transparent layer that covers the whole window and leaves only modal popup in focus.
 *
 * @author Mikle Garin
 * @see PopupManager
 */
public class ShadeLayer extends PopupLayer
{
    /**
     * Whether modal shade should be animated or not.
     * It might cause serious lags in case it is used in a large window with lots of UI elements.
     */
    protected boolean animate = true;

    /**
     * Layer current opacity.
     */
    protected int opacity = 0;

    /**
     * Layer opacity animator.
     */
    protected WebTimer animator;

    /**
     * Whether popup close attemps should be blocked or not.
     */
    protected boolean blockClose = false;

    /**
     * Constructs new shade layer.
     */
    public ShadeLayer ()
    {
        super ( new AlignLayout () );

        final MouseAdapter mouseAdapter = new MouseAdapter ()
        {
            @Override
            public void mousePressed ( final MouseEvent e )
            {
                if ( !blockClose )
                {
                    hideAllPopups ();
                }
            }
        };
        addMouseListener ( mouseAdapter );
        addMouseMotionListener ( mouseAdapter );
    }

    @Override
    public void showPopup ( final WebInnerPopup popup )
    {
        showPopup ( popup, false, false );
    }

    /**
     * Displays the specified popup on this popup layer.
     *
     * @param popup popup to display
     * @param hfill whether popup should fill the whole available window width or not
     * @param vfill whether popup should fill the whole available window height or not
     */
    public void showPopup ( final WebInnerPopup popup, final boolean hfill, final boolean vfill )
    {
        // Informing that popup will now become visible
        popup.firePopupWillBeOpened ();

        // Updating layout settings
        final LayoutManager layoutManager = getLayout ();
        if ( layoutManager instanceof AlignLayout )
        {
            final AlignLayout layout = ( AlignLayout ) layoutManager;
            layout.setHfill ( hfill );
            layout.setVfill ( vfill );
        }

        // Updating popup layer
        setBounds ( new Rectangle ( 0, 0, getParent ().getWidth (), getParent ().getHeight () ) );

        // Adding popup
        removeAll ();
        add ( popup, SwingConstants.CENTER + AlignLayout.SEPARATOR + SwingConstants.CENTER, 0 );
        setVisible ( true );
        revalidate ();
        repaint ();
    }

    /**
     * Returns whether modal shade should be animated or not.
     *
     * @return true if modal shade should be animated, false otherwise
     */
    public boolean isAnimate ()
    {
        return animate;
    }

    /**
     * Sets whether modal shade should be animated or not.
     *
     * @param animate whether modal shade should be animated or not
     */
    public void setAnimate ( final boolean animate )
    {
        this.animate = animate;
    }

    /**
     * Returns whether popup close attemps should be blocked or not.
     *
     * @return true if popup close attemps should be blocked, false otherwise
     */
    public boolean isBlockClose ()
    {
        return blockClose;
    }

    /**
     * Sets whether popup close attemps should be blocked or not.
     *
     * @param blockClose whether popup close attemps should be blocked or not
     */
    public void setBlockClose ( final boolean blockClose )
    {
        this.blockClose = blockClose;
    }

    @Override
    public void paint ( final Graphics g )
    {
        // todo Really bad workaround
        GraphicsUtils.setupAlphaComposite ( ( Graphics2D ) g, ( float ) opacity / 100, opacity < 100 );
        super.paint ( g );
    }

    @Override
    protected void paintComponent ( final Graphics g )
    {
        super.paintComponent ( g );

        final Graphics2D g2d = ( Graphics2D ) g;
        final Object old = GraphicsUtils.setupAntialias ( g2d );
        final Composite comp = GraphicsUtils.setupAlphaComposite ( g2d, 0.8f );

        g2d.setPaint ( Color.LIGHT_GRAY );
        g2d.fillRect ( 0, 0, getWidth (), getHeight () );

        GraphicsUtils.restoreComposite ( g2d, comp );
        GraphicsUtils.restoreAntialias ( g2d, old );
    }

    @Override
    public void setVisible ( final boolean visible )
    {
        super.setVisible ( visible );
        if ( visible )
        {
            if ( animator != null )
            {
                animator.stop ();
            }
            if ( animate )
            {
                opacity = 0;
                animator = new WebTimer ( "ShadeLayer.fadeIn", SwingUtils.frameRateDelay ( 24 ), new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        if ( opacity < 100 )
                        {
                            opacity += 25;
                            ShadeLayer.this.repaint ();
                        }
                        else
                        {
                            animator.stop ();
                        }
                    }
                } );
                animator.start ();
            }
            else
            {
                opacity = 100;
                ShadeLayer.this.repaint ();
            }
        }
    }

    /**
     * Returns whether the specified point is within bounds of this popup layer or not.
     *
     * @param x X coordinate
     * @param y Y coordinate
     * @return true if the specified point is within bounds of this popup layer, false otherwise
     */
    @Override
    public boolean contains ( final int x, final int y )
    {
        return normalContains ( x, y );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy