Event handler not called (button) [message #809466] |
Tue, 28 February 2012 22:51 |
Karl Weber Messages: 63 Registered: September 2010 |
Member |
|
|
When I start a clean application and create an MPart from an MPartDescriptor and show it, it automatically receives the focus. When I click on a button in the MPart for the first time, the event is fired and the event handler is called. This is the expected behaviour.
When I close this application without deleting the MPart and start it again, the MPart is immediately created from the model state that has been saved before. This time MPart does not immediately receive the focus. This is o.k., since there might be more than one MPart. If I now click on the same button again for the first time, the MPart receives the focus (o.k.), but the event is not fired, i.e. the handler of the button is not called. It is only called, when I click for the second time on the button.
To summarize: The handler of a button is only called, when the corresponding MPart had the focus before the button is clicked. Otherwise one has to click the button twice, to get the handler called once, which is completely unexpected.
Have I missed something, or is this a bug in e4 (Version: 4.2.0 / Build id: I20120209-1230)?
|
|
|
|
|
|
|
Re: Event handler not called (button) [message #812246 is a reply to message #812141] |
Sat, 03 March 2012 13:25 |
Karl Weber Messages: 63 Registered: September 2010 |
Member |
|
|
Ok, the hint with a missing setFocus was basically correct. The following line of code fixes the problem:
However, this line of code has to be added as last line of the method buildUI().
When the MPart is created in the handler using the code
@Execute
public void execute(EPartService partService) {
MPart part = partService.findPart(LogView.ID);
if (part == null) {
part = partService.createPart(LogView.ID);
}
if (part != null) {
part.setLabel("DBLogView");
part.setTooltip("Tooltip");
partService.showPart(part, PartState.ACTIVATE);
}
}
then partService.showPart(...) ensures, that the @Focus method is called immediately. Even more, everything works properly without explicitly calling composite.setFocus() at all. I.e. it must neither be called in buildUI() nor in the @Focus method.
If the UI is built after the application restarts, the Part is shown but the @Focus method is not called immediately. Although the Part is completely visible, the @Focus method is only called when I first click into the part. However, for the part to work properly in this case, composite.setFocus() has to be called explicitly in buildUI().
If, on the other hand, composite.setFocus() is called in buildUI(), then in certain cases this method is called twice.
This behaviour should be a bug.
|
|
|
Re: Event handler not called (button) [message #813698 is a reply to message #812246] |
Mon, 05 March 2012 16:11 |
|
Hi Karl,
I'm not sure if I understand your example. Can you check if the following work:
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
public class LogView {
public static String ID = "de.gps.log.db.ui.LogView";
private final Composite parent;
private Button button;
// e4 will inject the composite "parent" into the view
@Inject
public LogView(Composite parent) {
// the following is standard SWT Stuff
this.parent = parent;
}
@Focus
public void setFocus() {
System.out.println("DBLogView -- setFocus");
button.setFocus();
}
// PostConstruct ensures that the dependency injection has been finished
// when this method is called
@PostConstruct
public void buildUI() {
System.out.println("DBLogView -- buildUI");
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.horizontalSpacing = 0;
layout.verticalSpacing = 0;
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
createViewer(composite);
}
@PreDestroy
public void dispose() {
// this is necessary
System.out.println("DBLogView -- dispose");
}
private void createViewer(Composite parent) {
button = new Button(parent, SWT.NONE);
button.setText("Focus lost");
button.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
System.out.println("Button pressed");
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
System.out.println("Button pressed");
}
});
}
}
Best regards, Lars
|
|
|
|
Powered by
FUDForum. Page generated in 0.03984 seconds