Eclipse Plugin Development – Bar54 http://www.bar54.de Software Engineering, Web Technologies, eCommerce and some more Wed, 11 Sep 2019 04:44:07 +0000 en-US hourly 1 https://wordpress.org/?v=5.9.4 Bold Font in Eclipse JFace Viewer http://www.bar54.de/2014/06/bold-font-eclipse-jface-viewer/ Sun, 15 Jun 2014 09:53:16 +0000 http://www.bar54.de/?p=723 Working with fonts in Eclipse ui plugins is sometimes a bit indirectly.
For example, if you want to set an element’s font to bold, you can not simply set item.setBold() or item.getFont().setBold().

The best way to get around this, is to :

  1. get a default font from any element
  2. create a font descriptor from it,
  3. set the style of the font descriptor to bold,
  4. get a new font instance from this descriptor, and
  5. set this font to your element of choice.

Doing this, you can cache the font instance to reuse it later one.

The method getFont() allows to get a styled font based on the font of an swt control element:

    private Font getFont(Control control, int style) {
        Display display = Display.getCurrent();
        FontDescriptor fontDescriptor = FontDescriptor.createFrom(control.getFont());
        return fontDescriptor.setStyle(style).createFont(display);
    }

For example, this can be used to get a bold font to be set for tree items based on the font of the enclosing tree:

Control control = treeViewer.getTree();
Font fontBold = getFont(control, SWT.BOLD);
...
treeItem.setFont(fontBold);

This more a reminder for myself, but perhaps, someone will find this usefull as well…

]]>
Eclipse JFace ViewerFilter http://www.bar54.de/2014/04/eclipse-jface-viewerfilter/ Sun, 20 Apr 2014 22:37:14 +0000 http://www.bar54.de/?p=698 Eclipse JFace infrastructure provides a powerful infrastructure called ViewerFilter, to allow the user to filter content presented in a viewer.
Especially TreeViewers as extensively used by common navigator framework (CNF) based viewers such as the Project Explorer or Package Explorer make use of them.Eclipse Viewer Filter Configuration

Providing as Extension or Programmatically

To provide such a filter one can either programmatically add it to a filter enabled viewer such as to FilteredTreeViewers

PatternFilter filter = new PatternFilter();
FilteredTree tree = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, filter, true);

To use an Eclipse extension point declare it this way:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
  <extension
      point="org.eclipse.ui.navigator.navigatorContent">
    <commonFilter
      class="org.splevo.jamopp.ui.vpexplorer.filter.ImportOnlyVPFilter"
      description="Show only VariationPoints which are about variying imports"
      id="org.splevo.jamopp.ui.vpexplorer.filter.Imports"
      name="VariationPoints: Imports Only">
    </commonFilter>
  ...
  </extension>
  <extension
      point="org.eclipse.ui.navigator.viewer">
    <viewerContentBinding
        viewerId="org.splevo.ui.vpexplorer">
      <includes>
        <contentExtension
          pattern="org.splevo.jamopp.ui.vpexplorer.filter.*">
        </contentExtension>
      </includes>
    </viewerContentBinding>
  </extension>
</plugin>

Filtering Empty Parent Folders

If you have implemented a filter for specific elements explicitly and to filter parent elements if they do not include any sub element.


public abstract class MyFilter extends ViewerFilter {

@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {

if (isChildElement(element)) {
return handleChild(element);

} else {
// manipulate tree viewer based on select
// decision for the sub elements
StructuredViewer sviewer = (StructuredViewer) viewer;
ITreeContentProvider provider = (ITreeContentProvider) sviewer.getContentProvider();
for (Object child : provider.getChildren(element)) {
if (select(viewer, element, child)) {
return true;
}
}
return false;
}
}
]]>
Eclipse Icon Resources http://www.bar54.de/2014/04/eclipse-icon-resources/ Sun, 06 Apr 2014 10:16:14 +0000 http://www.bar54.de/?p=682 Online Resources for Eclipse standard and compatible Icons

