]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/EmbeddedChildFocusTraversalPolicy.java
Introduce WrapLayout to replace FlowLayout
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / internal / awt / EmbeddedChildFocusTraversalPolicy.java
diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/EmbeddedChildFocusTraversalPolicy.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/EmbeddedChildFocusTraversalPolicy.java
new file mode 100644 (file)
index 0000000..b43832a
--- /dev/null
@@ -0,0 +1,93 @@
+/*******************************************************************************\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