[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Newsgroup Home]
|
[news.eclipse.platform.swt] Re: When can setFocus return false?
|
Hi Grant,
thanks for response. After some research, I was able to find the
mechanism, how this happens - and it seems like SWT is fine.
We have a framework which performs some checks when editor (Text) looses
focus. These checks might involve a server call which is done async and
while waiting for it's completition, the framework spins
display.readAndDispatch() to keep UI responsive.
When it happens that the test automation thread fits it's asyncExecuted
setFocus call into this 'inside' event loop, the setFocus returns false.
The mechanism is illustrated in the attached snippet.
So it seems, that the problem is caused by the fact, that we run
display.readAndDispatch() from inside of FocusOut handling (or in other
words, that we call setFocus from inside of FocusOut handling).
If I get it correctly, the lesson learn is that no "rich" (i.e.
involving unknown listeners) code should be executer directly from SWT
event handlers, but rather display.asyncExec should be used to run them
with "clean" stack trace. Is this correct?
Thanks,
Michal
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
public class SetFocusTest3
{
public static void main(String[] args)
{
final Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
final Text t1 = new Text(shell, SWT.SINGLE | SWT.BORDER);
t1.setText("setFocus target");
final Text t2 = new Text(shell, SWT.SINGLE | SWT.BORDER);
t2.setText("Tab Source. Focus here and press TAB");
final Text t3 = new Text(shell, SWT.SINGLE | SWT.BORDER);
t3.setText("Tab Target");
t2.addListener(SWT.FocusOut, new Listener() {
public void handleEvent(Event event) {
System.out.println("Focus out, " + event.widget);
// this would have the same false Result
// System.out.println("setFocus: " + t1.setFocus());
// This happens in parallel from other thread
display.asyncExec(new Runnable() {
public void run() {
System.out.println("setFocus: " + t1.setFocus());
}
});
// Chain of events leads to waiting for some background work
// which launches the event loop
long timeout = System.currentTimeMillis() + 200;
while(timeout > System.currentTimeMillis()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}});
t3.addListener(SWT.FocusIn, new Listener() {
public void handleEvent(Event event) {
System.out.println("Focus in, " + event.widget);
}
});
shell.pack();
shell.open ();
while (!shell.isDisposed()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}