In addition to using Eclipse build in image/icon access API (see my previous Post ), there are reasonable websites to access Eclipse icons or free ones that are compatible with them.

 

Icons in EMF Edit Plugin

To customize the image returned for an EMF model element you need to either replace the default icons generated in icons/full/obj16/ or to adapt the getImage() method in the appropriate ItemProvider.
For the latter, you can modify the following statement. Note, that the path to the icon is relative to the icons/ directory and without any file extension at the end.

return overlayImage(object, getResourceLocator().getImage("full/obj16/JaMoPPSoftwareElement"));
]]>
Accessing Eclipse Standard Icon Images http://www.bar54.de/2014/03/accessing-eclipse-standard-icon-images/ Thu, 27 Mar 2014 10:53:31 +0000 http://www.bar54.de/?p=677 When developing Eclipse plugins that should contribute to the UI, it is reasonable to align with the Eclipse UI design.

For example, within tree representations or in other UI elements, you might want to include the standard icons used in Eclipse.
To do this, Eclipse provides infrastructure that makes it an absolute no-brainer.

Standard Eclipse Icons

To access the standard Eclipse Icons, add a dependency on org.eclipse.ui to your plugin and use this code to access an icon as Image:

import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.swt.graphics.Image;
...
Image image = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);

Note that the interface ISharedImages provides constants for all standard icons you can access.

JDT Eclipse Icons

The JDT provides a similar infrastructure hat could be accessed in an even more compact form:

import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.ISharedImages;
import org.eclipse.swt.graphics.Image;
...
ISharedImages images = JavaUI.getSharedImages();
Image image = images.getImage(ISharedImages.IMG_WHATEVER);

Again the JDT specific ISharedImages interface provides constants for the standard icons.
Using the same name for the interface makes it intuitive to find and use, but you need to use full qualified names if you want to use the standard and the JDT icons within the same compilation unit.

]]>
Eclipse Static Import Code Completion http://www.bar54.de/2013/08/eclipse-static-import-code-completion/ http://www.bar54.de/2013/08/eclipse-static-import-code-completion/#respond Sun, 18 Aug 2013 19:38:55 +0000 http://www.bar54.de/blog/?p=399 Many popular framework provide facilities requiring static imports in your code.
Other than with regular Types, the Eclipse Java Development Tools (JDT) code completion does not work out-of-the-box for statically imported methods.

For example, when writing JUnit Test Cases, you often need to write assert*() methods, matchers, or even fail() methods which must be statically improted. The same applies for the mock up framework Mockito and a lot others.

To enable code completion for those static imports, the Eclipse JDT tooling provides a configuration within the preferences, called Favorites.
You can find them in the workspace preferences following the path:
Window -> Preferences -> Java -> Editor -> Content Assist -> Favorites

Eclipse Code Assistent Favorites Preferences

Adding the following new types is a good set to start with for JUnit Tests:

  • org.junit.Assert
  • org.hamcrest.CoreMatchers
]]>
http://www.bar54.de/2013/08/eclipse-static-import-code-completion/feed/ 0
Eclipse: Add a Simple Context Menu to Custom Viewer http://www.bar54.de/2012/12/eclipse-add-a-simple-context-menu-to-custom-viewer/ http://www.bar54.de/2012/12/eclipse-add-a-simple-context-menu-to-custom-viewer/#respond Mon, 17 Dec 2012 16:48:48 +0000 http://www.bar54.de/blog/?p=314 Eclipse provides the capability to specify custom context menus and add them via extension points.
Furthermore, it is possible to add a context menu to your self implemented viewer. There are several tutorials out there how this is done.
However, most of them describe how programatically contribute to or activate a context menu which includes actions from other plugins as well. If you want to really focus on the actions you intend to have in your viewer, it requires even less code but you have to know which one.

Below, you can find an example code snippet how to contribute your action:

