Showing posts with label rcp. Show all posts
Showing posts with label rcp. Show all posts

SWT File Dialog

During the development of an Rich Client Platform (RCP) I needed to perform a file browse, here's how to show a file dialog in SWT:

import org.eclipse.swt.widgets.FileDialog;

FileDialog dialog = new FileDialog(this.getShell(), SWT.NULL);
dialog.setFilterExtensions(new String[] { "*.txt", "*.*" });
dialog.setFilterNames(new String[] { "Text files", "All files" });
String path = dialog.open();
if (path != null) {
File file = new File(path);
if (file.isFile()) {
System.out.println(file.toString());
}
}

The snippet above filters by text files (*.txt) and all files (*.*) only, and it can be easily applied to any button or file menu option click event.

./M6

RCP save workbench status

In Rich Client Platform (RCP) application, the workbench status can be easily saved and restored by simply including the snippet bellow in the ApplicationWorkbenchAdvisor class, that extends WorkbenchAdvisor.

@Override
public void initialize(IWorkbenchConfigurer configurer) {
super.initialize(configurer);

// tell eclipse to save workbench state when it quits
// (things like window size, view layout, etc.)
configurer.setSaveAndRestore(true);
}

This will automatically save the status of the workbench when the application is closed and will automatically restore that status when the application is executed again. The settings are saved on the [runtime-{your-product}]/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml file.

./M6

Selecting a value from a SWT CCombo on RCP

It looks like the CCombo custom SWT object lacks some selection functionality. I'm using a CCombo as a table cell editor on my Rich Client Platform (RCP) application and I've found out that it is (almost) impossible to detect the user selection with both the keyboard and the mouse.

The selection listener does not work as expected. Documentation says:
  • the widgetSelected method is triggered whenever a selection occurs in the control, i.e. when the user browses the option list this event is triggered;
  • the widgetDefaultSelected method is triggered when default selection occurs in the control, i.e. when the user selects an option from the list this event is triggered.
One might think, as I thought, that all one has to do is to catch the widgetDefaultSelected event and one would know which option the user has selected from the list.
This is only true when the user performs the selection using the keyboard, i.e. after browsing through the options list the Enter/Return key is pressed.
If the user decides to use the mouse, the widgetDefaultSelected event is not triggered at all, but widgetSelected is.

I though I could detect the user selection with the mouse listener. I was wrong. After trying a couple more possibilities, it turns out there's no (easy) way to detect if the user has performed a selection using the mouse...

So I had to do a workaround for it. Since the widgetSelected is triggered by the mouse clicks, I tried to use that event. Unfortunately the event has no real useful information, like if it was triggered by a right button mouse click. But fortunately, the CCombo object does have a couple of methods that allowed to infer that a selection has been made. In particular, it has a method to check if the options list is visible or not. Since a selection with the mouse makes the options list disappear, I've used it.

Here's the snippet:

// Selections events
combo.addSelectionListener(new SelectionAdapter() {
// Selection changed, check if the options are still visible
public void widgetSelected(SelectionEvent e) {
// If list is not visible assume that the user has
// performed selection with the mouse
if (!combo.getListVisible()) {
setEditionValue(combo);
}
}

// Option selected
public void widgetDefaultSelected(SelectionEvent e) {
// User performed a selection with the keyboard
setEditionValue(combo);
}
});
This is not a perfect solution, it's a workaround, but it's working just fine for me.

./M6

RCP Message Dialog

It looks like every time I need a message dialog in an Rich Client Platform (RCP) application, it takes me too much time finding which JFace dialog class is better for me...

This time I decided to post it here so that the next time I won't waste time.
All the methods needed are statically available in the org.eclipse.jface.dialogs.MessageDialog class:
  • MessageDialog.openConfirm, for a confirmation dialog with an Ok/Cancel button set.
  • MessageDialog.openError, for an error dialog with an Ok button.
  • MessageDialog.openInformation, for an information dialog with an Ok button.
  • MessageDialog.openQuestion, for a question dialog with and Yes/No button set.
  • MessageDialog.openWarning, for warning dialog with an Ok button.
The org.eclipse.jface.dialogs.MessageDialogWithToggle is similar,but allows the user to adjust a toggle setting, like Yes Always/Yes/No or Yes/No/Never.

You can use org.eclipse.jface.dialogs.DialogSettings for a dialog setting, supporting loading and saving of properties in an XML file.

You can use org.eclipse.jface.dialogs.ProgressMonitorDialog to display progress during a long running operation.

And you can design your own dialog windows, just extend the org.eclipse.jface.dialogs.IconAndMessageDialog class.


Note: in RCP, you can get the shell using PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();.

./M6

RCP Open and Save File Dialogs

