Das Eclipse 4.x Rendering Konzept – Vortrag in München

Am 12.03.2012 hält Kai Tödter einen Vortrag bei der Münchner JUG zum Thema “Das Eclipse 4.x Rendering Konzept”. Die neue Eclipse 4.x Application Platform  bringt eine ganze Reihe von neuen Features mit. Ein Ziel von Eclipse 4.x war es, die Entwicklung von Plug-ins und Rich Clients einfacher zu machen. Unter anderem gibt es CSS-Unterstützung, Theme-switching und eben die Unterstützng von unterschiedlichen Rendering-Engines (z.B. JavaFX 2.0 und Swing)

Wer bislang noch nicht bei der JUGM zu Gast war, findet hier nähere Informationen:

Event-Ankündigung auf XING

Homepage der JUGM

Wer noch tiefer in das Thema einsteigen möchte: Kai’s Eclipse 4.x Training findet bald in München statt:

Rich-Client-Entwicklung mit der Eclipse 4.x Application Platform

 

 

Treffen Sie Kai Tödter auf der JAX 2012 in Mainz

Die JAX ist die führende Konferenz für pragmatisches Know-how im Java- und Enterprise-Umfeld. Hier kommen die besten Experten aus dem deutschsprachigen Raum zusammen, um ihr Wissen an die Teilnehmer weiter zu geben. International bekannte Speaker geben dazu Trendausblicke sowie Ratschläge beim Einsatz etablierter Technologien.

Dieses Jahr findet die JAX in Mainz, Rheingoldhalle Mainz statt.

Treffen Sie Kai Tödter auf der JAX 2012 in seiner Session Dynamische RIAs mit Equinox und Vaadin

am 18.04.2012

16:15 bis 17:15 Uhr

UND

bei seinem Power Workshop Rich-Client-Entwicklung mit Eclipse RCP 4.x

am 20.04.2012

9:00 bis 17:00 Uhr

Wir freuen uns auf Ihren Besuch!

Kai Tödter auf der OOP 2012

Bereits seit 1992 veranstaltet SIGS DATACOM einmal jährlich die Konferenzmesse OOP im ICM, International Congress Center München. Zahlreiche internationale Experten halten hier Vorträge zu aktuellen und praxisnahen Softwarethemen. Seit 20 Jahren ist die OOP eine der größten und renommiertesten Weiterbildungsveranstaltungen für innovative Themen rund um die Softwareentwicklung in Europa.

Auf der diesjährigen OOP 2012 gibt es am 23.Januar einen Vortrag von Kai zum Thema “Google Web Toolkit: Ausgewählte coole Features“. Viel Spass dabei!

Eclipse 4.x talk for JUG Ostfalen

If you are interested in the Eclipse 4.x Application Platform and happen to live close to Braunschweig (Germany), join my talk for the JUG-Ostfalen:

Was ist neu bei der Eclipse Rich Client Platform 4.x?

When: Friday, January 20th, 7:00 pm
Where: CKC Braunschweig, Am Alten Bahnhof 13, 38122 Braunschweig
Language: German

After my session there is another talk: “Agile Review” (Eclipse Plugin) by
Malte Brunnlieb, Philipp Diebold, Thilo Rauch und Peter Reuter.

The event is free: Registration and info is here: http://eclipse4.eventbrite.com/

Would be great to see you there!

Kai

You find me on Twitter and Google+.
Next Eclipse RCP 3.x/4.x trainings in Munich

flattr this!

GWT Contacts Demo with MVP and Testing

On Monday, January 23th, I am going to talk about some cool features of the Google Web Toolkit (GWT) at the OOP 2012 conference in Munich. To have a live demo for discussion, I implemented a GWT port of my Eclipse 4 Contacts Demo. In this blog post, I talk a bit about my experience with Google’s MVP (Model View Presenter) approach, including activities, places and event bus. Furthermore about UIBinder in combination with GWT Designer and Presenter testing using Mockito.

You can find the latest source of the demo at https://github.com/toedter/gwt-mvp-contacts. Here is a screen shot, as you see, I did not focus on nice design. Click on the image to see it in original size.

Model View Presenter (MVP)

The Model View Presenter Pattern has different flavors: “Passive View” and “Supervising controller“. In Passive View there is no dependency between model and view, Supervising Controller is not so strict and allows e.g. data binding from model to view. In GWT, presenters are represented by Activities, views are implemented by GWT UI classes. There are 2 common ways to define the binding between views and presenters: Either the presenter defines a display interface that the view has to implement, or the view interface provides a presenter interface. The latter one is often used in GWT when the UI is created with UIBinder, because it makes it easier for the view to call back to his presenter. In the contacts demo, the view interface for the list view looks like

public interface IContactListView extends IsWidget, AcceptsOneWidget {
  public interface Presenter {
    void goTo(Place place);
    void select(int index);
    void select(Contact contact);
  }

  void setPresenter(Presenter presenter);
  void selectInitialContact(Contact contact);
  void initialize(List contacts);
}

As you see, for laziness reasons I don’t use “Passive View” since I pass a domain object (Contact) to the view. A good introduction into GWT MVP you find at the GWT Web site. If you have a more application-like layout with kind of toolbar and several display regions, you might think you will need nested presenters/activities, but you don’t have to nest them. Thomas Broyer wrote a nice article about this issue, and I used his approach in my demo.

UIBinder and GWT Designer

UIBinder splits a UI component into a Java part and an XML/CSS part. That makes it easier to separate concerns and helps designers and developers working together. GWT Designer is a nice and free GWT UI Editor for Eclipse. One feature is the automatic creation of MPV related infrastructure, like corresponding activities and places. In the demo I have several implementations of the list view and the details view. You can change them by altering the ClientFactory implementation. The screen shot below shows a small details view example in GWT Designer, klick on it to see the image in original size.

Presenter Testing with mockito

One advantage of MVP based approaches is the good testability. For that purpose I wrote a few exemplary tests using mockito as Mocking framework. The reason for using plain JUnit tests together with mocks is mostly speed. With mockito it is pretty easy to mock all the involved GWT MVP infrastructure like activities, places, event bus and even a GWT Remote Procedure Call. Here is an example for a presenter test:

@RunWith(MockitoJUnitRunner.class)
public class ContactListActivityTest {

	@Mock
	private IClientFactory clientFactoryMock;

	@Mock
	private PlaceController placeControllerMock;

	@Mock
	private IContactListView contactListViewMock;

	@Mock
	private AcceptsOneWidget acceptsOneWidgetMock;

	@Mock
	private IContactServiceAsync contactServiceAsyncMock;

	@Mock
	private EventBus eventBusMock;

	private List contacts;
	private Contact contact1;
	private Contact contact2;

	@SuppressWarnings("unchecked")
	@Before
	public void setUp() throws Exception {
		when(clientFactoryMock.getPlaceController()).thenReturn(placeControllerMock);
		when(clientFactoryMock.getContactListView()).thenReturn(contactListViewMock);
		when(clientFactoryMock.getContactService()).thenReturn(contactServiceAsyncMock);

		// Mock a GWT RPC
		Answer answer = new Answer() {
			@Override
			public Void answer(InvocationOnMock invocation) {
				Object[] args = invocation.getArguments();
				AsyncCallback> asyncCallback = (AsyncCallback>) args[0];
				contact1 = new Contact();
				contact1.setFirstName("Kai");
				contact1.setLastName("Toedter");
				contact1.setEmail("kai@toedter.com");
				contact2 = new Contact();
				contact2.setFirstName("Kai2");
				contact2.setLastName("Toedter2");
				contact2.setEmail("kai2@toedter.com");
				final List contacts2 = new ArrayList();
				contacts2.add(contact1);
				contacts2.add(contact2);
				asyncCallback.onSuccess(contacts2);
				return null;
			}
		};

		doAnswer(answer).when(contactServiceAsyncMock).
                getAllContacts(any(AsyncCallback.class));

		// set the real contacts object, when clientFactory.setContacts is
		// called
		Answer setContactsAnswer = new Answer() {
			@Override
			public Void answer(InvocationOnMock invocation) throws Throwable {
				contacts = (List) invocation.getArguments()[0];
				// System.out.println("answer() to setContacts(): " + contacts);
				return null;
			}
		};

		doAnswer(setContactsAnswer).when(clientFactoryMock).setContacts(any(List.class));

		// Return the real contacts object, when clientFactory.getContacts is
		// called
		Answer> getContactsAnswer = new Answer>() {
			@Override
			public List answer(InvocationOnMock invocation) throws Throwable {
				return contacts;
			}
		};

		doAnswer(getContactsAnswer).when(clientFactoryMock).getContacts();
	}