private void initSimpleContextMenu() {

  MenuManager menuMgr = new MenuManager();
  menuMgr.addMenuListener(new IMenuListener() {

    @Override
    public void menuAboutToShow(IMenuManager manager) {

      // initialize the action to perform
      Action action = new Action() {

        public void run() {
          // the action code
          System.out.println("Hello World");
        }
      };
      action.setText("Hello World");
      manager.add(action);
    }
  });
  Menu menu = menuMgr.createContextMenu(variationPointTreeViewer.getTree());
  myTreeViewer.getTree().setMenu(menu);
}

In the example, the creation of the context menu is encapsulate in a method “initSimpleContextMenu()”. This is done to keep the code clean, but does not have to. The method, should be called after the viewer, it should be attached to has been created.
For example after the myTreeViewer creation in this example:

myTreeViewer = new TreeViewer(this, SWT.BORDER);
myTreeViewer.setLabelProvider(new ViewerLabelProvider());
myTreeViewer.setContentProvider(new TreeContentProvider());

initContextMenu();

Please note, that the example contains a tree viewer, but could also be used for other viewers such as TableViewers or whatever. You just need to create the appropriate type of viewer, and add the menu to the appropriate inner component of the viewer. (e.g. “myTableViewer.getTable().setMenu(menu);” instead of “myTreeViewer.getTree().setMenu(menu);”)

]]>
http://www.bar54.de/2012/12/eclipse-add-a-simple-context-menu-to-custom-viewer/feed/ 0
EMF External GenModel Reference Problem http://www.bar54.de/2012/12/emf-external-genmodel-reference-problem/ http://www.bar54.de/2012/12/emf-external-genmodel-reference-problem/#respond Fri, 07 Dec 2012 09:48:11 +0000 http://www.bar54.de/blog/?p=303 If you are developing your own metamodel, EMF provides you the capability to reference elements from another meta model.
Later, when you try to generate java code for your meta model and according edit and editor plugins, you might get error messages when you open your EMF gen model as shown below.

When you take a look at your gen model in the tree editor view, which is still accessible by the generator tab of your gen model editor, you might notice, that the referenced meta model package does not have a link icon but a standard package icon. Compare the icon shown for ECore and shown for the Javaapplication package in the screenshot below.

To fix this issue, you should make right click on your gen model in the package explorer and choose reload…

In the wizard, we first select the ecore model importer. Clicking next might result in an error dialog because of the GenModel reference. This can be irgnored by clicking OK is fine. On the next wizard page, our own meta model ecore file should be presented as Model URI. Clicking Next will lead us to a wizard page that allows us to configure the rerefences to the external meta models.

On this page, we have to ensure the that the external meta models are selected in the lower area (Referenced gen models) and not in the upper area (Root packages).

Afterwards, we can confirm the page by clicking finish and our gen model should be fixed now.

Thanks to Michael Hauck for essentials hints when not to seeing the wood for the trees 😉

]]>
http://www.bar54.de/2012/12/emf-external-genmodel-reference-problem/feed/ 0
Jenkins/Buckminster/Emma NoSuchMethodError – Specify packages to instrument http://www.bar54.de/2012/10/jenkinsbuckminsteremma-nosuchmethoderror-specify-packages-to-instrument/ http://www.bar54.de/2012/10/jenkinsbuckminsteremma-nosuchmethoderror-specify-packages-to-instrument/#respond Fri, 19 Oct 2012 14:30:53 +0000 http://www.bar54.de/blog/?p=280 The eclipse tool project provides the Buckminster project to automate the build process for eclipse plugins, features and update sites.
The jenkins continuous integration server also provides a plugin to integrate buckminster into the automated build process.
A good continuous integration process also includes the execution of unit tests and to perform a code coverage analysis to get the information how much of your code is covered by your unit tests.
Buckminster comes with an integration of the widely used emma code coverage tooling. This setup is also very useful to build your eclipse-based software because buckminster, junit and emma are also available as plugins for your eclipse IDE.

