X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Fawt%2FAwtDialogListener.java;fp=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Fawt%2FAwtDialogListener.java;h=0000000000000000000000000000000000000000;hb=ac5f1da15cc639da880fea86a7b828c8fa2e1b7e;hp=25728b8e220510aadc63cc8683cf7daa74ee5690;hpb=b8392422ec5b5961202d941ec447018526d26dd2;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/awt/AwtDialogListener.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/awt/AwtDialogListener.java deleted file mode 100644 index 25728b8e2..000000000 --- a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/awt/AwtDialogListener.java +++ /dev/null @@ -1,225 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 SAS Institute. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * SAS Institute - initial API and implementation - *******************************************************************************/ -package org.simantics.utils.ui.awt; - -import java.awt.AWTEvent; -import java.awt.Dialog; -import java.awt.EventQueue; -import java.awt.Toolkit; -import java.awt.Window; -import java.awt.event.AWTEventListener; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.widgets.Display; - -/** - * A listener that insures the proper modal behavior of Swing dialogs when running - * within a SWT environment. When initialized, it blocks and unblocks SWT input - * as modal Swing dialogs are shown and hidden. - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -class AwtDialogListener implements AWTEventListener, ComponentListener { - - // modalDialogs should be accessed only from the AWT thread, so no - // synchronization is needed. - private final List modalDialogs = new ArrayList(); - private final Display display; - - /** - * Registers this object as an AWT event listener so that Swing dialogs have the - * proper modal behavior in the containing SWT environment. This is called automatically - * when you construct a {@link EmbeddedSwingComposite}, and it - * need not be called separately in that case. - * @param shell - */ - AwtDialogListener(Display display) { - assert display != null; - - this.display = display; - Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.WINDOW_EVENT_MASK); - } - - private void handleRemovedDialog(Dialog awtDialog, boolean removeListener) { - assert awtDialog != null; - assert modalDialogs != null; - assert display != null; - assert EventQueue.isDispatchThread(); // On AWT event thread - - // System.out.println("Remove dialog: " + awtDialog); - if (removeListener) { - awtDialog.removeComponentListener(this); - } - // Note: there is no isModal() check here because the dialog might - // have been changed from modal to non-modal after it was opened. In this case - // the currently visible dialog would still act modal and we'd need to unblock - // SWT here when it goes away. - if (modalDialogs.remove(awtDialog)) { - display.asyncExec(new Runnable() { - public void run() { - SwtInputBlocker.unblock(); - } - }); - } - } - - private void handleAddedDialog(final Dialog awtDialog) { - assert awtDialog != null; - assert modalDialogs != null; - assert EventQueue.isDispatchThread(); // On AWT event thread - - // System.out.println("Add dialog: " + awtDialog); - if (modalDialogs.contains(awtDialog) || !awtDialog.isModal() || !awtDialog.isVisible()) { - return; - } - modalDialogs.add(awtDialog); - awtDialog.addComponentListener(this); - display.asyncExec(new Runnable() { - public void run() { - SwtInputBlocker.block(); - } - }); - } - - void requestFocus() { - // TODO: this does not always bring the dialog to the top - // under some Linux desktops/window managers (e.g. metacity under GNOME). - EventQueue.invokeLater(new Runnable() { - public void run() { - assert modalDialogs != null; - - int size = modalDialogs.size(); - if (size > 0) { - final Dialog awtDialog = (Dialog)modalDialogs.get(size - 1); - - // In one case, a call to requestFocus() alone does not - // bring the AWT dialog to the top. This happens if the - // dialog is given a null parent frame. When opened, the dialog - // can be hidden by the SWT window even when it obtains focus. - // Calling toFront() solves the problem, but... - // - // There are still problems if the Metal look and feel is in use. - // The SWT window will hide the dialog the first time it is - // selected. Once the dialog is brought back to the front by - // the user, there is no further problem. - // - // Why? It looks like SWT is not being notified of lost focus when - // the Metal dialog first opens; subsequently, when focus is regained, the - // focus gain event is not posted to the SwtInputBlocker. - // - // The workaround is to use Windows look and feel, rather than Metal. - // System.out.println("Bringing to front"); - - awtDialog.requestFocus(); - awtDialog.toFront(); - } - } - }); - } - - private void handleOpenedWindow(WindowEvent event) { - assert event != null; - assert EventQueue.isDispatchThread(); // On AWT event thread - - Window window = event.getWindow(); - if (window instanceof Dialog) { - handleAddedDialog((Dialog)window); - } - } - - private void handleClosedWindow(WindowEvent event) { - assert event != null; - assert EventQueue.isDispatchThread(); // On AWT event thread - - // Dispose-based close - Window window = event.getWindow(); - if (window instanceof Dialog) { - // Remove dialog and component listener - handleRemovedDialog((Dialog)window, true); - } - } - - private void handleClosingWindow(WindowEvent event) { - assert event != null; - assert EventQueue.isDispatchThread(); // On AWT event thread - - // System-based close - Window window = event.getWindow(); - if (window instanceof Dialog) { - final Dialog dialog = (Dialog) window; - // Defer until later. Bad things happen if - // handleRemovedDialog() is called directly from - // this event handler. The Swing dialog does not close - // properly and its modality remains in effect. - EventQueue.invokeLater(new Runnable() { - public void run() { - // Remove dialog and component listener - handleRemovedDialog(dialog, true); - } - }); - } - } - - public void eventDispatched(AWTEvent event) { - assert event != null; - assert EventQueue.isDispatchThread(); // On AWT event thread - - switch (event.getID()) { - case WindowEvent.WINDOW_OPENED: - handleOpenedWindow((WindowEvent)event); - break; - - case WindowEvent.WINDOW_CLOSED: - handleClosedWindow((WindowEvent)event); - break; - - case WindowEvent.WINDOW_CLOSING: - handleClosingWindow((WindowEvent)event); - break; - - default: - break; - } - } - - public void componentHidden(ComponentEvent e) { - assert e != null; - assert EventQueue.isDispatchThread(); // On AWT event thread - - // System.out.println("Component hidden"); - Object obj = e.getSource(); - if (obj instanceof Dialog) { - // Remove dialog but keep listener in place so that we know if/when it is set visible - handleRemovedDialog((Dialog)obj, false); - } - } - - public void componentShown(ComponentEvent e) { - assert e != null; - assert EventQueue.isDispatchThread(); // On AWT event thread - - // System.out.println("Component shown"); - Object obj = e.getSource(); - if (obj instanceof Dialog) { - handleAddedDialog((Dialog)obj); - } - } - - public void componentResized(ComponentEvent e) { - } - - public void componentMoved(ComponentEvent e) { - } - -}