Friday, November 21, 2008

Back from ESE

I'm back in reality and just recap what happened the last 4 days.

My talks

Let me first recap my talks. I think all in all they went quite well though there are always things to improve (it was my first time doing a talk my own)

E4 - Modeling the workbench

I think I never talked to so many people ever before because I did my presentation in the biggest room available.I think I got the message around what the E4 project is about and in particular what the subtask-team I'm in is doing. The first reviews tell me that I didn't fail but I look forward for more comments.After my talk many people showed up personally. From what I can tell they agree with us about heading in the right direction. I think I even got the message about the joy, passion and openess the current E4-team is working together around that good that people think about joining us and bring in their own vision about the future of the Eclipse Platform. Hope to see you soon showing up at the E4-Mailing list.

Datacentric RCP with EMF and Databinding

I did the presentation in the 2nd biggest room and there even haven't been enough chairs for all people who wanted to attend my talk so they had to stand in the back. Woohoo.

I felt more comfortable speaking without a microphone and I think I showed people when mixing the right Eclipse technologies it's possible to write Enterprise ready Database frontends.

I admit my presentation was a bit focused about UI (Key-Binding, UI-Contexts, Commands) and not so how to access data. The only review I found until now is a short sentence in Ed Merks blog where people told him that the talk was "really good". So looking forward for more comments. I think the small application I presented there is what many people requested on the "E4-symposia" when they asked about a best practice example.

I even thought about restarting on an accompanying book about all the stuff one can find in the example and technologies but dismissed this thought immediately because I simply don't have the time and financial grounding to spend my time on it. The time (=money) my small company is investing in Eclipse is big enough already.

Conclusion

I would appreciate to get more comments about my presentation and ask myself why the same we had one EclipseCon was done where people got small pieces of paper to give back comments.

I think the intention was that people use gPublication to do so but it looks like people don't know about this. So if you want to give feedback and get access to the slides please do so at:

  • E4-Modeling the workbench: here

  • Datacentric RCP: here

but I'm afraid not all people attending my talks are really following my blog or the Planet so the feedback is going to be less than it was on EclipseCon.

If you and your company need help to get started with Eclipse RCP and other Eclipse technologies like OSGi, the modeling stack like (EMF, Teneo, CDO) my company is offering consultancy and development resources to anyone interested.

The E4 symposia

The symposia once more was I think a well received offer of Eclipse Summit Europe to the community and we talked about a lot different things in the E4 space. Boris Bokowski summarized the symposia in here.

For me as someone taking part in E4 project it is important to get feedback from the community to integrate their wishes (if my time permits) in the code base.

Socializing

I got to know my new people and we had a lot of interesting chats about new ideas (e.g. declarative ui) so it's hard to get back to reality and working on all those boring stuff.

Tuesday, November 04, 2008

Rotating Image in a PaintListener

For those who have a better understanding of matrices and 2-D graphics this may sound strange but today I struggeled about 2 hours rotating an image in a PaintListener.

Let me first of explain the exercise I had to solve, then show you my solution and then maybe someone can point out a better one.

Exercise

Draw an Image at Point(50,50) in a Canvas which is rotated a variable angle.

The solution

Solveing this problem one can use a SWT-Transform to adjust the Graphics-Context looks straight forward but it took me like said 2 hours to wrap my head around the problem. The following function is the solution I came up with.

public void paintControl(PaintEvent e) {
GC gc = e.gc;
gc.setAdvanced(true);

Bounds b = image.getBounds();

Transform transform = new Transform(display);
// The rotation point is the center of the image
transform.translate(50 + b.width/2, 50 + b.height/2);
// Rotate
transform.rotate(45);
// Back to the orginal coordinate system
transform.translate(-50 - b.width/2, -50 - b.height/2);
gc.setTransform(transform);
gc.drawImage(image, 50, 50);
transform.dispose();
}

Is the solution right? Is there a better solution?

My skills are very very bad when it comes to matrices and 2-D graphics so the above solution to the problem might be completely wrong and only works by chance.

Monday, October 27, 2008

News about UFacekit

There are some important news I'd like to share with all of you:

1. UFacekit Proposal


The proposal is out and we hope some of you are interested in the targets and ideas we follow with UFacekit. If you are please leave a note on the newly created newsgroup. Share your wishes, critism with us so that we can make UFacekit a success.

2. QT-Port


Just a few minutes ago I checked in a first running version of a QT-Port of the UFacekit-API. Besides providing this API we naturally provide bundles you can consume standalone (e.g. to only use a JFace-Viewer-API in QT-Jambi-Projects, ...).

So we now have:

  • Support for SWT/JFace

  • Support for Swing

  • Support for QT (Cleanlooks Style)


Platforms I'd like to see a port in future:

  • GWT - is going to be revived soon by one of the team-members

    • GXT

    • Other UI-Toolkits based upon GWT



  • Eclipse-Forms - Should be fairly easy to do

  • Android - The first test suggest it is possible though we need to see if all widget types are available. Maybe we can only provide some viewer and UI-Observables but not a full fledged UFace-API


Platforms I dream of a port in future:

  • Draw2d

  • OpenGL

Friday, October 24, 2008

There's no place where Eclipse-Databinding doesn't work

Tonight I thought I'll give Android a spin, I download the sources and worked through some samples. After an hour this got boring and because I already managed to get Eclipse-Databinding working in other Environments (GWT, Swing, QT) I thought now it is time to see if I can manage to get a minimal example working on Android.
Here's the application:



The model code looks like this (I'm using UBeans here because they are completely self contained and have no dependencies)

private static class Person extends UBean {
public static final int NAME = 1;

public String getName() {
return (String) get(NAME);
}

public void setName(String name) {
set(NAME, name);
}

@Override
public Object getValueType(int featureId) {
return String.class;
}

};

The UI-Code looks like this (fairly straight forward UI-Code):

TextView view = new TextView(this);
view.setText("Name: ");
TableLayout layout = new TableLayout(this);
layout.addView(view);

EditText text = new EditText(this);
layout.addView(text);

Button button = new Button(this);
button.setText("Say Hello");
button.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
Dialog dialog = new Dialog(Test.this);
dialog.setTitle("Hello " + p.getName() + "!");
dialog.show();
}

});
layout.addView(button);

