| Summary: | Shell.setDefaultButton is not working. | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Eduardo Pereira <eduardo_pereira> |
| Component: | SWT | Assignee: | Steve Northover <snorthov> |
| Status: | RESOLVED WONTFIX | QA Contact: | |
| Severity: | enhancement | ||
| Priority: | P3 | CC: | Kevin_Haaland, Tod_Creasey |
| Version: | 1.0 | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | |||
| Bug Depends on: | |||
| Bug Blocks: | 7700, 13002 | ||
I have never understood how this code works. Last time I checked, it was working properly, but non-intuitively. SN to either fix the bug, or explain why it should be working the way it is. Fixed > 20020426 Tested build 0508 and the problem is still happening. We put in code that attempted to fix the first problem by assigning focus to the default button if no focus was assigned by the programmer. Not only did this break Eclipse, it was a dumb thing to do. Setting focus to the button was useless because the user can hit return to activate the button. Setting the focus to a single line text field in the same window for example would be more useful. I can now see that setting focus to the default button when no focus is assigned only makes sense in the case that you have (ie. there are no widgets, other than buttons in the window). This case seems too specific for SWT to code and ensure on all platforms. I suggest that you set both the focus and the default button. This should work fine. The problem is actually with not having a focus widget now (20020925).
If you instead run the code below you will see that the default button is
correct because we have set focus on a different widget. If we use Eduardos
example it will not work as focus was arbitrarily set to the first child of
the shell - the first button.
This is an issue for us in the MessageDialog (which only has labels) as it
prevents developers from setting default buttons.
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
public class DefaultButtonTest {
public static void main(String args[]) {
Shell shell = new Shell();
Display display = shell.getDisplay();
Text label = new Text(shell, SWT.BORDER);
label.setText("line 1\nline2\nline3\n\nline5");
Point size = label.computeSize(SWT.DEFAULT,SWT.DEFAULT);
shell.setBounds(100,100,200,200);
label.setBounds(10,10,size.x,size.y);
label.setFocus();
for (int i = 0; i < 3; i++) {
Button b = new Button(shell,SWT.NULL);
b.setBounds(20 + (i * 50),120,50,25);
b.setText("B::" + i);
if(i==1) {
shell.setDefaultButton(b);
System.out.println("Default should be: " + b.getText
());
}
}
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
}
Because default button look is assigned to the focus widget on most platforms, when we assign focus to the first widget in the tree that takes focus and this widget is a button, the defualt look is removed from the button that was assigned by the application. This is what is happening. In order to fix this, SWT would need to traverse the widget tree to determine that there are no widgets other than buttons that will take focus (ie. the window is made up of labels and buttons), detect the fact that a default button has been set, and set focus to that button, instead of the first widget (a button) that will take focus. Agreed with TC that JFace should set the focus to the default button in this case. Would it be possible for the Shell to remember if setDefaultButton() was called and then use the result of that to choose the focus widget if it is going to make a random choice later? Nope, that was the original "fix" and Eclipse relies on setting focus to the first widget when no focus is explicitly set. We once did this and ripped the code out, real fast. |
Here is an example showing that default button is not right. First problem: 1) Run the example ** B::1 Should be de default button but B::0 is instead. Second problem: 1) Run the example 2) Activate another window 3) Activate the example window 4) B::0 has focus but B::1 is the default. ++++++++++++++++++++++++++++++++++++++++++++++++++++++ import org.eclipse.swt.widgets.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.*; import org.eclipse.swt.events.*; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Point; public class Explorer { public static void main(String args[]) { Shell shell = new Shell(); Display display = shell.getDisplay(); Label label = new Label(shell, SWT.BORDER); label.setText("line 1\nline2\nline3\n\nline5"); Point size = label.computeSize(SWT.DEFAULT,SWT.DEFAULT); shell.setBounds(100,100,200,200); label.setBounds(10,10,size.x,size.y); for (int i = 0; i < 3; i++) { Button b = new Button(shell,SWT.NULL); b.setBounds(20 + (i * 50),120,50,25); b.setText("B::" + i); if(i==1) { shell.setDefaultButton(b); System.out.println("Default should be: " + b.getText ()); } } shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } }