Adding Menu Button Eclipse Plugin - eclipse

I added a main menu button for an eclipse plugin, and this code was generated to handle the action when the button is pressed:
package de.vogella.plugin.experiment;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;
public class SomethingHandler implements IHandler {
#Override
public void addHandlerListener(IHandlerListener handlerListener) {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
System.out.println("Hello");
// TODO Auto-generated method stub
return null;
}
#Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isHandled() {
// TODO Auto-generated method stub
return false;
}
#Override
public void removeHandlerListener(IHandlerListener handlerListener) {
// TODO Auto-generated method stub
}
}
I added the print statement in the execute class to test to see if anything would happen when I pressed the button. However, when I run this plugin as an eclipse application, and press the button, the button stays pressed until I click it again, and nothing else happens. How can I execute some event when I press the button? And then have the process complete so I don't have to press the button again to turn it off?
EDIT:
Here is my plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin
>
<extension
point="org.eclipse.ui.commands">
<command
defaultHandler="de.vogella.plugin.experiment.SomethingHandler"
id="de.vogella.plugin.experiment.SomethingHandler"
name="name">
</command>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="SomethingHandler"
commandId="de.vogella.plugin.experiment.SomethingHandler">
</handler>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="menu:org.eclipse.ui.main.menu">
<command
commandId="de.vogella.plugin.experiment.SomethingHandler"
label="DoSomething"
style="push">
</command>
</menuContribution>
</extension>
</plugin>

The menuContribution you have is just defining the top level menu item which doesn't work like a normal push button. You need to define a menu to appear in the drop down list for the menu. Something like:
<extension
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="menu:org.eclipse.ui.main.menu">
<menu
id="menu.id"
label="Top Level Menu">
<command
commandId="de.vogella.plugin.experiment.SomethingHandler"
label="DoSomething"
style="push">
</command>
</menu>
</menuContribution>
</extension>

Related

How does the parameter of the extension point "org.eclipse.ui.handlers" work?

I define an extension
<extension point="org.eclipse.ui.handlers">
<handler commandId="com.abc.test.command">
<class class="com.abc.test.TestHandler">
<parameter
name="a"
value="111">
</parameter>
</class>
</handler>
</extension>
TestHandler
public class TestHandler extends AbstractHandler {
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
Map parameters = event.getParameters() ;
return null;
}
}
When TestHandler.execute(ExecutionEvent) is called, the parameters is empty.
Why? How does it work ?
The ExecutionEvent.getParameters method returns the parameters defined using the commandParameter element of the org.eclipse.ui.commands extension point defining the command.
For example:
<extension
point="org.eclipse.ui.commands">
<command
categoryId="org.eclipse.ui.category.window"
defaultHandler="org.eclipse.help.ui.internal.handlers.OpenBundleResourceHandler"
description="%command.openBundleResource.description"
id="org.eclipse.ui.browser.openBundleResource"
name="%command.openBundleResource.name">
<commandParameter
id="plugin"
name="%commandParameter.openBundleResource.plugin.name"
optional="true"/>
<commandParameter
id="path"
name="%commandParameter.openBundleResource.path.name"
optional="true"/>
</command>
</extension>
The parameter element of org.eclipse.ui.handlers is only available to the class implementing the handler if it implements the IExecutableExtension interface. This has the single method:
public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException;
This gives the class access to the handler configuration element. In addition the parameter values are passed in the data object which will be a java.util.Hashtable containing the name, value pairs.
#Override
public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
throws CoreException
{
if (data instanceof Hashtable<?, ?> table) {
var value = table.get("a");
}
}

Eclipse: How to get the MenuManager for a specific menu id defined in plugin.xml

I have a standalone eclipse RCP application. The main interaction happens through the main toolbar. Here is the relevant snippet from plugin.xml:
<extension
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="toolbar:org.eclipse.ui.main.toolbar">
<toolbar
id="my.toolbar.id">
...
<command
commandId="my.command.id"
id="my.connect.id"
label="Connect"
style="pulldown">
</command>
...
</toolbar>
</menuContribution>
<menuContribution
allPopups="false"
locationURI="menu:my.connect.id">
</menuContribution>
I would like to populate the pulldown menu my.connect.id when it is about to be shown, which can hold different items every time it is opened. It can be done using the MenuManager for this id and add a IMenuListener.
How to obtain the instance of the MenuManager for the given id from plugin.xml?
Thanks a lot.
PS: It is still e3.
I took me a couple of days and research to figure this out. Here is the answer to my own question:
Give the menu a dyanmic contribution with a class that handles all the contributions.
plugin.xml:
<menuContribution
allPopups="false"
locationURI="menu:my.connect.id">
<dynamic
class="my.ConnectMenu"
id="my.connect.menu">
</dynamic>
</menuContribution>
ConnectMenu.java:
public class ConnectMenu extends ContributionItem {
private IMenuListener menuListener = new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
fillMenu(manager);
}
};
public ConnectMenu() {
this("my.connect.menu");
}
public ConnectMenu(String id) {
super(id);
}
#Override
public void fill(Menu menu, int index) {
super.fill(menu, index);
if (getParent() instanceof MenuManager) {
((MenuManager) getParent()).setRemoveAllWhenShown(true);
((MenuManager) getParent()).addMenuListener(menuListener);
}
}
private void fillMenu(IMenuManager mgr) {
mgr.add(createContributionItem());
mgr.update();
}
private IContributionItem createContributionItem() {
// ...
}
}
Hope this helps.
Very helpful to me: https://phisymmetry.wordpress.com/2010/01/03/eclipse-tips-how-to-create-menu-items-dynamically/