And now the important thing how do we connect UI and Model-Attributes? Right we use Eclipse-Databinding (well not the one you get from Eclipse directly because it doesn't compile out of the box but patching it took about 30 minutes :-).

IObservableValue mObs = UBeansObservables.observeValue(realm, p, Person.NAME);
IObservableValue uiObs = AndroidObservables.observeText(realm, text);
DataBindingContext ctx = new DataBindingContext(realm);
ctx.bindValue(uiObs, mObs, null, null);

Cool isn't it? Would a Eclipse-Databinding port for Android help you? Then take a look at the newly proposed Eclipse-Project UFacekit. We already provide Viewer and UI-Observable implementations for different Platforms (SWT,Swing,QT) and plan to provide one for other platforms (GWT, Eclipse-Forms, ... you name it). Why should we not provide them for Android-Widgets too?

Sunday, October 19, 2008

Update on UFacekit

UFacekit has a new source structure


We have restructured the repository to clearly separate our modules into:

  • proper:

    This holds stable and actively maintained modules - currently Swing and SWT implementations. Checking them out and compiling works always else it's a bug and someone is to blame.

  • incubation:

    This holds newly and not yet stable modules - currently our new brand new QT support is in there. Checking them out and compiling works most of the times it's not a bug!

  • dormant:

    This holds old modules currently not actively maintained and don't even compile. Sad enough our GWT ports are currently located there. Hopefully we are good to push them forwards once more in the next months. You are a GWT guru and want to help making the GWT port as stable as possible? Come and join us.


The layout is taken from the Apache-Jakrata project.

UFacekit has an QT-Port


I started 2 or 3 weeks ago a port which uses QT-Jambi to bind against QT-Widgets. There's no ufacekit API available but Viewer implementation and observables for some widgets are already available. I hope I can finish this work as soon as possible. Might be interesting what happens when we are moving the sources to Eclipse.

UFacekit has a build story


Having a stable build story is one of the most important things for OpenSource-Projects. Kenneth did amazing work on making UFacekit managed and build with maven. The repository now doesn't hold any IDE-specific settings any more everything is done by maven.
We are not using PDE-build or any Eclipse-specific things because this would interfere with an important UFacekit-target:
"improve adoption of Eclipse Core technologies (like Eclipse-Databinding) outside RCP and SWT (e.g. Swing, GWT, QT)". Having a build story relying on Eclipse would be a bad thing.

The process e.g. for the proper-modules is like this:

svn co http://uface.googlecode.com/svn/trunk/proper/
cd proper
cd org.ufacekit
mvn clean install
mvn eclipse:eclipse

Afterwards fire up eclipse and import the modules. Done. Kenneth you are my king.

Wednesday, October 08, 2008

Disable parts SWT-Table/Tree with SWT.CHECK

This is a hack, a hack, a hack posting.

I have read many many entries on the newsgroups asking a question like this:

How can I disable certain check boxes in an SWT-Tree/Table. Is this possible?

The standard answer to this was: "Sorry no this is not possible". Today I faced the same problem (mine had to do with ViewerObservables#observeCheckElements()) where the user is not allowed to check the Top-Level-Nodes.

The tree looks like this:

+ Application 1
+ Privilege A
+ Privileg A1
+ Privilege B
+ Privileg B2
+ Application 1
+ Privileg C


The values bound are the ones in Privileg* so I have to lock the Application-checkboxes

The setup is something like this:

Databinding ctx = ....
IObservableSet mObs = ....

Tree tree = new Tree(parent,SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);
CheckBoxTreeViewer v = new CheckBoxTreeViewer(tree);
IObservableSet uiOs = ViewerObservables.observeCheckedElements(v,IPrivileges.class);
ctx.bindSet(uiObs,mObs,null,null);


I nearly gave up but then I had the following idea.


final Tree tree = new Tree(parent,SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);
// Attach a listener directly after the creation
tree.addListener(SWT.Selection,new Listener() {
public void handleEvent(Event event) {
if( event.detail == SWT.CHECK ) {
if( !(event.item.getData() instanceof IPrivileg) ) {
event.detail = SWT.NONE;
event.type = SWT.None;
event.doIt = false;
try {
tree.setRedraw(false);
TreeItem item = (TreeItem)tree.item;
item.setChecked(! item.getChecked() );
} finally {
tree.setRedraw(true);
}
}
}
}
});

CheckBoxTreeViewer v = new CheckBoxTreeViewer(tree);
// ....


This is a hack, I only tested it on Win32 (XP) and don't know how cross platform it is so don't kill me for posting this hack of hacks.

Monday, September 22, 2008

JFace-Viewers for Swing, is this possible?

You might think "Now he's gone completely crazy" but hold on and read through the next few paragrpahs to hopefully find out that I'm not.

0. The background


Do you sometimes have to code against Swing and have also been disappointed that you could not remember how to deal with Tables, Trees and TreeTables (I find myself always opening this tedious Swing-Tutorial to find how to do it)?

In last few days I worked on UFacekit's Swing implementation for Tree and TreeTable. JFace-Databinding has added support for Trees and TreeTables in 3.4 and naturally they build upon the JFace-Viewer implementation but naturally JFace-Viewers are bound to SWT and so it is impossible to use this support (or a slighlty one modified) Swing, right?

Well the above is not completely right the main JFace-Viewer-API is fairly free from SWT (besides some Widget, Item stuff) the internals are naturally not. After having noticed this I:

1. Extracted an Widget-Toolkit-Neutral API from JFace


... moved it to a new plugin (org.ufacekit.ui.viewers). I didn't only move the classes and interfaces to a new home I also added support for generics so all this casting is gone and done by the compiler for us.

A content provider now looks like this:

IContentProvider<Person,Collection<Person>> cp =
new IContentProvider<Person,Collection<Person>> {
// ...
}

and a collection can get iterated with a foreach-loop

for( Person p: v.getSelection() ) {
// ...
}

I rearranged some other classes and made interfaces from most of them, ... . So now I have a widget-toolkit-clean Viewer-API.

2. Copied some SWT-Classes (Widget, Table, TableItem, Tree, ...)


... replaced the internals through Swing-counter parts (some of the code is highly ineffecient because e.g. for a Tree we now have 3 Objects (UserObject, TreeItem, DefaultMutableTreeNode) )

3. Commented some JFace-code not needed to provide the minimum JFace-API


... providing a selection, and firing events when the selection changed but I currently e.g. don't need inline Editing so I simply commented all parts of the viewers that deal with this, including Mouse-Handling, ... . The problems from 2. & 3. are hidden from the user because all these are internal classes so I can replace them step by step.

4. Blog how nicely now I can setup a TreeTableViewer for Swing


(in fact SwingX because Swing doesn't has a TreeTable implementation by default - don't ask me why a Toolkit being around for such a long time doesn't has such a standard-control)

So now I don't have to remember how I have to create a TableTree in Swing which loads subnodes lazily because I can simple use the API I already know from JFace for SWT.

@Override
protected Component createUI(JFrame frame, List<Person> model) {
JXTreeTable tree = new JXTreeTable();

TableColumnExt c1 = new TableColumnExt(1);
c1.setHeaderValue("Givenname");
c1.setWidth(200);
tree.getColumnModel().addColumn(c1);

TableColumnExt c2 = new TableColumnExt(1);
c2.setHeaderValue("Surname");
c2.setWidth(200);
tree.getColumnModel().addColumn(c2);

JScrollPane scroll = new JScrollPane(tree);

TreeTableViewer<Person, Collection<Person>> viewer =
new TreeTableViewer<Person, Collection<Person>>(tree);
viewer.addSelectionChangedListener(
new ISelectionChangedListener<Person>() {
public void selectionChanged(SelectionChangedEvent<Person> event) {
for( Person p: event.getSelection() ) {
System.out.println(p);
}
}
});

TreeViewerColumn<Person> c = new TreeViewerColumn<Person>(viewer,c1);
c.setLabelProvider(new LabelConverter<Person>() {
@Override
public String getText(Person element) {
return element.getGivenname();
}
});
c = new TreeViewerColumn<Person>(viewer,c2);
c.setLabelProvider(new LabelConverter<Person>() {
@Override
public String getText(Person element) {
return element.getSurname();
}
});

viewer.setContentProvider(
new ITreeContentProvider<Person,Collection<Person>>() {
public Collection<Person> getChildren(Person parentElement) {
return parentElement.getChildren();
}

public Person getParent(Person element) {
return element.getParent();
}

public boolean hasChildren(Person element) {
return ((Person)element).getChildren().size() > 0;
}

public Collection<Person> getElements(Collection<Person> inputElement) {
return inputElement;
}

public void dispose() {
// TODO Auto-generated method stub
}

public void inputChanged(IViewer<Person, Collection<Person>> viewer,
Collection<Person> oldInput,
Collection<Person> newInput) {
// TODO Auto-generated method stub
}
});
viewer.setInput(model);
return scroll;
}

5. Summary


The internals are quite ugly there is a huge amount of bugs (I'm sure that not all is working smoothly already), missing functionality (e.g. Icon, Color and Font support) but I now have the foundation to add Tree and TreeTable support to the UFacekit-Library. Cleaning up and bugfixing can happen later. Like all other parts of the UFacekit-Project you can consume this swing-jface-bundle standalone because it has no dependency at all (besides the one on org.ufacekit.ui.viewers).

6. So am I now?


  • Completely Crazy

  • Fairly Crazy

  • A bit Crazy

  • Fairly normal if you know me and all the crazy ideas I already had

Tuesday, September 09, 2008

UFacekit - Proposed as a Component under Platform/Incubator

So the news is out [Mailinglist, Newsgroups]. UFacekit is proposed as a Component under Platform/Incubator project (proposal). I think this is the right move for UFacekit to gather momentum towards our first release. If you want to support this move:
  1. Comment on the following newsgroup post from Boris

  2. Add yourself/company as an interested party on the proposal page
I'm currently working on the JavaDoc and for SWT/JFace a build should be available right after we moved the sources to foundations repositories, swiched namespaces, ... .

Wednesday, September 03, 2008

Exploring new technologies part of Ganymede-Release Train

I took myself some time the last days exploring new technologies available with Ganymede 3.4:

  • Eclipse-Databinding and its new features

  • EMF-Databinding (Provisional but working very smoothly)

  • Teneo: Persist your model via hibernate in a SQL-Database

  • CDO: Share your model between different clients and persist it into an SQL-Database (with Revision support)

  • New Extension Points to enhance the Expression Framework

  • Spring & OSGi

  • P2 to install the Products using the P2-Agent

I did this to understand those technologies better because we at my company have to decide which technologies our next generation of products is built on (The current ones are based on selfwritten libs because at that time there was no Eclipse-Databinding, Teneo and CDO or we didn't knew about it).

As always when learning new technologies I created an example application but before I started I defined some goals I think are curcial to all Enterprise Datacentric Desktop Applications:

  • Nice L&F (as good as I can make an UI Look without a designer)

  • Plugable storage technology

  • Undo/Redo Support

Then I started hacking, creating an Ecore-Model, some plugins, extension points, browsing documentation and noticed that there are no examples around for most of the things I wanted use:

  • How to create an EditingDomain myself when not using the generated editor-classes from EMF?

  • How to use the new org.eclipse.ui.services-Extension point to enhance the expression framework?

  • Best strategy to use Extension Points when bundles are installed/uninstalled/updated while the application is running


All those things are not hard if you know how to do it but if you don't it's quite tricky to solve these problems. It even gets harder if the technologies you plan to use are quite new and/or are not used together and because of this bugs arise.

So the immediate output of my work was that 2 bugs [239015, 245183] in Eclipse-Databinding got fixed in 3.4.1.

The longterm output for me is:

  • I now have a good picture how our next technology stack looks like

  • I have an example application (I will add other things in the next weeks) to teach my co-workers the technologies

  • I had a lot of fun (besides struggeling with P2)

The longterm output for you is:

  • You have a small application showing you a lot of different concepts around RCP+EMF+Databinding applications

    • EMF-Ecore

    • Usage/Creation of your own Extension Points

    • Using EditingDomain outside the scope of EMF-Generated artefacts

    • Using Teneo

    • Using CDO

  • I started summerizing all the ideas, technologies and concepts combined in this example in a document, I'm working on from time to time. So maybe some time you'll get a "book" explaining you everything

  • Some nice reusable classes e.g. one to use EMF/Databinding-LabelProviders with cool features, a new drop down widget showing a Tree in the popup, ...


This is the application:


If you want to run it locally get a copy of the P2-Agent and point the metadata repository and artifacts repository to this location.

To use the CDO-Version you also need a server component which can be installed when pointing the agent to this location. After having installed the CDO-Server you also have to create a CDO-Configuration (cdo-server.xml) in the installations "configuration" directory which you can fetch from here.

The repository name in the above config "CDO-1" has to be the id of the CDO-Configuration you create in your application.

Finally if you are interested only in the sources then install a subversion plugin in your eclipse and use one of te Team-ProjectSet files from here to check out the necessary projects.

If you want to learn more about these cool technologies. I've proposed beside a talk about E4 - The new platform-ui concepts a talk about this example application on ESE.

Sunday, August 24, 2008

Writing a CTreeCombo-Widget

I was working on my example RCP/EMF/Databinding application


I'm going to use to present various parts of those technologies to my co-workers and getting familiar with new technologies like CDO, Teneo, Spring and others when I hit the problem that standard CCombo didn't suited my needs.

What I wanted to have was a CCombo which presents a Tree like structure like this


for my Login-Screen and as you all know there's no such widget available currently. As you might guess from the above Screenshot I somehow managed to get such a widget.

Before we dive into it another requirement I had was that the implementation plugs itself into the existing viewer and databinding concepts of Eclipse.

So what did I do and how did it work? Well 95% of the work I had to do is C&P. I copied the CCombo-Code replaced List against Tree and solved compilation errors. To make a CTreeCombo widget I would have been done almost if this would have been the only requirement.

The real problem is that widgets are reparentable and that this can happen across Shells which makes it necessary to recreate the Tree and its popup shell from time to time so directly attaching a TreeViewer on the underlying Tree-Widget is not possible. So the only possibility was to create Proxy objects around TreeItem/TreeColumn who proxy the real implemementation so that they could be recreated whenever needed.

So if one wants to use the widget he/she has to write code like this:

int style = SWT.BORDER|SWT.READ_ONLY|SWT.FULL_SELECTION;
CTreeCombo combo = new CTreeCombo(shell,style);

CTreeComboItem item = new CTreeComboItem(combo,SWT.NONE);
item.setText("Parent 1");

CTreeComboItem childItem = new CTreeComboItem(item,SWT.NONE);
childItem.setText("Child 1.1");

childItem = new CTreeComboItem(item,SWT.NONE);
childItem.setText("Child 1.2");

item = new CTreeComboItem(combo,SWT.NONE);
item.setText("Parent 2");

childItem = new CTreeComboItem(item,SWT.NONE);
childItem.setText("Child 2.1");

childItem = new CTreeComboItem(item,SWT.NONE);
childItem.setText("Child 2.2");

CTreeCombo now works like an ordinary SWT-Tree providing the same API as SWT-Tree (at least currently the one which is necessary to write a JFace-Viewer) so that I could subclass AbstractTreeViewer and providing an implementation for it. So if one uses JFace-Viewers in his/her code they simply need to write:

int style = SWT.READ_ONLY|SWT.BORDER|SWT.FULL_SELECTION
CTreeCombo combo = new CTreeCombo(parent,style);

CTreeComboViewer viewer = new CTreeComboViewer(combo);
viewer.setLabelProvider(new LabelProviderImpl());
viewer.setContentProvider(new ContentProviderImpl());
viewer.setInput(input);

In the end it took me longer than I first thought but after 4 hours I had a working CTreeComboViewer (although it is not thoroughly tested yet) which behaves appropiately (at least in the way I currently use it).

If you are interested in the code of the widget or in the application to learn about:

  • Writing a modular RCP-Application

  • Using SWT, JFace and Databinding

  • Using EMF and EMF-Databinding

  • Using and creating your own Extension Points

  • Using and extending the Commands, Handlers and the Expression Framework


You can fetch the code from my companies svn-repository but the application is still in flux. If you are only interested in the widget and viewer code you can find it here for the widget and here for the viewer.

Friday, June 13, 2008

Ganymede - What's in JFace and Databinding

The History


JFace-Viewers/ToolTips


In 3.3 the whole Viewer-Infrastructur has been reworked to make it easier to add new features in upcoming releases. Some new features where part of 3.3 (e.g. LabelProvider/Column, CellNavigation, Customizable-Editor). Additionally JFace opened up its viewers for subclassers by wrapping Widget-Specific API (ViewerRow/ViewerCell).

Databinding


3.3 saw the first public release of the Eclipse-Databinding-Framework which removes the need for myiards of listeners to keep your model and UI in sync. Anbody who ever had write a Master-Detail-UI knows how hard it is to get it right.

Today


JFace-Viewers


We saw great adoption of our new API and new features added ontop of it. The most significat one is a LabelProvider which understands StyledText-Instructions named StyledCellLabelProvider. You'll see this LabelProvider in action if you open the Java-ProjectExplorer.

On the other hand we also saw great adoption of our API-Opening-Up effort which allows widget vendors to provide a JFace-Viewer-API for their structured widgets. There are 2 Nebula-Components (Nebula-Gallery and Nebula-Grid) who already adopted the concept and provide a viewer.

Thanks for the great feedback and bug reports from the community we fixed some [92] problems and feature request some of them dating back to 2003!

In comparison to Europa-Release we didn't introduced much new API. From my point of the main focus was to evolve the new API we provided in 3.3 and fix problems which have been introduced. If you saw how much code has been rewritten in 3.3 I think this was thr right thing (although we fairly broke no backward code anyways in 3.3).

Databinding


Thanks to the community and Ed Merks and his team there's now a 2nd possibility to back up your UI with a model beside JavaBeans.

Naturally they provide integration for their EMF-Objects with 2 brand new plugins named org.eclipse.emf.databinding and org.eclipse.emf.databinding.edit. Those plugins are marked as provisional but I'm using them since day 1 in my projects and for the standard cases they just work fine and whenever a bug occurs it's fixed immediately. Give it a try and see how fast you can develop powerful SWT-UIs.

At the very moment you bring EMF into your project it opens up the door for fairly everything you and your customers ever dreamed of (take a look at the teneo to presist your model in a SQL-Database using hibernate, working with distributed objects using CDO, validating your model using OCL and much more).

On UI-Side of Databinding also many new features have been added. You have support for Inline-Editing in Table/TreeViewers (every control inheriting from it e.g. GridViewer), there's new support for Observable-TreeViewers and naturally many many bugfixes [75].

The future


JFace-Viewers/ToolTips


Naturally we are going to fix bugs and problems. I have already some bugs in my queue I can address after the Ganymede-Release is out of the doors. Looking at this back log of viewer bugs [228] I'm going to try to bring this bug count down a bit (say 200 is a good number).

Databinding


I see a bright future for databinding and I'll restart my work on bringing all this (databinding+emf) to the web using it in my GWT-Enabled applications inside my UFace-project if time permits.

Summary


I think all people worked on the projects above have done an amazing job. We fixed many bugs added many great new features, many with the help from the community whether they filed sensetational bug reports or even provided patches. A big thank goes out to you, the community.

One more note in the end. In time of 3.4 we saw the creation of a new project called E4. It was discussed controversial in the blog space and on mailling list as you all known.

After EclipseCon I decided as a community member to take part in this effort for the next generation of an UI-Framework provided by the Eclipse Organisation and had a lot of fun until then. If you are interested in learning new things and exploring new areas in space of ui, resource-managment, model-driven development I can only advice you to take part and learn how to organize, design and implement one of the tools that will have infulence on the next generation of thousands of commercial and none-commercial products.

Thursday, June 05, 2008

E4 is more about bringing it to the web

Since the E4-Presentation at EclipseCon and the SWT-Talk most people think that E4 is only about bringing Eclipse to the web. THAT'S NOT TRUE.

E4 is much more and that SWT gets a web-port is only a small part. Here's my top list of things for E4:

  • Modeldriven:
    One extensible model backing up the whole workbench

  • DOM: At the moment the Workbench is backed up by ONE model you automatically have a DOM and you can do with this DOM the same you do in Web-Applications (See my prototype)

  • New Resource Framework:
    Making handling resources much more Flexible

  • New Listener Concept:
    The current listener concept in eclipse sucks and makes eclipse slower than it could be

  • NO SINGLETONS AND STATIC FIELDS

  • Plugins in NONE-Java: Make it possible to write an Eclipse-Plugin in other languages (JavaScript, ...)

  • Declarative UI, Easier Styling .... and much more

Tuesday, May 20, 2008

A radical approach to explore new paths for e4

After EclipseCon 2008 and the E4 noise I started to rewrite the prototype shown there to use an EMF-Model (I'm going to refer to this prototype in the rest of this posting as PROTOTYPE_1).

It was quite cool to get insights into the platform code and with the code already created for EclipseCon it was not really an achievement to get something running within a fairly short time but finally I wasn't really happy because of multiple things:

  • I had to work around problems from the beginning to get a workbench up and running

  • It was hard to add new features because I was limited to things I could find a work-around for or going to learn the complete platform code which would have driven me mad

  • There was lack of feedback on the real code and we talked more about EMF pros and cons than concentrating on how we want to solve things (I'm still an EMF believer :-)


I asked myself how to solve the following problems:

  • How can I get up an Workbench-Window without any of the legacy code

  • How can I easily add features

  • How can I encourage people to work on E4 without having a deep understanding what's going on inside the current platform. In fact how can I get people outside the Platform-UI-Team to look at the code and understand in an affordable amount of time the concepts behind the workbench and bring up interesting ideas or outline how they think a feature can be implemented
Approximately 1 month ago I sat down and started to define a project which had the following targets:

  • A workbench with dependency on org.eclipse.jface, org.eclipse.equinox.common, org.eclipse.osgi, org.eclipse.emf

  • Built around an extensible EMF-Model

  • NO plugin.xml and NO .exsd (you'll see later how I extend the platform - it's a radical approach I know and looking back it got even more radical then I first thought it's going to be)

  • Similar but slightly improved EMF-Model compared the original one used to straight port the EclipseCon-Example

  • Allow multiple instances of the workbench inside one OSGi-Env - no singletons, no static variables!

  • As few API-Methods as possible (=suppress all the EMF-Methods and adding API-Methods e.g. to attach listeners or traverse the DOM generically) but still strongly typed

  • provide support for Scripting

Step 1: Redesign The Model From PROTOTYPE_1


I started to redesign the original model and removed some things I didn't like or found they are not needed yet. For example styles/styleclasses now work like they do in a Browser:
.myActiveView {
color: #FF0000;
background-color: #0000FF;
}

<span class="myActiveView" >Green on Blue</span>
where the style-properties and the class-properties are merged. I also moved all UI-Data (Font,Color,Gradient,...) from the UI-Element to the "css"-style definition whether an UI-Element reacts on a style property is the choice of the UI-Element and its implementor.

Step 2: Implementing the Workbench-UI-Core From Scratch

With the .ecore-Definition from Step 1 I created a static workbench.xmi file which defines a model of a static workbench.(Yes I started from a static model you'll see how dynamic such a model gets later). The final source code is ~ 88KB and the resulting .jar 36KB (the model, emf-dependencies are not part of this figures of course). But I think the target is reached I think there's no class having more than 500 Lines of Code (including the comments).
Creating .xmi-Files is a fairly trivial task because EMF comes with a generic editor and I guess people who know GMF could have written a graphical one with in a minute (any GMF-volunteers around?). When this step was finished my XMI-File looked like this

Step 3: Making the model dynamic


When starting Step 3 I first headed of and created .exsd-Files (you can see them here) to contribute the information to my model (views/perspectives). But while doing this I recognized that I'm redefining my .ecore-Model-Elements using .exsd so why the hell do I not provide plugin.xmi-artefacts instead of those plugin.xml files and at runtime create a complete workbench.xmi from all those artefacts. The hard part was to reimplement the loading of xmi-File (or rather to identify the source-code where the plugin.xml is processed to copy the logic). This left me with 3 files
  • workbench.xmi in org.eclipse.e4.workbench.ui

  • plugin.xmi in org.eclipse.e4.workbench.ui.ide contributing to workbench.xmi

  • plugin.xmi in org.eclipse.e4.workbench.ui.rhino contributing to plugin.xmi from org.eclipse.e4.workbench.ui.ide

Step 4: Implementing a Scritable-DOM


So now I had a workbench-model constructed at runtime using XMI-Artefacts. Doing some cool UI-Stuff was the next on my list. Wraping up an EObject as an Object-Scritable for Rhino was something I had already written for PROTOTYPE_1 so I "stole" the code from myself. The top feature on my list was to move a View (in 3.3 a ViewPart) in the model and automatically update the UI. So I wrote a view which presented the current workbench model inside a TreeViewer and allowed me to drag a view from stack to stack. It wasn't really is to distinguish a move from a remove but with help from Ed I managed to get it working. See the screen cast at the end of this posting.

Step 5: Persisting the current workbench state


So I was able to drag around the views but everytime I shut down the workbench and restarted model was recreated from the artifacts and started in the initial state. So adding persistance was next the next "big" issue. Well there's nothing more to say than these lines of code:

if (!restore) {
uri = URI.createPlatformPluginURI(
"/org.eclipse.e4.workbench.ui/META-INF/EWorkbench.xmi",true);
} else {
uri = URI.createFileURI(restoreFile);
}

// Save
try {
((EObject)workbench).eResource().save(null);
} catch (IOException e) {
e.printStackTrace();
}

Step 6: Extending the extension


Haven't you ever dreamed of extending an extension. I decided that my WorkbenchStructureViewPart should restore the current selection when coming up from a restored state but my generic model-element I contribute didn't had a slot to restore the information. So I digged into and searched how EMF allows me to extend an existing element (in fact once more Ed pointed me in the right direction). Now the plugin.xmi contributed by org.eclipse.e4.workbench.ui.rhino looks like this.

Step 7: Multiple Instances of the workbench


Not using org.eclipse.ui, no singletons and static variables automatically allows to have multiple workbench instances running. So in theory making this workbench run on top of the RAP framework should be possible without patching any code parts.

Acknowledgement / A Screencast / How to get it run


Before I forget about it two other guys (Boris and Ed) provided ideas, code and input to those freaking lines of code available from Eclipse-CVS using this ProjectSet.

Finally I created a Screencast for you to look at (it's a bit big (15MB) because I have no idea how to do Screencasting with OSS-Software on OS-X).



You'll see that I radically stripped down everything and made some strange decisions (e.g. no plugin.xml), backwards compatibility is not addressed at all, ... . Whether you like the idea of contributing XMI-Artefacts instead of .exsd & plugin.xml is not the question. The interesting thing IMHO is that it takes so few lines of code to show a nice workbench backed up by a model and reacting on (structural-)changes inside of it.

Thursday, March 20, 2008

Eclipse E4 and UFacekit

E4 and my impression

Haveing attended the E4 Talk, A Future of SWT and the E4 BOF. I'm looking forward for a lot of innovation and discussion about new architectures at various levels of the Eclipse-Platform.

The most important thing to notice is that E4 is much more than simply bringing RCP to the webspace. Still I'm going to concentrate on the UI-Aspect of E4 in the rest of the post.

There's never been a better time to start getting involved because I myself (or you yourself) can to some extend define how the future looks like.

From the discussion I had with all the guys from the Platform/SWT/...-team I feel fairly comfortable infact I'm glad the Platform/SWT-Team recognized that RAP is not the only solution to get RCP-Applications run inside the browsers. The current SWT-prototype code uses established technologies like GWT, Dojo. In fact with the current prototype design SWT is going to be for DOJO what GWT-Ext/MyGWT are for Ext-Js nowadays.

UFacekit and E4

Do we still have to put effort into UFacekit?

When I first saw what's been done by the E4-Prototypers my first reaction was: Do we still need to work UFacekit? My answer is definately YES because UFacekite is more than providing a possibility to run your Desktop-UI inside a Browser. UFacekit has more to offer than a uniform Widget-API. UFacekit provides other values:

  • Eclipse-Core-Databinding compatible to GWT

  • Eclipse-EMF-Ecore compatible to GWT

  • Highlevel-Abstraction for Eclipse-Databinding

  • Easy support for Decoration, ...

  • ... and much more

If SWT for Browser is getting reality (and it will trust me) people will want to use all this stuff in their application and then UFace provides them with all they need.

How can UFacekit profit


Well we get a first class Browser-Widget implementation for free or even better we can take part to make this happen (I'm willing get part of this effort) and use it in UFacekit.

UFacekit News

  • I added an Example how to use EMF + UFacekit inside GWT.
    You can take a look at the code here.

  • Angelo started to add CSS-Support for SWT-Widget in his own project and offered to donate it to UFacekit but I didn't had time to take look how to use it in UFacekit until now

  • Work on GWT-Ext port continues but getting the layout stuff right is a real pain

Thursday, March 06, 2008

UFace - Update

I recognized today that I haven't blogged about one of my favorite OSS-project (UFace/UFacekit) lately.

For those of you who have never heard of this project let me introduce it in a few sentences.

UFace or UFacekit has the following targets:

  • Add a highlevel API above Eclipse-Databinding

  • Helping Eclipse-Databinding to gain momentum outside Eclipse/SWT/JFace world by providing Observable-Implementation for various UI-Toolkits like Swing, GWT, ...

  • Helping OSGi to be used in UI-Applications outside Eclipse-RCP e.g. in Swing Applications

  • Providing a uniform UI-API for all those widget-systems including builders for common form layouts (e.g. 2 column label/field list)


We have been fairly busy lately and added the following things into UFace:

  • Validation and Decoration Support (contributed by Kenneth Westelinck) for Swing and SWT

  • Worked heavily on the MyGWT integration

  • Maven-Build-System


Validation and Decoration


Adding decorations to a UIForms (our abstraction above the databindingContext providing a uniform API for different Databinding-Implementations JavaBean/EMF/UBean/...) is not more than adding these 2 lines to your sources:

StatusDecoratingInterceptor interceptor = 
new StatusDecoratingInterceptor(detailComposite);
detailForm_1.setAfterBindInterceptor(interceptor);


Darn cool, isn't it?

The resulting UI with validation error looks like this:

SWT on Win32:



Swing on Win32:


UFacekit implementation for MyGWT



Beside providing a higherlevel API above Eclipse-Databinding the other idea of UFace is to provide a uniform API to deploy your applications in different ways (Desktop, Web, Mobile-Devices, ...). In Web-Space we decided to go the GWT way which means your application is running completely in the browser and only business data is fetched from the server.

This concept is different from the one of RAP who, as far as I have understood the framework, does most of the work on the server-side and uses the browser "only" for rendering purposes (RAP devs please correct if I'm wrong here).

The hardest thing to bring to browsers are SWT-Layouts and that's where I'm currently progressing slowly but steadily at the moment. This is how the the same form looks like in the browser rendered with MyGWT:



It's not 100% right and Combo and List aren't working either but it was quite an achievement to get that far.

Current status / Release plans


My first draft plan was to have an M1-Milestone for JFace, Swing and MyGWT implementation ready for EclipseCon but I had to delay this because my current work load hasn't give me enough time to work on UFacekit too many hours. Today JFace and Swing are complete (as complete a first Milestone can be) and only MyGWT is missing so I hope we could have a first Milestone by April.

What's in the queue


We already have a queue for features we'd like to integrate (an incomplete list is this):

  • Support for more Widgets Tree/TreeTable, TabFolders, ...

  • Implementation ontop of Eclipse-Forms

  • Better looking decorations on Swing

  • Support for CSS to style your widgets

  • Extensible converts

Wednesday, January 23, 2008

EMF + Databinding - I'm adicted to this stuff

Ed blogged somedays ago about the progress he made makeing EMF available to RAP and J2ME and there are more and more people requesting a simple example project where some EMF-Databinding-Features are shown.

I've already send some code to the EMF-newsgroup and today I've added some more bits showing how to bind a Detail-List.



I'm going to add some more interesting stuff (e.g. field-dependencies, validation, ...) when I have time and will restart working on my article on EMF+Databinding+RCP+iBatis.

If you want to take a look at source code you can grab it from here.

There are some issues you need to be aware of when it comes to
e.g. Master-Detail + Field-Dependencies.

This is where UFace comes into play which handles this kind of thing for you (and even more).

Because I'm talking about UFace. We are making progress since the last blog entry the following things have happend:

  • refactored Factory-API to get extensible and not cluttered with overloaded methods

  • started to think how UForm can be used by native implementators (UForm is an abstraction level above Databinding and your Model-Implementation-Technology)

  • we added a new committer just today (Angelo Zerr) who develops some cool XML-UI things (See Akrogen) and is enhancing our Swing-Binding and SWT-Bindings. Welcome Angelo.

  • Set up a Committer and Contributor policy. I hate this legal stuff and we want to keep it at minimum but this has to be the foundation of every project

  • Received a code donation (SWT GridLayout for Swing) from Daniel Spiewak (See Daniels Code contribution)

Thursday, January 10, 2008

One month of UFacekit-Development

A month ago James Strachan and I started hacking on a project we named UFacekit.

We both faced the need to write datacentric applications for different deployment environments (Desktop (Swing/SWT), GWT (MyGWT/GWT-Ext), ...) and we thought there must be an easy and fast way to come up with something that makes our day job easier. At this very moment UFacekit was born.

There are different things we are targeting with the project.

  1. Provide a uniform Facade above widget implementations (SWT,Swing,GWT,...)

  2. Promote the use of Eclipse-Databinding (and other related technologies e.g. EMF) outside Eclipse-World (Swing,GWT, ...) and provide a highlevel API above the low-level databinding API

  3. Provide reuseable Bundles which can be used independently
    • you are only interested in Swing-Databinding but still want to use the native Swing-API? - UFacekit provides an indepented Swing-Observable bundle for you
    • you want to use an alternative Bean-like implementation not relying on reflection and EMF is too heavy for you? - UFacekit provides an independent implementation for you named UBean



Instead of writing an SWT-Port for GWT/Swing (I know for Swing there's already an SWT port) we decided to go the Facade/Factory way and started hacking and the progress we made in this very short period of time (we are only working on it in the evening) is more than amazing.

Take a look at the following Screenshots they show what's already possible with the current sources.





They look fairly identical (the only reason they not look completely the same is that I haven't ported the GridLayout from SWT to Swing but relying on Mig-Layout).

They are full of features you need many lines code without a framework doing the nifity bits for you (e.g. MasterDetail + Field-Dependencies):

  • Master-Detail support

  • Model-UI-Binding

  • Field-Dependencies (Country/Federalstate)



Setting up this UI needs:

  • ~ 80 Lines of Widget-Toolkit-Independent code

  • ~ 20 Lines of Widget-Dependent code (= the start of the application which is currently not abstracted)



The amazing thing is that both UIs are made up by the same source code:


public void createFormUI(UIComposite root) {
UIFactory ui = root.getFactory();

UBeanForm listForm = new UBeanForm();
final UBeanForm detailForm_1 = new UBeanForm();

UIComposite containerComposite = ui.newComposite(root, null, ui.newGridLayout(2));

TableColumn[] columns = {
new TableColumn("People", new NameLabelProvider())
};

UITable table = ui.newTable(listForm, containerComposite, new GridLayoutData(200, GridLayoutData.DEFAULT, GridLayoutData.ALIGN_BEGINNING, GridLayoutData.ALIGN_FILL, false, true), listForm.detailList(AddressBook.PEOPLE, Collection.class), columns);

// ---------------------

UIComposite detailComposite = ui.newComposite(containerComposite, new GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, true, true), ui.newGridLayout(2));
ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "ID");
ui.newTextField(detailForm_1, detailComposite, new GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, true, false), detailForm_1.detailValue(Person.ID, int.class));

ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "Name");
ui.newTextField(detailForm_1, detailComposite, new GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, true, false), detailForm_1.detailValue(Person.NAME, String.class));

ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "Location");
ui.newTextArea(detailForm_1, detailComposite, new GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, true, false), detailForm_1.detailValue(Person.LOCATION, String.class));

ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "Country");
UICombo combo = ui.newCombo(detailForm_1, detailComposite, new GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, true, false), detailForm_1.detailValue(Person.COUNTRY, Country.class), ModelHelper.createWritableList(getModel().getCountries(), Country.class), new CountryLabelProvider());

ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_BEGINNING), "Federalstate");
ui.newDependentListBox(detailForm_1, detailComposite, new GridLayoutData(GridLayoutData.DEFAULT,120,GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, true, false), detailForm_1.detailValue(Person.FEDERAL_STATE, FederalState.class), (IObservableList) detailForm_1.detailList(Country.FEDERAL_STATES, Collection.class).createObservable(combo.getSelectionObservable()), new FederalStateLabelProvider());

WritableValue value = ModelHelper.createWritableValue(getModel());
listForm.bind(value);

IObservableValue detailObservable = table.getSelectionObservable();
detailForm_1.bind(detailObservable);

UBeanForm detailForm_2 = new UBeanForm();

columns = new TableColumn[] {
new TableColumn("ID", new IDLabelProvider()),
new TableColumn("Name", new NameLabelProvider()),
new TableColumn("Location", new LocationLabelProvider())
};

ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "");
ui.newTable(detailForm_2, detailComposite, new GridLayoutData(GridLayoutData.ALIGN_FILL,GridLayoutData.ALIGN_FILL,true,true), detailForm_2.detailList(Person.FRIENDS, Collection.class), columns);
detailForm_2.bind(detailObservable);
}


  public void run(final String uiMethod) {
Display display = new Display();

Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
public void run() {
Shell shell = createUI(uiMethod);
shell.setSize(650, 500);
shell.setText("UFacekit - JFace-Demo ");
Display display = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
});
}

private Shell createUI(String uiMethod) {
final Shell shell = new Shell();
SWTComposite composite = new SWTComposite(shell,new JFaceFactory().newFillLayout());
// generic code as shown above


You can even more reduce the size and complexity of the source by using FormBuilder-classes we are going to provide to make creating standard-forms like this as simple as possible.

Before we are publishing a first cut we need to finish the GWT-implementation (GWT/MyGWT/GWT-Ext) but we (in this case James) are on a good way and we should have a release fairly soon. Naturally there are some gaps (e.g. missing widgets, API inconsistencies) but hey the project just got 1 month so I hope you don't mind.

Did this spot your interest? Come and join our google group and share your ideas with us.

Saturday, January 05, 2008

EclipseCon: I'll be there

News 1:

Just booked my flight and my room at the Hyatt. I'm excited to meet you all.

There are so many interesting talks like Steve's talk about the future of SWT which I'm very interested in because recently the Web-2.0 movement hit me hard and I've started to make Eclipse-Core-Technologies available in Web-Env.

News 2:

The other news I'd like to share with we you is that together with James Strachan I started a fairly interesting "experiment" called UFaceKit.

In short the project aims to provide a facade above widget implementations to use a uniform API above various Java-Widget implementations to create Datacentric-Applications.

Beside providing this generic API the project is split into many individual plugins/bundles which can be used out of the uface-scope:

  • A light weight JavaBean like implementation useable without any reflection-API the implementation is called UBean

  • Observables for UBean like Eclipse provides an implementation for JavaBeans

  • UI-Observables for GWT/MyGWT/GWT-EXT

  • UI-Observables for Swing



As you see one of the "waste products" of this project is that Eclipse-Databinding is can be used by Swing/GWT/... developers.

If you are interested in the project take a look at our project page and join the google-group. We are in pre-alpha stage and code changes a lot but we appreciate your help e.g. to provide an implementation for other Java-UI toolkits (QT-Jambi, Android, ...), help us with the Swing, GWT implementations of course all code is released under EPL.

Primary targets currently are:

  • SWT/JFace

  • GWT-implementations