I have a requirement to show a status indicator in the status bar of an Eclipse application. I can't contribute through the ApplicationWindowAdviser (another team owns the core product), but I feel sure that I should be able to contribute through an extension point. Despite much googling, I can't find anything describing how to do this.
In the org.eclipse.ui.menuContributions extensions, use "toolbar:org.eclipse.ui.trim.status" as the locationURI. You can contribute commands/custom controls to the status bar.
A possible solution to check:
You should be able to define a fragment in order to be able to add to the core product functionality. (see here for another example).
The idea is to add functionality to the core plugin. May be your contribution can then merged to that main product that way.
Firstly, adding status bar to application.e4xmi (Application > Windows and Dialogs > Trimmed Window > TrimBars > WindowTrim (Bottom) > Toolbar > Tool Control)
Create .java class and give address in toolbar (class uri).
e4 status bar implementation is different than e3 implementation. In e4, you can use eventbroker to send text (info) to status bar.
#Inject
private IEventBroker eventBroker;
private static final String STATUSBAR ="statusbar";
#Inject #Optional
public void getEvent(#UIEventTopic(STATUSBAR) String message) {
updateInterface(message);
}
#PostConstruct
public void createControls(Composite parent) {
.... \\ swt definitions e.g. label
}
public void updateInterface(String message)
{
try{
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
try{
label.setText(message);
}
catch(Exception exc){
System.out.println(exc);
}
}
});
}
catch(Exception exception){
System.out.println(exception);
}
}
Also, don't forget add eventbrokersender to another java class.
#Inject
private IEventBroker eventBroker;
private static final String STATUSBAR ="statusbar";
eventBroker.send(STATUSBAR, "status bar test message..");
Related
I have a Jbutton added on a frame automaticaly by netbeans.
I want to add this Actionlistener to a button.
public class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null,"hello");
}
My problem is that when I add this code
jButton2.addActionListener(MyActionListener);
in order to add the listener to the button I get a "non-static variable jButton2 cannot be referenced from a static context" message.
Since jButton2 is automatically created by netbeans as non static, how can overcome this problem and set the actionlistener as I want?
The error lies in that you are sending an object that has never been instantiated. When you add an action listener to any component you need to send an object that implements the ActionListener interface. Is like adding an instance of the listener to the object.
try this:
jButton2.addActionListener(new MyActionListener());
if you want to use an Anonymous implementation then you will do:
jButton2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//some code
}
});
An easy way to add a listener is just to right-click on the button from the design view, select
Events -> Action -> actionPerformed
and the code will be auto-generated for you
public void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// put what you want to happen, here
}
I have a GWT application where MVP pattern is followed.
We have multiple views to show data on UI.
We set the data to view via Activity. Something like this
public class SomeActivityImpl extends AbstractActivity implements SomeView.Presenter {
public SomeActivityImpl{
//some initialization goes here.
}
public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
//presenter is set here
loadDetails();
}
private void loadDetails(){
SomeRequestFactory.context().findSomeEntity().fire(new Receiver<SomeProxy>() {
#Override
public void onSuccess(SomeProxy proxyObject) {
someView.setName("name");
someview.setSurname("surname");
someview.setMothersName("mothers name");
}
)
}
Now my question is how can I make sure that all the setters of View are set and nothing is missed?
Is there any solution which is GWT specific or can someone suggest a design pattern?
You should use the editor framework. It has a Request Factory driver to help you use it with request Factory. Here's a good tutorial
If you don't like that tutorial, consider looking at GWT in action
I am using GWT 2.5.0
My intent was to create an editor hierarchy which binds to a ParentBean object. The ParentBean contains a List<Group>, and the Group bean has a List<ChildBean> and List<Group>. From the Editor tutorials I have found, it seemed simple enough to create an editor which contains a ListEditor as one of its sub-editors. But the parent editor never seems to properly initialize the sub ListEditor.
Here is an explanation of how I attempted to do this.
From the code below, I created a ParentBeanEditor which is composed of one other editor, GroupListEditor.
The GroupListEditor implements IsEditor<ListEditor<Group, GroupEditor>>.
Then, the GroupEditor contains a GroupListEditor subeditor and a ChildBeanEditor.
I initialized the ParentBeanEditor with a ParentBean which contained a list of Group objects, but no GroupEditor was ever constructed for any of the Group objects. I put break points in the EditorSource<GroupEditor>.create(int) method to verify that GroupEditors were being created for each Group in the ParentBean, but the break point was never hit (the ListEditor was not constructing editors).
I expected that the GroupListEditor would be initialized since it was a subeditor of ParentBeanEditor. Neither the list nor the editor chain was set in the GroupListEditor. I tried to set the list of the GroupListEditor subeditor directly in ParentBeanEditor by having it extend ValueAwareEditor<ParentBean>. Doing this, the break point I mentioned above was hit, and the GroupListEditor tried to attach a GroupEditor to the editor chain. But the editor chain was never set, and a NPE is thrown in ListEditorWrapper line 95.
Example
Here is the example where the GroupListEditor is not initializing as expected. The EditorChain is never set, and this results in a NPE being thrown in ListEditorWrapper line 95.
Data Model
public interface ParentBean {
...
List<Group> getGroups();
}
public interface Group {
...
List<ChildBean> getChildBeans();
List<Group> getGroups();
}
public interface ChildBean {
// ChildType is an enum
ChildType getChildType();
}
Editors
The ParentBean Editor
public class ParentBeanEditor extends Composite implements ValueAwareEditor<ParentBean> {
interface ParentBeanEditorUiBinder extends UiBinder<Widget, ParentBeanEditor> {
}
private static ParentBeanEditorUiBinder BINDER = GWT.create(ParentBeanEditorUiBinder.class);
#Path("groups")
#UiField
GroupListEditor groupsEditor;
public ParentBeanEditor() {
initWidget(BINDER.createAndBindUi(this));
}
#Override
public void setDelegate(EditorDelegate<ParentBean> delegate) {}
#Override
public void flush() {}
#Override
public void onPropertyChange(String... paths) {}
#Override
public void setValue(ParentBean value) {
groupsEditor.asEditor().setValue(value.getGroups());
}
}
GroupListEditor
public class GroupListEditor extends Composite implements IsEditor<ListEditor<Group, GroupEditor>>{
interface GroupListEditorUiBinder extends UiBinder<VerticalLayoutContainer, TemplateGroupListEditor> {
}
private static GroupListEditorUiBinder BINDER = GWT.create(GroupListEditorUiBinder.class);
private class GroupEditorSource extends EditorSource<GroupEditor> {
private final GroupListEditor GroupListEditor;
public GroupEditorSource(GroupListEditor GroupListEditor) {
this.GroupListEditor = GroupListEditor;
}
#Override
public GroupEditor create(int index) {
GroupEditor subEditor = new GroupEditor();
GroupListEditor.getGroupsContainer().insert(subEditor, index);
return subEditor;
}
#Override
public void dispose(GroupEditor subEditor){
subEditor.removeFromParent();
}
#Override
public void setIndex(GroupEditor editor, int index){
GroupListEditor.getGroupsContainer().insert(editor, index);
}
}
private final ListEditor<Group, GroupEditor> editor = ListEditor.of(new GroupEditorSource(this));
#UiField
VerticalLayoutContainer groupsContainer;
public GroupListEditor() {
initWidget(BINDER.createAndBindUi(this));
}
public InsertResizeContainer getGroupsContainer() {
return groupsContainer;
}
#Override
public ListEditor<Group, GroupEditor> asEditor() {
return editor;
}
}
GroupEditor
public class GroupEditor extends Composite implements ValueAwareEditor<Group> {
interface GroupEditorUiBinder extends UiBinder<Widget, GroupEditor> {}
private static GroupEditorUiBinder BINDER = GWT.create(GroupEditorUiBinder.class);
#Ignore
#UiField
FieldSet groupField;
#UiField
#Path("childBeans")
ChildBeanListEditor childBeansEditor;
#UiField
#Path("groups")
GroupListEditor groupsEditor;
public GroupEditor() {
initWidget(BINDER.createAndBindUi(this));
}
#Override
public void setDelegate(EditorDelegate<Group> delegate) {}
#Override
public void flush() { }
#Override
public void onPropertyChange(String... paths) {}
#Override
public void setValue(Group value) {
// When the value is set, update the FieldSet header text
groupField.setHeadingText(value.getLabel());
groupsEditor.asEditor().setValue(value.getGroups());
childBeansEditor.asEditor().setValue(value.getChildBeans());
}
}
The ChildBeanListEditor will be using the polymorphic editor methodology mention here. Meaning that a specific leafeditor is attached to the editor chain based off the value of the ChildBean.getType() enum. However, I am not showing that code since I am unable to get the GroupListEditor to properly initialize.
Two concerns about your code:
Why is ParentBeanEditor.setValue feeding data to its child? It appears from this that this was a way to work around the fact that the GroupListEditor was not getting data. This should not be necessary, and may be causing your NPE by wiring up a subeditor before it is time.
Then, assuming this, it seems to follow that the GroupListEditor isn't getting data or a chain. The lack of these suggests that the Editor Framework isn't aware of it. All the basic wiring looks correct, except for one thing: Where is your EditorDriver?
If you are trying to use the editor framework by just invoking parentBeanEditor.setValue and do not have a driver, you are missing most of the key features of this tool. You should be able to ask the driver to do this work for you, and not not to call your own setValue methods throughout the tree.
A quick test - try breaking something in such a way that shouldn't compile. This would include changing the #Path annotation to something like #Path("doesnt.exist"), and trying to run the app. You should get a rebind error, as there is no such path. If you do not get this, you definitely need to be creating and user a driver.
First, try driver itself:
It isn't quite clear from your code what kind of models you are using, so I'll assume that the SimpleBeanEditorDriver will suffice for you - the other main option is the RequestFactoryEditorDriver, but it isn't actually necessary to use the RequestFactoryEditorDriver even if you use RequestFactory.
The Driver is generic on two things: The bean type you intend to edit, and the editor type that will be responsible for it. It uses these generic arguments to traverse both objects and generate code required to bind the data. Yours will likely look like this:
public interface Driver extends
SimpleBeanEditorDriver<ParentBean, ParentBeanEditor> { }
We declare these just like UiBinder interfaces - just enough details to let the code generator look around and wire up essentials. Now that we have the type, we create an instance. This might be created in your view, but may still be owned and controlled by some presenter logic. Note that this is not like uibinder - we cannot keep a static instance, since each one is wired directly to a specific editor instance.
Two steps here - create the driver, and initialize it to a given editor instance (and all sub-editors, which will be automatic):
ParentBeanEditor editor = ...;
Driver driver = GWT.create(Driver.class);
driver.initialize(editor);
Next we bind data by passing it to the driver - it is its responsibility to pass sub-objects to each sub-editor's setValue method, as well as wiring up the editor chain required by the ListEditor.
driver.edit(parentInstance);
Now the user can view or edit the object, as your application requirement works. When editing is complete (say they click the Save button), we can flush all changes from the editors back into the instance (and note that we are still using the same driver instance, still holding that specific editor instance):
ParentBean instance = driver.flush();
Note that we also could have just invoked driver.flush() and reused the earlier reference to parentInstance - its the same thing.
Assuming this has all made sense so far, there is some cleanup that can be done - ParentBeanEditor isn't really using the ValueAwareEditor methods, so they can be removed:
public class ParentBeanEditor extends Composite implements Editor<ParentBean> {
interface ParentBeanEditorUiBinder extends UiBinder<Widget, ParentBeanEditor> {
}
private static ParentBeanEditorUiBinder BINDER = GWT.create(ParentBeanEditorUiBinder.class);
#Path("groups")
#UiField
GroupListEditor groupsEditor;
public ParentBeanEditor() {
initWidget(BINDER.createAndBindUi(this));
}
}
Observe that we still implement Editor<ParentBean> - this allows the driver generics to make sense, and declares that we have fields that might themselves be sub-editors to be wired up. Also: it turns out that the #Path annotation here is unnecessary - any field/method with the same name as the property (getGroups()/setGroups() ==> groups) or the name of the property plus 'Editor' (groupsEditor). If the editor contains a field that is an editor but doesn't map to a property in the bean, you'll get an error. If you actually did this on purpose (say, a text box for searching, not for data entry), you can tag it with #Ignore.
Stemming from this article more efficient way of updating UI from service I was wondering if I could take that a step further and implement the following. I may have a misunderstanding of my Apps lifecycle though.
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private static Stack<MyActivity> mActivityStack = new Stack<MyActivity>();
private static String mTopActivity = "none";
public static void pushActivity(MyActivity activity)
{
mActivityStack.push(activity);
mTopActivity = activity.getClass().getSimpleName();
Log.i(TAG, "push::"+mTopActivity);
}
public static void popActivity()
{
Log.i(TAG, "pop::"+mTopActivity);
mActivityStack.pop();
}
#Override
public void onLowMemory() {
super.onLowMemory();
Log.w(TAG, "low memory!!!");
Log.w(TAG, "Current::"+mTopActivity);
}
}
public class MyActivity extends Activity
{
private static final String TAG = MyActivity.class.getSimpleName();
public void onCreate(Bundle last)
{
super.onCreate(last);
MyApplication.pushActivity(this);
}
public void onDestroy()
{
super.onDestroy();
MyApplication.popActivity();
}
}
Would the stack be valid during the lifecycle of the application?
As CommonsWare said, this did not work out. Also, it is not a great idea to derive from Activity, because you would then have to also derive listactivity, preferenceactivity, etc. Obviously, I did not think this would solve any problem it was just an experiment in android life cycles.
Would the stack be valid during the lifecycle of the application?
Of course it won't be valid. You assume every activity is created and destroyed in the same sequence. They won't be in many cases (e.g., user presses HOME).
Whatever problem you think you are solving this way, this is not the right solution by any stretch of the imagination.
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) {
...
}
...
});