]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/internal/awt/EmbeddedChildFocusTraversalPolicy.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / internal / awt / EmbeddedChildFocusTraversalPolicy.java
1 /*******************************************************************************
2  * Copyright (c) 2007 SAS Institute.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     SAS Institute - initial API and implementation
10  *******************************************************************************/
11 package org.simantics.utils.ui.internal.awt;
12
13 import java.awt.Component;
14 import java.awt.Container;
15 import java.awt.EventQueue;
16
17 import javax.swing.LayoutFocusTraversalPolicy;
18
19
20 public class EmbeddedChildFocusTraversalPolicy extends LayoutFocusTraversalPolicy {
21
22     private static final long serialVersionUID = -7708166698501335927L;
23     private final AwtFocusHandler awtHandler;
24
25     public EmbeddedChildFocusTraversalPolicy(AwtFocusHandler handler) {
26          assert handler != null;
27          awtHandler = handler;
28     }
29
30     public Component getComponentAfter(Container container, Component component) {
31         assert container != null;
32         assert component != null;
33         assert awtHandler != null;
34         assert EventQueue.isDispatchThread();    // On AWT event thread
35         
36         if (component.equals(getLastComponent(container))) {
37             // Instead of cycling around to the first component, transfer to the next SWT component
38             awtHandler.transferFocusNext();
39             return null;
40         } else {
41             return super.getComponentAfter(container, component);
42         }
43     }
44
45     public Component getComponentBefore(Container container, Component component) {
46         assert container != null;
47         assert component != null;
48         assert awtHandler != null;
49         assert EventQueue.isDispatchThread();    // On AWT event thread
50         
51         if (component.equals(getFirstComponent(container))) {
52             // Instead of cycling around to the last component, transfer to the previous SWT component
53             awtHandler.transferFocusPrevious();
54             return null;
55         } else {
56             return super.getComponentBefore(container, component);
57         }
58     }
59     
60     public Component getDefaultComponent(Container container) {
61         assert container != null;
62         assert awtHandler != null;
63         assert EventQueue.isDispatchThread();    // On AWT event thread
64         
65         // This is a hack which depends on knowledge of current JDK implementation to 
66         // work. The implementation above of getComponentBefore/After
67         // properly returns null when transferring to SWT. However, the calling AWT container
68         // will then immediately try this method to find the next recipient of
69         // focus. But we don't want *any* AWT component to receive focus... it's just
70         // been transferred to SWT. So, this method must return null when AWT does 
71         // not own the focus. When AWT *does* own the focus, behave normally.  
72         if (awtHandler.awtHasFocus()) {
73             // System.out.println("getDefault: super");
74             return super.getDefaultComponent(container);
75         } else {
76             // System.out.println("getDefault: null");
77             return null;
78         }
79     }
80
81     public Component getCurrentComponent(Container container) {
82         assert container != null;
83         assert awtHandler != null;
84         assert EventQueue.isDispatchThread();    // On AWT event thread
85         
86         Component currentAwtComponent = awtHandler.getCurrentComponent();
87         if ((currentAwtComponent != null) && container.isAncestorOf(currentAwtComponent)){
88             return currentAwtComponent;
89         } else {
90             return getDefaultComponent(container);
91         }
92     }
93 }