I'm currently developing an Eclipse application, and since some of the usual functionalities is the open and save file, or project, I'm posting here a nice code snippet for using open and save dialogs in Rich Client Platform (RCP) applications.

Both the FileOpen and FileSave classes bellow are ready for usage as a command default handler for the extension org.eclipse.ui.commands in the plugin.xml file. Don't forget to create the menu entry to use this command.

Here's the open file snippet (don't forget to update the package)
package your.package.in.here;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
* Opens a file
*/
public class FileOpen extends AbstractHandler implements IHandler {

@Override
public Object execute(ExecutionEvent event)
throws ExecutionException {

Shell shell = PlatformUI.getWorkbench().
getActiveWorkbenchWindow().getShell();

FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setFilterExtensions(new String[] {"*.txt", "*.*"});
dialog.setFilterNames(new String[] {"Text File", "All Files"});
String fileSelected = dialog.open();

if (fileSelected != null) {
// Perform Action, like open the file.
System.out.println("Selected file: " + fileSelected);
}
return null;
}
}


And here's the save file snippet (don't forget to update the package):
package your.package.in.here;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
* Save file as...
*/
public class ProjectFileAs extends AbstractHandler implements IHandler {

@Override
public Object execute(ExecutionEvent event)
throws ExecutionException {
Shell shell = PlatformUI.getWorkbench().
getActiveWorkbenchWindow().getShell();

FileDialog dialog = new FileDialog(shell, SWT.SAVE);
dialog.setFilterExtensions(new String[] {"*.txt", "*.*"});
dialog.setFilterNames(new String[] {"Text File", "All Files"});
String fileSelected = dialog.open();

if (fileSelected != null) {
// Perform Action, like save the file.
System.out.println("Selected file: " + fileSelected);
}
return null;
}
}

./M6

Eclipse RCP Tutorial with Eclipse 3.4

I was digging for some RCP development information and I've found this nice tutorial: Eclipse RCP - Tutorial with Eclipse 3.4

As for the complete RCP development documentatio, it can be found in the Eclipse documentation site.

./M6

Talend Open Studio

Since one of my professional interests is ETL/Data Migration, I'm evaluating Talend Open Studio, version 3.1 RC1, since it's an open source solution.

I've downloaded the product, installed it and when I opened it, I had to read and accept the license, and then I got a dialog box that was asking for a connection and a project. Obviously I had none of those so I tried to create one... That proved to be a not so easy task! I was not understanding what should I do, so I pressed F1 for help and... No luck... I had to figure out what the hell I was supposed to do to be able to create a project. It as not that hard to find it out, but still, the first impression was not a very positive one.
I had to register, or at least so it seemed since I had to insert my email address, and the I was able to import a Java demo project, which I did.
Then, I opened the project and, finally, I've arrived to what I was expecting to be the real first Open Studio window, the Welcome page! Talend is an RCP application, and in RCP applications, the welcome page is the first thing that the user sees, after the traditional splash screen.

Finally, on the welcome page, I got a register pop-up, where I should write my email address and state my location... I really don't get it! If registration is optional, why the hell did I had to write my email address to create a new repository and then a project on that repository?
All Open Studio does with this awkward interface is confusing its users, since it is using hiding, on a very confusing way, the Eclipse workspace and projects.
From the starting page I went to the, previously desired but inaccessible, help page from where I could watch a, also desired, kick start tutorial where the workspace and project creations were visible. Unfortunately, it was totally time dislocated, since it was now totally irrelevant.
I know I'm using a RC, but this kind of issues are not RC bugs, they are design faults!

Since I'm a technical guy, unfortunately I'm used to bad user interfaces, so I focused on the juicy stuff, its features, performance and transformations.

I started to explore the application and I got into one ugly dialog box! I haven't seen a dialog box so ugly for a long time. And it is so big that I almost felt that if I was not using an wide screen (1280x800) I would be unable to see the dialog box. The dialog box rules are also a bit confusing, for instance, I was forced to choose a week day, Monday was my choice, even after I had chosen an month day, day 1 was my choice. I wonder what will happen if the first day of the next month is not a Monday...

Talend Open Studio ugly "Add a task" dialog box.

Definitely, Open Studio interface has a long way to go before becoming really user friendly.

After that shocking moment, I continue to explore the product.

There's a business model area, where it is possible to specify very simple business diagrams. My first impression about this is that I have doubts about the real value and usefulness of this feature. I'll have to explore it more to know if it is really useful or not.
Open Studio has some simple data quality components, including a fuzzy one. Talend already has a data cleaning tool, Talend Data Quality.
It supports a variety of file formats, including Excel, XML and EBCDIC. EBCDIC in particular is extremely useful when it involves files from IBM mainframes.
There's a nice set of connections, including a connection for AS/400 and SAP.
It supports orchestration through a set of iterative and job execution components.
There's a set of SQL templates, some of them are not really that useful. There are templates what just have COMMIT; or DROP TABLE <%= __DATABASE_NAME__ %>.<%=__TABLE_NAME_TARGET__%>;.

