X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Finternal%2Fawt%2FSwtFocusHandler.java;h=93433d0a5a7906765de46f332b66423df249efb5;hb=refs%2Fchanges%2F38%2F238%2F2;hp=9c73ab6f9669b12dfe5a1a4898152241de9d5171;hpb=ac5f1da15cc639da880fea86a7b828c8fa2e1b7e;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/SwtFocusHandler.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/SwtFocusHandler.java index 9c73ab6f9..93433d0a5 100644 --- a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/SwtFocusHandler.java +++ b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/SwtFocusHandler.java @@ -1,162 +1,162 @@ -/******************************************************************************* - * 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.internal.awt; - -import java.awt.EventQueue; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -public class SwtFocusHandler implements FocusListener, KeyListener { - - private Composite composite; - private final Display display; - private AwtFocusHandler awtHandler; - - public SwtFocusHandler(Composite composite) { - assert composite != null; - assert Display.getCurrent() != null; // On SWT event thread - - this.composite = composite; - display = composite.getDisplay(); - composite.addFocusListener(this); - composite.addKeyListener(this); - } - - public void setAwtHandler(AwtFocusHandler handler) { - assert handler != null; - assert awtHandler == null; // this method is meant to be called once - assert composite != null; - assert Display.getCurrent() != null; // On SWT event thread - - awtHandler = handler; - - // Dismiss Swing popups when the main window is moved. (It would be - // better to dismiss popups whenever the titlebar is clicked, but - // there does not seem to be a way.) - final ControlAdapter controlAdapter = new ControlAdapter() { - public void controlMoved(ControlEvent e) { - assert awtHandler != null; - awtHandler.postHidePopups(); - } - }; - final Shell shell = composite.getShell(); - shell.addControlListener(controlAdapter); - - // Cleanup listeners on dispose - composite.addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - // Remove listener from shell before nullifying awtHandler - shell.removeControlListener(controlAdapter); - awtHandler.dispose(); - awtHandler = null; - composite = null; - } - }); - } - - void gainFocusNext() { - traverse(SWT.TRAVERSE_TAB_NEXT); - } - - void gainFocusPrevious() { - traverse(SWT.TRAVERSE_TAB_PREVIOUS); - } - - private void traverse(final int traversal) { - //assert composite != null; - if (composite == null) - return; - - // Tab from the containing SWT component while - // running on the SWT thread - Runnable r = new Runnable() { - public void run() { - composite.traverse(traversal); - } - }; - display.asyncExec(r); - } - -// boolean hasFocus() { -// assert composite != null; -// -// // This will return true if the composite has focus, or if any -// // foreign (e.g. AWT) child of the composite has focus. -// if (display.isDisposed()) { -// return false; -// } -// final boolean[] result = new boolean[1]; -// display.syncExec(new Runnable() { -// public void run() { -// result[0] = (!composite.isDisposed() && -// (display.getFocusControl() == composite)); -// } -// }); -// return result[0]; -// } - - // ..................... Listener implementations - - public void focusGained(FocusEvent e) { - assert awtHandler != null; - assert Display.getCurrent() != null; // On SWT event thread - - // System.out.println("Gained: " + e.toString() + " (" + e.widget.getClass().getName() + ")"); - EventQueue.invokeLater(new Runnable() { - public void run() { - // composite DisposeListener may have nullified this meanwhile! - // Not a bug. - if (awtHandler != null) - awtHandler.gainFocus(); - } - }); - } - - public void focusLost(FocusEvent e) { - // System.out.println("Lost: " + e.toString() + " (" + e.widget.getClass().getName() + ")"); - } - - public void keyPressed(KeyEvent e) { - assert Display.getCurrent() != null; // On SWT event thread - - // If the embedded swing root pane has no components to receive focus, - // then there will be cases where the parent SWT composite will keep - // focus. (For example, when tabbing into the root pane container). - // By default, in these cases, the focus is swallowed by the Composite - // and never escapes. This code allows tab and back-tab to do the - // proper traversal to other SWT components from the composite. - // TODO: other keys? - if (e.keyCode == SWT.TAB) { - // TODO: In some cases, this gobbles up all the tabs, even from AWT children. Find a more selective way. - /*if (e.stateMask == SWT.NONE) { - traverse(SWT.TRAVERSE_TAB_NEXT); - } else if (e.stateMask == SWT.SHIFT) { - traverse(SWT.TRAVERSE_TAB_PREVIOUS); - }*/ - } - } - - public void keyReleased(KeyEvent e) { - } - - -} +/******************************************************************************* + * 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.internal.awt; + +import java.awt.EventQueue; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +public class SwtFocusHandler implements FocusListener, KeyListener { + + private Composite composite; + private final Display display; + private AwtFocusHandler awtHandler; + + public SwtFocusHandler(Composite composite) { + assert composite != null; + assert Display.getCurrent() != null; // On SWT event thread + + this.composite = composite; + display = composite.getDisplay(); + composite.addFocusListener(this); + composite.addKeyListener(this); + } + + public void setAwtHandler(AwtFocusHandler handler) { + assert handler != null; + assert awtHandler == null; // this method is meant to be called once + assert composite != null; + assert Display.getCurrent() != null; // On SWT event thread + + awtHandler = handler; + + // Dismiss Swing popups when the main window is moved. (It would be + // better to dismiss popups whenever the titlebar is clicked, but + // there does not seem to be a way.) + final ControlAdapter controlAdapter = new ControlAdapter() { + public void controlMoved(ControlEvent e) { + assert awtHandler != null; + awtHandler.postHidePopups(); + } + }; + final Shell shell = composite.getShell(); + shell.addControlListener(controlAdapter); + + // Cleanup listeners on dispose + composite.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + // Remove listener from shell before nullifying awtHandler + shell.removeControlListener(controlAdapter); + awtHandler.dispose(); + awtHandler = null; + composite = null; + } + }); + } + + void gainFocusNext() { + traverse(SWT.TRAVERSE_TAB_NEXT); + } + + void gainFocusPrevious() { + traverse(SWT.TRAVERSE_TAB_PREVIOUS); + } + + private void traverse(final int traversal) { + //assert composite != null; + if (composite == null) + return; + + // Tab from the containing SWT component while + // running on the SWT thread + Runnable r = new Runnable() { + public void run() { + composite.traverse(traversal); + } + }; + display.asyncExec(r); + } + +// boolean hasFocus() { +// assert composite != null; +// +// // This will return true if the composite has focus, or if any +// // foreign (e.g. AWT) child of the composite has focus. +// if (display.isDisposed()) { +// return false; +// } +// final boolean[] result = new boolean[1]; +// display.syncExec(new Runnable() { +// public void run() { +// result[0] = (!composite.isDisposed() && +// (display.getFocusControl() == composite)); +// } +// }); +// return result[0]; +// } + + // ..................... Listener implementations + + public void focusGained(FocusEvent e) { + assert awtHandler != null; + assert Display.getCurrent() != null; // On SWT event thread + + // System.out.println("Gained: " + e.toString() + " (" + e.widget.getClass().getName() + ")"); + EventQueue.invokeLater(new Runnable() { + public void run() { + // composite DisposeListener may have nullified this meanwhile! + // Not a bug. + if (awtHandler != null) + awtHandler.gainFocus(); + } + }); + } + + public void focusLost(FocusEvent e) { + // System.out.println("Lost: " + e.toString() + " (" + e.widget.getClass().getName() + ")"); + } + + public void keyPressed(KeyEvent e) { + assert Display.getCurrent() != null; // On SWT event thread + + // If the embedded swing root pane has no components to receive focus, + // then there will be cases where the parent SWT composite will keep + // focus. (For example, when tabbing into the root pane container). + // By default, in these cases, the focus is swallowed by the Composite + // and never escapes. This code allows tab and back-tab to do the + // proper traversal to other SWT components from the composite. + // TODO: other keys? + if (e.keyCode == SWT.TAB) { + // TODO: In some cases, this gobbles up all the tabs, even from AWT children. Find a more selective way. + /*if (e.stateMask == SWT.NONE) { + traverse(SWT.TRAVERSE_TAB_NEXT); + } else if (e.stateMask == SWT.SHIFT) { + traverse(SWT.TRAVERSE_TAB_PREVIOUS); + }*/ + } + } + + public void keyReleased(KeyEvent e) { + } + + +}