E4 – A New Area For RCP/RIA Applications
I’m on the road to prepare my example for the E4 talk I’m delivering on the Eclipse-Developers-Day in Karlsruhe and I have to say that in my eyes E4 is going to open up a new world for Eclipse-RCP-Developers.
Though RCP-Applications written in 3.x might not look too bad no one can deny that the UI-Design is coming from an IDE background and compared to modern Web-UIs it looks boring (which is not a bad thing per se for business applications). The problem in 3.x is that it is very hard to impossible to change the L&F of your application.
E4 provides different multiple solutions to fix the L&F:
- Declarative-Styleing through CSS
- The possibility to define your own renderes to exchange Widget A through Widget B if CSS is not enough to theme your application
To demostrate what you can achieve when you combine the 1st and 2nd possibility I create a small screencast
where you see the famous E4-Photo-Application revamped

A second example application is our E4-Contacts-Demo created and maintained by Kai Tödter which shows advanced css-styles like radial gradients.

I use this application to show you another nice thing you can do with E4’s declarative styling support. You can adjust the styling of your application while it is running so that you can experiment with various font and color settings WITHOUT shutting down your application.
If all this would not be enough you can run the unmodified code (please take this literally) from the example application above in your browser using the RAP-Framework.

If you are interested in E4 and what’s going on behind the scenes of the next major Eclipse-Release I hope to see you in Karlsruhe on Tuesday July 7th.
- Login or register to post comments
- 7168 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)