	@Test
	public void testGotoPlace() {
		ContactListActivity contactListActivity =
                new ContactListActivity(new ContactPlace(null), clientFactoryMock);

		ContactPlace contactPlace = new ContactPlace("kai@toedter.com");
		contactListActivity.goTo(contactPlace);

		verify(placeControllerMock).goTo(contactPlace);
	}

	@Test
	public void testStartWithEmptyToken() {
		clientFactoryMock.setContacts(null); // force RCP
		ContactListActivity contactListActivity =
                   new ContactListActivity(new ContactPlace(""), clientFactoryMock);
		contactListActivity.start(acceptsOneWidgetMock, eventBusMock);

		verify(contactListViewMock).setPresenter(contactListActivity);
		verify(contactListViewMock).initialize(contacts);
	}

	@Test
	public void testStartWithToken() {
		String token = "kai@toedter.com";
		clientFactoryMock.setContacts(null); // force RCP

		ContactListActivity contactListActivity =
                new ContactListActivity(new ContactPlace(token), clientFactoryMock);
		contactListActivity.start(acceptsOneWidgetMock, eventBusMock);

		verify(contactListViewMock).setPresenter(contactListActivity);
		verify(contactListViewMock).initialize(contacts);
		verify(contactListViewMock).selectInitialContact(contact1);
		verify(eventBusMock).fireEvent(any(ContactViewEvent.class));
	}

	@Test
	public void testMayStop() {
		ContactListActivity contactListActivity =
                new ContactListActivity(new ContactPlace(null), clientFactoryMock);
		contactListActivity.start(acceptsOneWidgetMock, eventBusMock);
		contactListActivity.mayStop();

		verify(contactListViewMock).setPresenter(null);
	}

	@Test
	public void clientFactoryTest() {
		List testList = new ArrayList();
		clientFactoryMock.setContacts(testList);
		Assert.assertNotNull(clientFactoryMock.getContacts());
	}
}

If you are interested in above stuff and happen to be in Munich on January 23th 2012, join my Night School, 6:30pm at the OOP 2012.

Have Fun!

Kai

You find me on Twitter and Google+.
Next Eclipse RCP 3.x/4.x trainings in Munich

flattr this!

My Upcoming Events & Sessions

In the next months I am going to give sessions/trainings at several conferences and other events, mostly Eclipse related. I’d be happy to meet you there.

January 20th, 7:00 pm (free event):
Java User Group Ostfalen, Braunschweig, Germany:
Was ist neu bei der Eclipse Rich Client Platform 4.x?“,

January 23th, 6:30 pm:
OOP 2012, Munich, Germany:
Google Web Toolkit: Ausgewählte coole Features“,

January 26th, 11:00 am (free event):
Oracle Developer Day, Munich, Germany:
JavaFX 2.0 Integration with the Eclipse 4.x Application Platform“,

March 26th, 1:00 pm:
EclipseCon 2012, Reston, USA:
Creating Rich Clients with Eclipse RCP 4.x“,
3 hour tutorial

March 28th, 1:30 pm:
EclipseCon 2012, Reston, USA:
Dynamic RIAs with OSGi and Vaadin“,

April 16th – 19th:
Jax 2012, Mainz, Germany:
“Dynamische RIAs mit Equinox und Vaadin”,

April 20th, 9:00 am:
Jax 2012, Mainz, Germany:
Rich-Client-Entwicklung mit Eclipse RCP 4.x“,