Binary XML file line #11: Error inflating class fragment

I am getting two Errors in my Code.
Caused by: java.lang.IllegalStateException: Fragment com.example.dfoley.write_to_file.topFragment did not create a view.
Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class fragment both pointing to Line MainActivity.java:21 which is the following setContentView(R.layout.activity_main);
bottomFragment
package com.example.dfoley.write_to_file;
import android.app.ListFragment;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import java.util.ArrayList;
public class bottomFragment extends ListFragment {
private ArrayAdapter<StateUser> adapter;
#Override
public void onActivityCreated(Bundle saveInstanceState){
ArrayList<StateUser> flight = MainContoller.getInstance().getFlights();
this.adapter = new ArrayAdapter<StateUser>(getActivity(), android.R.layout.simple_list_item_1, flight);
setListAdapter(this.adapter);
super.onActivityCreated(saveInstanceState);
}
public void refreshList(){
this.adapter.notifyDataSetChanged();
}
}
Top Fragment
package com.example.dfoley.write_to_file;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import.android.util.Log;
import android.view.View;
import.android.widget.Button;
import android.widget.EditText;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class topFragment extends Fragment{
private FlightSearcher searcher;
EditText text1;
public interface FlightSearcher {
public void refreshFlightList();
}
#Override
public void onAttach(Activity activity) {
searcher = (FlightSearcher) activity;
super.onAttach(activity);
}
#Override
public void onActivityCreated(Bundle savedInstanceState){
setupListeners();
super.onActivityCreated(savedInstanceState);
}
public void setupListeners() {
Button addUser = (Button)getActivity().findViewById(R.id.button);
addUser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
writeToFile();
searcher.refreshFlightList();
}
});
}
private void writeToFile() {
text1=(EditText)getActivity().findViewById(R.id.editText);
String AddUsers = text1.getText().toString();
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(getActivity().openFileOutput("UserList", Context.MODE_PRIVATE));
outputStreamWriter.write(AddUsers);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
}
Main Activity
package com.example.dfoley.write_to_file;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends FragmentActivity implements topFragment.FlightSearcher{
public void refreshFlightList() {
FragmentManager mgr = getFragmentManager();
bottomFragment bottomFragmentRef =(bottomFragment) mgr.findFragmentById(R.id.bottom_fragment);
bottomFragmentRef.refreshList();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
activiy_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.example.dfoley.write_to_file.topFragment"
android:id="#+id/top_fragment"
android:layout_weight="1"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
tools:layout="#layout/topfragment" />
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.example.dfoley.write_to_file.bottomFragment"
android:id="#+id/bottom_fragment"
android:layout_weight="1"
android:layout_below="#+id/top_fragment"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
tools:layout="#layout/bottomfragment" />
Change fragment to FrameLayout
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
For both of your fragments, you are not telling it how to create a view. I see that you are using the tools:layout tag, but according to the Tools doc, that is only a hint to the designer; it does not actually inflate that layout:
"This attribute is typically set in a tag and is used to record which layout you want to see rendered at designtime (at runtime, this will be determined by the actions of the fragment class listed by the tag)."
Thus you need to override onCreateView, inflate your view hierarchy, and then return that:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.topfragment, container, false);
}

custom submenu won't react on click

