Package org.fenrir.yggdrasil.ui

Source Code of org.fenrir.yggdrasil.ui.ApplicationTray

package org.fenrir.yggdrasil.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.JDialog;
import javax.swing.AbstractAction;
import javax.swing.event.MouseInputAdapter;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.fenrir.yggdrasil.ui.action.Action;
import org.fenrir.yggdrasil.ui.event.INotificationActionSupport;
import org.fenrir.yggdrasil.ui.widget.TrayNotificationWidget;
import org.fenrir.yggdrasil.ui.widget.TrayPopup;
import org.fenrir.yggdrasil.ui.widget.TrayPopupEntry;
import org.fenrir.yggdrasil.core.event.IApplicationNotification;
import org.fenrir.yggdrasil.core.event.IApplicationNotificationListener;
import org.fenrir.yggdrasil.core.event.annotation.EventListener;

/**
* TODO v1.0 Documentació
* @author Antonio Archilla Nava
* @version v0.1.20131215
*/
@EventListener(definitions=IApplicationNotificationListener.class)
public class ApplicationTray extends JPanel implements IApplicationNotificationListener
{
  private static final long serialVersionUID = -3431599851638474183L;

  private final Logger log = LoggerFactory.getLogger(ApplicationTray.class);
   
    private TrayPopup trayPopup;   
    private Box trayZone;
    private Map<String, TrayNotificationWidget> trayZoneElements = new HashMap<String, TrayNotificationWidget>();
    private Timer clearNotificationTimer;
    private JDialog notificationDialog;
   
    public ApplicationTray()
    {
        createContents();
    }
   
