5 comments Wednesday, March 31, 2010

When you use some of the Eclipse IDE plugins they may contribute preference pages that you may not necessarily want to show to your users.

Remove them in the ApplicationWorkbenchWindowAdvisor.postWindowCreate():


PreferenceManager pm = PlatformUI.getWorkbench( ).getPreferenceManager();
pm.remove("org.eclipse.ui.preferencePages.Workbench");


The "org.eclipse.ui.preferencePages.Workbench" id removes the "General" preference page group. If you do not know the id for the page you want to remove. You can first print them like this:

PreferenceManager pm = PlatformUI.getWorkbench( ).getPreferenceManager();
IPreferenceNode[] arr = pm.getRootSubNodes();

for(IPreferenceNode pn:arr){
System.out.println("Label:" + pn.getLabelText() + " ID:" + pn.getId());
}

2 comments Friday, March 19, 2010

How to set color and font for a table cell using TableViewer in JFace?

All you need to do is make your ITableLabelProvider implementation also implement ITableFontProvider and ITableColorProvider.




public class TypeLabelProvider implements ITableLabelProvider,
ITableFontProvider, ITableColorProvider {
...
...
ITableLabelProvider methods
...
...

@Override
public Font getFont(Object element, int columnIndex) {
return JFaceResources.getFontRegistry().getBold(
JFaceResources.DIALOG_FONT);
}

@Override
public Color getBackground(Object element, int columnIndex) {
return new Color(display, new RGB(125,189,0));
}

@Override
public Color getForeground(Object element, int columnIndex) {
return new Color(display, new RGB(125,189,0));
}
}

0 comments Friday, July 17, 2009

How to create a key binding in your Eclipse RCP application?
You need to create a command and its command handler and then create a key binding for it.

1. Define a command:
See an example below for a Save command:
I have a defaulthandler specified and I have categorized this command under the MyCategory category. This is useful when this command is shown in the Keys view in the Preferences dialog.


<extension point="org.eclipse.ui.commands">
<category description="My category for commands" id="MyCategory" name="My Category">
</category>
<command categoryid="MyCategory" description="Save the active screen" defaulthandler="my.package.MySaveHandler" id="save.command" name="Save">
</command>
</extension>


2. Create a command handler for the command:
In the above step I defined the defaultHandler as my.package.MySaveHandler. This is the fully qualified class name for the handler class that implements IHandler. This is called when this command is executed.

3. Create a key binding for and bind it to the command:

Shown below is the minimal key binding for the CTRL+S key sequence. It is bound to the save command through the commandId property. the schemeId is set to the default key binding scheme. This works for me because there arent any other key bindings for CTRL+S defined in the default scheme. If you are faced with a situation where the default scheme already has a binding for your sequence, then you can either define your key binding in another scheme (See the 'Defining your own key binding scheme' section below for more information.) or you can define your key binding's active context. ( See How to selectively enable or disable the key binding)

<extension point="org.eclipse.ui.bindings">
<key commandid="save.command" schemeid="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="M1+S">
</key>
</extension>


How to selectively enable or disable the key binding?
This is the same as enabling or disabling the command associated with the key binding.

You do this by using the org.eclipse.ui.handlers extension point. In the example below I enable my handler for the command only if a specific part is active

<extension point="org.eclipse.ui.handlers">
<handler class="my.package.MySaveHandler" commandid="save.command">
<enabledwhen>
<with variable="activePartId">
<equals value="my.package.editors.MyEditor">
</equals>
</with>
</enabledwhen>
</handler>
</extension>

The handlers extension is also useful when you want to have multiple handlers for the same command. For e.g. if you want your save command to save the currently active editor, and you have different types of editors in your application each requiring a different saving mechanism, you can define three different handlers, bind them all to the Save command through the commandId property and just make sure only one of them is active based on which editor is active at the time the command is invoked. Actually, when it comes to editors you can get away with one handler because all editors that extend IEditorPart have a doSave method anyways which can be called by the common handler. You implement your differing save mechanisms by overriding the doSave method in your editor.

How to override an existing key binding?
There are two ways to do this, one, by defining your key binding in your own scheme, or two, by defining the context in which this key binding is active.


1. Defining your own key binding scheme:
Using the bindings extension point you can define your own scheme and then using the schemeId property of the key element you can define your key binding to belong to your schema.
See this Vogel.de tutorial on how to do this.


2: Defining context for your key binding:
there are three steps as shown below...

a. Define your context:
You can do this using the org.eclipse.ui.contexts extension.

<extension point="org.eclipse.ui.contexts">
<context id="my.context" name="My Context" parentid="org.eclipse.ui.contexts.window">
</context>
</extension>



b. Set the key binding's context to the one you defined in a.:

Each key binding has the contextId property that you can use for this..

<extension point="org.eclipse.ui.bindings">
<key commandid="save.command" contextid="my.context" schemeid="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="M1+S">
</key>
</extension>



c. Switch the context in your application

PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
((IContextService) PlatformUI.getWorkbench()
.getService(IContextService.class))
.activateContext("my.context");
}
});


If you want to do this at the start a good place to do it is in the createInitialLayout method of the IPerspectiveFactory class.


Resources:
http://www.vogella.de/articles/EclipseCommands/article.html#keybinding
http://sry-for-my-english.blogspot.com/2007/05/rcp-keybinding-issues.html

2 comments Wednesday, July 8, 2009

When you use the FilteredTree with a PatternFilter, the visible nodes include the leaves as well as their parents in the tree that match the filter text. However if your usecase requires that a matched node's children also be shown then you need to use a custom PatternFilter which will select an element if any of its ancestors are a match.

Here is how I did it:


public class ShowChildrenPatternFilter extends PatternFilter {

protected boolean isChildMatch(Viewer viewer, Object element) {
System.out.println("inchildmatch");
Object parent = ((ITreeContentProvider) ((AbstractTreeViewer) viewer)
.getContentProvider()).getParent(element);

if(parent!=null){
return (isLeafMatch(viewer, parent)?true:isChildMatch(viewer,parent));
}
return false;

}


@Override
protected boolean isLeafMatch(Viewer viewer, Object element) {
String labelText = ((ILabelProvider) ((StructuredViewer) viewer)
.getLabelProvider()).getText(element);

if(labelText == null) {
return false;
}

return (wordMatches(labelText)?true:isChildMatch(viewer, element));
}
}
Now from a good UI design perspective we should also show the actual pattern matches in a bold font similar to how the default Preferences Dialog filtered tree works.

For that we need our ILabelProvider to implement IFontProvider and in the getFont method we need to call the FilteredTree.getBoldFont method. This method takes a PatternFilter as an argument. This is the filter that is used to select which elements are shown in bold. Since we just want our true matches ( and not their children) to be bolded, we cannot use our modified ShowChildrenPatterFilter. Instead we can just use the regular PatternFilter here. Here is how your LabelProvider class will look:

public class MyFilteredTreeLabelProvider implements ILabelProvider,IFontProvider {

private FilteredTree filterTree;
private PatternFilter filterForBoldElements = new PatternFilter();

public TypeSystemTreeLabelProvider(FilteredTree filterTree) {
super();
this.filterTree = filterTree;
}


@Override
public String getText(Object element) {
//your code to get the display text for the element
}

@Override
public void addListener(ILabelProviderListener listener) {}

@Override
public void dispose() {}

@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}

@Override
public void removeListener(ILabelProviderListener listener) {}

public Font getFont(Object element) {
return FilteredTree.getBoldFont(element, filterTree,
filterForBoldElements);
}
}

1 comments Monday, July 6, 2009

If you are using Annotations to do some text decorations and highlighting in your TextEditor or StatusTextEditor sub classes, you have to make sure to add the AnnotationPainter as a TextPresentationListener to the SourceViewer, in addition to adding it as a Painter. This is required when you want to use text styling strategies (ITextStyleStrategy) instead of the IDrawingStrategy.

The easiest way to highlight text in your color using the AnnotationPainter is to use its inbuilt addHighlightAnnotationType method.


public class AnnotatedDocumentEditor extends StatusTextEditor{

public static final String ID = "edu.pitt.dbmi.odie.ui.editors.AnnotatedDocumentEditor";
private AnnotationPainter annotationPainter;

public AnnotatedDocumentEditor() {
super();
setDocumentProvider(new AnnotatedDocumentProvider());
}

@Override
protected ISourceViewer createSourceViewer(Composite parent,
IVerticalRuler ruler, int styles) {
SourceViewer sv = (SourceViewer) super.createSourceViewer(parent, ruler, styles);
initAnnotationPainter(sv);

sv.addPainter(annotationPainter);
sv.addTextPresentationListener(annotationPainter);
return sv;
}

private void initAnnotationPainter(SourceViewer sv) {
IAnnotationAccess annotationAccess = new IAnnotationAccess() {
public Object getType(Annotation annotation) {
return annotation.getType();
}
public boolean isMultiLine(Annotation annotation) {
return true;
}
public boolean isTemporary(Annotation annotation) {
return true;
}
};

annotationPainter = new AnnotationPainter(sv,annotationAccess);

annotationPainter.addHighlightAnnotationType("DUMMY1");
annotationPainter.addHighlightAnnotationType("DUMMY2");
annotationPainter.addHighlightAnnotationType("DUMMY3");

Display display = Display.getDefault();

annotationPainter.setAnnotationTypeColor("DUMMY1", new Color(display, new RGB(125,189,0)));
annotationPainter.setAnnotationTypeColor("DUMMY2", new Color(display, new RGB(228,142,52)));
annotationPainter.setAnnotationTypeColor("DUMMY3", new Color(display, new RGB(244,229,61)));
}

}

Please note that the above code is not complete. You need to create the AnnotationModel for each document using your implementation of the AbstractDocumentProvider

See the following links for good tutorials on using AnnotationPainter and extending TextEditors in Eclipse:

http://eclipse.dzone.com/articles/beyond-rich-text-tricks-using-
http://www.realsolve.co.uk/site/tech/jface-text.php

0 comments Wednesday, July 1, 2009

If you dont know the amount of work involved you need an indeterminate progress bar.

If using ProgressMonitorDialog, in the run method of IRunnableWithProgress, instead of specifying an integer indicating the total as an argument do this:


public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException {
monitor.beginTask("Task name",IProgressMonitor.UNKNOWN);

0 comments Monday, October 27, 2008

I looked for this for a while. Eclipse 3.x has the swooshed tab headers that taper towards the end.

To get that in your RCP application where you may use IFolderLayout to group views, or have multiple editors you need to make your Eclipse application a product and do the following:


To get the swoosh on any tabfolder that you create in your code. You have to use CTabFolder as follows:


CTabFolder tabFolder = new CTabFolder(shell, SWT.CLOSE | SWT.BOTTOM);


The following line does the magic:

tabFolder.setSimple(false);