jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java
author yan
Mon, 06 Oct 2008 16:45:00 +0400
changeset 1966 12a51fb0db0d
parent 439 3488710b02f8
child 2472 b7aba00cabb6
permissions -rw-r--r--
5100701: Toolkit.getLockingKeyState() does not work on XToolkit, but works on Motif Summary: Does not work on Motif but works on XToolkit now; implemented using XQueryPointer. Reviewed-by: anthony
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
116
9c43d9eb1029 6645856: static field XWindowPeer.defaultFont hides XWindow.defaultFont
son
parents: 2
diff changeset
     2
 * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.awt.X11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.event.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.peer.TrayIconPeer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import sun.awt.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.image.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.text.BreakIterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.logging.Logger;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.util.logging.Level;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.util.concurrent.ArrayBlockingQueue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.security.AccessController;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.security.PrivilegedAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.lang.reflect.InvocationTargetException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
public class XTrayIconPeer implements TrayIconPeer {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    private static final Logger ctrLog = Logger.getLogger("sun.awt.X11.XTrayIconPeer.centering");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    TrayIcon target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    TrayIconEventProxy eventProxy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    XTrayIconEmbeddedFrame eframe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    TrayIconCanvas canvas;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    Balloon balloon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    Tooltip tooltip;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    PopupMenu popup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    String tooltipString;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    boolean isTrayIconDisplayed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    long eframeParentID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    final XEventDispatcher parentXED, eframeXED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    static final XEventDispatcher dummyXED = new XEventDispatcher() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
            public void dispatchEvent(XEvent ev) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
        };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    volatile boolean isDisposed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    boolean isParentWindowLocated;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    int old_x, old_y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    int ex_width, ex_height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    final static int TRAY_ICON_WIDTH = 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    final static int TRAY_ICON_HEIGHT = 24;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    XTrayIconPeer(TrayIcon target)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
      throws AWTException
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        this.target = target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        eventProxy = new TrayIconEventProxy(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        canvas = new TrayIconCanvas(target, TRAY_ICON_WIDTH, TRAY_ICON_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        eframe = new XTrayIconEmbeddedFrame();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        eframe.setSize(TRAY_ICON_WIDTH, TRAY_ICON_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        eframe.add(canvas);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        // Fix for 6317038: as EmbeddedFrame is instance of Frame, it is blocked
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        // by modal dialogs, but in the case of TrayIcon it shouldn't. So we
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        // set ModalExclusion property on it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        AccessController.doPrivileged(new PrivilegedAction() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
            public Object run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
                eframe.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        });
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        if (XWM.getWMID() != XWM.METACITY_WM) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            parentXED = dummyXED; // We don't like to leave it 'null'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            parentXED = new XEventDispatcher() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                // It's executed under AWTLock.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                public void dispatchEvent(XEvent ev) {
439
3488710b02f8 6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents: 431
diff changeset
   101
                    if (isDisposed() || ev.get_type() != XConstants.ConfigureNotify) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                    XConfigureEvent ce = ev.get_xconfigure();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                    ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}: {1}x{2}+{3}+{4} (old: {5}+{6})",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                               new Object[] { XTrayIconPeer.this, ce.get_width(), ce.get_height(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                                              ce.get_x(), ce.get_y(), old_x, old_y });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                    // A workaround for Gnome/Metacity (it doesn't affect the behaviour on KDE).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
                    // On Metacity the EmbeddedFrame's parent window bounds are larger
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                    // than TrayIcon size required (that is we need a square but a rectangle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                    // is provided by the Panel Notification Area). The parent's background color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                    // differs from the Panel's one. To hide the background we resize parent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                    // window so that it fits the EmbeddedFrame.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                    // However due to resizing the parent window it loses centering in the Panel.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                    // We center it when discovering that some of its side is of size greater
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                    // than the fixed value. Centering is being done by "X" (when the parent's width
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                    // is greater) and by "Y" (when the parent's height is greater).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                    // Actually we need this workaround until we could detect taskbar color.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                    if (ce.get_height() != TRAY_ICON_HEIGHT && ce.get_width() != TRAY_ICON_WIDTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                        // If both the height and the width differ from the fixed size then WM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                        // must level at least one side to the fixed size. For some reason it may take
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                        // a few hops (even after reparenting) and we have to skip the intermediate ones.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                        ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Skipping as intermediate resizing.",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                                   XTrayIconPeer.this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                    } else if (ce.get_height() > TRAY_ICON_HEIGHT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                        ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Centering by \"Y\".",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                                   XTrayIconPeer.this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                        XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), eframeParentID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                                                      ce.get_x(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                                                      ce.get_y()+ce.get_height()/2-TRAY_ICON_HEIGHT/2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                                                      TRAY_ICON_WIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                                                      TRAY_ICON_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                        ex_height = ce.get_height();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                        ex_width = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                    } else if (ce.get_width() > TRAY_ICON_WIDTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                        ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Centering by \"X\".",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                                   XTrayIconPeer.this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                        XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), eframeParentID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                                                      ce.get_x()+ce.get_width()/2 - TRAY_ICON_WIDTH/2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                                                      ce.get_y(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                                                      TRAY_ICON_WIDTH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                                                      TRAY_ICON_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                        ex_width = ce.get_width();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                        ex_height = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                    } else if (isParentWindowLocated && ce.get_x() != old_x && ce.get_y() != old_y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                        // If moving by both "X" and "Y".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                        // When some tray icon gets removed from the tray, a Java icon may be repositioned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                        // In this case the parent window also lose centering. We have to restore it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                        if (ex_height != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                            ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Move detected. Centering by \"Y\".",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                                       XTrayIconPeer.this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                            XlibWrapper.XMoveWindow(XToolkit.getDisplay(), eframeParentID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                                                    ce.get_x(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                                                    ce.get_y() + ex_height/2 - TRAY_ICON_HEIGHT/2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                        } else if (ex_width != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                            ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Move detected. Centering by \"X\".",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                                       XTrayIconPeer.this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
                            XlibWrapper.XMoveWindow(XToolkit.getDisplay(), eframeParentID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                                                    ce.get_x() + ex_width/2 - TRAY_ICON_WIDTH/2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                                                    ce.get_y());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                            ctrLog.log(Level.FINE, "ConfigureNotify on parent of {0}. Move detected. Skipping.",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                                       XTrayIconPeer.this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                    old_x = ce.get_x();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
                    old_y = ce.get_y();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                    isParentWindowLocated = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        eframeXED = new XEventDispatcher() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                // It's executed under AWTLock.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                XTrayIconPeer xtiPeer = XTrayIconPeer.this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                public void dispatchEvent(XEvent ev) {
439
3488710b02f8 6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents: 431
diff changeset
   197
                    if (isDisposed() || ev.get_type() != XConstants.ReparentNotify) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                    XReparentEvent re = ev.get_xreparent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                    eframeParentID = re.get_parent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                    if (eframeParentID == XToolkit.getDefaultRootWindow()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                        if (isTrayIconDisplayed) { // most likely Notification Area was removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                            SunToolkit.executeOnEventHandlerThread(xtiPeer.target, new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                                    public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                                        SystemTray.getSystemTray().remove(xtiPeer.target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                                });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                    if (!isTrayIconDisplayed) {
439
3488710b02f8 6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents: 431
diff changeset
   217
                        addXED(eframeParentID, parentXED, XConstants.StructureNotifyMask);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                        isTrayIconDisplayed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                        XToolkit.awtLockNotifyAll();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
439
3488710b02f8 6623459: Get rid of XConstant, XProtocolConstants and XUtilConstants antipattern
dav
parents: 431
diff changeset
   225
        addXED(getWindow(), eframeXED, XConstants.StructureNotifyMask);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        XSystemTrayPeer.getPeerInstance().addTrayIcon(this); // throws AWTException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        // Wait till the EmbeddedFrame is reparented
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        long start = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        final long PERIOD = 2000L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        XToolkit.awtLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            while (!isTrayIconDisplayed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                    XToolkit.awtLockWait(PERIOD);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                } catch (InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                if (System.currentTimeMillis() - start > PERIOD) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            XToolkit.awtUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        // This is unlikely to happen.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        if (!isTrayIconDisplayed || eframeParentID == 0 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            eframeParentID == XToolkit.getDefaultRootWindow())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            throw new AWTException("TrayIcon couldn't be displayed.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        eframe.setVisible(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        updateImage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        balloon = new Balloon(this, eframe);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        tooltip = new Tooltip(this, eframe);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        addListeners();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    public void dispose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        if (SunToolkit.isDispatchThreadForAppContext(target)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            disposeOnEDT();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                SunToolkit.executeOnEDTAndWait(target, new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                            disposeOnEDT();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                    });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            } catch (InterruptedException ie) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            } catch (InvocationTargetException ite) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    private void disposeOnEDT() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        // All actions that is to be synchronized with disposal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        // should be executed either under AWTLock, or on EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        // isDisposed value must be checked.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        XToolkit.awtLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        isDisposed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        XToolkit.awtUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        removeXED(getWindow(), eframeXED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        removeXED(eframeParentID, parentXED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        eframe.realDispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        balloon.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        isTrayIconDisplayed = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        XToolkit.targetDisposedPeer(target, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    public static void suppressWarningString(Window w) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        WindowAccessor.setTrayIconWindow(w, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    public void setToolTip(String tooltip) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        tooltipString = tooltip;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    public void updateImage() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        Runnable r = new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                    canvas.updateImage(target.getImage());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        if (!SunToolkit.isDispatchThreadForAppContext(target)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            SunToolkit.executeOnEventHandlerThread(target, r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            r.run();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    public void displayMessage(String caption, String text, String messageType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        Point loc = getLocationOnScreen();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        Rectangle screen = eframe.getGraphicsConfiguration().getBounds();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        // Check if the tray icon is in the bounds of a screen.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        if (!(loc.x < screen.x || loc.x >= screen.x + screen.width ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
              loc.y < screen.y || loc.y >= screen.y + screen.height))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            balloon.display(caption, text, messageType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    // It's synchronized with disposal by EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    public void showPopupMenu(int x, int y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        if (isDisposed())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        assert SunToolkit.isDispatchThreadForAppContext(target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        PopupMenu newPopup = target.getPopupMenu();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        if (popup != newPopup) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            if (popup != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                eframe.remove(popup);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            if (newPopup != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                eframe.add(newPopup);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            popup = newPopup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        if (popup != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            Point loc = ((XBaseWindow)eframe.getPeer()).toLocal(new Point(x, y));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            popup.show(eframe, loc.x, loc.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    // ******************************************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    // ******************************************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    private void addXED(long window, XEventDispatcher xed, long mask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        if (window == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        XToolkit.awtLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            XlibWrapper.XSelectInput(XToolkit.getDisplay(), window, mask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            XToolkit.awtUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        XToolkit.addEventDispatcher(window, xed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    private void removeXED(long window, XEventDispatcher xed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        if (window == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        XToolkit.awtLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            XToolkit.removeEventDispatcher(window, xed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            XToolkit.awtUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    // Private method for testing purposes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    private Point getLocationOnScreen() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        return eframe.getLocationOnScreen();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    private Rectangle getBounds() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        Point loc = getLocationOnScreen();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        return new Rectangle(loc.x, loc.y, loc.x + TRAY_ICON_WIDTH, loc.y + TRAY_ICON_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    void addListeners() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        canvas.addMouseListener(eventProxy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        canvas.addMouseMotionListener(eventProxy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    long getWindow() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        return ((XEmbeddedFramePeer)eframe.getPeer()).getWindow();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    boolean isDisposed() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        return isDisposed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    static class TrayIconEventProxy implements MouseListener, MouseMotionListener {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        XTrayIconPeer xtiPeer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        TrayIconEventProxy(XTrayIconPeer xtiPeer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            this.xtiPeer = xtiPeer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        public void handleEvent(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
            //prevent DRAG events from being posted with TrayIcon source(CR 6565779)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            // Event handling is synchronized with disposal by EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
            if (xtiPeer.isDisposed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            Point coord = XBaseWindow.toOtherWindow(xtiPeer.getWindow(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                                                    XToolkit.getDefaultRootWindow(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                                                    e.getX(), e.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            if (e.isPopupTrigger()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
                xtiPeer.showPopupMenu(coord.x, coord.y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            e.translatePoint(coord.x - e.getX(), coord.y - e.getY());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            // This is a hack in order to set non-Component source to MouseEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            // instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            // In some cases this could lead to unpredictable result (e.g. when
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            // other class tries to cast source field to Component).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            // We already filter DRAG events out (CR 6565779).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            e.setSource(xtiPeer.target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        public void mouseClicked(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            if ((e.getClickCount() > 1 || xtiPeer.balloon.isVisible()) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                e.getButton() == MouseEvent.BUTTON1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                ActionEvent aev = new ActionEvent(xtiPeer.target, ActionEvent.ACTION_PERFORMED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                                                  xtiPeer.target.getActionCommand(), e.getWhen(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                                                  e.getModifiers());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(aev);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            if (xtiPeer.balloon.isVisible()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                xtiPeer.balloon.hide();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            handleEvent(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        public void mouseEntered(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            xtiPeer.tooltip.enter();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            handleEvent(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        public void mouseExited(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            xtiPeer.tooltip.exit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            handleEvent(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        public void mousePressed(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            handleEvent(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        public void mouseReleased(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
            handleEvent(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        public void mouseDragged(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            handleEvent(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        public void mouseMoved(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            handleEvent(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    static boolean isTrayIconStuffWindow(Window w) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        return (w instanceof Tooltip) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
               (w instanceof Balloon) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
               (w instanceof XTrayIconEmbeddedFrame);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    // ***************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    // Special embedded frame for tray icon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    // ***************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    private static class XTrayIconEmbeddedFrame extends XEmbeddedFrame {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        public XTrayIconEmbeddedFrame(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
            super(XToolkit.getDefaultRootWindow(), true, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        public boolean isUndecorated() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        public boolean isResizable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        // embedded frame for tray icon shouldn't be disposed by anyone except tray icon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        public void dispose(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        public void realDispose(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            super.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    // ***************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    // Classes for painting an image on canvas
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    // ***************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
    static class TrayIconCanvas extends IconCanvas {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        TrayIcon target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        boolean autosize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        TrayIconCanvas(TrayIcon target, int width, int height) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            super(width, height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            this.target = target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        // Invoke on EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        protected void repaintImage(boolean doClear) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            boolean old_autosize = autosize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            autosize = target.isImageAutoSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            curW = autosize ? width : image.getWidth(observer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            curH = autosize ? height : image.getHeight(observer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            super.repaintImage(doClear || (old_autosize != autosize));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    static class IconCanvas extends Canvas {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        volatile Image image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        IconObserver observer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        int width, height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        int curW, curH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        IconCanvas(int width, int height) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            this.width = curW = width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            this.height = curH = height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        // Invoke on EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
        public void updateImage(Image image) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            this.image = image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            if (observer == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                observer = new IconObserver();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            repaintImage(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        // Invoke on EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        protected void repaintImage(boolean doClear) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            Graphics g = getGraphics();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            if (g != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                    if (isVisible()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                        if (doClear) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                            update(g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                            paint(g);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                    g.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        // Invoke on EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        public void paint(Graphics g) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            if (g != null && curW > 0 && curH > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                BufferedImage bufImage = new BufferedImage(curW, curH, BufferedImage.TYPE_INT_ARGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                Graphics2D gr = bufImage.createGraphics();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                if (gr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                        gr.setColor(getBackground());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                        gr.fillRect(0, 0, curW, curH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                        gr.drawImage(image, 0, 0, curW, curH, observer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                        gr.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                        g.drawImage(bufImage, 0, 0, curW, curH, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                    } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                        gr.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        class IconObserver implements ImageObserver {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            public boolean imageUpdate(final Image image, final int flags, int x, int y, int width, int height) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                if (image != IconCanvas.this.image || // if the image has been changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                    !IconCanvas.this.isVisible())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                if ((flags & (ImageObserver.FRAMEBITS | ImageObserver.ALLBITS |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                              ImageObserver.WIDTH | ImageObserver.HEIGHT)) != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                    SunToolkit.executeOnEventHandlerThread(IconCanvas.this, new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                            public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                                repaintImage(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                        });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                return (flags & ImageObserver.ALLBITS) == 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    // ***************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    // Classes for toolitp and balloon windows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    // ***************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    static class Tooltip extends InfoWindow {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        XTrayIconPeer xtiPeer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        Label textLabel = new Label("");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        Runnable starter = new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                    display();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                }};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        final static int TOOLTIP_SHOW_TIME = 10000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        final static int TOOLTIP_START_DELAY_TIME = 1000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        final static int TOOLTIP_MAX_LENGTH = 64;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
116
9c43d9eb1029 6645856: static field XWindowPeer.defaultFont hides XWindow.defaultFont
son
parents: 2
diff changeset
   629
        final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        Tooltip(XTrayIconPeer xtiPeer, Frame parent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            super(parent, Color.black);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            this.xtiPeer = xtiPeer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            suppressWarningString(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
            setCloser(null, TOOLTIP_SHOW_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
            textLabel.setBackground(TOOLTIP_BACKGROUND_COLOR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            textLabel.setFont(TOOLTIP_TEXT_FONT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            add(textLabel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
         * WARNING: this method is executed on Toolkit thread!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        void display() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
            String tip = xtiPeer.tooltipString;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
            if (tip == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
            } else if (tip.length() >  TOOLTIP_MAX_LENGTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                textLabel.setText(tip.substring(0, TOOLTIP_MAX_LENGTH));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                textLabel.setText(tip);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            // Execute on EDT to avoid deadlock (see 6280857).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            SunToolkit.executeOnEventHandlerThread(xtiPeer.target, new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                    public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                        if (xtiPeer.isDisposed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                        Point pointer = (Point)AccessController.doPrivileged(new PrivilegedAction() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                                public Object run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                                    if (!isPointerOverTrayIcon(xtiPeer.getBounds())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                                        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                                    return MouseInfo.getPointerInfo().getLocation();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                            });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                        if (pointer == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                        show(new Point(pointer.x, pointer.y), TOOLTIP_MOUSE_CURSOR_INDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        void enter() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            XToolkit.schedule(starter, TOOLTIP_START_DELAY_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        void exit() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            XToolkit.remove(starter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            if (isVisible()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                hide();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        boolean isPointerOverTrayIcon(Rectangle trayRect) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            Point p = MouseInfo.getPointerInfo().getLocation();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
            return !(p.x < trayRect.x || p.x > (trayRect.x + trayRect.width) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                     p.y < trayRect.y || p.y > (trayRect.y + trayRect.height));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    static class Balloon extends InfoWindow {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        final static int BALLOON_SHOW_TIME = 10000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        final static int BALLOON_TEXT_MAX_LENGTH = 256;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        final static int BALLOON_WORD_LINE_MAX_LENGTH = 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        final static int BALLOON_WORD_LINE_MAX_COUNT = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        final static int BALLOON_ICON_WIDTH = 32;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        final static int BALLOON_ICON_HEIGHT = 32;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        final static int BALLOON_TRAY_ICON_INDENT = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
        final static Color BALLOON_CAPTION_BACKGROUND_COLOR = new Color(200, 200 ,255);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        final static Font BALLOON_CAPTION_FONT = new Font(Font.DIALOG, Font.BOLD, 12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        XTrayIconPeer xtiPeer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
        Panel mainPanel = new Panel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        Panel captionPanel = new Panel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        Label captionLabel = new Label("");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        Button closeButton = new Button("X");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        Panel textPanel = new Panel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        IconCanvas iconCanvas = new IconCanvas(BALLOON_ICON_WIDTH, BALLOON_ICON_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        Label[] lineLabels = new Label[BALLOON_WORD_LINE_MAX_COUNT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        ActionPerformer ap = new ActionPerformer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        Image iconImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        Image errorImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        Image warnImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        Image infoImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        boolean gtkImagesLoaded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        Displayer displayer = new Displayer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        Balloon(final XTrayIconPeer xtiPeer, Frame parent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            super(parent, new Color(90, 80 ,190));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            this.xtiPeer = xtiPeer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            suppressWarningString(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            setCloser(new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
                    public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                        if (textPanel != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                            textPanel.removeAll();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                            textPanel.setSize(0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                            iconCanvas.setSize(0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                            XToolkit.awtLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                                displayer.isDisplayed = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                                XToolkit.awtLockNotifyAll();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
                            } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
                                XToolkit.awtUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                }, BALLOON_SHOW_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
            add(mainPanel);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
            captionLabel.setFont(BALLOON_CAPTION_FONT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
            captionLabel.addMouseListener(ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            captionPanel.setLayout(new BorderLayout());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
            captionPanel.add(captionLabel, BorderLayout.WEST);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
            captionPanel.add(closeButton, BorderLayout.EAST);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
            captionPanel.setBackground(BALLOON_CAPTION_BACKGROUND_COLOR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
            captionPanel.addMouseListener(ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
            closeButton.addActionListener(new ActionListener() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                    public void actionPerformed(ActionEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                        hide();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            mainPanel.setLayout(new BorderLayout());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            mainPanel.setBackground(Color.white);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            mainPanel.add(captionPanel, BorderLayout.NORTH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            mainPanel.add(iconCanvas, BorderLayout.WEST);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            mainPanel.add(textPanel, BorderLayout.CENTER);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
            iconCanvas.addMouseListener(ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            for (int i = 0; i < BALLOON_WORD_LINE_MAX_COUNT; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                lineLabels[i] = new Label();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                lineLabels[i].addMouseListener(ap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                lineLabels[i].setBackground(Color.white);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
            displayer.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        void display(String caption, String text, String messageType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            if (!gtkImagesLoaded) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                loadGtkImages();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
            displayer.display(caption, text, messageType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        private void _display(String caption, String text, String messageType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
            captionLabel.setText(caption);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
            BreakIterator iter = BreakIterator.getWordInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
            if (text != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                iter.setText(text);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                int start = iter.first(), end;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                int nLines = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                    end = iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                    if (end == BreakIterator.DONE ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                        text.substring(start, end).length() >= 50)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
                        lineLabels[nLines].setText(text.substring(start, end == BreakIterator.DONE ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                                                                  iter.last() : end));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                        textPanel.add(lineLabels[nLines++]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                        start = end;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                    if (nLines == BALLOON_WORD_LINE_MAX_COUNT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                        if (end != BreakIterator.DONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                            lineLabels[nLines - 1].setText(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                                new String(lineLabels[nLines - 1].getText() + " ..."));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                } while (end != BreakIterator.DONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                textPanel.setLayout(new GridLayout(nLines, 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            if ("ERROR".equals(messageType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                iconImage = errorImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            } else if ("WARNING".equals(messageType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                iconImage = warnImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
            } else if ("INFO".equals(messageType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                iconImage = infoImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                iconImage = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            if (iconImage != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                Dimension tpSize = textPanel.getSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                iconCanvas.setSize(BALLOON_ICON_WIDTH, (BALLOON_ICON_HEIGHT > tpSize.height ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                                                        BALLOON_ICON_HEIGHT : tpSize.height));
431
6aea7c26a8dc 6637204: TrayIcon.displayMessage fails to show icon twice
dcherepanov
parents: 116
diff changeset
   836
                iconCanvas.validate();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            SunToolkit.executeOnEventHandlerThread(xtiPeer.target, new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                    public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                        if (xtiPeer.isDisposed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                        Point parLoc = getParent().getLocationOnScreen();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                        Dimension parSize = getParent().getSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                        show(new Point(parLoc.x + parSize.width/2, parLoc.y + parSize.height/2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                             BALLOON_TRAY_ICON_INDENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                        if (iconImage != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
                            iconCanvas.updateImage(iconImage); // call it after the show(..) above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        public void dispose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            displayer.interrupt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            super.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        void loadGtkImages() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            if (!gtkImagesLoaded) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                errorImage = (Image)Toolkit.getDefaultToolkit().getDesktopProperty(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    "gtk.icon.gtk-dialog-error.6.rtl");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                warnImage = (Image)Toolkit.getDefaultToolkit().getDesktopProperty(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                    "gtk.icon.gtk-dialog-warning.6.rtl");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                infoImage = (Image)Toolkit.getDefaultToolkit().getDesktopProperty(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                    "gtk.icon.gtk-dialog-info.6.rtl");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                gtkImagesLoaded = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        class ActionPerformer extends MouseAdapter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
            public void mouseClicked(MouseEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                // hide the balloon by any click
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                hide();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                if (e.getButton() == MouseEvent.BUTTON1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                    ActionEvent aev = new ActionEvent(xtiPeer.target, ActionEvent.ACTION_PERFORMED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                                                      xtiPeer.target.getActionCommand(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                                                      e.getWhen(), e.getModifiers());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(aev);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
        class Displayer extends Thread {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
            final int MAX_CONCURRENT_MSGS = 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
            ArrayBlockingQueue<Message> messageQueue = new ArrayBlockingQueue<Message>(MAX_CONCURRENT_MSGS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
            boolean isDisplayed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
            Displayer() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                setDaemon(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
            public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                    Message msg = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
                    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
                        msg = (Message)messageQueue.take();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
                    } catch (InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
                     * Wait till the previous message is displayed if any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
                    XToolkit.awtLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
                    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
                        while (isDisplayed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
                            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
                                XToolkit.awtLockWait();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
                            } catch (InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
                                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
                        isDisplayed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
                    } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
                        XToolkit.awtUnlock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
                    _display(msg.caption, msg.text, msg.messageType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
            void display(String caption, String text, String messageType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
                messageQueue.offer(new Message(caption, text, messageType));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
        class Message {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
            String caption, text, messageType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
            Message(String caption, String text, String messageType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
                this.caption = caption;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
                this.text = text;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
                this.messageType = messageType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
    static class InfoWindow extends Window {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
        Container container;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
        Closer closer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        InfoWindow(Frame parent, Color borderColor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
            super(parent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
            container = new Container() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
                    public Insets getInsets() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
                        return new Insets(1, 1, 1, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
                };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
            setLayout(new BorderLayout());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
            setBackground(borderColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
            add(container, BorderLayout.CENTER);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            container.setLayout(new BorderLayout());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            closer = new Closer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        public Component add(Component c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
            container.add(c, BorderLayout.CENTER);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            return c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        void setCloser(Runnable action, int time) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
            closer.set(action, time);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        // Must be executed on EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
        protected void show(Point corner, int indent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
            assert SunToolkit.isDispatchThreadForAppContext(InfoWindow.this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
            pack();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
            Dimension size = getSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
            // TODO: When 6356322 is fixed we should get screen bounds in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
            // this way: eframe.getGraphicsConfiguration().getBounds().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
            Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
            if (corner.x < scrSize.width/2 && corner.y < scrSize.height/2) { // 1st square
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
                setLocation(corner.x + indent, corner.y + indent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
            } else if (corner.x >= scrSize.width/2 && corner.y < scrSize.height/2) { // 2nd square
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                setLocation(corner.x - indent - size.width, corner.y + indent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
            } else if (corner.x < scrSize.width/2 && corner.y >= scrSize.height/2) { // 3rd square
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
                setLocation(corner.x + indent, corner.y - indent - size.height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
            } else if (corner.x >= scrSize.width/2 && corner.y >= scrSize.height/2) { // 4th square
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                setLocation(corner.x - indent - size.width, corner.y - indent - size.height);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
            InfoWindow.super.show();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
            InfoWindow.this.closer.schedule();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
        public void hide() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
            closer.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        class Closer implements Runnable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
            Runnable action;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
            int time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
            public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
                doClose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
            void set(Runnable action, int time) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
                this.action = action;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
                this.time = time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
            void schedule() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
                XToolkit.schedule(this, time);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
            void close() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                XToolkit.remove(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
                doClose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
            // WARNING: this method may be executed on Toolkit thread.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
            private void doClose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
                SunToolkit.executeOnEventHandlerThread(InfoWindow.this, new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
                        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
                            InfoWindow.super.hide();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
                            invalidate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
                            if (action != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
                                action.run();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
                    });
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
}