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

com.alee.extended.layout.NotificationsLayout Maven / Gradle / Ivy

/*
 * 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.extended.layout;

import com.alee.managers.notification.DisplayType;
import com.alee.managers.notification.NotificationManager;
import com.alee.managers.notification.WebNotificationPopup;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Custom layout for proper notifications placement on glass pane.
 *
 * @author Mikle Garin
 */

public class NotificationsLayout extends AbstractLayoutManager implements SwingConstants
{
    /**
     * Cached notifications.
     */
    private List notifications = new ArrayList ( 2 );

    /**
     * {@inheritDoc}
     */
    @Override
    public void addComponent ( Component component, Object constraints )
    {
        if ( component instanceof WebNotificationPopup )
        {
            notifications.add ( ( WebNotificationPopup ) component );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void removeComponent ( Component component )
    {
        if ( component instanceof WebNotificationPopup )
        {
            notifications.remove ( component );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Dimension preferredLayoutSize ( Container parent )
    {
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void layoutContainer ( Container parent )
    {
        if ( notifications.size () > 0 )
        {
            // Notifications settings
            final int location = NotificationManager.getLocation ();
            final boolean east = location == SOUTH_EAST || location == NORTH_EAST;
            final boolean south = location == SOUTH_EAST || location == SOUTH_WEST;
            final boolean flowDisplayType = NotificationManager.getDisplayType () == DisplayType.flow;
            final Insets margin = NotificationManager.getMargin ();
            final int gap = NotificationManager.getGap ();
            final boolean cascade = NotificationManager.isCascade ();
            final int cascadeAmount = NotificationManager.getCascadeAmount ();

            // Container settings
            final int width = parent.getWidth ();
            final int height = parent.getHeight ();

            // Runtime values
            int maxWidth = 0;
            int maxCascade = 0;
            int x = east ? width - margin.right : margin.left;
            final int startY = south ? height - margin.bottom : margin.top;
            int y = startY;
            int count = 0;
            for ( WebNotificationPopup popup : notifications )
            {
                // Calculating settings
                final Dimension ps = popup.getPreferredSize ();
                if ( south ? ( y - ps.height < 0 ) : ( y + ps.height > height ) )
                {
                    final int gapsAmount = cascade ? Math.max ( 1, maxCascade ) : 1;
                    y = startY;
                    x = east ? ( x - maxWidth - gap * gapsAmount ) : ( x + maxWidth + gap );
                    maxWidth = 0;
                    maxCascade = 0;
                    count = 0;
                }
                final int cascadeShear = cascade ? gap * count : 0;

                // Placing notification
                final int x1 = east ? ( x - ps.width - cascadeShear ) : ( x + cascadeShear );
                final int y1 = south ? ( y - ps.height ) : y;
                popup.setBounds ( x1, y1, ps.width, ps.height );
                maxWidth = Math.max ( maxWidth, ps.width );

                // Incrementing notification position
                y = y + ( south ? -1 : 1 ) * ( flowDisplayType ? ps.height + gap : gap );
                if ( cascade )
                {
                    count++;
                    maxCascade = Math.max ( maxCascade, count );
                    if ( count > cascadeAmount - 1 )
                    {
                        count = 0;
                    }
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy