Search in sources :

Example 1 with SystemTray

use of java.awt.SystemTray in project jdk8u_jdk by JetBrains.

the class MostRecentKeyValue method dispose.

// Default to 1-second timeout for all
// interrupted Threads to exit, and another
// 1 second for all stopped Threads to die.
/**
     * Disposes of this AppContext, all of its top-level Frames, and
     * all Threads and ThreadGroups contained within it.
     *
     * This method must be called from a Thread which is not contained
     * within this AppContext.
     *
     * @exception  IllegalThreadStateException  if the current thread is
     *                                    contained within this AppContext
     * @since      1.2
     */
public void dispose() throws IllegalThreadStateException {
    // Check to be sure that the current Thread isn't in this AppContext
    if (this.threadGroup.parentOf(Thread.currentThread().getThreadGroup())) {
        throw new IllegalThreadStateException("Current Thread is contained within AppContext to be disposed.");
    }
    synchronized (this) {
        if (this.state != State.VALID) {
            // If already disposed or being disposed, bail.
            return;
        }
        this.state = State.BEING_DISPOSED;
    }
    final PropertyChangeSupport changeSupport = this.changeSupport;
    if (changeSupport != null) {
        changeSupport.firePropertyChange(DISPOSED_PROPERTY_NAME, false, true);
    }
    // First, we post an InvocationEvent to be run on the
    // EventDispatchThread which disposes of all top-level Frames and TrayIcons
    final Object notificationLock = new Object();
    Runnable runnable = new Runnable() {

        public void run() {
            Window[] windowsToDispose = Window.getOwnerlessWindows();
            for (Window w : windowsToDispose) {
                try {
                    w.dispose();
                } catch (Throwable t) {
                    log.finer("exception occurred while disposing app context", t);
                }
            }
            AccessController.doPrivileged(new PrivilegedAction<Void>() {

                public Void run() {
                    if (!GraphicsEnvironment.isHeadless() && SystemTray.isSupported()) {
                        SystemTray systemTray = SystemTray.getSystemTray();
                        TrayIcon[] trayIconsToDispose = systemTray.getTrayIcons();
                        for (TrayIcon ti : trayIconsToDispose) {
                            systemTray.remove(ti);
                        }
                    }
                    return null;
                }
            });
            // Alert PropertyChangeListeners that the GUI has been disposed.
            if (changeSupport != null) {
                changeSupport.firePropertyChange(GUI_DISPOSED, false, true);
            }
            synchronized (notificationLock) {
                // Notify caller that we're done
                notificationLock.notifyAll();
            }
        }
    };
    synchronized (notificationLock) {
        SunToolkit.postEvent(this, new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
        try {
            notificationLock.wait(DISPOSAL_TIMEOUT);
        } catch (InterruptedException e) {
        }
    }
    // Next, we post another InvocationEvent to the end of the
    // EventQueue.  When it's executed, we know we've executed all
    // events in the queue.
    runnable = new Runnable() {

        public void run() {
            synchronized (notificationLock) {
                // Notify caller that we're done
                notificationLock.notifyAll();
            }
        }
    };
    synchronized (notificationLock) {
        SunToolkit.postEvent(this, new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
        try {
            notificationLock.wait(DISPOSAL_TIMEOUT);
        } catch (InterruptedException e) {
        }
    }
    // We are done with posting events, so change the state to disposed
    synchronized (this) {
        this.state = State.DISPOSED;
    }
    // Next, we interrupt all Threads in the ThreadGroup
    this.threadGroup.interrupt();
    // Note, the EventDispatchThread we've interrupted may dump an
    // InterruptedException to the console here.  This needs to be
    // fixed in the EventDispatchThread, not here.
    // Next, we sleep 10ms at a time, waiting for all of the active
    // Threads in the ThreadGroup to exit.
    long startTime = System.currentTimeMillis();
    long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
    while ((this.threadGroup.activeCount() > 0) && (System.currentTimeMillis() < endTime)) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
        }
    }
    // Then, we stop any remaining Threads
    this.threadGroup.stop();
    // Next, we sleep 10ms at a time, waiting for all of the active
    // Threads in the ThreadGroup to die.
    startTime = System.currentTimeMillis();
    endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
    while ((this.threadGroup.activeCount() > 0) && (System.currentTimeMillis() < endTime)) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
        }
    }
    // Next, we remove this and all subThreadGroups from threadGroup2appContext
    int numSubGroups = this.threadGroup.activeGroupCount();
    if (numSubGroups > 0) {
        ThreadGroup[] subGroups = new ThreadGroup[numSubGroups];
        numSubGroups = this.threadGroup.enumerate(subGroups);
        for (int subGroup = 0; subGroup < numSubGroups; subGroup++) {
            threadGroup2appContext.remove(subGroups[subGroup]);
        }
    }
    threadGroup2appContext.remove(this.threadGroup);
    threadAppContext.set(null);
    // Finally, we destroy the ThreadGroup entirely.
    try {
        this.threadGroup.destroy();
    } catch (IllegalThreadStateException e) {
    // Fired if not all the Threads died, ignore it and proceed
    }
    synchronized (table) {
        // Clear out the Hashtable to ease garbage collection
        this.table.clear();
    }
    numAppContexts.decrementAndGet();
    mostRecentKeyValue = null;
}
Also used : Window(java.awt.Window) SystemTray(java.awt.SystemTray) PropertyChangeSupport(java.beans.PropertyChangeSupport) InvocationEvent(java.awt.event.InvocationEvent) TrayIcon(java.awt.TrayIcon)

Aggregations

SystemTray (java.awt.SystemTray)1 TrayIcon (java.awt.TrayIcon)1 Window (java.awt.Window)1 InvocationEvent (java.awt.event.InvocationEvent)1 PropertyChangeSupport (java.beans.PropertyChangeSupport)1