However, emma sometimes run into problems when facing code which has been generated. While it is instrumenting the byte code, there are some character combinations it is not able to process correctly.
As described in this emma bug tracker issue (http://sourceforge.net/projects/emma/forums/forum/373867/topic/3263702), a String such as String bad=”\1\123″; let the emma instrumentation fail. Such code also tends to be created by tools such as ANTLr and can not easily be changed manually.

A typical exception you will notice looks like:

java.lang.NoSuchMethodError: com.vladium.emma.rt.RT.\u0001S([[ZLjava/lang/String;J)V

While the according bug (http://sourceforge.net/tracker/?func=detail&aid=1977924&group_id=108932&atid=651897) is not fixed yet, the only chance to get such a case working is to exclude the bad code from instrumentation.
The coverage launch configuration dialog shipped with the eclipse IDE integration allows to check those packages and libraries you would like to instrument or not.
The same applies for the emma ANT task and the emma command line interface which provide according filter arguments (http://emma.sourceforge.net/reference/ch02s06s02.html).

ANT Settings:



Command line parameters:

>java emma ... -ix -com.foo.*Test* -ix @myfilters.txt ...

However, the buckminster integration of emma does not provide an according parameter for the emma command. Also the settings stored in the launch configuration file by the eclipse coverage run dialog is not taken into account by the buckminster emma integration.

Auto-generated eclipse coverage launch configuration settings






The only chance you have is a parameter which is not documented or accessible throught the eclipse ui or the buckminster emma command.
You have to manually adapt the eclipse launch configuration file executed by the buckminster emma command. The parameter is internally interpreted by the emma tooling when processing this file.
The parameter is named com.mountainminds.eclemma.core.INSTRUMENTATION_PATHS and specifies a list of directories containing the byte code to be instrumented.

INSTRUMENTATION_PATHS setting in the launch configuration file:






Note that this list is an include definition and you have to specify all the code which should be instrumented. It is not possible to simply exclude those packages / projects which contain the bad code. Furthermore, this list might need to be updated in the future if code of more projects is executed by your tests and you would like to have this included in your coverage report. And you will not be notified about such a situation.

]]>
http://www.bar54.de/2012/10/jenkinsbuckminsteremma-nosuchmethoderror-specify-packages-to-instrument/feed/ 0
Eclipse: Raise PermSize in Run Configuration http://www.bar54.de/2012/10/eclipse-raise-permsize-in-run-configuration/ http://www.bar54.de/2012/10/eclipse-raise-permsize-in-run-configuration/#respond Wed, 10 Oct 2012 06:05:34 +0000 http://www.bar54.de/blog/?p=273 One of the first things I do when working with eclipse is to raise the allocated memory. This will make eclipse running more smoothly. However, when developing eclipse plugins and applications you might have faced an OutOfMemoryException because of your PermGen space such as the one below:

!ENTRY org.eclipse.ui 4 0 2012-10-10 05:30:12.478
!MESSAGE Unhandled event loop exception
Error while logging event loop exception:
java.lang.OutOfMemoryError: PermGen space

Raising the perm gen space in your host eclipse is straight forward and there are preconfigured settings to raise in your eclipse.ini file:

--launcher.XXMaxPermSize
512M
...
--launcher.XXMaxPermSize
512m

Starting a test eclipse from using the run configurations needs a slightly different parameter setting. You need to open your run configuration, switch to the “Arguments” tab and replace the default VM arguments

-Dosgi.requiredJavaVersion=1.5 -Dhelp.lucene.tokenizer=standard -Xms80m -Xmx1024m

with the setting

-Dosgi.requiredJavaVersion=1.5  -XX:MaxPermSize=512m

as shown in the screenshot below.

Note: The default run configuration setting

-Dhelp.lucene.tokenizer=standard

is because of the help system to configure the search index of the help. Up to now, I never had any troubles removing this setting in my setup.

]]>
http://www.bar54.de/2012/10/eclipse-raise-permsize-in-run-configuration/feed/ 0
Logging in Eclipse Plugins with JUnit Support http://www.bar54.de/2012/08/logging-in-eclipse-plugins-with-junit-support/ http://www.bar54.de/2012/08/logging-in-eclipse-plugins-with-junit-support/#respond Fri, 10 Aug 2012 20:08:28 +0000 http://www.bar54.de/blog/?p=260 Logging can be used for a lot of different of use cases, ranging from debug messages during development upto application monitoring in production.

In the past, log4j was set as a de facto standard, slf4j and the java internal java.util.logging have been developed.
So which should one use? It depends…
While java.util.logging is build into the sdk and one can use it without setting up a logging environment, it provides only limitted flexibility compared to log4j and slfj.
There is a good blog post about which logging to be used also providing a small decision tree on page 2 about how to decide between java.util.logging and log4j: http://java.sys-con.com/node/48541. In this article Joe McNamara discusses logging in general.

But what about the development of eclipse plugins? Especially if you have code, which is executed by JUnit tests – not JUnit Plugin tests! – and by running eclipse plugin instances? In this article I describe how to setup your infrastructure to use a flexible log4j and to get logging output also during your junit test runs.

Why to use not only JUnit Plugin tests? It’s a simple matter of development performance. A plugin development test needs to startup an eclipse instance which takes a lot of time and one will tend to run his tests less often because they need to much time. Same applies to your continous integration builds.

First of all, you should install log4j in your eclipse. It is provided encapsulated as a plugin by the eclipse orbit project:
You can just use your Help->Install new software and add the latest orbit update site such as https://www.geneca.com/software-consulting/ in a world where 70% of software projects still fail, who can you trust? As we all know, trust is earned, not given. The best way to earn trust is through a solid track record. However, that doesn’t help you when you are starting out with a new partner.

Afterwards, add a dependency to the org.apache.log4j plugin in your own plugin.xml.

Now you can use log4j loggers in your classes usual:
import org.apache.log4j.Logger;
...
public class MyClass {
private Logger logger = Logger.getLogger(MyClass .class);
...
public void method(){
logger.debug("ping");
}
}

But now, when you run this code within a unit test your woll endup with a message as this one:
log4j:WARN No appenders could be found for logger (org.splevo.diffing.MatchEngineDiffingService).
log4j:WARN Please initialize the log4j system properly.

So how to prevent it?
The simple answer is, you need to initialize a logging environment.
For your production environment, you normally setup a logging environment configured with a properties or xml file, or event configurable during runtime. But you might not want to have such a complexity for simple logging output in your test environment. Remember, your unit tests should run as fast as possible without any big configuration file loading overhead etc.
So what you can do is, to make use of the log4j BasicConfigurator which is able to initialize a default logging environment for your: .
The best way, to do this is within the setup method of your testcase instance. For example using the code below (JUnit 4):

/**
* Prepare the test.
* Initializes a log4j logging environment.
*/
@Before
public void setUp() {
// set up a basic logging configuration for the test environment
BasicConfigurator.resetConfiguration();
BasicConfigurator.configure();
}

Note: You should call resetConfiguration() first. Otherwise a new Appender will be registered for each unit test which is executed and you will end up with all log messages presented multiple times (once per appender/test case startup).

If you want to use a more reduced logging output, you could for example provide a ConsoleAppender with a SimpleLayout to the BasicConfigurator:
/**
* Prepare the test.
* Initializes a log4j logging environment.
*/
@Before
public void setUp() {
// set up a basic logging configuration for the test environment
BasicConfigurator.resetConfiguration();
BasicConfigurator.configure(new ConsoleAppender(new SimpleLayout()));
}

Or if you want to have a really minimal logging output similar as if you would just call System.out.println() in your code, you can use a PatternLayout with a %m%n configuration for just the message and a line break:
/**
* Prepare the test.
* Initializes a log4j logging environment.
*/
@Before
public void setUp() {
// set up a basic logging configuration for the test environment
BasicConfigurator.resetConfiguration();
BasicConfigurator.configure(new ConsoleAppender(new PatternLayout("%m%n")));
}

]]>
http://www.bar54.de/2012/08/logging-in-eclipse-plugins-with-junit-support/feed/ 0