/** * Copyright (c) 2009 - 2010 AppWork UG(haftungsbeschränkt) <e-mail@appwork.org> * * This file is part of org.appwork.swing.trayicon.view * * This software is licensed under the Artistic License 2.0, * see the LICENSE file or http://www.opensource.org/licenses/artistic-license-2.0.php * for details */ package org.appwork.swing.trayicon; import java.awt.Component; import java.awt.Dimension; import java.awt.Image; import java.awt.MouseInfo; import java.awt.Point; import java.awt.TrayIcon; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.ArrayList; /** * @author thomas * */ public class ExtTrayIcon extends TrayIcon implements MouseListener, MouseMotionListener { private static int TOOLTIP_DELAY = 1000; private Component dummy; private MouseEvent lastEvent; private Point max; // private TrayIcon trayIcon; private Point min; private final ArrayList<MouseListener> mouseListeners; private Thread mouseLocationObserver; private boolean mouseover; private Dimension size; private final ArrayList<TrayMouseListener> traymouseListeners; /** * @param icon * @param title */ public ExtTrayIcon(final Image icon, final String title) { super(icon, title); this.setImageAutoSize(true); this.mouseListeners = new ArrayList<MouseListener>(); this.traymouseListeners = new ArrayList<TrayMouseListener>(); super.addMouseListener(this); super.addMouseMotionListener(this); } public void addMouseListener(final MouseListener listener) { if (listener == null) { return; } synchronized (this.mouseListeners) { this.mouseListeners.add(listener); } } public void addTrayMouseListener(final TrayMouseListener listener) { if (listener == null) { return; } synchronized (this.traymouseListeners) { this.traymouseListeners.add(listener); } } public Point getEstimatedTopLeft() { final int midx = (this.max.x + this.min.x) / 2; final int midy = (this.max.y + this.min.y) / 2; return new Point(midx - this.size.width / 2, midy - this.size.height / 2); } /** * Passt die iconsize in die festgestellte geschätzte position ein. und * prüft ob point darin ist * * @param point * @return */ protected boolean isOver(final Point point) { final int midx = (this.max.x + this.min.x) / 2; final int midy = (this.max.y + this.min.y) / 2; final int width = Math.min(this.size.width, this.max.x - this.min.x); final int height = Math.min(this.size.height, this.max.y - this.min.y); final int minx = midx - width / 2; final int miny = midy - height / 2; final int maxx = midx + width / 2; final int maxy = midy + height / 2; // java.awt.Point[x=1274,y=1175] - java.awt.Point[x=1309,y=1185] if ((point.x >= minx) && (point.x <= maxx)) { if ((point.y >= miny) && (point.y <= maxy)) { return true; } } return false; } public void mouseClicked(final MouseEvent e) { synchronized (this.mouseListeners) { for (final MouseListener l : this.mouseListeners) { l.mouseClicked(e); } } } /* * (non-Javadoc) * * @see * java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent * ) */ public void mouseDragged(final MouseEvent e) { // TODO Auto-generated method stub } public void mouseEntered(final MouseEvent e) { this.mouseover = true; final long enterTime = System.currentTimeMillis(); this.mouseLocationObserver = new Thread() { public void run() { try { boolean mouseStay = false; while (true) { final Point point = MouseInfo.getPointerInfo().getLocation(); if (!ExtTrayIcon.this.isOver(point)) { MouseEvent me; me = new MouseEvent(ExtTrayIcon.this.dummy, 0, System.currentTimeMillis(), 0, point.x, point.y, 0, false); me.setSource(ExtTrayIcon.this.lastEvent.getSource()); synchronized (ExtTrayIcon.this.mouseListeners) { for (final MouseListener l : ExtTrayIcon.this.mouseListeners) { l.mouseExited(me); } } return; } else { if (((System.currentTimeMillis() - enterTime) >= ExtTrayIcon.TOOLTIP_DELAY) && !mouseStay) { mouseStay = true; MouseEvent me; me = new MouseEvent(ExtTrayIcon.this.dummy, 0, System.currentTimeMillis(), 0, point.x, point.y, 0, false); // me.setSource(MouseAdapter.this); // deligate.mouseStay(me); synchronized (ExtTrayIcon.this.traymouseListeners) { for (final TrayMouseListener l : ExtTrayIcon.this.traymouseListeners) { l.mouseMoveOverTray(me); } } } } Thread.sleep(100); } } catch (final InterruptedException e) { e.printStackTrace(); return; } finally { ExtTrayIcon.this.mouseLocationObserver = null; } } }; this.mouseLocationObserver.start(); } public void mouseExited(final MouseEvent e) { this.mouseover = false; this.min = this.max = null; synchronized (this.mouseListeners) { for (final MouseListener l : this.mouseListeners) { l.mouseExited(e); } } } public void mouseMoved(final MouseEvent e) { this.lastEvent = e; /** * the more the user moves over the tray, the better we know it's * location * */ if (this.min == null) { this.min = new Point(e.getPoint().x, e.getPoint().y); this.max = new Point(e.getPoint().x, e.getPoint().y); } else { this.min.x = Math.min(e.getPoint().x, this.min.x); this.min.y = Math.min(e.getPoint().y, this.min.y); this.max.x = Math.max(e.getPoint().x, this.max.x); this.max.y = Math.max(e.getPoint().y, this.max.y); // System.out.println(min+" - "+max); } if (!this.mouseover) { synchronized (this.mouseListeners) { for (final MouseListener l : this.mouseListeners) { l.mouseEntered(e); } } } else { // deligate.mouseMoved(e); } } public void mousePressed(final MouseEvent e) { synchronized (this.mouseListeners) { for (final MouseListener l : this.mouseListeners) { l.mousePressed(e); } } } public void mouseReleased(final MouseEvent e) { synchronized (this.mouseListeners) { for (final MouseListener l : this.mouseListeners) { l.mouseReleased(e); } } } public void removeMouseListener(final MouseListener listener) { if (listener == null) { return; } synchronized (this.mouseListeners) { this.mouseListeners.remove(listener); } } public void removeTrayMouseListener(final TrayMouseListener listener) { if (listener == null) { return; } synchronized (this.traymouseListeners) { this.traymouseListeners.remove(listener); } } }