April 23th, 9:00 am:
3 days training in Munich, Germany:
Eclipse Rich Client Platform 3.x: Fundamentals“,

April 26th, 9:00 am:
1 day training in Munich, Germany:
Eclipse Rich Client Platform 3.x: Advanced“,

April 27th, 9:00 am:
1 day training in Munich, Germany:
Rich Client Development mit der Eclipse 4 Application Platform“,

Have Fun!

Kai

You find me on Twitter and Google+.

flattr this!

Trainingstermine Eclipse RCP Trainings für 2012

Wir freuen uns Euch die ersten Termine für die Trainings “Eclipse Rich Client Platform 3.x: Fundamentals mit Kai Tödter“, “Eclipse Rich Client Platform 3.x: Advanced mit Kai Tödter” und “Rich-Client-Entwicklung mit der Eclipse 4.x Application Platform mit Kai Tödter” mitteilen zu können:

23. – 25. April 2012 – Eclipse Rich Client Platform 3.x: Fundamentals mit Kai Tödter

26. April 2012 – Eclipse Rich Client Platform 3.x: Advanced mit Kai Tödter

27. April 2012 – Rich-Client-Entwicklung mit der Eclipse 4.x Application Platform mit Kai Tödter

Näheres über die Kurse erfahrt Ihr unter der Rubrik “Kurstermine“.

JavaFX 2.0, Swing & SWT Renderers for the Eclipse 4.x Application Platform

I wish you all a Happy New Year!

During the last weeks I had a bit of spare time and started experimenting with new rendering engines for the Eclipse 4.x Application Platform. Based on my experiences with  JavaFX 2.0 renderers in e(fx)clipse (by Tom Schindl from BestSolution.at, great JavaFX support for Eclipse), I started an experiment: Would it be possible to create a generic rendering engine that only has dependencies to the Eclipse 4.x workbench model and then delegate all UI toolkit specific logic to the UI toolkit specific renderers?

When I took a deep look at the projects org.eclipse.e4.ui.workbench.swt, org.eclipse.e4.ui.workbench.renderers.swt and org.eclipse.e4.ui.workbench.addons.swt, I figured out that most of the workbench model related code could be useful for other renderes, too. But there is a very strong coupling to SWT, so it is not possible to reuse any code without copying it. My approach is a simple generic rendering engine, that also provides a generic e4 application. Then, for every supported UI toolkit, just a derived application and new renderers have to be implemented. The basic bahavior is driven only by model changes, the renderes have to react on those changes. The engine also takes care of letting each renderer do the binding from the specific UI toolkit back to the model.

Currently I have implemented simple rendering engines for JavaFX 2.0, Swing, and SWT. I also started the same approach with a generic MinMax model addon. The addon gets the additions needed to adapt to a specific UI toolkit through DI.

I reimplemented my e4 contacts demo and split it into a generic project that contains the workbench model, the domain model and all parts, which are not UI toolkit specific. Then I created a UI toolkit specific implementation for JavaFX 2.0, Swing and SWT. The Details and the Table widgets I had to implement with the UI toolkits natively. Here are a few screen shots of the results, click on them to see the images in original size.

JavaFX 2.0 based contacts demo with 3 different CSS based themes:

     

Swing based contacts demo with Nimbus and Napkin Look & Feel (Napkin is my favorite Look & Feel to show prototypes to the management :) ):

  

SWT based contacts demo (my new rendering engine) with 2 different CSS based themes:

  

The current alpha version 0.0.1 you find at GitHub: https://github.com/toedter/e4-rendering

If you want to run the JavaFX 2.0 Contacts Demo, you also need to have the latest version (0.0.11 or better) of e(fx)clipse installed. The easiest way is to download the pre-configured Eclipse 4.x SDK from http://efxclipse.org/install.html#the-lazy-ones and then clone the above git repository.

Right now this is just a proof of concept, only very basic stuff is implemented. But I am planning to enhance the engine and UI toolkit specific renderers until EclipseCon 2012. If there is enough interest in the community, I would love to organize a BOF at EclipseCon to discuss the pros and cons of this approach.

