1 /*******************************************************************************
\r
2 * Copyright (c) 2007 SAS Institute.
\r
3 * All rights reserved. This program and the accompanying materials
\r
4 * are made available under the terms of the Eclipse Public License v1.0
\r
5 * which accompanies this distribution, and is available at
\r
6 * http://www.eclipse.org/legal/epl-v10.html
\r
9 * SAS Institute - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.utils.ui.awt;
\r
13 import java.awt.Component;
\r
14 import java.awt.Container;
\r
15 import java.awt.EventQueue;
\r
17 import javax.swing.LayoutFocusTraversalPolicy;
\r
20 public class EmbeddedChildFocusTraversalPolicy extends LayoutFocusTraversalPolicy {
\r
22 private static final long serialVersionUID = -7708166698501335927L;
\r
23 private final AwtFocusHandler awtHandler;
\r
25 public EmbeddedChildFocusTraversalPolicy(AwtFocusHandler handler) {
\r
26 assert handler != null;
\r
27 awtHandler = handler;
\r
30 public Component getComponentAfter(Container container, Component component) {
\r
31 assert container != null;
\r
32 assert component != null;
\r
33 assert awtHandler != null;
\r
34 assert EventQueue.isDispatchThread(); // On AWT event thread
\r
36 if (component.equals(getLastComponent(container))) {
\r
37 // Instead of cycling around to the first component, transfer to the next SWT component
\r
38 awtHandler.transferFocusNext();
\r
41 return super.getComponentAfter(container, component);
\r
45 public Component getComponentBefore(Container container, Component component) {
\r
46 assert container != null;
\r
47 assert component != null;
\r
48 assert awtHandler != null;
\r
49 assert EventQueue.isDispatchThread(); // On AWT event thread
\r
51 if (component.equals(getFirstComponent(container))) {
\r
52 // Instead of cycling around to the last component, transfer to the previous SWT component
\r
53 awtHandler.transferFocusPrevious();
\r
56 return super.getComponentBefore(container, component);
\r
60 public Component getDefaultComponent(Container container) {
\r
61 assert container != null;
\r
62 assert awtHandler != null;
\r
63 assert EventQueue.isDispatchThread(); // On AWT event thread
\r
65 // This is a hack which depends on knowledge of current JDK implementation to
\r
66 // work. The implementation above of getComponentBefore/After
\r
67 // properly returns null when transferring to SWT. However, the calling AWT container
\r
68 // will then immediately try this method to find the next recipient of
\r
69 // focus. But we don't want *any* AWT component to receive focus... it's just
\r
70 // been transferred to SWT. So, this method must return null when AWT does
\r
71 // not own the focus. When AWT *does* own the focus, behave normally.
\r
72 if (awtHandler.awtHasFocus()) {
\r
73 // System.out.println("getDefault: super");
\r
74 return super.getDefaultComponent(container);
\r
76 // System.out.println("getDefault: null");
\r
81 public Component getCurrentComponent(Container container) {
\r
82 assert container != null;
\r
83 assert awtHandler != null;
\r
84 assert EventQueue.isDispatchThread(); // On AWT event thread
\r
86 Component currentAwtComponent = awtHandler.getCurrentComponent();
\r
87 if ((currentAwtComponent != null) && container.isAncestorOf(currentAwtComponent)){
\r
88 return currentAwtComponent;
\r
90 return getDefaultComponent(container);
\r