I have a bean named SignUpBean and it's editor is SignUpBeanEditor and following is its Driver interface.
public interface SignUpDriver extends SimpleBeanEditorDriver<SignUpBean, SignUpEditor>{
}
Following is entry point class
public class Signup implements EntryPoint {
private SignUpDriver signUpDriver;
private SignUpEditor signUpEditor;
private SignUpBean signUpBean;
private VerticalPanel verticalPanel;
private Label signUpLbl;
private Button submitButton;
private Button cancelButton;
private RequestBuilder requestBuilder;
final SignUpConverter signUpConverter=GWT.create(SignUpConverter.class);
public void onModuleLoad() {
signUpLbl = new Label("Sign Up");
signUpDriver = GWT.create(SignUpDriver.class);
signUpBean = new SignUpBean();
signUpEditor = new SignUpEditor();
submitButton = new Button("Submit");
cancelButton = new Button("Cancel");
signUpDriver.initialize(signUpEditor);
signUpDriver.edit(signUpBean);
System.out.println(signUpBean.getUserName());
submitButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
SignUpBean signUpBeanEdited=signUpDriver.flush();
}
}
}
}
I am getting only null value from signUpBeanEdited after giving value in UI. If i am initializing SignUpBean with constructor then also data is not binding to UI. My problem is I cant bind data in GWT UI using editor framework.
The fields( sub editors ) declared in SignUpEditor should be of at least DEFAULT scope. I guess you declared them as private. If so, the Editor Impl classes generated cannot access the fields to bind the data.
Changing scope to at least DEFAULT might solve your problem.
Related
I'm developing an Eclipse plugin in which I need to access a view.
I've found this way to get the workbench, but I guess it only worked in Eclipse 3.x and I am using Eclipse 4 so it doesn't work:
IWorkbench workbench = PlatformUI.getWorkbench();
IViewPart part = workbench.getActiveWorkbenchWindow().getActivePage()
.findView("id_of_the_view");
I then found this way:
#Inject
private static EPartService epartService;
MPart mPart = epartService.findPart("id_of_the_view");
MyViewClass part = (MyViewClass)mPart.getObject();
which throws a NullPointerException. I've made sure the view is open.
What am I missing?
Edit:
I've also tried this, as found here (german)
#Inject
private static EPartService epartService;
#Inject
private static MApplication application;
#Inject
private static EModelService modelService;
...
MUIElement element = modelService.find("id_of_the_view", application);
if(element instanceof MPart) {
MPart part = (MPart) element;
...
}
but I also get a NPE in the .find()-line.
You're right. In E4 you should use injection.
To avoid NPEs, you can get the reference to the IEclipseContext in part constructor.
public class MyPart {
private IEclipseContext context;
#Inject
public MyPart(IEclipseContext context) {
this.context = context;
}
}
Assuming you have your part class defined in a plugin, and that the class is referenced as Part in an E4 Application, you can get a reference to the Part instance using its id
Somewhere in your code you use the id to get an instance of your part
// somewhere in your code ..
// (where you can access the context instance)
MPart myPart = getPart(context, "com.example.myPart");
The easy way is to use EPartService.findPart() , as follows:
/** with this method I can get reference to the part */
public static MPart getPart(IEclipseContext context, String partId) {
EPartService partService = context.get(EPartService.class);
MPart part = partService.findPart(partId);
return part;
}
Beware of static methods. Context Objects and static members are not friends !!
For multiple matches, or advanced searches, you can use EPartService.findElements(), as follows :
public static List<MPart> getParts(IEclipseContext context,
MWindow workbenchWindow, String partId) {
EPartService partService = context.get(EPartService.class);
EModelService modelService = context.get(EModelService.class);
List<MPart> parts =
modelService.findElements(workbenchWindow, partId, MPart.class,
null, EModelService.OUTSIDE_PERSPECTIVE
| EModelService.IN_ANY_PERSPECTIVE
| EModelService.IN_SHARED_AREA);
return parts;
}
I'm new to Eclipse e4 and I am trying to inject an object of my custom class into a Handler class like below :
public class MenuHandler {
#Inject
Test2 user;
#Execute
public void execute(MApplication app, EPartService partService, EModelService modelService) {
System.out.println(user.getUserName()); // DefaultUser
user.setUserName("anotherUser");
System.out.println(user.getUserName()); //anotherUser
}
}
#Creatable
public class Test2 {
private String userName = "DefaultUser";
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Having this code and If I launch my RCP application, and upon clicking the menu item (defined in the 'Application.e4xmi' file) my handler class ('MenuHandler') is not getting executed. Whereas if I remove the #Inject annotation from the handler class (i.e.., upon removing #Inject Test2 user; ) then the handler class is getting executed without any issues.
I think some problem exists if I have the annotation "#Inject" inside the Handler class.
Any suggestion will be greatly appreciated !
Maybe you should try to create and inject your custom object in the LifeCycleManager of your e4 application.
public class LifeCycleManager {
#PostContextCreate
public void postContextCreate(IEclipseContext context) {
final MCustomContext customContext = PersistenceUtils.load(MCustomContext.class);
context.set(MCustomContext.class, customContext);
}
}
This works fine for me.
i have this issue:
I have a PresenterWidget which contains sub-editors.
There are "container" elements which should be editable by this widget. These containers can be assigned to groups. To do so, i would like to fetch a list of all available groups from the server. So the widget is set up like this (i use GWTP):
public class ContainerEditorDialogPresenterWidget extends PresenterWidget<ContainerEditorDialogPresenterWidget.MyView> implements
ContainerEditorDialogUiHandlers {
private final PlaceManager placeManager;
private List<GroupDTO> groupList = new ArrayList<GroupDTO>();
private final DispatchAsync dispatcher;
#Inject
ContainerEditorDialogPresenterWidget(EventBus eventBus,
MyView view, PlaceManager placeManager, DispatchAsync dispatcher) {
super(eventBus, view);
getView().setUiHandlers(this);
this.dispatcher = dispatcher;
fetchGroups();
}
...
public void fetchGroups(){
FetchGroupsAction action = new FetchGroupsAction();
dispatcher.execute(action, new AsyncCallbackImpl<FetchGroupsResult>() {
#Override
public void onSuccess(FetchGroupsResult result) {
groupList = result.getGroupDtos();
eventBus.fireEvent(new GroupListUpdatedEvent(groupList));
}
});
}
So i call fetchGroups in the constructor to get it as early as possible. Since it is an AynchCallback, i get the result back "at some time". I then try to pass the values to the sub-editor with a GroupListUpdatedEvent. In there i have a Editor declared like this:
public class GroupListEditor extends Composite implements
IsEditor<ListEditor<String, GroupItemEditor>> {
private static StringListEditorUiBinder uiBinder = GWT
.create(StringListEditorUiBinder.class);
interface StringListEditorUiBinder extends
UiBinder<Widget, GroupListEditor> {
}
//Gives us access to the event bus.
#Inject private EventBus eventBus;
...
public GroupListEditor() {
initWidget(uiBinder.createAndBindUi(this));
eventBus.addHandler(GroupListUpdatedEvent.TYPE, new GroupListUpdatedEvent.GroupListUpdatedHandler() {
#Override
public void onGroupListUpdatedEvent(GroupListUpdatedEvent event) {
Log.debug("onContainerUpdatedEvent caught");
allGroups = event.getGroupList();
if(allGroups != null) {
for (GroupDTO g : allGroups) {
lbAllGroups.addItem(g.getName(), g.getId().toString());
}
lbAllGroups.setVisibleItemCount(5);
Log.debug("Item list = " + lbAllGroups.getItemCount());
} else {
Log.debug("GROUP LIST is Null!");
}
}
});
}
When i try to register the handler, i get an exception. So i expect the eventBus is not injected properly. What do i miss, how can i use events and the event bus if i am not in a Presenter?
And: Is this the right way at all to populate Editors with "utility" data? I guess Editor should be related directly to the data they care for. But how do i handle this kind of supplemental data?
Thanks :)
Do you use #UiField in your ContainerEditorDialogPresenterWidgetView for your GroupListEditor ?
If so then Dependency Injection won't work because you basically manually create the GroupListEditor which leads to EventBus being NULL.
I would also use Constructor Injection instead of field injection.
GroupListEditor:
#Inject
public GroupListEditor(EventBus eventBus) {
this.eventBus = eventBus;
}
ContainerEditorDialogPresenterWidgetView:
public class ContainerEditorDialogPresenterWidgetView {
#UiField(provided=true)
GroupListEditor groupListEditor;
#Inject
public ContainerEditorDialogPresenterWidgetView(GroupListEditor groupListEditor);
this.groupListEditor = groupListEditor;
initWidget();
}
}
Alternatively you could get an instance of your GroupListEditor via the Ginjector directly.
I have a HashMap inside my POJO that I am using the Editor framework in GWT to edit. While I have access to the standard member variables bound through thier getters/setters, I don't know how to access the values inside the HashMap. How do I get access to the underlying POJO that is being edited through my editor that is using the SimpleBeanEditorDriver?
My POJO:
#Entity(noClassnameStored=true)
public class ProfileConfig extends BaseEntity {
#Indexed(unique=true)
private String name;
private boolean isDefault;
private HashMap<ProfileID, ProfileInfo> profiles= new HashMap<ProfileID, ProfileInfo>();
public ProfileInfo getProfile(ProfileID id) {
return profiles.get(id);
}
public void setProfile(ProfileID id, ProfileInfo p) {
profiles.put(id, p);
}
My Editor:
public class ProfileConfigEditor extends Composite implements ManagedObjectEditor<ProfileConfig> {
private static ProfileConfigEditorUiBinder uiBinder = GWT.create(ProfileConfigEditorUiBinder.class);
interface ProfileConfigEditorUiBinder extends UiBinder<Widget, ProfileConfigEditor> {
}
private UserManager userManager;
#UiField
CellList Profiles;
#UiField
TextBox name;
#UiField
CheckBox isDefault;
So given that I have a list of valid Profile ids from the userManager, how do I go about calling the getProfile method from my POJO from within my Editor?
What you need is a ValueAwareEditor.
public class ProfileConfigEditor extends Composite implements ManagedObjectEditor<ProfileConfig>, ValueAwareEditor<ProfileConfig> {
void setValue(ProfileConfig value){
// TODO: Call ProfileConfig.getProfile()
}
void flush(){
// TODO: Call ProfileConfig.setProfile()
}
// ... Other methods here
Alternatively, if you want more of a challenge, you can look at rolling your own CompositeEditor, for example see the source code for ListEditor. In your case, you would implement a CompositeEditor<ProfileConfig, ProfileInfo, MyNewProfileInfoEditor>. You can this of this as "This editor will take a ProfileConfig object, extract one or more ProfileInfo objects and edit it with one or more MyNewProfileInfoEditor editors"
I have a view which would like to be notified about all the currently opened editors. Where can I add a listener to achieve this?
I was expecting WorkbenchPage or EditorManager to have some appropriate listener registry, but I couldn't find it.
Does your view uses a org.eclipse.ui.IPartListener2 ?
That is what is using this EditorListener, whose job is to react, for a given view, to Editor events (including open and close)
public class EditorListener implements ISelectionListener, IFileBufferListener,
IPartListener2 {
protected BytecodeOutlineView view;
EditorListener(BytecodeOutlineView view){
this.view = view;
}
[...]
/**
* #see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference)
*/
public void partOpened(IWorkbenchPartReference partRef) {
view.handlePartVisible(partRef.getPart(false));
}
Now if your ViewPart directly implements an IPartListener2, it can register itself to the various Editors, like this BytecodeReferenceView
public class BytecodeReferenceView extends ViewPart implements IPartListener2, ISelectionListener {
[...]
public void createPartControl(Composite parent) {
browser = new Browser(parent, SWT.BORDER);
browser.setText(BytecodeOutlinePlugin.getResourceString(NLS_PREFIX
+ "empty.selection.text"));
final IWorkbenchWindow workbenchWindow = getSite().getWorkbenchWindow();
workbenchWindow.getPartService().addPartListener(this);
[...]
I think you're on the right track. You need to listen to the IWorkbenchPage IPartService events:
page.addPartListener(new IPartListener() {
partOpened(IWorkbenchPart part) {
...
}
...
});