Almost all components and processes have history, which is a very nice feature. It looks like that there's no version control implemented, just history, but that is a good first step into a control versioning.
The same applies to documentation, almost all components and processes seem to have documentation associated, this is not just an interesting feature, it's a must have on such a tool.

Since it is possible to document the components, the processes and the business rules through diagrams, I look around for a way to export the project documentation, but I was unable to find such feature.
There's an Documentation area, but it's not what I was expected. It seems to be just a file link interface, where documentation files, like spreadsheets, can be accessed from.
And there's a javadoc export functionality, which also does not do what I expected, apparently it exports Talend components documentation.
There's no really usefulness for documentation when it is not easily accessible. It's like having a jar library all documented but no javadoc to build its documentation, forcing anyone who needs to read the documentation to open the source code and read it from there. It does not make much sense.

Finally, one of the most interesting features is the real time debug. I still haven't got the opportunity to try it out, but for what I could see, that is the ETL developer best friend Open Studio feature.

I've already watched some videos of how easy ETL is with Open Studio, dragging and dropping and graphically connecting the components and all that. In the next days, I'll try it for myself.

./M6

i18n RCP applications

I'm developing an RCP application, also known as Eclipse Application, with a couple of friends and it is internationalized (i18n) for English, Portuguese and, currently non-officially and incomplete, Spanish.

Currently it is being developed on Europa (3.3.2) and after fetching the i18n Eclipse packages for Portuguese, I was unable to use the i18n files withing the application.
What this means is that the application specific stuff was i18n but the RCP core was not. For instance, the menus were in Portuguese but the welcome page navigation buttons, and all JFace stuff and alike, were in English.

I've digged for "awhile" in the official RCP documentation, FAQs, How-Tos, and non-official stuff like news groups, forums and blogs. I've made some posts in some-what official RCP fóruns/news groups but I haven't got a single answer.

After almost two weeks fighting with this problem, I've finally solved it!
It's actually quite easy and all it requires is a couple mouse clicks.

Here's what it takes to i18n the core of an RCP application:
  1. Download the language packages from the Babel project using the Eclipse install/update mechanism.
  2. Open the RCP application ".product" file.
  3. Go to the "Configuration" section.
  4. Press "Add Required Plug-ins" button.
This last step is the "magical step", it includes the i18n plugins to the RCP application.
You can identify the language plugins by their name. They come in the "<plugin>.nl_<language>" format. For instance, Portuguese JFace translation file is "org.eclipse.jface.nl_pt".

I sure hope this information helps others and save their time.

./M6

JDeveloper Sucks

During 2008 I've been using Oracle JDeveloper 10.1.3.3 for J2EE, or JEE as SUN has renamed it, using ADF.
I can only say that JDeveloper sucks... And by the way, ADF sucks too...

JDeveloper deteriorates with usage, meaning if you use it a lot, as I do on a daily basis, will start behaving weird, like crashing when it's started or refusing to close a file that has been edited, even if it file is no longer accessible through a tab, it is still loaded, since it is reachable through the window list.
Degradation is not uncommon in such IDEs, sometimes Eclipse also deteriorates, specially when it has loads and loads of plugins. But Eclipse can be "restarted", just do a -clean and it stability will come back. JDeveloper does not have such parameter, and one has to reinstall it (overwriting will not work) and reinstall all necessary plugins or "clean" it manually, witch is not easy nor fast to do.
Degradation itself is bad enough, but it's not the only bad feature it has.
Some simple an common functionality is really bad implemented, so bad that it can ruin ones work, has it has already done with me. A "simple" rename of a variable, through the refactor functionality, will perform a textual search for the variable string name in all the files. The result can be catastrophic, since it can (an will) find that variable string as a substring on a non-related variable and method names... Yep, it's default refactoring will "blindly" perform a textual find-and-replace in all your .java project files... So be careful and check the preview option before doing it.
The Subversion (SVN) plugin sucks to... It's not really useful. I was expecting to commit/update over a project, but that is not possible. One can do such operation over files and some directories, but the SVN plugin is not that useful, since if your project has more that a module, you need to go to "special" directories/packages and perform the commit/update, on each module...
The debug task is also not very good. When one watches a variable or expression, most of the time it cannot retrieve/evaluate its value.

These are just some examples of how bad JDeveloper is. I knew it was not state-of-the-art, but I was not expecting something this bad...
Here's a hint for Oracle JDeveloper product management: how about using Eclipse RCP as the base of JDeveloper?

./M6