    private void createContents()
    {
        trayPopup = new TrayPopup(this);       
        trayPopup.setSize(350, 400);
        trayPopup.addWindowFocusListener(new WindowFocusListener()
        {
            @Override
            public void windowGainedFocus(WindowEvent event)
            {
                // No s'ha de fer res
            }

            @Override
            public void windowLostFocus(WindowEvent event)
            {
                ((JDialog)event.getSource()).setVisible(false);
            }
        });               
       
        this.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, new Color(200, 200, 200)));
        this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));       
        // Espai restant
        this.add(Box.createHorizontalGlue());
        // Ă€rea del tray
        trayZone = Box.createHorizontalBox()
        this.add(trayZone);               
        // Alçada mínima i marge dret
        this.add(Box.createRigidArea(new Dimension(25, 25)));               
    }   

    @Override
    public void singleNotification(IApplicationNotification notification)
    {
        // Entrada al popup
        final TrayPopupEntry entry = new TrayPopupEntry();
        entry.setNotificationId(notification.getId());
        entry.setMessage(notification.getMessage());
        if(notification instanceof INotificationActionSupport){
            Action action = ((INotificationActionSupport)notification).getAction();
            entry.setAction(action);
        }
        ImageIcon icon = new ImageIcon(getClass().getResource(notification.getIconPath()));
        entry.setIcon(icon);
       
        final boolean showNotification = ApplicationWindowManager.getInstance().isMainWindowActive();
        if(!showNotification){
            if(log.isDebugEnabled()){
                log.debug("Finestra no visible; Mostrant notificació al tray");
            }           
            ApplicationWindowManager.getInstance().displaySystemTrayMessage(notification.getCaption(), notification.getMessage(), TrayIcon.MessageType.INFO);
        }
       
        if(SwingUtilities.isEventDispatchThread()){
            addNotification(entry, showNotification);
        }
        else{
            try{
                SwingUtilities.invokeAndWait(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        addNotification(entry, showNotification);
                    }
                });
            }
            catch(InterruptedException e){
                log.error("Error mostrant notificació: {}", e.getMessage(), e);
            }
            catch(InvocationTargetException e){
                log.error("Error mostrant notificació: {}", e.getMessage(), e);
            }
        }
    }
   
    private void addNotification(TrayPopupEntry entry, boolean showNotification)
    {       
        trayPopup.addEntry(entry);       
        // Icona al tray
        TrayNotificationWidget trayLabel;       
        if(trayZoneElements.containsKey(entry.getNotificationId())){
            trayLabel = trayZoneElements.get(entry.getNotificationId());
        }
        else{
            trayLabel = new TrayNotificationWidget(entry.getIcon());
            trayZone.add(trayLabel.getWidget());
            trayZoneElements.put(entry.getNotificationId(), trayLabel);
            trayLabel.addMouseListener(new MouseInputAdapter()
            {
                @Override
                public void mouseClicked(MouseEvent event)
                {
                    showMessagesPopup();                               
                }           
            });
       
        trayLabel.incrementNotificationCount();       
        trayZone.revalidate();             
        // Necessari per reflectir els canvis del contador
        trayZone.repaint();
        // Si la finestra principal de l'aplicació es visible es motrarà la notificació
        if(showNotification){
            if(notificationDialog!=null && notificationDialog.isVisible()){
                notificationDialog.setVisible(false);
                notificationDialog.dispose();
                notificationDialog = null;
            }
            notificationDialog = createNotification(entry.getIcon(), entry.getMessage());
            notificationDialog.setVisible(true);
            notificationDialog.requestFocusInWindow();
            // Timer per esborrar el missatge de l'àrea
            if(clearNotificationTimer==null){
                // Delay 5seg.
                clearNotificationTimer = new Timer(5000, new AbstractAction()
                {
                    @Override
                    public void actionPerformed(ActionEvent event)
                    {
                        if(notificationDialog!=null){
                            notificationDialog.setVisible(false);
                            notificationDialog.dispose();
                            notificationDialog = null;
                        }
                    }
                });
                clearNotificationTimer.start();
            }
            else{
                clearNotificationTimer.restart();
            }           
        }
    }   
   
    private void showMessagesPopup()
    {
        JFrame appWindow = ApplicationWindowManager.getInstance().getMainWindow();
        Point appLocation = appWindow.getLocation();
        Dimension appDimension = appWindow.getSize();       
        int posX = appLocation.x + appDimension.width - trayPopup.getSize().width - 10;
        int posY = appLocation.y + appDimension.height - trayPopup.getSize().height - 35;
        trayPopup.setLocation(new Point(posX, posY));
        trayPopup.setVisible(true);
        trayPopup.requestFocusInWindow();
    }       
   
    private JDialog createNotification(Icon icon, String message)
    {
        JDialog dialog = new JDialog();
        dialog.setUndecorated(true);
        dialog.setVisible(false);        
       
        Box box = Box.createHorizontalBox();
        // Directament no es pot afegir border a la finestra de dialeg, pel que es fa al panell de contingut
        box.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        // Label icona
        JLabel lIcon = new JLabel(icon);
        lIcon.setMinimumSize(new Dimension(25, 25));
        lIcon.setPreferredSize(new Dimension(25, 25));
        lIcon.setMaximumSize(new Dimension(25, 25));
        box.add(lIcon);
        box.add(Box.createHorizontalStrut(10));
        // Label message
        String htmlMessage = "<html>" + message.replaceAll("\n", "<br/>") + "</html>";
        JLabel lMessage = new JLabel(htmlMessage);       
        box.add(lMessage);
        // Espai extra
        box.add(Box.createHorizontalGlue());
        // S'afegeix el contingut
        dialog.getContentPane().add(box);
        // Tamany
        dialog.setSize(320, box.getPreferredSize().height + 20);
        // Posició
        JFrame appWindow = ApplicationWindowManager.getInstance().getMainWindow();
        Point appLocation = appWindow.getLocation();
        Dimension appDimension = appWindow.getSize();       
        int posX = appLocation.x + appDimension.width - dialog.getSize().width - 10;
        int posY = appLocation.y + appDimension.height - dialog.getSize().height - 35;
        dialog.setLocation(new Point(posX, posY));       
       
        return dialog;
    }
   
    public void discardAllNotifications()
    {
        trayZone.removeAll();
        trayZone.revalidate();
        trayPopup.discardAllNotifications();
       
        trayZoneElements.clear();
    }
   
    public void discardNotification(TrayPopupEntry notificacionEntry)
    {       
        TrayNotificationWidget widget = trayZoneElements.get(notificacionEntry.getNotificationId());
        widget.decrementNotificationCount();
        // Només es treu la notificació del tray quan el contador del mateix tipus sigui <= 0
        if(widget.getNotificationCount()<=0){
            JComponent label = trayZoneElements.remove(notificacionEntry.getNotificationId()).getWidget();
            trayZone.remove(label);           
        }
        // Es repinta la zona per mostrar el canvi
        trayZone.revalidate();
        trayZone.repaint();
        trayPopup.discardNotification(notificacionEntry);
    }
}
TOP

Related Classes of org.fenrir.yggdrasil.ui.ApplicationTray

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.