I am trying to implement an extension in JDeveloper. It creats a submenu when you click on a DB package.
THe issue comes when I click on an element of my custom submenu, it returns a null pointer Exception.
I can't figure out where I did wrong.
Would you please help me?
Here is how a I created the submenu:
submenu.xml File:
<?xml version="1.0" encoding="windows-1252" ?>
<!-- usage of a name space?-->
<items id="my.contextMenu">
<folder type="PACKAGE">
<name>User Defined Context Menu</name>
<item reloadparent="true"
action-ref="utilitytools.customSave">
<title>saveThisPackage</title>
</folder>
</items>
extension.xml file:
<?xml version="1.0" encoding="UTF-8" ?>
<extension id="utilitytools" version="1.0" esdk-version="1.0"
rsbundle-class="utilitytools.Res"
xmlns="http://jcp.org/jsr/198/extension-manifest">
<name>Utility Tools</name>
<owner>A name</owner>
<dependencies>
<import>oracle.sqldeveloper</import>
<import>oracle.ide</import>
</dependencies>
<hooks>
<jdeveloper-hook xmlns="http://xmlns.oracle.com/jdeveloper/1013/extension">
<addins>
<addin>utilitytools.UtilityToolsAddin</addin>
</addins>
<actions xmlns="http://xmlns.oracle.com/jdeveloper/1013/extension">
<action id="utilitytools.customSave">
<properties>
<property name="Name">saveThisPackage</property>
<property name="SmallIcon"></property>
<property name="LongDescription"></property>
</properties>
<controller-class>utilitytools.savePackageController</controller-class>
<command-class>utilitytools.savePackageCommand</command-class>
</action>
</actions>
</jdeveloper-hook>
<sqldev-navigator-hook xmlns="http://xmlns.oracle.com/sqldeveloper/sqldev-navigator">
<descriptor>submenu.xml</descriptor>
</sqldev-navigator-hook>
</hooks>
</extension>
SubmenuListener file:
public final class SubMenuListener implements ContextMenuListener {
public SubMenuListener() {
super();
}
public void menuWillShow(ContextMenu contextMenu) {
contextMenu.add( contextMenu.createMenuItem(
IdeAction.find( savePackageCommand.actionId() )
));
}
public void menuWillHide(ContextMenu contextMenu) {
//Nothing
}
public boolean handleDefaultAction(Context context) {
return false;
}
}
And the command file:
/**
* Command handler for utilitytools.customSave.
*/
#RegisteredByExtension("utilitytools")
public final class sauvegardePackageCommand extends Command {
public savePackageCommand() {
super(actionId());
}
public int doit() {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
showSaveWindow();
}
});
return OK;
}
/**
* Returns the id of the action this command is associated with.
*
* #return the id of the action this command is associated with.
* #throws IllegalStateException if the action this command is associated
* with is not registered.
*/
public static int actionId() {
final Integer cmdId = Ide.findCmdID(".utilitytools.customSave");
if (cmdId == null)
throw new IllegalStateException("Action esdksample.showElementClass not found.");
return cmdId;
}
private static void showSaveWindow(){
JFrame frame = new JFrame("SAVE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JPanelSavePackage());//Or any window you want to popup
frame.pack();
frame.setVisible(true);
}
}

REST API with Struts

I'm trying to add a REST API to an existing struts 2 application.
The idea is to have part of the application using standard struts mapping, and another part using REST.
So I used the struts2-rest-plugin plugin, and added the following configuration:
struts.xml:
<constant name="rest" value="org.apache.struts2.rest.RestActionMapper"/>
<constant name="struts.mapper.class"
value="org.apache.struts2.dispatcher.mapper.PrefixBasedActionMapper"/>
<constant name="struts.mapper.prefixMapping" value="/rest:rest,/:struts"/>
struts.properties:
struts.action.extension=,htm,action,xml,json
TasksController.java:
package xxx.common.webservice.rest;
public class TasksController implements ModelDriven<Task> {
public String update() {
return "UPDATE";
}
// Handles /tasks/{id} GET requests
public String show() {
return "YES";
}
#Override
public Task getModel() {
// TODO Auto-generated method stub
return null;
}
}
With this configuration, the basic struts action work, but I can't get the REST actions to work.
I also tried different struts.xml configurations (including the convention plugin options), but without any success, the mappings are never shown with the config-brower plugin.
Any idea of what I have missed or done wrong?
It finally worked, but it was a while ago and I don't remember exactly what I did, here is my configuration, hope this helps.
struts.xml
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.package.locators" value="webservice"/>
<constant name="struts.convention.action.suffix" value="Controller"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
<constant name="struts.mapper.class" value="org.apache.struts2.dispatcher.mapper.PrefixBasedActionMapper" />
<constant name="struts.mapper.prefixMapping" value="/rest:rest,:struts" />
<package name="home" namespace="/" extends="struts-default">
...
</package>
TaskController.java
package com.test.webservice.rest;
public class TaskController extends RestActionSupport implements
ModelDriven<TaskDTO> {
public final HttpHeaderResult show() {
...
}
...
}