[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [albireo-dev] Focus Management Test Cases
|
Gordon Hirsch wrote:
> I have a different, simpler way of tracing the AWT focus events. It uses
> a property change listener on the keyboard focus manager. It's a little
> more helpful to me because it also tracks events on AWT dialogs.
Good.
> I'm committing this debug code to AwtEnvironment. If it can provide all
> the AWT information that the FocusDebugging provides, then I suggest
> keeping only this simpler version of the trace code and removing the AWT
> tracing from FocusDebugging.
With the example test case (I will soon rebuild for your testing) it
became clear to me that focus handling is a multi-player game. The players
involved are:
1- The focus manager of the SWT window,
2- The focus handling of the native SWT peer of the SwingControl,
3- The focus handling of the native AWT peer of the EmbeddedFrame,
4- The focus handling of each AWT Component in it,
5- The global AWT KeyboardFocusManager.
When you have a bug, you need to collect the focus-related information of
as many players as possible. Your debugging code gives info about player #5.
Mine gives info about players #2, #3, #4.
So the codes are complementary. It would be an illusion to think you can
understand focus bugs (and find reliable workarounds) by looking only at #5.
I'm integrating both debugging codes in the same class, because too much
debugging code in the main source code can clutter up the real code.
Bruno
Index: src/org/eclipse/albireo/core/SwingControl.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/core/SwingControl.java,v
retrieving revision 1.28
diff -c -3 -r1.28 SwingControl.java
*** src/org/eclipse/albireo/core/SwingControl.java 12 Feb 2008 15:11:38 -0000 1.28
--- src/org/eclipse/albireo/core/SwingControl.java 13 Feb 2008 19:11:12 -0000
***************
*** 47,56 ****
// Whether to print debugging information regarding size propagation
// and layout.
! private static final boolean verboseSizeLayout = false;
// Whether to print debugging information regarding focus events.
! private static final boolean verboseFocusEvents = false;
private Listener settingsListener = new Listener() {
public void handleEvent(Event event) {
--- 47,56 ----
// Whether to print debugging information regarding size propagation
// and layout.
! static final boolean verboseSizeLayout = false;
// Whether to print debugging information regarding focus events.
! static final boolean verboseFocusEvents = false;
private Listener settingsListener = new Listener() {
public void handleEvent(Event event) {
Index: src/org/eclipse/albireo/core/AwtEnvironment.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/core/AwtEnvironment.java,v
retrieving revision 1.7
diff -c -3 -r1.7 AwtEnvironment.java
*** src/org/eclipse/albireo/core/AwtEnvironment.java 11 Feb 2008 22:46:31 -0000 1.7
--- src/org/eclipse/albireo/core/AwtEnvironment.java 13 Feb 2008 19:11:12 -0000
***************
*** 25,30 ****
--- 25,31 ----
import javax.swing.UnsupportedLookAndFeelException;
+ import org.eclipse.albireo.internal.FocusDebugging;
import org.eclipse.albireo.internal.SwtInputBlocker;
import org.eclipse.albireo.internal.AwtDialogListener;
import org.eclipse.swt.SWT;
***************
*** 141,159 ****
EventQueue.invokeAndWait(new Runnable() {
public void run() {
setLookAndFeel();
!
! // if (focusDebugListener == null) {
! // focusDebugListener = new PropertyChangeListener() {
! // public void propertyChange(PropertyChangeEvent event) {
! // System.out.println("@"+System.currentTimeMillis() +
! // " " + event.getPropertyName() +
! // " new=" + event.getNewValue() +
! // " old=" + event.getOldValue());
! // }
! // };
! // KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
! // focusManager.addPropertyChangeListener(focusDebugListener);
! // }
}
});
} catch (InterruptedException e) {
--- 142,149 ----
EventQueue.invokeAndWait(new Runnable() {
public void run() {
setLookAndFeel();
! if (SwingControl.verboseFocusEvents)
! FocusDebugging.addFocusDebugListenerOnKeyboardFocusManager();
}
});
} catch (InterruptedException e) {
Index: src/org/eclipse/albireo/internal/FocusDebugging.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.albireo/org.eclipse.albireo.core/src/org/eclipse/albireo/internal/FocusDebugging.java,v
retrieving revision 1.1
diff -c -3 -r1.1 FocusDebugging.java
*** src/org/eclipse/albireo/internal/FocusDebugging.java 12 Feb 2008 15:11:38 -0000 1.1
--- src/org/eclipse/albireo/internal/FocusDebugging.java 13 Feb 2008 19:11:12 -0000
***************
*** 21,26 ****
--- 21,28 ----
import java.awt.event.FocusListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
+ import java.beans.PropertyChangeEvent;
+ import java.beans.PropertyChangeListener;
/**
* This class contains utility functions for debugging focus issues relating
***************
*** 31,48 ****
* application window to be deactivated. Therefore a println based approach
* has been adopted.
* <p>
! * There are three kinds of events:
* <ul>
* <li>SWT focus events relating to the IlvSwingControl.</li>
* <li>AWT window focus events relating to the topmost window under the
* IlvSwingControl.</li>
* <li>AWT focus events relating to components inside that window.</li>
* </ul>
*/
public class FocusDebugging {
/**
! * Adds listeners for debugging all kinds of focus events.
*/
public static void addFocusDebugListeners(org.eclipse.swt.widgets.Composite control,
Container topLevelComponent) {
--- 33,52 ----
* application window to be deactivated. Therefore a println based approach
* has been adopted.
* <p>
! * There are four kinds of events:
* <ul>
* <li>SWT focus events relating to the IlvSwingControl.</li>
* <li>AWT window focus events relating to the topmost window under the
* IlvSwingControl.</li>
* <li>AWT focus events relating to components inside that window.</li>
+ * <li>Property change events of the AWT
+ * <code>KeyboardFocusManager</code>.</li>
* </ul>
*/
public class FocusDebugging {
/**
! * Adds listeners for debugging the three first kinds of focus events.
*/
public static void addFocusDebugListeners(org.eclipse.swt.widgets.Composite control,
Container topLevelComponent) {
***************
*** 71,91 ****
* Shows focus events on the top-level window on the AWT side.
*/
private static class AWTWindowFocusListener implements WindowFocusListener {
public void windowGainedFocus(WindowEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" AWT focus gained by window "+event.getWindow());
! KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
! System.err.println("owner1: "+kfm.getPermanentFocusOwner());
! System.err.println("owner2: "+kfm.getFocusOwner());
! System.err.println("owner3: "+event.getWindow().getFocusOwner());
}
public void windowLostFocus(WindowEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" AWT focus lost by window "+event.getWindow());
! KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
! System.err.println("owner1: "+kfm.getPermanentFocusOwner());
! System.err.println("owner2: "+kfm.getFocusOwner());
! System.err.println("owner3: "+event.getWindow().getFocusOwner());
}
}
private static AWTWindowFocusListener _AWTWindowFocusListener = new AWTWindowFocusListener();
--- 75,95 ----
* Shows focus events on the top-level window on the AWT side.
*/
private static class AWTWindowFocusListener implements WindowFocusListener {
+ private void showKFMStatus(Window window) {
+ KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ System.err.println(" permanentFocusOwner: "+kfm.getPermanentFocusOwner());
+ System.err.println(" focusOwner: "+kfm.getFocusOwner());
+ System.err.println(" window's focusOwner: "+window.getFocusOwner());
+ }
public void windowGainedFocus(WindowEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" AWT focus gained by window "+event.getWindow());
! showKFMStatus(event.getWindow());
}
public void windowLostFocus(WindowEvent event) {
System.err.println("@"+System.currentTimeMillis()
+" AWT focus lost by window "+event.getWindow());
! showKFMStatus(event.getWindow());
}
}
private static AWTWindowFocusListener _AWTWindowFocusListener = new AWTWindowFocusListener();
***************
*** 143,146 ****
--- 147,172 ----
}
}
+ // ------------------------------------------------------------------------
+
+ private static PropertyChangeListener focusDebugListener;
+
+ /**
+ * Adds listeners for debugging the fourth kind of focus events,
+ * on the AWT <code>KeyboardFocusManager</code> singleton.
+ */
+ public static void addFocusDebugListenerOnKeyboardFocusManager() {
+ if (focusDebugListener == null) {
+ focusDebugListener = new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ System.err.println("@"+System.currentTimeMillis()
+ + " AWT KFMPC " + event.getPropertyName()
+ + " new=" + event.getNewValue()
+ + " old=" + event.getOldValue());
+ }
+ };
+ KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ focusManager.addPropertyChangeListener(focusDebugListener);
+ }
+ }
}