--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007 SAS Institute.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * SAS Institute - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.utils.ui.internal.awt;\r
+\r
+import java.awt.Component;\r
+import java.awt.Container;\r
+import java.awt.EventQueue;\r
+\r
+import javax.swing.LayoutFocusTraversalPolicy;\r
+\r
+\r
+public class EmbeddedChildFocusTraversalPolicy extends LayoutFocusTraversalPolicy {\r
+\r
+ private static final long serialVersionUID = -7708166698501335927L;\r
+ private final AwtFocusHandler awtHandler;\r
+\r
+ public EmbeddedChildFocusTraversalPolicy(AwtFocusHandler handler) {\r
+ assert handler != null;\r
+ awtHandler = handler;\r
+ }\r
+\r
+ public Component getComponentAfter(Container container, Component component) {\r
+ assert container != null;\r
+ assert component != null;\r
+ assert awtHandler != null;\r
+ assert EventQueue.isDispatchThread(); // On AWT event thread\r
+ \r
+ if (component.equals(getLastComponent(container))) {\r
+ // Instead of cycling around to the first component, transfer to the next SWT component\r
+ awtHandler.transferFocusNext();\r
+ return null;\r
+ } else {\r
+ return super.getComponentAfter(container, component);\r
+ }\r
+ }\r
+\r
+ public Component getComponentBefore(Container container, Component component) {\r
+ assert container != null;\r
+ assert component != null;\r
+ assert awtHandler != null;\r
+ assert EventQueue.isDispatchThread(); // On AWT event thread\r
+ \r
+ if (component.equals(getFirstComponent(container))) {\r
+ // Instead of cycling around to the last component, transfer to the previous SWT component\r
+ awtHandler.transferFocusPrevious();\r
+ return null;\r
+ } else {\r
+ return super.getComponentBefore(container, component);\r
+ }\r
+ }\r
+ \r
+ public Component getDefaultComponent(Container container) {\r
+ assert container != null;\r
+ assert awtHandler != null;\r
+ assert EventQueue.isDispatchThread(); // On AWT event thread\r
+ \r
+ // This is a hack which depends on knowledge of current JDK implementation to \r
+ // work. The implementation above of getComponentBefore/After\r
+ // properly returns null when transferring to SWT. However, the calling AWT container\r
+ // will then immediately try this method to find the next recipient of\r
+ // focus. But we don't want *any* AWT component to receive focus... it's just\r
+ // been transferred to SWT. So, this method must return null when AWT does \r
+ // not own the focus. When AWT *does* own the focus, behave normally. \r
+ if (awtHandler.awtHasFocus()) {\r
+ // System.out.println("getDefault: super");\r
+ return super.getDefaultComponent(container);\r
+ } else {\r
+ // System.out.println("getDefault: null");\r
+ return null;\r
+ }\r
+ }\r
+\r
+ public Component getCurrentComponent(Container container) {\r
+ assert container != null;\r
+ assert awtHandler != null;\r
+ assert EventQueue.isDispatchThread(); // On AWT event thread\r
+ \r
+ Component currentAwtComponent = awtHandler.getCurrentComponent();\r
+ if ((currentAwtComponent != null) && container.isAncestorOf(currentAwtComponent)){\r
+ return currentAwtComponent;\r
+ } else {\r
+ return getDefaultComponent(container);\r
+ }\r
+ }\r
+}\r