Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Event handler not called (button)
Event handler not called (button) [message #809466] Tue, 28 February 2012 22:51 Go to next message
Karl Weber is currently offline 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 #810641 is a reply to message #809466] Thu, 01 March 2012 11:10 Go to previous messageGo to next message
Lars Vogel is currently offline Lars Vogel
Messages: 1049
Registered: July 2009
Senior Member

Can you paste a simple version of the Part code, so that we can have a look?
Re: Event handler not called (button) [message #811621 is a reply to message #810641] Fri, 02 March 2012 16:01 Go to previous messageGo to next message
Karl Weber is currently offline Karl Weber
Messages: 63
Registered: September 2010
Member
Lars Vogel wrote on Thu, 01 March 2012 12:10
Can you paste a simple version of the Part code, so that we can have a look?

package de.gps.log.db.ui.views;

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;
	
	// e4 will inject the composite "parent" into the view
	@Inject
	public LogView(Composite parent) {
		// the following is standard SWT Stuff
		this.parent = parent;
	}

	@Focus
	void setFocus() {
		System.out.println("DBLogView -- 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 button = new Button(parent, SWT.NONE);
		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");
			}
			
		});
	}
	
}



It doesn't look nice, but it is sufficient to reproduce the problem -- or find my mistake.
Re: Event handler not called (button) [message #811976 is a reply to message #811621] Sat, 03 March 2012 03:08 Go to previous messageGo to next message
Brian de Alwis is currently offline Brian de Alwis
Messages: 242
Registered: July 2009
Senior Member
Your @Focus should be setting focus to the inner composite.
Re: Event handler not called (button) [message #812141 is a reply to message #811976] Sat, 03 March 2012 09:24 Go to previous messageGo to next message
Karl Weber is currently offline Karl Weber
Messages: 63
Registered: September 2010
Member
Brian de Alwis wrote on Sat, 03 March 2012 04:08
Your @Focus should be setting focus to the inner composite.


Which composite do you mean? I cannot set the focus on the "private final Composite parent", since this will result in the exception "Blocked recursive attempt to activate part".

Making the composite created in buildUI(), which has "private final Composite parent" as parent, a global variable and setting the focus on this composite does not change anything, i.e. the problem remains.
Re: Event handler not called (button) [message #812246 is a reply to message #812141] Sat, 03 March 2012 13:25 Go to previous messageGo to next message
Karl Weber is currently offline 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:

composite.setFocus();

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 Go to previous messageGo to next message
Lars Vogel is currently offline Lars Vogel
Messages: 1049
Registered: July 2009
Senior Member

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
Re: Event handler not called (button) [message #814412 is a reply to message #813698] Tue, 06 March 2012 12:17 Go to previous message
Karl Weber is currently offline Karl Weber
Messages: 63
Registered: September 2010
Member
Hi Lars,

thanks, I will try when I am at home. But I think the underlying problem is, that the "restarted" part does not get the focus in time, or, to be more precise, I suspect that the following bug is the cause of my trouble. After I added my comment it was rescheduled from 4.1.2 to 4.2, so there seems to be hope that it might be fixed soon....
Previous Topic:Perspective switcher and other stuff in the window borders
Next Topic:PartSashContainer: cascading delete
Goto Forum:
  


Current Time: Thu Oct 30 13:59:40 GMT 2014

Powered by FUDForum. Page generated in 0.03143 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software