Comments
Ronald Miura replied on Fri, 2009/07/03 - 6:18am
Tom Schindl replied on Fri, 2009/07/03 - 6:36am
It gives the developer the possibility to customize it if he wants to. Please note that all shown above is done using the CURRENT SWT-API no extra stuff was added to make this work.
Rajat Gupta replied on Fri, 2009/07/03 - 11:43am
I don't understand the value of creating so many UI toolkits. When we started creating PAW (a end-user focused product for data processing) using Eclipse ECP, we used all the normal SWT widgets and other Eclipse paradigms (perspectives, views, etc..). The feedback I constantly received was it was too difficult to understand how to get started - the UI didn't guide the user towards anything.
Ultimately, we started to think of the user experience from a web based paradigm and made the product a whole lot simpler. In terms of UI,auto-expanding sections, flow layout, additional explanatory text - these things are much more natural in a web paradigm and users need it. SWT doesn't provide good support for this and the effort in E4 with CSS is also an effort to fill some of these gaps. We ended up using a web UI, with creating our own widget classes keeping to the APIs of the SWT classes (that we were using) but bound to browser based widgets using Mozilla XPCOM.
I think ultimately with E4 (or E5) you're going to try to recreate all the layout flexibility that a browser provides. My view is that it would be a better choice to model SWT widgets over the browser (allowing the platform developer to extend an HTML page) rather than creating another widget language and another widget framework.
Miller Roger replied on Fri, 2009/07/03 - 7:24pm
Tom Schindl replied on Sat, 2009/07/04 - 3:55am
in response to: rgupta
I think you didn't understood what I was trying to say:
- We are not creating a new UI-Toolkit
- We rewrite the Workbench-Framework to make it useable with every widget technology you want giving you the freedom to choose your favorite technology (SWT, Qt, Swing, you name it).
- The core Workbench-Framework provides services and stuff every application needs like:
Out of curiosity is the SWT on XPCOM available to the public because it might interesting to see what one can do with it for example in a client-serversplit scenario* Commands
* Restoring the current workbench state on restart
* glueing together the different parts of your application
* ...
Chetan Sachdev replied on Mon, 2009/07/06 - 10:04am
@Tom
Can I make use of Flash/Flex content to create widgets. Is it possible to have a flash player integration with it ?
Tom Schindl replied on Mon, 2009/07/06 - 5:00pm
in response to: cksachdev
Rajat Gupta replied on Tue, 2009/07/07 - 1:44am
I'll try to post a snippet of what we ended up doing... The other thing that I realized along the way with PAW was that initially I was trying to be a standard Windows app, until I realized that there was no more a standard windows app (look at Windows Media Player, MS Office/ribbon UI, Yahoo Messenger, AOL Messenger, etc...). So the idea behind SWT was to expose Windows widgets (with the window L&F) to the Java developer is no longer as desirable as it was when the UI across applications was still pretty standard. So my view is that perhaps we should pick the new 'best' UI toolkit and make that a first-class citizen - in any case, providing CSS styling means that we're extending the underlying UI toolkits or creating an entirely new one.
Here's an example of a SWT API like wrapper to a browser hosted control.
public class Text implements IBrowserBasedWidget {
nsIDOMHTMLInputElement input;
nsIDOMEventListener listener;
ArrayList<IEventHandler> changeListeners = new ArrayList<IEventHandler>();
ArrayList<IEventHandler> focusListeners = new ArrayList<IEventHandler>();
Object data;
public Text() {}
public Text(nsIDOMElement elem) {
init(elem);
}
public String getText() {
return input.getValue();
}
public void setText(String text) {
if (text == null)
text = "";
input.setValue(text);
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getId() {
return input.getId();
}
@Override
public void addListener(EventType type, IEventHandler handler) {
if (listener == null) {
listener = new nsIDOMEventListener() {
@Override
public void handleEvent(nsIDOMEvent event) {
EventData ed = new EventData();
ed.widget = Text.this;
if (event.getType().compareToIgnoreCase("change") == 0) {
ed.type = EventType.change;
for (IEventHandler handler : changeListeners)
handler.handleEvent(ed);
}
else if (event.getType().compareToIgnoreCase("focus") == 0){
ed.type = EventType.focus;
for (IEventHandler handler : focusListeners)
handler.handleEvent(ed);
}
}
@Override
public nsISupports queryInterface(String classId) {
return Mozilla.queryInterface(this, classId);
}
};
nsIDOMEventTarget eventTarget = (nsIDOMEventTarget) input
.queryInterface(nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID);
eventTarget.addEventListener("change", listener, false);
eventTarget.addEventListener("focus", listener, false);
}
if (type == EventType.change)
changeListeners.add(handler);
else if (type == EventType.focus)
focusListeners.add(handler);
}
public void dispose() {
nsIDOMEventTarget eventTarget = (nsIDOMEventTarget) input
.queryInterface(nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID);
eventTarget.removeEventListener("change", listener, false);
eventTarget.removeEventListener("focus", listener, false);
changeListeners.clear();
focusListeners.clear();
}
@Override
public boolean init(nsIDOMElement element) {
this.input = (nsIDOMHTMLInputElement) element
.queryInterface(nsIDOMHTMLInputElement.NS_IDOMHTMLINPUTELEMENT_IID);
return false;
}
@Override
public void removeListener(EventType type, IEventHandler handler) {
if (type == EventType.change)
changeListeners.remove(handler);
else if (type == EventType.focus)
focusListeners.remove(handler);
}
}
Here's an example of a viewer (note that themethods aren't exactly the same but very similar).
public class ListViewerAdapter {
int numColumns;
IStructuredContentProvider contentProvider;
LabelProvider labelProvider;
List list;
Object input;
public ListViewerAdapter(List list) {
this.list = list;
}
public void setContentProvider (IStructuredContentProvider provider) {
this.contentProvider = provider;
}
public void setLabelProvider(LabelProvider provider) {
this.labelProvider = provider;
}
public void setInput(Object input) {
this.input = input;
refresh();
}
public ISelection getSelection() {
nsIDOMNodeList items = list.getUnderlyingList().getChildNodes();
Object[] dataItems = contentProvider.getElements(input);
if (dataItems == null)
return null;
for (int i = 0; i < items.getLength(); i++) {
nsIDOMNode node = items.item(i);
nsIDOMNode selector = node.getFirstChild();
nsIDOMHTMLInputElement selectElem = (nsIDOMHTMLInputElement) selector.queryInterface(nsIDOMHTMLInputElement.NS_IDOMHTMLINPUTELEMENT_IID);
if (selectElem.getChecked()) {
if (dataItems.length > i)
return new StructuredSelection(dataItems[i]);
else
return null;
}
}
return null;
}
public void refresh() {
list.removeAll();
Object[] items = contentProvider.getElements(input);
if (items == null || items.length == 0)
return;
for (int i = 0; i < items.length; i++) {
String value = labelProvider.getText(items[i]);
list.add(value);
}
}
}
I'll be happy to share more if it's useful, this isn't the core of our product.
Thanks,
Rajat