What do you think?

Stay tuned!

Kai

You find me on Twitter and Google+.
If you are interested in in-house Eclipse RCP 3.x or 4.x training,
please contact me…

flattr this!

Eclipse 4.x RCP + JavaFX Renderer

Recently I have ported my e4 Contacts Demo to Tom Schindl’s e(fx)clipse. Besides a very nice JavaFX tooling integration into the Eclipse IDE, Tom also started a JavaFX 2.0 based rendering engine for Eclipse 4.x  based applications. I enhanced the JavaFX renderer just a little bit to fit better to the needs of the contacts demo. I also integrated dynamic theme switching based on CSS themes. Here is the result (these pictures are not from mocks, but from the running e4 JavaFX contacts demo):

Just click on the pictures to see them in original size. Of course this is just a first start, but to me it looks very promising. If you happen to be at the W-JAX conference during the next days, just grab me and ask for a live demo. I will also show this at my full day workshop “Rich-Client-Entwicklung mit Eclipse RCP 4.1” on Friday.

As soon as we have merged it into the master of Tom’s github repo, I’ll let you know.

Stay tuned!

Kai

You find me on Twitter and Google+.
If you are interested in in-house Eclipse RCP 3.x or 4.x training,
please contact me…

flattr this!

Java FX 2.0 CSS Styling

Inspired by Tom Schindl’s e(fx)clipse (see his blog), I have spent some time investigating the CSS styling capabilities of JavaFX 2.0. I have to admit I like it a lot! The styling provides everything out of the box that I had wished for. The only thing that bothers me about the JavaFX rendering right now is that sub-pixel anti-aliased font rendering is not supported yet. This make all fonts appear blurred on LCD screens. But I hope that this will be fixed soon, there are already some bugs filed in the JavaFX Jira.

I could not resist to create a JavaFX based mock-up of my Eclipse 4.x contacts demo, the current result without any additional CSS styling (actually the caspian CSS style is used by default) looks like this:

IMHO, the result is nice (if you ignore the font rendering :) ). With a little bit of CSS styling I could create a straw-man dark theme. This is not meant to be a real theme but just a prove of concept. You might see that also radial gradients are supported:

The CSS for this theming is pretty small since it inherits most styling from the default theme. A very nice thing is that by default most of the colors are derived from -fx-base. So it is pretty easy to create themes based on base colors. Here is the complete CSS for the above styling:

.root {
-fx-base: rgb(50, 50, 50);
-fx-background: rgb(50, 50, 50);
-fx-control-inner-background:  rgb(50, 50, 50);
}

.tab {
-fx-background-color: linear-gradient(to top, -fx-base, derive(-fx-base,30%));
}

.menu-bar {
-fx-background-color: linear-gradient(to bottom, -fx-base, derive(-fx-base,30%));
}

.tool-bar:horizontal {
-fx-background-color:
linear-gradient(to bottom, derive(-fx-base,+50%), derive(-fx-base,-40%), derive(-fx-base,-20%));
}

.button {
-fx-background-color: transparent;
}

.button:hover {
-fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
-fx-color: -fx-hover-base;
}

.table-view {
-fx-table-cell-border-color:derive(-fx-base,+10%);
-fx-table-header-border-color:derive(-fx-base,+20%);
}

.split-pane:horizontal > * > .split-pane-divider {
-fx-border-color: transparent -fx-base transparent -fx-base;
-fx-background-color: transparent, derive(-fx-base,20%);
-fx-background-insets: 0, 0 1 0 1;
}

.my-gridpane {
-fx-background-color: radial-gradient(radius 100%, derive(-fx-base,20%), derive(-fx-base,-20%));
}

.separator-label {
-fx-text-fill: orange;
}

The next steps for me would to port the e4 Contacts Demo to Tom’s e(fx)clipse to have a working application.

One last thing: If you are a designer, could you provide me with a real great looking dark CSS theme for JavaFX 2.0?

Have Fun!

Kai

You find me on Twitter and Google+.
If you are interested in in-house Eclipse RCP training,
please contact me…

flattr this!