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

org.jclarion.clarion.swing.notify.EventNotifier Maven / Gradle / Ivy

There is a newer version: 1.86
Show newest version
/**
 * Copyright 2010, by Andrew Barnham
 *
 * The contents of this file are subject to
 * GNU Lesser General Public License (LGPL), v.3
 * http://www.gnu.org/licenses/lgpl.txt
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 */
package org.jclarion.clarion.swing.notify;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.StringTokenizer;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import org.jclarion.clarion.ClarionApplication;
import org.jclarion.clarion.runtime.CRun;
import org.jclarion.clarion.runtime.CWin;
import org.jclarion.clarion.swing.ClarionDesktopPane;
public class EventNotifier implements Runnable
{
    private static EventNotifier instance;
    
    public static EventNotifier getInstance()
    {
        if (instance==null) {
            synchronized(EventNotifier.class) {
                if (instance==null) {
                    instance=new EventNotifier();
                }
            }
        }
        return instance;
    }

    private static class Event
    {
        public Event(String message,Color forground,Color background,int wait,boolean keep)
        {
            this.message=message;
            this.forground=forground;
            this.background=background;
            this.wait=wait;
            this.keep=keep;
            status=new NotifyStatus();
        }
        
        private String  message;
        private Color   forground;
        private Color   background;
        private int     wait;
        private boolean keep;
        private NotifyStatus status;
    }
    
    private LinkedList events = new LinkedList();
    private JPanel component;
    private JComponent textBlock;
    private Thread notifyThread;
    private boolean shutdown;
    private boolean close=false;
    private Object closeMonitor=new Object();
    
    private EventNotifier()
    {
        CRun.addShutdownHook(new Runnable() {
            @Override
            public void run() {
                shutdown();
                instance=null;
            } } );
        
        component=new JPanel();
        component.putClientProperty("shadow","1");
        component.setSize(0,0);
        component.setLocation(0,0);
        component.setLayout(new BorderLayout(5,5));
        component.setBorder(new LineBorder(Color.black,2));

        JButton button = new JButton();
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                notifyClose();
            } } );
        button.setText("close");
        button.setFont(new Font("Serif",0,8));
        //UIDefaults nimbus=new UIDefaults();;
        //nimbus.put("Button.contentMargins",new Insets(3,6,3,6));        
        //button.putClientProperty("Nimbus.Overrides",nimbus);
        JComponent head = new JPanel(new BorderLayout());
        head.setBorder(new EmptyBorder(2,50,2,5));
        head.setBackground(null);
        JLabel title = new JLabel();
        title.setBorder(new EmptyBorder(2,15,2,15));
        title.setText("Notification");
        title.setFont(new Font("Serif",0,8));
        title.setHorizontalAlignment(SwingConstants.CENTER);
        //head.add(title,BorderLayout.CENTER);
        head.add(button,BorderLayout.EAST);
        component.add(head,BorderLayout.NORTH);
        
        
        textBlock=javax.swing.Box.createVerticalBox();
        textBlock.setBorder(new EmptyBorder(10,10,10,10));
        //textBlock.set)
        //textBlock.setLayout(new BoxLayout(textBlock,BoxLayout.Y_AXIS));
        component.add(textBlock,BorderLayout.CENTER);
        
        ClarionApplication app = CWin.getInstance().getApp();
        if (app!=null) {
            ((ClarionDesktopPane)app.getDesktopPane()).add(component,new Integer(1000));
            notifyThread = new Thread(this,"clarion notify");
            notifyThread.setDaemon(true);
            notifyThread.start();
        } else {
            instance=null;
        }
    }
    
    public Component getComponent()
    {
        return component;
    }

    public NotifyStatus message(String message,Color foreground,Color background,int wait,boolean keep) 
    {
        Event e = new Event(message,foreground,background,wait,keep);
        synchronized(events) {
            events.add(e);
            events.notifyAll();
        }
        return e.status;
    }
    
    private int lineCount(String in)
    {
        StringTokenizer tok = new StringTokenizer(in,"\n");
        return tok.countTokens();
    }
    
    public NotifyStatus info(String message)
    {
        return message(message,Color.BLACK,Color.GREEN,1000,false);
    }
    
    public NotifyStatus warning(String message)
    {
        return message(message,Color.BLACK,Color.ORANGE,5000*lineCount(message),false);
    }

    public NotifyStatus notify(String message)
    {
        return message(message,Color.BLACK,new Color(180,180,255),5000*lineCount(message),false);
    }
    
    public NotifyStatus error(String message)
    {
        return message(message,Color.BLACK,Color.RED,5000*lineCount(message),true);
    }

    
    @Override
    public void run() {
        
        while ( true ) {
            Event next=null;
            synchronized(events) {
                if (shutdown) return;
                if (!events.isEmpty()) {
                    next=events.removeFirst();
                } else {
                    try {
                        events.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    continue;
                }
            }
            
            if (next==null) continue;
            if (next.status.isProcessed()) continue;
            
            textBlock.removeAll();
            component.setBackground(next.background);
            
            int msgscan=0;
            while (msgscan=0;scan--) {
                setPosition(scan*5);
                sleep(10,false);
            }
            component.setVisible(false);
            
            if (next.keep && !isClosed()) {
                synchronized(events) {
                    events.add(next);
                }
            } else {
                next.status.setProcessed();
            }
            resetClose();
        }
    }

    private boolean isClosed() {
        synchronized(closeMonitor) {
            return close;
        }
    }

    private void resetClose() {
        synchronized(closeMonitor) {
            close=false;
        }
    }

    private void sleep(int wait,boolean useClose)
    {
        if (!useClose) {
            try {
                Thread.sleep(wait);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return;
        }
        
        long until = System.currentTimeMillis()+wait;

        synchronized(closeMonitor) {
            if (close) return;
            long waitUntil = until-System.currentTimeMillis();
            if (waitUntil<=0) return;
            try {
                closeMonitor.wait(waitUntil);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    private void notifyClose()
    {
        synchronized(closeMonitor) {
            close=true;
            closeMonitor.notifyAll();
        }
    }
    
    private void setPosition(int ratio)
    {
        Dimension preferredSize = component.getPreferredSize();
        JDesktopPane pane = (JDesktopPane)component.getParent();
        JScrollPane  scroll = (JScrollPane)pane.getParent().getParent();
        JViewport port = scroll.getViewport();
        Rectangle bounds = port.getViewRect();

        component.setLocation(
                bounds.x+bounds.width-preferredSize.width,
                bounds.y+bounds.height-preferredSize.height*ratio/100);
        if (!component.isVisible()) {
            component.setVisible(true);
            pane.moveToFront(component);
        }
        component.repaint();
    }

    public void shutdown() {
        
        synchronized(events) {
            shutdown=true;
            events.notifyAll();
        }
        
        try {
            notifyThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
            
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy