Pages

Tuesday, 25 October 2011

Ever thought of running a RCP in Browser ? RAP is here !

I have been hearing a lot in terms of web based version of Eclipse APIs and browser based RCP off late. On googling a bit, I found out that RAP has indeed made it possible to launch the RCP in a web browser.A RAP screencast showing how to convert the RCP Mail Template into a RAP application can be seen at this link - View screencast in new window.
Wait, what is RAP anyway?

RAP stands for Rich Ajax Platform. It is an Eclipse Project that enables Java developers to build browser-based AJAX applications using the full Java libraries, Eclipse APIs and a plug-in architecture. It does so by providing a web-enabled implementation of SWT, JFace and the Workbench.

Although, this experiment sort of works but I am not sure how useful will it be to try and run a HEAVY swt based app in a plain browser. Hope to see much more development happening in this context as one benefit that this is surely going to bring is the freedom from installing a RCP on each client machine.

WAY TO GO RAP.

Quick Access (Ctrl+3) feature added

Quick Access (Ctrl+3) command has been introduced in Eclipse 3.4.  

It allows you to access UI-elements - like Views, Perspectives, Commands, etc. - by just typing their name.
Some usage examples:
  • Open the Navigator View? Ctrl+3, Navi, return
  • Debug Last Launched? Ctrl+3, DLL, return
  • Open the Debug Perspective? Ctrl+3, Perspectives D (Perspectives Debug), return

Tuesday, 26 July 2011

Remove Unwanted Perspectives from your RCP

While creating a RCP recently I noticed that I had dependencies on some of the Eclipse JDT and Plugin development features and due to this the RCP was showing some really unnecessary entries in the Perspective selection bar.

On debugging a little I found out the concept of pre-defined perspectives (those which come as a result of contributions from Plugin.xml of any contributing plugin) and it is indeed pain to remove those perspectives from any RCP.

Here is the snippet that I hacked to get rid of those predefined perspectives -

Call the  removeUnWantedPerspectives() (attached below) method from postWindowCreate() method of your RCP's WorkbenchWindowAdvisor extension class -

     public static final String[] IGNORE_PERSPECTIVES = new String[] {
            "org.eclipse.birt.report.designer.ui.ReportPerspective", "org.eclipse.debug.ui.DebugPerspective",
            "org.eclipse.jdt.ui.JavaPerspective", "org.eclipse.jdt.ui.JavaHierarchyPerspective",
            "org.eclipse.jdt.ui.JavaBrowsingPerspective", "org.eclipse.mylyn.tasks.ui.perspectives.planning",
            "org.eclipse.pde.ui.PDEPerspective", "org.eclipse.team.cvs.ui.cvsPerspective",
            "org.eclipse.ui.resourcePerspective", };

    /**
     * Removes the unwanted perspectives from your RCP application
     */
    private void removeUnWantedPerspectives() {
        IPerspectiveRegistry perspectiveRegistry = PlatformUI.getWorkbench().getPerspectiveRegistry();
        IPerspectiveDescriptor[] perspectiveDescriptors = perspectiveRegistry.getPerspectives();
        List ignoredPerspectives = Arrays.asList(GenericConstants.IGNORE_PERSPECTIVES);
        List removePerspectiveDesc = new ArrayList();
       
        // Add the perspective descriptors with the matching perspective ids to the list
        for (IPerspectiveDescriptor perspectiveDescriptor : perspectiveDescriptors) {
            if(ignoredPerspectives.contains(perspectiveDescriptor.getId())) {
                removePerspectiveDesc.add(perspectiveDescriptor);
            }
        }
       
        // If the list is non-empty then remove all such perspectives from the IExtensionChangeHandler
        if(perspectiveRegistry instanceof IExtensionChangeHandler && !removePerspectiveDesc.isEmpty()) {
            IExtensionChangeHandler extChgHandler = (IExtensionChangeHandler) perspectiveRegistry;
            extChgHandler.removeExtension(null, removePerspectiveDesc.toArray());
        }
    }


Tuesday, 23 November 2010

Remove the Progress Monitor Part from Jface Wizard

Many a times the Jface wizards have posed an annoying problem to me... Even after setting the needsProgressMonitor attribute to false, there is some extra space left at the bottom of the wizard dialog which contains the invisible progress monitor part.

I finally managed a hack that removes that part, here is the code that you need to use -

WizardDialog dialog = new WizardDialog(null, wizard) {
           
            @Override
            protected Control createDialogArea(Composite parent) {
                Control ctrl = super.createDialogArea(parent);
                getProgressMonitor();
                return ctrl;
            }
           
            @Override
            protected IProgressMonitor getProgressMonitor() {
                ProgressMonitorPart monitor = (ProgressMonitorPart) super.getProgressMonitor();
                GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
                gridData.heightHint = 0;
                monitor.setLayoutData(gridData);
                monitor.setVisible(false);
                return monitor;
            }
   };

This safely removes the extra space from the bottom of the wizard. Though you will not be able to use the progress monitor from this point onwards in the wizard where this code is placed.

Thursday, 3 June 2010

Delete Logs action on Eclipse Problems View

The standard Eclipse Errors view has a provision for deleting all the logs by simply using the Delete Logs action available in the view tool bar as shown -

But there is no such provision available for the Eclipse Problems View. If you are planning to utilize the problems view in your product then this might be a big headache. I encountered the same thing and decided to contribute one of my own action for doing this job.

Extension Point Definition -





Extension Point Details -

The class DeleteLogsAction looks as follows -

public class DeleteLogsAction extends Action implements IViewActionDelegate {

    private IViewPart view;

    private final static String DIALOG_TITLE = "Confirm Delete";

    private final static String DIALOG_MESSAGE = "Are you sure you want to delete all logged events?";

    private final static String MARKER_TYPE = IMarker.PROBLEM;

    private final static int DEPTH = IResource.DEPTH_INFINITE;

    private final static boolean INCLUDE_SUB_TYPES = true;

    public DeleteLogsAction() {
        this.setImageDescriptor(Activator.getImageDescriptor("\\icons\\remove.gif"));
        this.setDisabledImageDescriptor(Activator.getImageDescriptor("\\icons\\remove_disabled.gif"));
    }

    @Override
    public void init(IViewPart view) {
        this.view = view;
    }

    @Override
    public void run(IAction action) {
        try
        {
            if(ResourcesPlugin.getWorkspace() != null)
            {
                IWorkspace workSpace = ResourcesPlugin.getWorkspace();
                if(workSpace.getRoot() != null)
                {
                    IWorkspaceRoot root = workSpace.getRoot();
                    IMarker[] markers = root.findMarkers(MARKER_TYPE, INCLUDE_SUB_TYPES, DEPTH);
                    if(markers != null && markers.length > 0)
                    {
                        boolean confirm = MessageDialog.openConfirm(view.getSite().getShell(), DIALOG_TITLE,
                                DIALOG_MESSAGE);

                        if(confirm)
                        {
                            root.deleteMarkers(MARKER_TYPE, INCLUDE_SUB_TYPES, DEPTH);
                        }
                        else
                        {
                            return;
                        }
                    }
                }
            }
        }
        catch ( CoreException e )
        {
            PALogger.logError(Activator.PLUGIN_ID, "Failed to delete the problem markers.", e);
        }
    }

    @Override
    public void selectionChanged(IAction action, ISelection selection) {
    }

Once this part is done, You will be able to see the new action in the problems view -

Run editor in event loop

We have only seen dialogs in a modal mode but recently I came across a requirement where we had to open an editor from a UI thread and then hold the Job until that editor was either closed or a button 'continue' was pressed upon it.


The challenge here was halting/suspending the job until some user action has been received. So here is the trick that I applied towards this problem -

  • Get the active workbench window -
 IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
  •  Get the active page -
IWorkbenchPage page = dw.getActivePage();        
  • Open the editor -
IEditorPart part = IDE.openEditor(page, editorInput, true);
  • Use the following method to keep the job suspended until the editorpart was disposed -
runEventLoop(page, part.getEditorInput(), monitor);

private void runEventLoop(IWorkbenchPage page, IEditorInput editorInput, ProgressMonitor monitor) {
        Display display = Display.getCurrent();
        if(page != null && editorInput != null)
        {
            while (page.findEditor(editorInput) != null)
            {
                IEditorPart part = page.findEditor(editorInput);
                if(!monitor.isCanceled())
                {
                    if(!display.readAndDispatch())
                    {
                        display.sleep();
                    }
                }
                else
                {
                    if(part.getSite() != null && part.getSite().getPage() != null)
                    {
                        part.getSite().getPage().closeEditor(part, false);
                    }
                }
            }
            display.update();
        }
    }

So, as long as the editor part is received on page.findEditor(editorInput) line the display would sleep and hence our job will sit dummy. As soon as the editor part is not found, the while loop will exit updating the display in the process.

Change types in Eclipse Problems View using EMF

An interesting problem that I recently faced was to change the type for the messages appearing in the Type column of Eclipse Problems view. I am working with EMF plugins at the moment and had to come up with a solution that suits the EMF environment. By default any validation message in EMF has a type of 'EMF Problem' associated with it but in certain situations we need to change that to meet our business needs. So, here is what you need to do -

  • Define your own Resource Markers in some plugin as shown -


  • Override the validate action present in the ActionBarContributor class of your EMF editor plugin. By default it points to the "org.eclipse.emf.edit.ui.action.ValidateAction", create your own class extending this one.
  • In the extended class, override the method "Diagnostic validate(final IProgressMonitor progressMonitor)" in the following manner -
protected Diagnostic validate(final IProgressMonitor progressMonitor) 

    /* Overridden the utility to supply the new Marker ID */
    eclipseResourcesUtil = EMFPlugin.IS_RESOURCES_BUNDLE_AVAILABLE ?
     new EclipseResourcesUtil() {
               @Override
                protected String getMarkerID() {
                 return "New Resource Marker ID" ;
                 }
       } : null;
               /*Changes finished*/
  }
  • When you will now execute the validate action, the custom type specified while defining your own resource marker shall be shown instead of 'EMF Problem'.