<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-33274870</id><updated>2011-11-28T01:17:39.153+01:00</updated><title type='text'>eclipse-dev</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>49</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-33274870.post-5181549066531217000</id><published>2009-06-07T16:12:00.001+02:00</published><updated>2009-06-07T16:14:06.242+02:00</updated><title type='text'>I'm moving to Wordpress</title><content type='html'>In the last few days I moved this blog to wordpress and you can reach the content through http://tomsondev.bestsolution.at/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-5181549066531217000?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/5181549066531217000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=5181549066531217000' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5181549066531217000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5181549066531217000'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2009/06/im-moving-to-wordpress.html' title='I&apos;m moving to Wordpress'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-7249269412328600965</id><published>2009-05-23T20:45:00.012+02:00</published><updated>2009-05-24T16:32:41.040+02:00</updated><title type='text'>Useing Qt to write Equinox-OSGi-UI-Applications</title><content type='html'>I saw I didn't blogged since about 2 months. So I thought I'll start a series of blog entries showing off new things and paths I'm exploring.&lt;br /&gt;&lt;br /&gt;I'll start with a Technical Topic because it's a really exciting thing I guess not only for me but also for the whole Equinox-OSGi/Java-Community.&lt;br /&gt;&lt;br /&gt;Since some time Qt is released under LGPL and since some weeks now their Java-Binding named Qt-Jambi is released too under LGPL. I've been playing with Qt-Jambi (because my UFaceKit project has a Qt-Port) before but now that the code is under LGPL it's getting more interesting to the wider Java-audience and naturally also people who use Equinox-OSGi for their applications.&lt;br /&gt;&lt;h2&gt;A simple QtJambi-Application&lt;/h2&gt;&lt;br /&gt;Before digging into the details what I've done let's look at a simply QtJambi-Application if we are not using Equinox-OSGi.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_cWFEe8uui9o/ShiqT9QqaSI/AAAAAAAAAHE/jnyz5FK0HXg/s1600-h/screen_1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 217px; height: 69px;" src="http://4.bp.blogspot.com/_cWFEe8uui9o/ShiqT9QqaSI/AAAAAAAAAHE/jnyz5FK0HXg/s400/screen_1.png" alt="" id="BLOGGER_PHOTO_ID_5339204618086410530" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;package at.bestsolution.qt;&lt;br /&gt;&lt;br /&gt;import com.trolltech.qt.gui.QApplication;&lt;br /&gt;import com.trolltech.qt.gui.QGridLayout;&lt;br /&gt;import com.trolltech.qt.gui.QLabel;&lt;br /&gt;import com.trolltech.qt.gui.QLineEdit;&lt;br /&gt;import com.trolltech.qt.gui.QMainWindow;&lt;br /&gt;import com.trolltech.qt.gui.QWidget;&lt;br /&gt;&lt;br /&gt;public class HelloWorld extends QMainWindow {&lt;br /&gt;&lt;br /&gt; public HelloWorld() {&lt;br /&gt;   setWindowTitle("Hello World!");&lt;br /&gt;&lt;br /&gt;   QWidget composite = new QWidget();&lt;br /&gt;  &lt;br /&gt;   QGridLayout layout = new QGridLayout();&lt;br /&gt;   composite.setLayout(layout);&lt;br /&gt;  &lt;br /&gt;   QLabel label = new QLabel();&lt;br /&gt;   label.setText("Label");&lt;br /&gt;   layout.addWidget(label,0,0);&lt;br /&gt;  &lt;br /&gt;   QLineEdit text = new QLineEdit();&lt;br /&gt;   layout.addWidget(text,0,1);&lt;br /&gt;  &lt;br /&gt;   setCentralWidget(composite);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public static void main(String[] args) {&lt;br /&gt;   QApplication.initialize(new String[0]);&lt;br /&gt;  &lt;br /&gt;   HelloWorld world = new HelloWorld();&lt;br /&gt;   world.show();&lt;br /&gt;  &lt;br /&gt;   QApplication.exec();&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This looks not much different to a SWT-Application besides the fact that one doesn't has to pass a parent when creating a widget and instead of running the event loop one simply calls QApplication.exec().&lt;br /&gt;&lt;h2&gt;QtJambi and Equinox-OSGi&lt;/h2&gt;&lt;br /&gt;Couldn't be hard you think when you've used other UI-Toolkits (SWT,Swing) in your Equinox-OSGi-Applications already but the problem is that Swing is not problematic because it is part of the JRE and SWT is shipped as an (in fact multiple) Equinox-OSGi-Bundle/Fragment.&lt;br /&gt;&lt;br /&gt;What we need to do is to Equinox-OSGify the bundles coming from Qt but this task is more complex then it looks on the first sight because using the simple converter provided by PDE is not providing us a solution because QtJambi-Code expects to load the libraries in very special way which means we need to patch their Java-Code to make it aware of Equinox-OSGi.&lt;br /&gt;&lt;br /&gt;The really cool thing is that patching and maintaining the patch is easier than one might think because they provide their sources through a &lt;a href="http://qt.gitorious.org/qt-jambi"&gt;git-repo&lt;/a&gt; one could simply &lt;a href="http://qt.gitorious.org/%7Etomson/qt-jambi/tomsons-clone"&gt;clone&lt;/a&gt; and maintain the patched sources. So maintaining the patch is easier than it is for example to maintain a patch for the eclipse-platform because of git.&lt;br /&gt;&lt;br /&gt;The tough thing is to get the environment setup in a way than one can produce .jars from the sources because one&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Has to compile the Qt-Sources&lt;/li&gt;&lt;br /&gt;&lt;li&gt;To generate the Java-Binding-Classes to the Qt-Sources (extracted from the C++-Header-Files)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;which is a bit time consuming and not documented very well at the moment. Though this is doable for a medium skilled Java-Dev I think one should be able to checkout the complete project with native and generated Java-Code and doesn't have to compile all the stuff.&lt;br /&gt;&lt;br /&gt;After having managed to setup a build environment I patched the libary loading classes and recreated the .jar-packages. QtJambi is split in 2 .jars:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;qtjambi.jar: Hold platform independent Java-Classes&lt;/li&gt;&lt;br /&gt;&lt;li&gt;qtjambi-${os}.jar: Holding native libraries for the platform and the JNI-Glue&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;So the setup is similar to SWT but in SWT also the Java-Code is part of the native fragment because it differs from platform to platform and the host bundle is simply an empty bundle. In contrast to that in Qt the Host-Bundle is holding all Java-Classes and in the native fragments one has the native-libs and JNI-Glue.&lt;br /&gt;&lt;br /&gt;So what this all means for you? Not too much because I did 2 things as part of &lt;a href="http://wiki.eclipse.org/UFaceKit/Development_Setup_In_Eclipse"&gt;UFaceKit-Target-Setup&lt;/a&gt;:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Packaged my changes to the Java-Code and provide it for download&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added ant-tasks who fetch the native libs from &lt;a href="http://www.qtsoftware.com/downloads"&gt;Qt-Software&lt;/a&gt; and repackage them&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/ShkL39v8p7I/AAAAAAAAAHM/FAvqBugaYBU/s1600-h/screen_4.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 252px; height: 320px;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/ShkL39v8p7I/AAAAAAAAAHM/FAvqBugaYBU/s400/screen_4.png" alt="" id="BLOGGER_PHOTO_ID_5339311889320814514" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;One could also use these &lt;a href="http://dev.eclipse.org/svnroot/eclipse/org.eclipse.ufacekit/develop/setup/setup-target.xml"&gt;ant-tasks&lt;/a&gt; when not using UFaceKit (I'm using it for my RCP-Development-Setup).&lt;br /&gt;&lt;br /&gt;The Equinox-OSGi-Support is not fully finished and I'll maybe rework it a bit in future when understanding the code better but for now it sufficient to go on and file a CQ to make use of Qt in UFaceKit. Let's see what's coming out from this now that Qt is LGPL.&lt;br /&gt;&lt;h2&gt;Simple Qt-Jambi and Equinox-OSGi-Application&lt;/h2&gt;&lt;br /&gt;Let's create an Equinox-Application which uses Qt as UI-Toolkit now. The easiest thing is to use the PDE-Wizard to create a "Headless Hello RCP" and add a MainWindow.java.&lt;br /&gt;&lt;pre&gt;package at.bestsolution.qt;&lt;br /&gt;&lt;br /&gt;import java.io.BufferedReader;&lt;br /&gt;import java.io.ByteArrayOutputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.InputStream;&lt;br /&gt;import java.io.InputStreamReader;&lt;br /&gt;&lt;br /&gt;import com.trolltech.qt.gui.QApplication;&lt;br /&gt;import com.trolltech.qt.gui.QGridLayout;&lt;br /&gt;import com.trolltech.qt.gui.QLabel;&lt;br /&gt;import com.trolltech.qt.gui.QLineEdit;&lt;br /&gt;import com.trolltech.qt.gui.QMainWindow;&lt;br /&gt;import com.trolltech.qt.gui.QPixmap;&lt;br /&gt;import com.trolltech.qt.gui.QPushButton;&lt;br /&gt;import com.trolltech.qt.gui.QWidget;&lt;br /&gt;&lt;br /&gt;public class MainWindow extends QMainWindow {&lt;br /&gt; &lt;br /&gt; public MainWindow() {&lt;br /&gt;   QWidget widget = new QWidget();&lt;br /&gt;   widget.setObjectName("main_window");&lt;br /&gt;&lt;br /&gt;   QGridLayout layout = new QGridLayout();&lt;br /&gt;   layout.setMargin(0);&lt;br /&gt;   widget.setLayout(layout);  &lt;br /&gt;  &lt;br /&gt;   addHeader(layout,"Tom Schindl","at/bestsolution/qt/bookmarks.png");&lt;br /&gt;  &lt;br /&gt;   QWidget content = new QWidget();&lt;br /&gt;   QGridLayout contentLayout = new QGridLayout();&lt;br /&gt;   content.setLayout(contentLayout);&lt;br /&gt;  &lt;br /&gt;   addLine(0, contentLayout, "Firstname");&lt;br /&gt;   addLine(1, contentLayout, "Lastname");&lt;br /&gt;   addLine(2, contentLayout, "Age");&lt;br /&gt;  &lt;br /&gt;   QPushButton button = new QPushButton();&lt;br /&gt;   button.setObjectName("submit");&lt;br /&gt;   button.setText("Submit");&lt;br /&gt;   contentLayout.addWidget(button,3,1);&lt;br /&gt;  &lt;br /&gt;   layout.addWidget(content);&lt;br /&gt;  &lt;br /&gt;   setCentralWidget(widget);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private void addHeader(QGridLayout layout, String labelText, String icon) {&lt;br /&gt;   QLabel header = new QLabel();&lt;br /&gt;   layout.addWidget(header);&lt;br /&gt;   header.setObjectName("header");&lt;br /&gt;   QGridLayout headerLayout = new QGridLayout();&lt;br /&gt;   headerLayout.setMargin(0);&lt;br /&gt;   header.setLayout(headerLayout);&lt;br /&gt;  &lt;br /&gt;   QLabel headerIcon = new QLabel();  &lt;br /&gt;   headerIcon.setObjectName("header_icon");&lt;br /&gt;   headerIcon.setPixmap(loadImage(icon));&lt;br /&gt;  &lt;br /&gt;   headerLayout.addWidget(headerIcon);&lt;br /&gt;  &lt;br /&gt;   QLabel headerText = new QLabel();&lt;br /&gt;   headerLayout.addWidget(headerText,0,1);&lt;br /&gt;   headerLayout.setColumnStretch(1, 100);&lt;br /&gt;   headerText.setObjectName("header_text");&lt;br /&gt;   headerText.setText(labelText);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; private void addLine(int line, QGridLayout contentLayout, String labelText) {&lt;br /&gt;   QLabel label = new QLabel();&lt;br /&gt;   label.setText(labelText);&lt;br /&gt;   label.setObjectName("label");&lt;br /&gt;   contentLayout.addWidget(label);&lt;br /&gt;  &lt;br /&gt;   QLineEdit text = new QLineEdit();&lt;br /&gt;   text.setObjectName("text");&lt;br /&gt;   contentLayout.addWidget(text,line,1);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; private QPixmap loadImage(String path) {&lt;br /&gt;   try {&lt;br /&gt;     InputStream in = getClass().getClassLoader().getResourceAsStream(path);&lt;br /&gt;     ByteArrayOutputStream out = new ByteArrayOutputStream();&lt;br /&gt;&lt;br /&gt;     int l;&lt;br /&gt;     byte[] buffer = new byte[1024];&lt;br /&gt;&lt;br /&gt;     while ((l = in.read(buffer)) != -1) {&lt;br /&gt;       out.write(buffer, 0, l);&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     QPixmap pic = new QPixmap();&lt;br /&gt;     pic.loadFromData(out.toByteArray());&lt;br /&gt;     return pic;&lt;br /&gt;   } catch (Exception e) {&lt;br /&gt;     e.printStackTrace();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return null;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and modify the generated application class like this:&lt;br /&gt;&lt;pre&gt;package at.bestsolution.qt;&lt;br /&gt;&lt;br /&gt;import org.eclipse.equinox.app.IApplication;&lt;br /&gt;import org.eclipse.equinox.app.IApplicationContext;&lt;br /&gt;&lt;br /&gt;import com.trolltech.qt.gui.QApplication;&lt;br /&gt;&lt;br /&gt;public class Application implements IApplication {&lt;br /&gt; public Object start(IApplicationContext context) throws Exception {&lt;br /&gt;   QApplication.initialize(new String[0]);&lt;br /&gt;&lt;br /&gt;   MainWindow window = new MainWindow();&lt;br /&gt;   window.show();&lt;br /&gt;  &lt;br /&gt;   QApplication.exec();&lt;br /&gt;  &lt;br /&gt;   return IApplication.EXIT_OK;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;  public void stop() {}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Well as you see I'm not a good designer and the application looks well not really nice though it looks native on my OS-X though this is only faked by Qt because they are drawing everything on the screen as far as I understood it.&lt;br /&gt;&lt;br /&gt;One could think that this fact is a draw back of Qt but IMHO it's the other way round because with this strategy they can support things SWT can't support easily - Completely restyle your application using a declarative language and well they use CSS like e.g. &lt;a href="http://wiki.eclipse.org/E4/UI/Running_CSS_demos"&gt;E4&lt;/a&gt; does too.&lt;br /&gt;&lt;br /&gt;The first thing to do is to add a method to load a stylesheet to Application.java:&lt;br /&gt;&lt;pre&gt;private String loadStyles(String cssPath) {&lt;br /&gt; InputStream in = getClass().getClassLoader().getResourceAsStream(cssPath);&lt;br /&gt; BufferedReader r = new BufferedReader(new InputStreamReader(in));&lt;br /&gt; StringBuilder s = new StringBuilder();&lt;br /&gt; String line;&lt;br /&gt;&lt;br /&gt; try {&lt;br /&gt;   while( (line = r.readLine()) != null ) {&lt;br /&gt;     s.append(line);&lt;br /&gt;   }&lt;br /&gt; } catch (IOException e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return s.toString();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;and set the style sheet on the main window:&lt;br /&gt;&lt;pre&gt;public Object start(IApplicationContext context) throws Exception {&lt;br /&gt; QApplication.initialize(new String[0]);&lt;br /&gt;  &lt;br /&gt; MainWindow window = new MainWindow();&lt;br /&gt; window.setStyleSheet(loadStyles("at/bestsolution/qt/style.css"));&lt;br /&gt; window.show();&lt;br /&gt;  &lt;br /&gt; QApplication.exec();&lt;br /&gt;  &lt;br /&gt; return IApplication.EXIT_OK;&lt;br /&gt;}&lt;/pre&gt; and we need to define some styles:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/ShkU-0jymKI/AAAAAAAAAHc/S60dnBXxG-M/s1600-h/screen_5.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 347px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/ShkU-0jymKI/AAAAAAAAAHc/S60dnBXxG-M/s400/screen_5.png" alt="" id="BLOGGER_PHOTO_ID_5339321902717638818" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;resulting in this application:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/ShkVZi9neUI/AAAAAAAAAHk/LH0gD_Mlplc/s1600-h/screen_3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 177px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/ShkVZi9neUI/AAAAAAAAAHk/LH0gD_Mlplc/s400/screen_3.png" alt="" id="BLOGGER_PHOTO_ID_5339322361850591554" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;which we all agree looks better than:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/ShkQzfV-1dI/AAAAAAAAAHU/bMElHjGS8I4/s1600-h/screen_2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 165px;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/ShkQzfV-1dI/AAAAAAAAAHU/bMElHjGS8I4/s400/screen_2.png" alt="" id="BLOGGER_PHOTO_ID_5339317309997503954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you see this is also not my design but then one you get when using the Eclipse-Forms-API with the difference that in Eclipse one has to learn a new API to deal with besides SWT whereas in Qt the UI-Code is still Qt and styled by a declarative syntax and if you ask me the Forms-API is going to replace in space of Eclipse in E4 through SWT + CSS but this is only my personal opinion.&lt;br /&gt;&lt;br /&gt;So should we all now move to Qt-Jambi to write UI-Applications in Java like we did years ago when we abandoned Swing and started using SWT?&lt;br /&gt;&lt;br /&gt;Let's look at some potentially problematic areas:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Qt and QtJambi misses an application framework like eclipse RCP provides one for SWT-Application developers&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Qt and QtJambi misses Databinding support like Eclipse-Databinding provides one for SWT, JavaBeans and EMF&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Nokia removed all resources from QtJambi development and wants to build a community to work on it&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;For at least 2 of the above there are solutions already today:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;E4's core application platform is UI-Toolkit agonstic so though E4 is not released until 1.5 years it would give people the possibility to use Qt as their UI-Toolkit of choice which supports many many things starting from animations, multimedia integration, ...&lt;/li&gt;&lt;br /&gt;&lt;li&gt;UFaceKit provides &lt;a href="http://dev.eclipse.org/svnroot/eclipse/org.eclipse.ufacekit/bundles/incubation/org.eclipse.ufacekit.incubation/org.eclipse.ufacekit.ui.qt/"&gt;JFace-Viewer&lt;/a&gt; like and &lt;a href="http://dev.eclipse.org/svnroot/eclipse/org.eclipse.ufacekit/bundles/incubation/org.eclipse.ufacekit.incubation/org.eclipse.ufacekit.ui.qt/"&gt;Eclipse-Databinding support&lt;/a&gt; for QtJambi if the CQ I'm going to file is approved&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Still the killer problem is the lacking support from Nokia on QtJambi and it's unclear if a community could be build around it who not even maintains but also adds new features. &lt;br /&gt;&lt;br /&gt;I think this is a bitty because with getting a real application framework with E4, it's themeing, multimedia and animation support I think QtJambi could get a real possibility to write cross-platform RCP-Applications in Java without the sometimes really hurting lowest common denominator problem we have in SWT.&lt;br /&gt;&lt;br /&gt;So what should one do? Though QtJambi looks like a real solution for writing nice looking RCP-Applications the uncertainness caused by Nokia by cutting resources makes it unusable for most companies. &lt;br /&gt;&lt;br /&gt;For form developers I could point you once more to &lt;a href="http://wiki.eclipse.org/UFaceKit"&gt;UFaceKit&lt;/a&gt; which supports both SWT and Qt and your &lt;b&gt;form application code&lt;/b&gt; is not affected by changing the underlying technology but one can still rely on native stuff where needed (e.g. using Qt animation/multimedia support).&lt;br /&gt;&lt;br /&gt;For me as one of E4 committers and UFaceKit-Project lead it means:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;I'd try to keep the application runtime widget agonstic if possible (well we are on a good track here)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I'll file a CQ to let UFaceKit make use of QtJambi and provide first class JFace-Viewer and Eclipse-Databinding support for QtJambi&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. updated my wrong capitalization of Qt&lt;/b&gt;&lt;br /&gt;&lt;b&gt;2. please note that I'm using Equinox specific stuff to make this work so it is maybe not runnable on other OSGi implementations but I'm happy to incooperate feedback and suggestions into my git-clone to support other OSGi implementations&lt;/b&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-7249269412328600965?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/7249269412328600965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=7249269412328600965' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7249269412328600965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7249269412328600965'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2009/05/useing-qt-to-write-equinox-osgi-ui.html' title='Useing Qt to write Equinox-OSGi-UI-Applications'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_cWFEe8uui9o/ShiqT9QqaSI/AAAAAAAAAHE/jnyz5FK0HXg/s72-c/screen_1.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-6116746125367224980</id><published>2009-03-02T11:28:00.008+01:00</published><updated>2009-03-02T13:00:18.218+01:00</updated><title type='text'>Give your E4-Application a modern Look&amp;Feel</title><content type='html'>&lt;p&gt;EclipseCon is coming in about 3 weeks and I started preparing the stuff for my talks about &lt;a href="http://www.eclipsecon.org/2009/sessions?id=565"&gt;E4&lt;/a&gt; and &lt;a href="http://www.eclipsecon.org/2009/sessions?id=278"&gt;UFaceKit&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In E4 we are trying to address some of the main pain points RCP-Application developers faced - &lt;b&gt;Their application looks like Eclipse and the theming/presentation API is not flexible enough to modify all aspects of the UI (e.g. Toolbar/MenuBar, ...)!&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The first step to make your application look different was that we introduced the concept of declarative styleing (CSS). &lt;br /&gt;&lt;br /&gt;Let's take the demo E4-Photo-Demo-application as example. &lt;br /&gt;This is the application &lt;b&gt;without&lt;/b&gt; CSS:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/Sau6Z4as3bI/AAAAAAAAAGk/XRGSw0X87Eo/s1600-h/screen_nocss.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 309px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/Sau6Z4as3bI/AAAAAAAAAGk/XRGSw0X87Eo/s400/screen_nocss.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308541539590135218" /&gt;&lt;/a&gt;&lt;br /&gt;This is the application &lt;b&gt;with&lt;/b&gt; CSS:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_cWFEe8uui9o/Sau6r_-jr1I/AAAAAAAAAGs/HZFRCHeF7dk/s1600-h/screen_css.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 303px;" src="http://4.bp.blogspot.com/_cWFEe8uui9o/Sau6r_-jr1I/AAAAAAAAAGs/HZFRCHeF7dk/s400/screen_css.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308541850857221970" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;But like in other aspects E4 goes further and allows you to exchange complete widgets like the application-shell, the menu and toolbar, the Stack-Folders (the standard theme uses CTabFolder) resulting in an E4-Demo-Application like this:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/Sau7lDRTZVI/AAAAAAAAAG0/jI79qhJvn3Q/s1600-h/screen_ribbon.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 291px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/Sau7lDRTZVI/AAAAAAAAAG0/jI79qhJvn3Q/s400/screen_ribbon.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308542830993696082" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You want to know more about how this works and how the internals of the workbench make such things possible? Then I'd suggest to you attend the &lt;a href="http://www.eclipsecon.org/2009/sessions?id=565"&gt;EcliseCon-talk&lt;/a&gt; about the modeled workbench Boris and I are delivering at EclipseCon09&lt;/p&gt;&lt;p&gt;&lt;b&gt;But E4 goes even further!&lt;/b&gt; It allows you to plugin every widget-technology you want to! The internals don't care whether your application gets renderered by QT, Swing, UFaceKit you name it. So I've done that and here's my UFaceKit-Demo-Application built on top of E4:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/Sau9RNFx6UI/AAAAAAAAAG8/4RB4XVsDPJo/s1600-h/screen_cocoa.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/Sau9RNFx6UI/AAAAAAAAAG8/4RB4XVsDPJo/s400/screen_cocoa.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5308544689055590722" /&gt;&lt;/a&gt;Makeing UFaceKit a possible renderer of E4 opens the doors to all technologies supported by UFaceKit (Swing, QT, GWT, ...) and its advanced DeclartiveStyling-Support&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-6116746125367224980?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/6116746125367224980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=6116746125367224980' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/6116746125367224980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/6116746125367224980'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2009/03/give-your-e4-application-modern-look.html' title='Give your E4-Application a modern Look&amp;Feel'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_cWFEe8uui9o/Sau6Z4as3bI/AAAAAAAAAGk/XRGSw0X87Eo/s72-c/screen_nocss.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-147003199704276522</id><published>2009-02-27T00:06:00.003+01:00</published><updated>2009-02-27T00:35:44.363+01:00</updated><title type='text'>News on UFaceKit</title><content type='html'>&lt;h2&gt;IP-Review passed&lt;/h2&gt;This is a great day in the short life of UFaceKit. We passed the initial IP-Review for our code base and I thank all the IP-Team for the great assistance and help to make our code base IP-clean.&lt;br /&gt;&lt;h2&gt;Abstraction of Application-Bootstrapping&lt;/h2&gt;Until today the start up process of an application has been Toolkit specific (e.g. spinning the event-loop) this is now abstracted in a new interface called UIDesktop which can be compared to the mixture of SWT-Display and the Eclipse-Workbench.&lt;br /&gt;&lt;br /&gt;This abstraction means that switching from SWT to QT means switching exactly one factory and that's it. This new UIDesktop concept is also a result of discussing a potential OpenGL-Implementation of the UFaceKit-API with one of our employees.&lt;pre&gt;&lt;br /&gt;public void startup(UIFactory&lt;?&gt; factory) {&lt;br /&gt;  UIDesktop desktop = factory.newDesktop();&lt;br /&gt;&lt;br /&gt;  desktop.runWithDefaultRealm(new UIRunnable&lt;UIDesktop&gt;() {&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected IStatus run(UIDesktop element) {&lt;br /&gt;      createUI(element,uiMethod);&lt;br /&gt;      return Status.OK_STATUS;&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;  desktop.run();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Creating application with SWT&lt;br /&gt;startup(new JFaceFactory());&lt;br /&gt;&lt;br /&gt;// Creating application with QT&lt;br /&gt;startup(new QTFactory());&lt;/pre&gt;&lt;h2&gt;A first real world application&lt;/h2&gt;One of our employees is rewritting our one of our applications using UFaceKit and is making good progress. Writing a real world applications helps us to fill the last missing gaps in API. Maybe I can already show an intial version of the application on EclipseCon 09 then people can see a real world application using UFaceKit + EMF + CDO in my talks:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.eclipsecon.org/2009/sessions?id=446"&gt;Mixing Eclipse Technologies to create Enterprise Ready Database-RCP-Frontends&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.eclipsecon.org/2009/sessions?id=278"&gt;UFaceKit - A highlevel Databinding and Widget-Toolkit-Abstraction&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;By the way I'm nominated for 2 &lt;a href="http://www.eclipse.org/org/foundation/eclipseawards/index.php"&gt;Eclipse-Awards&lt;/a&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://eclipse.dzone.com/articles/meet-years-top-ambassador?page=0,4"&gt;Top Ambassador&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://eclipse.dzone.com/articles/meet-years-top-contributor"&gt;Top Contributor&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-147003199704276522?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/147003199704276522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=147003199704276522' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/147003199704276522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/147003199704276522'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2009/02/news-on-ufacekit.html' title='News on UFaceKit'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-7593960697340297359</id><published>2009-01-17T02:36:00.005+01:00</published><updated>2009-01-17T03:10:16.688+01:00</updated><title type='text'>Getting started with UFaceKit and QT</title><content type='html'>&lt;h2&gt;QT and UFaceKit&lt;/h2&gt;So the big news this week in opensource space was the announcement of Nokia to release their C++ cross-platform widget toolkit under LGPL. This is great and people now once more start to request a SWT-Port for QT. I don't know if any company is going to invest the development resources into such a port at least I haven't heard anything.&lt;br /&gt;&lt;br /&gt;From UFaceKit point of view the announcement is great because we've been working since some time on an UFaceKit-Implementation for QT. Today I invested some time to implement features to render the AddressBook-Application i showed you in my &lt;a href="http://tom-eclipse-dev.blogspot.com/2009/01/pimp-your-application-l-with-ufacekit.html"&gt;last blog entry&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Below is the application rendered using the CleanlooksStyle on MacOSX:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_cWFEe8uui9o/SXE5NtMCa0I/AAAAAAAAAGU/8RQxJTeJOZ8/s1600-h/screen.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 364px;" src="http://4.bp.blogspot.com/_cWFEe8uui9o/SXE5NtMCa0I/AAAAAAAAAGU/8RQxJTeJOZ8/s400/screen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5292073944768211778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The only change to the code I showed you last week is how the application is launched. &lt;br /&gt;For SWT the launcher looks like this:&lt;pre&gt;public class Launcher {&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;    final Display display = new Display();&lt;br /&gt;&lt;br /&gt;    Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {&lt;br /&gt;      public void run() {&lt;br /&gt;        JFaceFactory factory = new JFaceFactory();&lt;br /&gt;        Workbench workbench = new Workbench(factory);&lt;br /&gt;        workbench.open();&lt;br /&gt;&lt;br /&gt;        while( ! workbench.isDisposed() ) {&lt;br /&gt;          if( ! display.readAndDispatch() ) {&lt;br /&gt;            display.sleep();&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And for QT:&lt;pre&gt;public class Launcher {&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;    QApplication.initialize(new String[0]);&lt;br /&gt;    QApplication.setStyle(new QCleanlooksStyle());&lt;br /&gt;    &lt;br /&gt;    Realm.runWithDefault(QTObservables.getRealm(), new Runnable() {&lt;br /&gt;      public void run() {&lt;br /&gt;        QTFactory factory = new QTFactory();&lt;br /&gt;        Workbench workbench = new Workbench(factory);&lt;br /&gt;        workbench.open();&lt;br /&gt;        QApplication.exec();&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And now with styles applied the whole application looks like this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/SXE7MmRDeFI/AAAAAAAAAGc/PZDuhXC_YuA/s1600-h/screen.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/SXE7MmRDeFI/AAAAAAAAAGc/PZDuhXC_YuA/s400/screen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5292076124753590354" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm still in the process to make myself familiar with the QT-API and how I'm supposed to use and implement certain functions. Even if you don't want to use our UFaceKit-API the work we are doing here is interesting to you probably because we provide for example QTObservables for use with Eclipse-Databinding and a Combo/List/Table/Tree-Viewer implementation for QT-Controls.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;UFaceKit Dokuware&lt;/h2&gt;I was asked to provide instructions how to get the applications I show in my blog running the locally and play with them. I've opened a new section in the &lt;a href="http://wiki.eclipse.org/UFaceKit"&gt;Eclipse-Wiki&lt;/a&gt; holding all informations about our project - outlining our goals, instructions how to get the current code base running, and hopefully much more information soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-7593960697340297359?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/7593960697340297359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=7593960697340297359' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7593960697340297359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7593960697340297359'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2009/01/getting-started-with-ufacekit-and-qt.html' title='Getting started with UFaceKit and QT'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_cWFEe8uui9o/SXE5NtMCa0I/AAAAAAAAAGU/8RQxJTeJOZ8/s72-c/screen.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-8309773084020352719</id><published>2009-01-14T01:32:00.009+01:00</published><updated>2009-01-14T03:09:53.434+01:00</updated><title type='text'>Pimp your application L&amp;F with UFaceKit</title><content type='html'>Does your application look like this or hopefully a bit better than this really ugly example?&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/SW01CAV39yI/AAAAAAAAAFs/4r8H6C5a_CQ/s1600-h/screenshot_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/SW01CAV39yI/AAAAAAAAAFs/4r8H6C5a_CQ/s400/screenshot_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5290943445797959458" /&gt;&lt;/a&gt;&lt;br /&gt;Making applications look nice and still not cluttering your code with these theming informations is something not provided out of the box by Eclipse. Still the situation is changing since the E4-Team is working on "native" SWT-CSS integration (&lt;a href="http://dev.eclipse.org/blogs/kevinmcguire/2009/01/08/e4-css-working-example/"&gt;Kevin McGuire&lt;/a&gt; and &lt;a href="http://www.toedter.com/blog/?p=31"&gt;Kai Tödter&lt;/a&gt;) - if I'm not mistaken the code should in theory also work in 3.x.&lt;br /&gt;&lt;br /&gt;But besides E4 there's another project called &lt;a href="http://www.eclipse.org/ufacekit/"&gt;UFaceKit&lt;/a&gt; which provides a high-level widget-toolkit API (the application above is written with UFaceKit in about ~250 Lines of code) and part of this high-level abstraction is direct support for Declarative-Styleing.&lt;br /&gt;&lt;br /&gt;Let's at first take a look at the above application. I've split it into 3 Classes:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://dev.eclipse.org/svnroot/eclipse/org.eclipse.ufacekit/examples/org.eclipse.ufacekit.example.ui.workbench/src/org/eclipse/ufacekit/example/ui/workbench/Workbench.java"&gt;Workbench.java&lt;/a&gt;: Creates the workbench and the TabFolder&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/SW07i1BIGVI/AAAAAAAAAF8/Dr4TreMn7lc/s1600-h/workbench.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 219px;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/SW07i1BIGVI/AAAAAAAAAF8/Dr4TreMn7lc/s400/workbench.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5290950606763596114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://dev.eclipse.org/svnroot/eclipse/org.eclipse.ufacekit/examples/org.eclipse.ufacekit.example.ui.parts/src/org/eclipse/ufacekit/example/ui/parts/ContactsPart.java"&gt;ContactsPart.java&lt;/a&gt;: Creates the Content shown in the Contacts-TabItem&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_cWFEe8uui9o/SW06bt4s4sI/AAAAAAAAAF0/ehIESTCnux8/s1600-h/contacts.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 141px;" src="http://2.bp.blogspot.com/_cWFEe8uui9o/SW06bt4s4sI/AAAAAAAAAF0/ehIESTCnux8/s400/contacts.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5290949385078497986" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://dev.eclipse.org/svnroot/eclipse/org.eclipse.ufacekit/examples/org.eclipse.ufacekit.example.ui.parts/src/org/eclipse/ufacekit/example/ui/parts/DetailsPart.java"&gt;DetailsPart.java&lt;/a&gt;: Creates the Content shown in the Details-TabItem&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_cWFEe8uui9o/SW07sbMHkrI/AAAAAAAAAGE/PXl7ibw5NmI/s1600-h/details.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 247px;" src="http://4.bp.blogspot.com/_cWFEe8uui9o/SW07sbMHkrI/AAAAAAAAAGE/PXl7ibw5NmI/s400/details.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5290950771629068978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;When coding with UFaceKit and you choose to use the SWT-Implementation (we also provide Swing and QT though SWT is the most stable and feature rich) you get the native platform L&amp;F (as you see above) but the application is not really visually appealing. &lt;br /&gt;&lt;br /&gt;If you don't have support for declarative styling you'd now have to clutter your code with themeing informations (e.g. setting background-colors, ...) and your code is soon getting unmaintainable. The Web-Guys already found this out for a while and invented CascadingStyleSheets (CSS). So why not learning from them and bring CSS (I more like the term Declarative-Styleing) to the world of Java-Desktops. &lt;br /&gt;&lt;br /&gt;As mentionned before the E4-Team is working on CSS support and so does UFaceKit but this is not the only thing. UFaceKit abstracts styling support and you can plug-in your own declarative syntax. Out of the box we support:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;CSS: Like you know it from Web-Development. We currently don't support all features from CSS2 but only the most important ones&lt;/li&gt;&lt;br /&gt;&lt;li&gt;USML: &lt;b&gt;U&lt;/b&gt;FaceKit&lt;b&gt;S&lt;/b&gt;tyling&lt;b&gt;M&lt;/b&gt;arkup&lt;b&gt;L&lt;/b&gt;anguage is a very simply XML-Definition for css-like styles which has the adavantage that it doesn't add any dependencies like CSS-Support does&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;As state we don't suppport all features CSS2 defines but a subset of the most important things:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;ID-Definitions like #myelement { }&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Class-Definitions like .mylabel { }&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Element-Definitions like UILabel { }&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for pseudo-Attributes like :hover, :focus&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for attribute-selectors like .mylabel[@value &gt;= 10]&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Let's see what we can achieve by adding this styling support our application.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/SW1ENWcs6ZI/AAAAAAAAAGM/Flyy8CynyyY/s1600-h/screenshot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/SW1ENWcs6ZI/AAAAAAAAAGM/Flyy8CynyyY/s400/screenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5290960133385152914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Amazing isn't it? No single line of application code has changed between those screenshots! As you might noticed I've used &lt;a href="http://www.toedter.com/blog/?p=31"&gt;Kai Tödters&lt;/a&gt; E4-Example application as master and the data is backed up in XMI useing the EMF-Toolchain.&lt;br /&gt;&lt;br /&gt;What can you expect in future from UFaceKit:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Working on better support for Swing (many Styling things are missing)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Working on better support for QT (some styling and control things are missing)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Finishing implementation of current API functions&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Adding JUnit-Test, ... &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Declarative Syntax to describe and visual design your UI using EMF&lt;/li&gt;&lt;br /&gt;&lt;li&gt;...&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;As you see there's much work that needs to be done and if you are interested in helping out you are more than welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-8309773084020352719?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/8309773084020352719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=8309773084020352719' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8309773084020352719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8309773084020352719'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2009/01/pimp-your-application-l-with-ufacekit.html' title='Pimp your application L&amp;F with UFaceKit'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_cWFEe8uui9o/SW01CAV39yI/AAAAAAAAAFs/4r8H6C5a_CQ/s72-c/screenshot_2.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-3403884551648391973</id><published>2009-01-08T21:19:00.008+01:00</published><updated>2009-01-08T23:39:41.993+01:00</updated><title type='text'>Where do you go (JFace)Viewers</title><content type='html'>&lt;h2&gt;The presence&lt;/H2&gt;&lt;br /&gt;Today I thought about a problem of JFace-Viewers when it comes to clever memory management like it is provided for example by CDO. CDO has a very clever memory management concept where objects are swapped out of the memory if they are not referenced in application code. &lt;br /&gt;&lt;br /&gt;When using CDO in conjunction with JFace-Viewers this concept doesn't work because JFace-Viewers restore the model element into the TableItem/TreeItem-data-slot and so CDOs clever memory management is not working and the whole model resides in memory. &lt;br /&gt;&lt;br /&gt;Inspired by Ed's efforts to minimize the memory footprint of EObject (see &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=252501"&gt;bug 252501&lt;/a&gt;), I started to think how we could improve on the other side of the fence. I've started today implementing a set of specialized viewer classes which makes it possible for you to take advantage of the clever memory management supplied for example by CDO.&lt;br /&gt;&lt;br /&gt;The idea is simple. Instead of restoring the real object in the viewer the object gets translated into a key value (in case of CDO it could the a CDOID) and so CDO can free memory ASAP. The code is available from the &lt;a href="http://dev.eclipse.org/svnroot/eclipse/org.eclipse.ufacekit/bundles/incubation/org.eclipse.ufacekit.incubation/org.eclipse.ufacekit.ui.jface/org.eclipse.ufacekit.ui.jface.util/"&gt;UFaceKit-Repository&lt;/a&gt; because the scope of &lt;a href="http://www.eclipse.org/ufacekit/"&gt;UFaceKit&lt;/a&gt; is also to provide higherlevel utilities for current Eclipse-Technologies beside inventing it's own high-level API.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The future&lt;/h2&gt;&lt;br /&gt;The Viewer-Concept provided by JFace for StructuredControls (Combo, List, Table, Tree, TreeTable) is one of the most used concept in Eclipse-Applications and although they are very powerful and we fixed many deficiencies we could provide much better useablility and user experience in E4. &lt;br /&gt;&lt;br /&gt;Some of them coming to my mind are:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;No Toolkit-Independence we can only target SWT like controls&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Usage of Java5 generics&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Multiple different APIs to achieve solve a problem&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Problem with memory intensive models&lt;/li&gt;&lt;br /&gt;&lt;li&gt;(Fill in your favorite problem)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;If you are a regular reader of my blog you know that in my UFaceKit-Project I've already written a JFace-Viewer like implementation for other widget toolkits (QT, Swing). I've today restarted think whether this would be a good thing for E4 in general and so I filed &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=260451"&gt;bug 260451&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'd like to see Eclipse-Viewer getting a project like Eclipse-Databinding which is split into a general and toolkit specific part and integrate itself seamless into the concepts provided by Eclipse-Databinding. I'd invite all of you to take part in a renewed implementation of the viewer concept by adding yourself to &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=260451"&gt;bug 260451&lt;/a&gt; and take part in the design discussion hopefully takeing place there.&lt;br /&gt;&lt;br /&gt;The intial list of points I'd mentionned in the bug are:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Cross-Toolkit like Eclipse-Databinding I'd like to see Viewers getting split&lt;br /&gt;a Toolkit-Neutral and Toolkit-Specific API so that implementation for e.g.&lt;br /&gt;Swing, QT, ... can be created.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Better support for big model graphs (e.g. better support for CDO) (see &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=260422"&gt;bug&lt;br /&gt;260422&lt;/a&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Revised inline editing&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Direct-Databinding support&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Builtin support Async-Programming (see &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=253777"&gt;bug 253777&lt;/a&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for Java5-Generics&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Builtin databinding support (e.g. a Viewer could direclty implement the&lt;br /&gt;IObservableValue interface)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-3403884551648391973?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/3403884551648391973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=3403884551648391973' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3403884551648391973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3403884551648391973'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2009/01/where-do-you-go-jface.html' title='Where do you go (JFace)Viewers'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-5734645196545360002</id><published>2008-11-21T11:49:00.006+01:00</published><updated>2008-11-21T14:00:07.616+01:00</updated><title type='text'>Back from ESE</title><content type='html'>I'm back in reality and just recap what happened the last 4 days.&lt;br /&gt;&lt;h2&gt;My talks&lt;/h2&gt;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)&lt;br /&gt;&lt;h3&gt;E4 - Modeling the workbench&lt;/h3&gt;I think I never talked to so many people ever before because I did my presentation in the biggest room available.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/SSaX4TRTbhI/AAAAAAAAADw/Xu-JFbWz6sU/s1600-h/DSC_3650_small.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 268px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/SSaX4TRTbhI/AAAAAAAAADw/Xu-JFbWz6sU/s400/DSC_3650_small.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5271067407385062930" /&gt;&lt;/a&gt;I think I got the message around what the &lt;a href="http://wiki.eclipse.org/E4"&gt;E4 project&lt;/a&gt; is about and in particular what the subtask-team I'm in is doing. The first &lt;a href="http://eclipse.dzone.com/articles/single-sourcing-agility-and-os"&gt;reviews&lt;/a&gt; tell me that I didn't fail but I look forward for more comments.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/SSaYFmvijZI/AAAAAAAAAD4/5QYMivtL9Yc/s1600-h/DSC_3656_small.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 268px; height: 400px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/SSaYFmvijZI/AAAAAAAAAD4/5QYMivtL9Yc/s400/DSC_3656_small.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5271067635950456210" /&gt;&lt;/a&gt;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 &lt;a href="https://dev.eclipse.org/mailman/listinfo/e4-dev"&gt;E4-Mailing&lt;/a&gt; list.&lt;h3&gt;Datacentric RCP with EMF and Databinding&lt;/h3&gt;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.&lt;br /&gt; &lt;br /&gt;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.&lt;br /&gt; &lt;br /&gt;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 &lt;a href="http://ed-merks.blogspot.com/2008/11/eclipse-summit-europe-2008-day-two.html"&gt;Ed Merks blog&lt;/a&gt; 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. &lt;br /&gt;&lt;br /&gt;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.&lt;h3&gt;Conclusion&lt;/h3&gt;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. &lt;br /&gt;&lt;br /&gt;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:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;E4-Modeling the workbench: &lt;a href="https://www.gpublication.com/eclipse/#requestedContent=contentID://EclipseConferences/ESE2008/205"&gt;here&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Datacentric RCP: &lt;a href="https://www.gpublication.com/eclipse/#requestedContent=contentID://EclipseConferences/ESE2008/48"&gt;here&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; 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.&lt;br /&gt;&lt;br /&gt;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) &lt;a href="http://www.bestsolution.at/"&gt;my company&lt;/a&gt; is offering consultancy and development resources to anyone interested.&lt;h2&gt;The E4 symposia&lt;/h2&gt;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 &lt;a href="http://blip.tv/file/1485080"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;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.&lt;h2&gt;Socializing&lt;/h2&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-5734645196545360002?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/5734645196545360002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=5734645196545360002' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5734645196545360002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5734645196545360002'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/11/back-from-ese.html' title='Back from ESE'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_cWFEe8uui9o/SSaX4TRTbhI/AAAAAAAAADw/Xu-JFbWz6sU/s72-c/DSC_3650_small.JPG' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-7121253335896609357</id><published>2008-11-04T14:15:00.002+01:00</published><updated>2008-11-04T14:41:35.266+01:00</updated><title type='text'>Rotating Image in a PaintListener</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;h2&gt;Exercise&lt;/h2&gt;Draw an Image at Point(50,50) in a Canvas which is rotated a variable angle.&lt;br /&gt;&lt;h2&gt;The solution&lt;/h2&gt;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.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public void paintControl(PaintEvent e) {&lt;br /&gt;  GC gc = e.gc;&lt;br /&gt;  gc.setAdvanced(true);&lt;br /&gt;  &lt;br /&gt;  Bounds b = image.getBounds();&lt;br /&gt;&lt;br /&gt;  Transform transform = new Transform(display);&lt;br /&gt;  // The rotation point is the center of the image&lt;br /&gt;  transform.translate(50 + b.width/2, 50 + b.height/2);&lt;br /&gt;  // Rotate&lt;br /&gt;  transform.rotate(45);&lt;br /&gt;  // Back to the orginal coordinate system&lt;br /&gt;  transform.translate(-50 - b.width/2, -50 - b.height/2);&lt;br /&gt;  gc.setTransform(transform);&lt;br /&gt;  gc.drawImage(image, 50, 50);&lt;br /&gt;  transform.dispose();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;h2&gt;Is the solution right? Is there a better solution?&lt;/h2&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-7121253335896609357?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/7121253335896609357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=7121253335896609357' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7121253335896609357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7121253335896609357'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/11/rotating-image-in-paintlistener.html' title='Rotating Image in a PaintListener'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-8081904061161922926</id><published>2008-10-27T21:50:00.004+01:00</published><updated>2008-10-27T22:18:32.753+01:00</updated><title type='text'>News about UFacekit</title><content type='html'>There are some important news I'd like to share with all of you:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;1. UFacekit Proposal&lt;/h2&gt;&lt;br /&gt;The &lt;a href="http://www.eclipse.org/proposals/ufacekit/"&gt;proposal&lt;/a&gt; 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 &lt;a href="http://www.eclipse.org/newsportal/thread.php?group=eclipse.ufacekit"&gt;newsgroup&lt;/a&gt;. Share your wishes, critism with us so that we can make UFacekit a success.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;2. QT-Port&lt;/h2&gt;&lt;br /&gt;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, ...).&lt;br /&gt;&lt;br /&gt;So we now have:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Support for SWT/JFace&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/SQYsuXeBBpI/AAAAAAAAADY/1F4MyOdF3KY/s1600-h/SWT.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 287px;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/SQYsuXeBBpI/AAAAAAAAADY/1F4MyOdF3KY/s400/SWT.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5261942389714519698" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for Swing&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/SQYs3fnhEEI/AAAAAAAAADg/FKAlbZhjLwo/s1600-h/Swing.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/SQYs3fnhEEI/AAAAAAAAADg/FKAlbZhjLwo/s400/Swing.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5261942546520674370" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for QT (Cleanlooks Style)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/SQYtDa4v5uI/AAAAAAAAADo/SRlUirOKVjg/s1600-h/QT.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 293px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/SQYtDa4v5uI/AAAAAAAAADo/SRlUirOKVjg/s400/QT.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5261942751409202914" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Platforms I'd like to see a port in future:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;GWT - is going to be revived soon by one of the team-members&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;GXT&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Other UI-Toolkits based upon GWT&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Eclipse-Forms - Should be fairly easy to do&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Platforms I dream of a port in future:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Draw2d&lt;/li&gt;&lt;br /&gt;&lt;li&gt;OpenGL&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-8081904061161922926?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/8081904061161922926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=8081904061161922926' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8081904061161922926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8081904061161922926'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/10/news-about-ufacekit.html' title='News about UFacekit'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_cWFEe8uui9o/SQYsuXeBBpI/AAAAAAAAADY/1F4MyOdF3KY/s72-c/SWT.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-1180786354100025323</id><published>2008-10-24T02:38:00.005+02:00</published><updated>2008-10-24T03:03:08.802+02:00</updated><title type='text'>There's no place where Eclipse-Databinding doesn't work</title><content type='html'>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.&lt;br /&gt;Here's the application:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_cWFEe8uui9o/SQEa2jiEmHI/AAAAAAAAADI/roj7aVo6ols/s1600-h/Screen_1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 221px; height: 400px;" src="http://2.bp.blogspot.com/_cWFEe8uui9o/SQEa2jiEmHI/AAAAAAAAADI/roj7aVo6ols/s400/Screen_1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5260515364298856562" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/SQEbCGPZVYI/AAAAAAAAADQ/jXAr-dF1ujQ/s1600-h/Screen_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 234px; height: 400px;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/SQEbCGPZVYI/AAAAAAAAADQ/jXAr-dF1ujQ/s400/Screen_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5260515562594325890" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The model code looks like this (I'm using UBeans here because they are completely self contained and have no dependencies)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; private static class Person extends UBean {&lt;br /&gt;  public static final int NAME = 1;&lt;br /&gt;&lt;br /&gt;  public String getName() {&lt;br /&gt;   return (String) get(NAME);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setName(String name) {&lt;br /&gt;   set(NAME, name);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public Object getValueType(int featureId) {&lt;br /&gt;   return String.class;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; };&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The UI-Code looks like this (fairly straight forward UI-Code):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;        TextView view = new TextView(this);&lt;br /&gt;        view.setText("Name: ");&lt;br /&gt;        TableLayout layout = new TableLayout(this);&lt;br /&gt;        layout.addView(view);&lt;br /&gt;&lt;br /&gt;        EditText text = new EditText(this);&lt;br /&gt;        layout.addView(text);&lt;br /&gt;&lt;br /&gt;        Button button = new Button(this);&lt;br /&gt;        button.setText("Say Hello");&lt;br /&gt;        button.setOnClickListener(new OnClickListener() {&lt;br /&gt;&lt;br /&gt;   public void onClick(View v) {&lt;br /&gt;    Dialog dialog = new Dialog(Test.this);&lt;br /&gt;    dialog.setTitle("Hello " + p.getName() + "!");&lt;br /&gt;    dialog.show();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;        });&lt;br /&gt;        layout.addView(button);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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 :-).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;        IObservableValue mObs = UBeansObservables.observeValue(realm, p, Person.NAME);&lt;br /&gt;        IObservableValue uiObs = AndroidObservables.observeText(realm, text);&lt;br /&gt;        DataBindingContext ctx = new DataBindingContext(realm);&lt;br /&gt;        ctx.bindValue(uiObs, mObs, null, null);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Cool isn't it? Would a Eclipse-Databinding port for Android help you? Then take a look at the newly proposed Eclipse-Project &lt;a href="http://www.eclipse.org/proposals/ufacekit/"&gt;UFacekit&lt;/a&gt;. 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?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-1180786354100025323?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/1180786354100025323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=1180786354100025323' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1180786354100025323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1180786354100025323'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/10/theres-no-place-where-eclipse.html' title='There&apos;s no place where Eclipse-Databinding doesn&apos;t work'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_cWFEe8uui9o/SQEa2jiEmHI/AAAAAAAAADI/roj7aVo6ols/s72-c/Screen_1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-713260678869407519</id><published>2008-10-19T23:13:00.004+02:00</published><updated>2008-10-19T23:41:06.617+02:00</updated><title type='text'>Update on UFacekit</title><content type='html'>&lt;h2&gt;UFacekit has a new source structure&lt;/h2&gt;&lt;br /&gt;We have restructured the repository to clearly separate our modules into:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;proper:&lt;br/&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;incubation:&lt;br/&gt;&lt;br /&gt;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!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;dormant:&lt;br/&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;The layout is taken from the Apache-Jakrata project.&lt;br /&gt;&lt;h2&gt;UFacekit has an QT-Port&lt;/h2&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;h2&gt;UFacekit has a build story&lt;/h2&gt;&lt;br /&gt;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. &lt;br /&gt;We are not using PDE-build or any Eclipse-specific things because this would  interfere with an important UFacekit-target:&lt;br /&gt;"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.&lt;br /&gt;&lt;br /&gt;The process e.g. for the proper-modules is like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;svn co http://uface.googlecode.com/svn/trunk/proper/&lt;br /&gt;cd proper&lt;br /&gt;cd org.ufacekit&lt;br /&gt;mvn clean install&lt;br /&gt;mvn eclipse:eclipse&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Afterwards fire up eclipse and import the modules. Done. Kenneth you are my king.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-713260678869407519?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/713260678869407519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=713260678869407519' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/713260678869407519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/713260678869407519'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/10/update-on-ufacekit.html' title='Update on UFacekit'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-6784641168660876109</id><published>2008-10-08T18:23:00.002+02:00</published><updated>2008-10-08T18:43:20.210+02:00</updated><title type='text'>Disable parts SWT-Table/Tree with SWT.CHECK</title><content type='html'>&lt;b&gt;This is a hack, a hack, a hack posting.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I have read many many entries on the newsgroups asking a question like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;How can I disable certain check boxes in an SWT-Tree/Table. Is this possible?&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;The tree looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;+ Application 1&lt;br /&gt;  + Privilege A&lt;br /&gt;    + Privileg A1&lt;br /&gt;  + Privilege B&lt;br /&gt;    + Privileg B2&lt;br /&gt;+ Application 1&lt;br /&gt;  + Privileg C&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The values bound are the ones in Privileg* so I have to lock the Application-checkboxes&lt;br /&gt;&lt;br /&gt;The setup is something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Databinding ctx = ....&lt;br /&gt;IObservableSet mObs = ....&lt;br /&gt;&lt;br /&gt;Tree tree = new Tree(parent,SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);&lt;br /&gt;CheckBoxTreeViewer v = new CheckBoxTreeViewer(tree);&lt;br /&gt;IObservableSet uiOs = ViewerObservables.observeCheckedElements(v,IPrivileges.class);&lt;br /&gt;ctx.bindSet(uiObs,mObs,null,null);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I nearly gave up but then I had the following idea.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;final Tree tree = new Tree(parent,SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);&lt;br /&gt;// Attach a listener directly after the creation&lt;br /&gt;tree.addListener(SWT.Selection,new Listener() {&lt;br /&gt;   public void handleEvent(Event event) {&lt;br /&gt;       if( event.detail == SWT.CHECK ) {&lt;br /&gt;           if( !(event.item.getData() instanceof IPrivileg) ) {&lt;br /&gt;              event.detail = SWT.NONE;&lt;br /&gt;              event.type   = SWT.None;&lt;br /&gt;              event.doIt   = false;&lt;br /&gt;              try {&lt;br /&gt;                 tree.setRedraw(false);&lt;br /&gt;                 TreeItem item = (TreeItem)tree.item;&lt;br /&gt;                 item.setChecked(! item.getChecked() );&lt;br /&gt;              } finally {&lt;br /&gt;                 tree.setRedraw(true);&lt;br /&gt;              }&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;CheckBoxTreeViewer v = new CheckBoxTreeViewer(tree);&lt;br /&gt;// ....&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-6784641168660876109?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/6784641168660876109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=6784641168660876109' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/6784641168660876109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/6784641168660876109'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/10/disable-parts-swt-tabletree-with.html' title='Disable parts SWT-Table/Tree with SWT.CHECK'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-3634957269479590068</id><published>2008-09-22T21:27:00.004+02:00</published><updated>2008-09-22T22:47:03.611+02:00</updated><title type='text'>JFace-Viewers for Swing, is this possible?</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;0. The background&lt;/h2&gt;&lt;br /&gt;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)?&lt;br /&gt;&lt;br /&gt;In last few days I worked on &lt;a href="http://wiki.eclipse.org/Incubator/Platform/UFacekit"&gt;UFacekit's&lt;/a&gt; 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?&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;h2&gt;1. Extracted an Widget-Toolkit-Neutral API from JFace&lt;/h2&gt;&lt;br /&gt;... moved it to a new plugin (&lt;a href="http://uface.googlecode.com/svn/trunk/org.ufacekit.ui.viewers/"&gt;org.ufacekit.ui.viewers&lt;/a&gt;). 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.&lt;br /&gt;&lt;br /&gt;A content provider now looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;IContentProvider&amp;lt;Person,Collection&amp;lt;Person&gt;&gt; cp = &lt;br /&gt;   new IContentProvider&amp;lt;Person,Collection&amp;lt;Person&gt;&gt; {&lt;br /&gt;      // ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and a collection can get iterated with a foreach-loop&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;for( Person p: v.getSelection() ) {&lt;br /&gt;   // ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I rearranged some other classes and made interfaces from most of them, ... . So now I have a widget-toolkit-clean Viewer-API.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;2. Copied some SWT-Classes (Widget, Table, TableItem, Tree, ...)&lt;/h2&gt;&lt;br /&gt;... 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) )&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;3. Commented some JFace-code not needed to provide the minimum JFace-API&lt;/h2&gt;&lt;br /&gt;... 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. &amp;amp; 3. are hidden from the user because all these are internal classes so I can replace them step by step.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;4. Blog how nicely now I can setup a TreeTableViewer for Swing&lt;/h2&gt;&lt;br /&gt;(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)&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@Override&lt;br /&gt;protected Component createUI(JFrame frame, List&amp;lt;Person&gt; model) {&lt;br /&gt;  JXTreeTable tree = new JXTreeTable();&lt;br /&gt;&lt;br /&gt;  TableColumnExt c1 = new TableColumnExt(1);&lt;br /&gt;  c1.setHeaderValue("Givenname");&lt;br /&gt;  c1.setWidth(200);&lt;br /&gt;  tree.getColumnModel().addColumn(c1);&lt;br /&gt;&lt;br /&gt;  TableColumnExt c2 = new TableColumnExt(1);&lt;br /&gt;  c2.setHeaderValue("Surname");&lt;br /&gt;  c2.setWidth(200);&lt;br /&gt;  tree.getColumnModel().addColumn(c2);&lt;br /&gt;&lt;br /&gt;  JScrollPane scroll = new JScrollPane(tree);&lt;br /&gt;&lt;br /&gt;  TreeTableViewer&amp;lt;Person, Collection&amp;lt;Person&gt;&gt; viewer = &lt;br /&gt;     new TreeTableViewer&amp;lt;Person, Collection&amp;lt;Person&gt;&gt;(tree);&lt;br /&gt;  viewer.addSelectionChangedListener(&lt;br /&gt;    new ISelectionChangedListener&amp;lt;Person&gt;() {&lt;br /&gt;      public void selectionChanged(SelectionChangedEvent&amp;lt;Person&gt; event) {&lt;br /&gt;        for( Person p: event.getSelection() ) {&lt;br /&gt;          System.out.println(p);&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;  TreeViewerColumn&amp;lt;Person&gt; c = new TreeViewerColumn&amp;lt;Person&gt;(viewer,c1);&lt;br /&gt;  c.setLabelProvider(new LabelConverter&amp;lt;Person&gt;() {&lt;br /&gt;    @Override&lt;br /&gt;    public String getText(Person element) {&lt;br /&gt;      return element.getGivenname();&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;  c = new TreeViewerColumn&amp;lt;Person&gt;(viewer,c2);&lt;br /&gt;  c.setLabelProvider(new LabelConverter&amp;lt;Person&gt;() {&lt;br /&gt;    @Override&lt;br /&gt;    public String getText(Person element) {&lt;br /&gt;      return element.getSurname();&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;  viewer.setContentProvider(&lt;br /&gt;    new ITreeContentProvider&amp;lt;Person,Collection&amp;lt;Person&gt;&gt;() {&lt;br /&gt;      public Collection&amp;lt;Person&gt; getChildren(Person parentElement) {&lt;br /&gt;        return parentElement.getChildren();&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public Person getParent(Person element) {&lt;br /&gt;        return element.getParent();&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public boolean hasChildren(Person element) {&lt;br /&gt;        return ((Person)element).getChildren().size() &gt; 0;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public Collection&amp;lt;Person&gt; getElements(Collection&amp;lt;Person&gt; inputElement) {&lt;br /&gt;        return inputElement;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public void dispose() {&lt;br /&gt;        // TODO Auto-generated method stub&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public void inputChanged(IViewer&amp;lt;Person, Collection&amp;lt;Person&gt;&gt; viewer, &lt;br /&gt;        Collection&amp;lt;Person&gt; oldInput,&lt;br /&gt;        Collection&amp;lt;Person&gt; newInput) {&lt;br /&gt;          // TODO Auto-generated method stub&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;  viewer.setInput(model);&lt;br /&gt;  return scroll;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;5. Summary&lt;/h2&gt;&lt;br /&gt;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 &lt;a href="http://uface.googlecode.com/svn/trunk/org.ufacekit.ui.swing.jface/"&gt;swing-jface-bundle&lt;/a&gt; standalone because it has no dependency at all (besides the one on &lt;a href="http://uface.googlecode.com/svn/trunk/org.ufacekit.ui.viewers/"&gt;org.ufacekit.ui.viewers&lt;/a&gt;).&lt;br /&gt;&lt;h2&gt;6. So am I now?&lt;/h2&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;input type="radio"&gt;Completely Crazy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;input type="radio"&gt;Fairly Crazy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;input type="radio"&gt;A bit Crazy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;input type="radio"&gt;Fairly normal if you know me and all the &lt;a href="http://tom-eclipse-dev.blogspot.com/2008/05/radical-approach-to-explore-new-paths.html"&gt;crazy ideas&lt;/a&gt; I already had&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-3634957269479590068?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/3634957269479590068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=3634957269479590068' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3634957269479590068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3634957269479590068'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/09/jface-viewers-for-swing-is-this.html' title='JFace-Viewers for Swing, is this possible?'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-7550738897391604042</id><published>2008-09-09T09:39:00.002+02:00</published><updated>2008-09-09T10:00:40.375+02:00</updated><title type='text'>UFacekit - Proposed as a Component under Platform/Incubator</title><content type='html'>So the news is out [&lt;a href="http://dev.eclipse.org/mhonarc/lists/eclipse-dev/msg08319.html"&gt;Mailinglist&lt;/a&gt;, &lt;a href="http://www.eclipse.org/newsportal/article.php?id=77610&amp;group=eclipse.platform#77610"&gt;Newsgroups&lt;/a&gt;]. UFacekit is proposed as a Component under Platform/Incubator project (&lt;a href="http://wiki.eclipse.org/Incubator/Platform/UFacekit"&gt;proposal&lt;/a&gt;). I think this is the right move for UFacekit to gather momentum towards our first release. If you want to support this move:&lt;ol&gt;&lt;li&gt;Comment on the following newsgroup &lt;a href="http://www.eclipse.org/newsportal/article.php?id=77610&amp;group=eclipse.platform#77610"&gt;post&lt;/a&gt; from Boris&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Add yourself/company as an interested party on the &lt;a href="http://wiki.eclipse.org/Incubator/Platform/UFacekit"&gt;proposal page&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;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, ... .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-7550738897391604042?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/7550738897391604042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=7550738897391604042' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7550738897391604042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7550738897391604042'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/09/ufacekit-proposed-as-component-under.html' title='UFacekit - Proposed as a Component under Platform/Incubator'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-5721026519818698344</id><published>2008-09-03T16:19:00.008+02:00</published><updated>2008-09-04T01:35:02.428+02:00</updated><title type='text'>Exploring new technologies part of Ganymede-Release Train</title><content type='html'>I took myself some time the last days exploring new technologies available with Ganymede 3.4:&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Eclipse-Databinding and its new features&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;EMF-Databinding (Provisional but working very smoothly)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Teneo: Persist your model via hibernate in a SQL-Database&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;CDO: Share your model between different clients and persist it into an SQL-Database (with Revision support)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;New Extension Points to enhance the Expression Framework&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Spring &amp; OSGi&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;P2 to install the Products using the P2-Agent&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;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).&lt;br /&gt;&lt;br /&gt;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:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Nice L&amp;F (as good as I can make an UI Look without a designer)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Plugable storage technology&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Undo/Redo Support&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; 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:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;How to create an EditingDomain myself when not using the generated editor-classes from EMF?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;How to use the new org.eclipse.ui.services-Extension point to enhance the expression framework?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Best strategy to use Extension Points when bundles are installed/uninstalled/updated while the application is running&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;So the immediate output of my work was that 2 bugs [&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=239015"&gt;239015&lt;/a&gt;, &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=245183"&gt;245183&lt;/a&gt;] in Eclipse-Databinding got fixed in 3.4.1.&lt;br /&gt;&lt;br /&gt;The longterm output for me is:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;I now have a good picture how our next technology stack looks like&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I have an example application (I will add other things in the next weeks) to teach my co-workers the technologies&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I had a lot of fun (besides struggeling with P2)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;The longterm output for &lt;b&gt;you&lt;/b&gt; is:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;You have a small application showing you a lot of different concepts around RCP+EMF+Databinding applications&lt;ul&gt;&lt;br /&gt;&lt;li&gt;EMF-Ecore&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Usage/Creation of your own Extension Points&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using EditingDomain outside the scope of EMF-Generated artefacts&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using Teneo&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using CDO&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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, ...&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;This is the application:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/SL6zsYD5R7I/AAAAAAAAAC4/W2upas6EIyY/s1600-h/screen.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/SL6zsYD5R7I/AAAAAAAAAC4/W2upas6EIyY/s400/screen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5241824591260239794" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you want to run it locally get a copy of the &lt;a href="http://download.eclipse.org/eclipse/equinox/drops/R-3.4-200806172000/index.php"&gt;P2-Agent&lt;/a&gt; and point the metadata repository and artifacts repository to this &lt;a href="http://publicsvn.bestsolution.at/repos/java/examples/EMF-Databinding/releases/1.0.0/client-repository/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To use the CDO-Version you also need a server component which can be installed when pointing the agent to this &lt;a href="http://publicsvn.bestsolution.at/repos/java/examples/EMF-Databinding/releases/1.0.0/server-repository/"&gt;location&lt;/a&gt;. 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 &lt;a href="http://publicsvn.bestsolution.at/repos/java/examples/EMF-Databinding/at.bestsolution.soccer.server.cdo/configuration/cdo-server.xml"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_cWFEe8uui9o/SL62n_TmmxI/AAAAAAAAADA/66QX7IcJiLU/s1600-h/Screen.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_cWFEe8uui9o/SL62n_TmmxI/AAAAAAAAADA/66QX7IcJiLU/s400/Screen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5241827814430645010" /&gt;&lt;/a&gt;&lt;br /&gt;The repository name in the above config "CDO-1" has to be the id of the CDO-Configuration you create in your application.&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://publicsvn.bestsolution.at/repos/java/examples/EMF-Databinding/project/psf/"&gt;here&lt;/a&gt; to check out the necessary projects.&lt;br /&gt;&lt;br /&gt;If you want to learn more about these cool technologies. I've proposed beside a talk about &lt;a href="https://www.eclipsecon.org/submissions/ese2008/view_talk.php?id=205"&gt;E4 - The new platform-ui concepts&lt;/a&gt; a &lt;a href="https://www.eclipsecon.org/submissions/ese2008/view_talk.php?id=48"&gt;talk&lt;/a&gt; about this example application on ESE.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-5721026519818698344?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/5721026519818698344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=5721026519818698344' title='33 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5721026519818698344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5721026519818698344'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/09/exploring-new-technologies-part-of.html' title='Exploring new technologies part of Ganymede-Release Train'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_cWFEe8uui9o/SL6zsYD5R7I/AAAAAAAAAC4/W2upas6EIyY/s72-c/screen.png' height='72' width='72'/><thr:total>33</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-1925520751562141360</id><published>2008-08-24T18:10:00.005+02:00</published><updated>2008-08-25T00:00:53.239+02:00</updated><title type='text'>Writing a CTreeCombo-Widget</title><content type='html'>I was working on my example RCP/EMF/Databinding application&lt;br /&gt; &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/SLGPNYduGiI/AAAAAAAAACo/_klI5vTYhAw/s1600-h/Screen_1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/SLGPNYduGiI/AAAAAAAAACo/_klI5vTYhAw/s400/Screen_1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5238125301676775970" /&gt;&lt;/a&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;What I wanted to have was a CCombo which presents a Tree like structure like this &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_cWFEe8uui9o/SLGP4djBqzI/AAAAAAAAACw/8rWJ94UWC-k/s1600-h/Screen_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_cWFEe8uui9o/SLGP4djBqzI/AAAAAAAAACw/8rWJ94UWC-k/s400/Screen_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5238126041775582002" /&gt;&lt;/a&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Before we dive into it another requirement I had was that the implementation plugs itself into the existing viewer and databinding concepts of Eclipse. &lt;br /&gt;&lt;br /&gt;So what did I do and how did it work? Well 95% of the work I had to do is C&amp;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;So if one wants to use the widget he/she has to write code like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int style = SWT.BORDER|SWT.READ_ONLY|SWT.FULL_SELECTION;&lt;br /&gt;CTreeCombo combo = new CTreeCombo(shell,style);&lt;br /&gt;&lt;br /&gt;CTreeComboItem item = new CTreeComboItem(combo,SWT.NONE);&lt;br /&gt;item.setText("Parent 1");&lt;br /&gt;&lt;br /&gt;CTreeComboItem childItem = new CTreeComboItem(item,SWT.NONE);&lt;br /&gt;childItem.setText("Child 1.1");&lt;br /&gt;&lt;br /&gt;childItem = new CTreeComboItem(item,SWT.NONE);&lt;br /&gt;childItem.setText("Child 1.2");&lt;br /&gt;&lt;br /&gt;item = new CTreeComboItem(combo,SWT.NONE);&lt;br /&gt;item.setText("Parent 2");&lt;br /&gt;&lt;br /&gt;childItem = new CTreeComboItem(item,SWT.NONE);&lt;br /&gt;childItem.setText("Child 2.1");&lt;br /&gt;&lt;br /&gt;childItem = new CTreeComboItem(item,SWT.NONE);&lt;br /&gt;childItem.setText("Child 2.2");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int style = SWT.READ_ONLY|SWT.BORDER|SWT.FULL_SELECTION&lt;br /&gt;CTreeCombo combo = new CTreeCombo(parent,style);&lt;br /&gt;&lt;br /&gt;CTreeComboViewer viewer = new CTreeComboViewer(combo);&lt;br /&gt;viewer.setLabelProvider(new LabelProviderImpl());&lt;br /&gt;viewer.setContentProvider(new ContentProviderImpl());&lt;br /&gt;viewer.setInput(input);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;If you are interested in the code of the widget or in the application to learn about:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Writing a modular RCP-Application&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using SWT, JFace and Databinding&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using EMF and EMF-Databinding&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using and creating your own Extension Points&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using and extending the Commands, Handlers and the Expression Framework&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;You can fetch the code from my companies &lt;a href="http://publicsvn.bestsolution.at/repos/java/examples/EMF-Databinding/"&gt;svn-repository&lt;/a&gt; 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 &lt;a href="http://publicsvn.bestsolution.at/repos/java/examples/EMF-Databinding/at.bestsolution.soccer.ui.common/src/at/bestsolution/soccer/ui/common/widgets/"&gt;widget&lt;/a&gt; and here for the &lt;a href="http://publicsvn.bestsolution.at/repos/java/examples/EMF-Databinding/at.bestsolution.soccer.ui.common/src/at/bestsolution/soccer/ui/common/viewers/"&gt;viewer&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-1925520751562141360?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/1925520751562141360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=1925520751562141360' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1925520751562141360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1925520751562141360'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/08/writing-ctreecombo-widget.html' title='Writing a CTreeCombo-Widget'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_cWFEe8uui9o/SLGPNYduGiI/AAAAAAAAACo/_klI5vTYhAw/s72-c/Screen_1.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-6047056970064552841</id><published>2008-06-13T15:28:00.005+02:00</published><updated>2008-06-13T17:14:39.377+02:00</updated><title type='text'>Ganymede - What's in JFace and Databinding</title><content type='html'>&lt;h2&gt;The History&lt;/h2&gt;&lt;br /&gt;&lt;h3&gt;JFace-Viewers/ToolTips&lt;/h3&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;h3&gt;Databinding&lt;/h3&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Today&lt;/h2&gt;&lt;br /&gt;&lt;h3&gt;JFace-Viewers&lt;/h3&gt;&lt;br /&gt;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 &lt;a href="http://wiki.eclipse.org/JFaceSnippets#Snippet049StyledCellLabelProvider"&gt;StyledCellLabelProvider&lt;/a&gt;. You'll see this LabelProvider in action if you open the Java-ProjectExplorer.&lt;br /&gt;&lt;br /&gt;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 (&lt;a href="http://www.eclipse.org/nebula/widgets/gallery/gallery.php"&gt;Nebula-Gallery&lt;/a&gt; and &lt;a href="http://www.eclipse.org/nebula/widgets/grid/grid.php"&gt;Nebula-Grid&lt;/a&gt;) who already adopted the concept and provide a viewer.&lt;br /&gt;&lt;br /&gt;Thanks for the great feedback and bug reports from the community we fixed some [&lt;a href="https://bugs.eclipse.org/bugs/buglist.cgi?bug_file_loc=&amp;bug_file_loc_type=allwordssubstr&amp;bug_id=&amp;bugidtype=include&amp;chfieldfrom=&amp;chfieldto=Now&amp;chfieldvalue=&amp;classification=Eclipse&amp;component=UI&amp;email1=&amp;email2=&amp;emailtype1=substring&amp;emailtype2=substring&amp;field-1-0-0=classification&amp;field-1-1-0=product&amp;field-1-2-0=component&amp;field-1-3-0=target_milestone&amp;field-1-4-0=resolution&amp;field-1-5-0=short_desc&amp;field0-0-0=noop&amp;keywords=&amp;keywords_type=allwords&amp;long_desc=&amp;long_desc_type=allwordssubstr&amp;product=Platform&amp;query_format=advanced&amp;remaction=&amp;resolution=FIXED&amp;short_desc=%5BJFace%5D%20%5BViewers%5D&amp;short_desc_type=anywordssubstr&amp;status_whiteboard=&amp;status_whiteboard_type=allwordssubstr&amp;target_milestone=3.4&amp;target_milestone=3.4%20M1&amp;target_milestone=3.4%20M2&amp;target_milestone=3.4%20M3&amp;target_milestone=3.4%20M4&amp;target_milestone=3.4%20M5&amp;target_milestone=3.4%20M6&amp;target_milestone=3.4%20M7&amp;target_milestone=3.4%20RC1&amp;target_milestone=3.4%20RC2&amp;target_milestone=3.4%20RC3&amp;target_milestone=3.4%20RC4&amp;type-1-0-0=anyexact&amp;type-1-1-0=anyexact&amp;type-1-2-0=anyexact&amp;type-1-3-0=anyexact&amp;type-1-4-0=anyexact&amp;type-1-5-0=anywordssubstr&amp;type0-0-0=noop&amp;value-1-0-0=Eclipse&amp;value-1-1-0=Platform&amp;value-1-2-0=UI&amp;value-1-3-0=3.4%2C3.4%20M1%2C3.4%20M2%2C3.4%20M3%2C3.4%20M4%2C3.4%20M5%2C3.4%20M6%2C3.4%20M7%2C3.4%20RC1%2C3.4%20RC2%2C3.4%20RC3%2C3.4%20RC4&amp;value-1-4-0=FIXED&amp;value-1-5-0=%5BJFace%5D%20%5BViewers%5D&amp;value0-0-0=&amp;votes=&amp;order=bugs.creation_ts%2Cbugs.creation_ts%2Cmap_assigned_to.login_name%2Cbugs.target_milestone%2Cbugs.priority%2Cbugs.bug_severity&amp;query_based_on="&gt;92&lt;/a&gt;] problems and feature request some of them dating back to 2003!&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Databinding&lt;/h3&gt;&lt;br /&gt;Thanks to the community and &lt;a href="http://ed-merks.blogspot.com/"&gt;Ed Merks&lt;/a&gt; and his team there's now a 2nd possibility to back up your UI with a model beside JavaBeans.&lt;br /&gt;&lt;br /&gt;Naturally they provide integration for their EMF-Objects with 2 brand new plugins named &lt;b&gt;org.eclipse.emf.databinding&lt;/b&gt; and &lt;b&gt;org.eclipse.emf.databinding.edit&lt;/b&gt;. 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. &lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://www.eclipse.org/modeling/emft/?project=teneo"&gt;teneo&lt;/a&gt; to presist your model in a SQL-Database using hibernate, working with distributed objects using &lt;a href="http://www.eclipse.org/modeling/emft/?project=cdo"&gt;CDO&lt;/a&gt;, validating your model using &lt;a href="http://www.eclipse.org/modeling/emf/?project=validation"&gt;OCL&lt;/a&gt; and much more).&lt;br /&gt;&lt;br /&gt;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 [&lt;a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced&amp;short_desc_type=anywordssubstr&amp;short_desc=%5BDatabinding%5D&amp;classification=Eclipse&amp;product=Platform&amp;component=UI&amp;target_milestone=3.4&amp;target_milestone=3.4+M1&amp;target_milestone=3.4+M2&amp;target_milestone=3.4+M3&amp;target_milestone=3.4+M4&amp;target_milestone=3.4+M5&amp;target_milestone=3.4+M6&amp;target_milestone=3.4+M7&amp;target_milestone=3.4+RC1&amp;target_milestone=3.4+RC2&amp;target_milestone=3.4+RC3&amp;target_milestone=3.4+RC4&amp;long_desc_type=allwordssubstr&amp;long_desc=&amp;bug_file_loc_type=allwordssubstr&amp;bug_file_loc=&amp;status_whiteboard_type=allwordssubstr&amp;status_whiteboard=&amp;keywords_type=allwords&amp;keywords=&amp;resolution=FIXED&amp;emailtype1=substring&amp;email1=&amp;emailtype2=substring&amp;email2=&amp;bugidtype=include&amp;bug_id=&amp;votes=&amp;chfieldfrom=&amp;chfieldto=Now&amp;chfieldvalue=&amp;cmdtype=doit&amp;order=Reuse+same+sort+as+last+time&amp;field0-0-0=noop&amp;type0-0-0=noop&amp;value0-0-0="&gt;75&lt;/a&gt;].&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The future&lt;/h2&gt;&lt;br /&gt;&lt;h3&gt;JFace-Viewers/ToolTips&lt;/h3&gt;&lt;br /&gt;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 [&lt;a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced&amp;short_desc_type=allwordssubstr&amp;short_desc=%5BViewers%5D&amp;classification=Eclipse&amp;product=Platform&amp;component=UI&amp;long_desc_type=allwordssubstr&amp;long_desc=&amp;bug_file_loc_type=allwordssubstr&amp;bug_file_loc=&amp;status_whiteboard_type=allwordssubstr&amp;status_whiteboard=&amp;keywords_type=allwords&amp;keywords=&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;emailtype1=substring&amp;email1=&amp;emailtype2=substring&amp;email2=&amp;bugidtype=include&amp;bug_id=&amp;votes=&amp;chfieldfrom=&amp;chfieldto=Now&amp;chfieldvalue=&amp;cmdtype=doit&amp;order=Reuse+same+sort+as+last+time&amp;field0-0-0=noop&amp;type0-0-0=noop&amp;value0-0-0="&gt;228&lt;/a&gt;] I'm going to try to bring this bug count down a bit (say 200 is a good number).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Databinding&lt;/h3&gt;&lt;br /&gt;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 &lt;a href="http://code.google.com/p/uface/"&gt;UFace&lt;/a&gt;-project if time permits.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt; &lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-6047056970064552841?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/6047056970064552841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=6047056970064552841' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/6047056970064552841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/6047056970064552841'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/06/ganymede-whats-in-jface-and-databinding.html' title='Ganymede - What&apos;s in JFace and Databinding'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-5368936175293479207</id><published>2008-06-05T01:15:00.002+02:00</published><updated>2008-06-05T01:35:28.371+02:00</updated><title type='text'>E4 is more about bringing it to the web</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Modeldriven:&lt;/b&gt;&lt;br/&gt; One extensible model backing up the whole workbench&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;DOM:&lt;/b&gt; 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)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;New Resource Framework:&lt;/b&gt;&lt;br /&gt; Making handling resources much more Flexible&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;New Listener Concept:&lt;/b&gt;&lt;br/&gt; The current listener concept in eclipse sucks and makes eclipse slower than it could be&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;NO SINGLETONS AND STATIC FIELDS&lt;/b&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Plugins in NONE-Java&lt;/b&gt;: Make it possible to write an Eclipse-Plugin in other languages (JavaScript, ...)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Declarative UI, Easier Styling .... and much more&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-5368936175293479207?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/5368936175293479207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=5368936175293479207' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5368936175293479207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5368936175293479207'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/06/e4-is-more-about-bringing-it-to-web.html' title='E4 is more about bringing it to the web'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-8487829728090765485</id><published>2008-05-20T07:32:00.020+02:00</published><updated>2008-05-20T18:53:09.265+02:00</updated><title type='text'>A radical approach to explore new paths for e4</title><content type='html'>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 &lt;font face="Courier"&gt;PROTOTYPE_1&lt;/font&gt;).&lt;br /&gt;&lt;br /&gt;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:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;I had to work around problems from the beginning to get a workbench up and running&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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 :-)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;I asked myself how to solve the following problems:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;How can I get up an Workbench-Window without any of the legacy code&lt;/li&gt;&lt;br /&gt;&lt;li&gt;How can I easily add features&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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&lt;/li&gt;&lt;/ul&gt;Approximately 1 month ago I sat down and started to define a project which had the following targets:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;A workbench with dependency on org.eclipse.jface, org.eclipse.equinox.common, org.eclipse.osgi, org.eclipse.emf&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Built around an extensible EMF-Model&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;NO plugin.xml and NO .exsd&lt;/b&gt; (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)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Similar but slightly improved EMF-Model compared the original one used to straight port the EclipseCon-Example&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Allow multiple instances of the workbench inside one OSGi-Env - no singletons, no static variables!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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&lt;/li&gt;&lt;br /&gt;&lt;li&gt;provide support for Scripting&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Step 1: Redesign The Model From &lt;font face="Courier"&gt;PROTOTYPE_1&lt;/font&gt;&lt;/h2&gt;&lt;br /&gt;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:&lt;pre&gt;.myActiveView {&lt;br /&gt;color: #FF0000;&lt;br /&gt;background-color: #0000FF;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&amp;lt;span class="myActiveView" &amp;gt;Green on Blue&amp;lt;/span&amp;gt;&lt;br /&gt;&lt;/pre&gt; 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.&lt;br /&gt;&lt;h2&gt;Step 2: Implementing the Workbench-UI-Core From Scratch&lt;/h2&gt;With the &lt;font face="Courier"&gt;.ecore&lt;/font&gt;-Definition from Step 1 I created a &lt;b&gt;static&lt;/b&gt; &lt;font face="Courier"&gt;workbench.xmi&lt;/font&gt; file which defines a model of a &lt;b&gt;static&lt;/b&gt; 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).&lt;br /&gt;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 &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/e4-incubator/ui/org.eclipse.e4.workbench.ui/META-INF/EWorkbench.xmi?revision=1.1&amp;amp;view=markup"&gt;this&lt;/a&gt;&lt;br /&gt;&lt;h2&gt;Step 3: Making the model dynamic&lt;/h2&gt;&lt;br /&gt;When starting Step 3 I first headed of and created .exsd-Files (you can see them &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/e4-incubator/ui/org.eclipse.e4.workbench.ui/schema/?hideattic=0"&gt;here&lt;/a&gt;) 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&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/e4-incubator/ui/org.eclipse.e4.workbench.ui/META-INF/EWorkbench.xmi?revision=1.3&amp;amp;view=markup"&gt;workbench.xmi&lt;/a&gt; in org.eclipse.e4.workbench.ui&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/SDLKK5cv99I/AAAAAAAAACY/SeMG5h9L4Jo/s1600-h/screen.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/SDLKK5cv99I/AAAAAAAAACY/SeMG5h9L4Jo/s400/screen.png" alt="" id="BLOGGER_PHOTO_ID_5202442808135251922" border="0"&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/e4-incubator/ui/org.eclipse.e4.workbench.ui.ide/plugin.xmi?revision=1.5&amp;amp;view=markup"&gt;plugin.xmi&lt;/a&gt; in org.eclipse.e4.workbench.ui.ide contributing to workbench.xmi&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/SDLKZ5cv9-I/AAAAAAAAACg/08_9RL9cbPY/s1600-h/screen_2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/SDLKZ5cv9-I/AAAAAAAAACg/08_9RL9cbPY/s400/screen_2.png" alt="" id="BLOGGER_PHOTO_ID_5202443065833289698" border="0"&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/e4-incubator/ui/org.eclipse.e4.workbench.ui.rhino/plugin.xmi?revision=1.1&amp;amp;view=markup"&gt;plugin.xmi&lt;/a&gt; in org.eclipse.e4.workbench.ui.rhino contributing to plugin.xmi from org.eclipse.e4.workbench.ui.ide&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Step 4: Implementing a Scritable-DOM&lt;/h2&gt;&lt;br /&gt;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 &lt;font face="Courier"&gt;PROTOTYPE_1&lt;/font&gt; 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.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_cWFEe8uui9o/SDK_upcv97I/AAAAAAAAACI/fAICYkvlV8Q/s1600-h/workbench.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_cWFEe8uui9o/SDK_upcv97I/AAAAAAAAACI/fAICYkvlV8Q/s400/workbench.png" alt="" id="BLOGGER_PHOTO_ID_5202431327687669682" border="0"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h2&gt;Step 5: Persisting the current workbench state&lt;/h2&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if (!restore) {&lt;br /&gt;uri = URI.createPlatformPluginURI(&lt;br /&gt;       "/org.eclipse.e4.workbench.ui/META-INF/EWorkbench.xmi",true);&lt;br /&gt;} else {&lt;br /&gt;uri = URI.createFileURI(restoreFile);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Save&lt;br /&gt;try {&lt;br /&gt;((EObject)workbench).eResource().save(null);&lt;br /&gt;} catch (IOException e) {&lt;br /&gt;e.printStackTrace();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Step 6: Extending the extension&lt;/h2&gt;&lt;br /&gt;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 &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/e4-incubator/ui/org.eclipse.e4.workbench.ui.rhino/plugin.xmi?revision=1.3&amp;amp;view=markup"&gt;this&lt;/a&gt;.&lt;br /&gt;&lt;h2&gt;Step 7: Multiple Instances of the workbench&lt;/h2&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_cWFEe8uui9o/SDLACpcv98I/AAAAAAAAACQ/vB5JLvpawV0/s1600-h/screen_multi.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_cWFEe8uui9o/SDLACpcv98I/AAAAAAAAACQ/vB5JLvpawV0/s400/screen_multi.png" alt="" id="BLOGGER_PHOTO_ID_5202431671285053378" border="0"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h2&gt;Acknowledgement / A Screencast / How to get it run&lt;/h2&gt;&lt;br /&gt;Before I forget about it two other guys (&lt;a href="http://borisoneclipse.blogspot.com/"&gt;Boris&lt;/a&gt; and &lt;a href="http://ed-merks.blogspot.com/"&gt;Ed&lt;/a&gt;) provided ideas, code and input to those freaking lines of code available from Eclipse-CVS using this &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/e4-incubator/ui/org.eclipse.e4.workbench/projectSet.psf?view=log"&gt;ProjectSet&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-748035793a67d97" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v3.nonxt2.googlevideo.com/videoplayback?id%3D0748035793a67d97%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1329864617%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D7CEAA515E4D5B16DE0065CDED3040370B7656305.1A3ECE309C9E2FD7692878CE4B752A0CC1546B26%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D748035793a67d97%26offsetms%3D5000%26itag%3Dw160%26sigh%3Dnhm48-R2p2jligbK3eWbXp1OAPA&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v3.nonxt2.googlevideo.com/videoplayback?id%3D0748035793a67d97%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1329864617%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D7CEAA515E4D5B16DE0065CDED3040370B7656305.1A3ECE309C9E2FD7692878CE4B752A0CC1546B26%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D748035793a67d97%26offsetms%3D5000%26itag%3Dw160%26sigh%3Dnhm48-R2p2jligbK3eWbXp1OAPA&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;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 &amp;amp; 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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-8487829728090765485?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=748035793a67d97&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/8487829728090765485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=8487829728090765485' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8487829728090765485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8487829728090765485'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/05/radical-approach-to-explore-new-paths.html' title='A radical approach to explore new paths for e4'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_cWFEe8uui9o/SDLKK5cv99I/AAAAAAAAACY/SeMG5h9L4Jo/s72-c/screen.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-8489349747731980542</id><published>2008-03-20T22:13:00.006+01:00</published><updated>2008-03-20T23:32:40.770+01:00</updated><title type='text'>Eclipse E4 and UFacekit</title><content type='html'>&lt;h2&gt;E4 and my impression&lt;/h2&gt;Haveing attended the E4 Talk, &lt;b&gt;A&lt;/b&gt; 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. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;UFacekit and E4&lt;/h2&gt;&lt;h3&gt;Do we still have to put effort into UFacekit?&lt;/h3&gt;When I first saw what's been done by the E4-Prototypers my first reaction was: Do we still need to work &lt;a href="http://uface.googlecode.com"&gt;UFacekit&lt;/a&gt;? 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:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Eclipse-Core-Databinding compatible to GWT&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Eclipse-EMF-Ecore compatible to GWT&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Highlevel-Abstraction for Eclipse-Databinding&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Easy support for Decoration, ...&lt;/li&gt;&lt;br /&gt;&lt;li&gt;... and much more&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;h3&gt;How can UFacekit profit&lt;/h3&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;h2&gt;UFacekit News&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;I added an Example how to use EMF + UFacekit inside GWT. &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_cWFEe8uui9o/R-LfQcUW7jI/AAAAAAAAACA/im16y6x4sK8/s1600-h/screen.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_cWFEe8uui9o/R-LfQcUW7jI/AAAAAAAAACA/im16y6x4sK8/s400/screen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5179947995001974322" /&gt;&lt;/a&gt;&lt;br /&gt;You can take a look at the code &lt;a href="http://uface.googlecode.com/svn/trunk/org.ufacekit.ui.gwtext.example.eform/src/org/ufacekit/ui/gwtext/example/eform/client/expls/EFormExample.java"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;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&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Work on GWT-Ext port continues but getting the layout stuff right is a real pain&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-8489349747731980542?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/8489349747731980542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=8489349747731980542' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8489349747731980542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8489349747731980542'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/03/eclipse-e4-and-ufacekit.html' title='Eclipse E4 and UFacekit'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_cWFEe8uui9o/R-LfQcUW7jI/AAAAAAAAACA/im16y6x4sK8/s72-c/screen.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-1330007110834509921</id><published>2008-03-06T21:01:00.006+01:00</published><updated>2008-03-06T22:30:59.906+01:00</updated><title type='text'>UFace - Update</title><content type='html'>I recognized today that I haven't blogged about one of my favorite OSS-project (UFace/UFacekit) lately. &lt;br /&gt;&lt;br /&gt;For those of you who have never heard of this project let me introduce it in a few sentences.&lt;br /&gt;&lt;br /&gt;UFace or UFacekit has the following targets:&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Add a highlevel API above Eclipse-Databinding&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Helping Eclipse-Databinding to gain momentum outside Eclipse/SWT/JFace world by providing Observable-Implementation for various UI-Toolkits like Swing, GWT, ...&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Helping OSGi to be used in UI-Applications outside Eclipse-RCP e.g. in Swing Applications&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Providing a uniform UI-API for all those widget-systems including builders for common form layouts (e.g. 2 column label/field list)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;We have been fairly busy lately and added the following things into UFace:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;   &lt;li&gt;Validation and Decoration Support (contributed by Kenneth Westelinck) for Swing and SWT&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;Worked heavily on the MyGWT integration&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;Maven-Build-System&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Validation and Decoration&lt;/h2&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;StatusDecoratingInterceptor interceptor = &lt;br /&gt;       new StatusDecoratingInterceptor(detailComposite);&lt;br /&gt;detailForm_1.setAfterBindInterceptor(interceptor);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Darn cool, isn't it?&lt;br /&gt;&lt;br /&gt;The resulting UI with validation error looks like this:&lt;br /&gt;&lt;br /&gt;SWT on Win32:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/R9BSI-1lXtI/AAAAAAAAABo/2F024Sc94Lw/s1600-h/screen-jdk-swt.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/R9BSI-1lXtI/AAAAAAAAABo/2F024Sc94Lw/s400/screen-jdk-swt.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5174726286108876498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Swing on Win32:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_cWFEe8uui9o/R9BSVu1lXuI/AAAAAAAAABw/zSj5DSXLrs0/s1600-h/screen-jdk-swing.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_cWFEe8uui9o/R9BSVu1lXuI/AAAAAAAAABw/zSj5DSXLrs0/s400/screen-jdk-swing.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5174726505152208610" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h2&gt;UFacekit implementation for MyGWT&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;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). &lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/R9BU_e1lXvI/AAAAAAAAAB4/ynWVSW9v8pM/s1600-h/screen-mygwt.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/R9BU_e1lXvI/AAAAAAAAAB4/ynWVSW9v8pM/s400/screen-mygwt.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5174729421435002610" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's not 100% right and Combo and List aren't working either but it was quite an achievement to get that far.&lt;br /&gt;&lt;h2&gt;Current status / Release plans&lt;/h2&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;h2&gt;What's in the queue&lt;/h2&gt;&lt;br /&gt;We already have a queue for features we'd like to integrate (an incomplete list is this):&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Support for more Widgets Tree/TreeTable, TabFolders, ...&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Implementation ontop of Eclipse-Forms&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Better looking decorations on Swing&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Support for CSS to style your widgets&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Extensible converts&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-1330007110834509921?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/1330007110834509921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=1330007110834509921' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1330007110834509921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1330007110834509921'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/03/uface-update.html' title='UFace - Update'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_cWFEe8uui9o/R9BSI-1lXtI/AAAAAAAAABo/2F024Sc94Lw/s72-c/screen-jdk-swt.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-269386033958125813</id><published>2008-01-23T13:42:00.000+01:00</published><updated>2008-01-23T14:25:00.222+01:00</updated><title type='text'>EMF + Databinding - I'm adicted to this stuff</title><content type='html'>Ed blogged somedays ago about the progress he made makeing EMF available to &lt;a href="http://ed-merks.blogspot.com/2008/01/emf-and-rap-go-great-together-too.html"&gt;RAP and J2ME&lt;/a&gt; and there are more and more people requesting a simple example project where some EMF-Databinding-Features are shown.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/R5c35_leNRI/AAAAAAAAABg/VHOhdJ-hH98/s1600-h/screen.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/R5c35_leNRI/AAAAAAAAABg/VHOhdJ-hH98/s400/screen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5158653367636866322" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://wiki.eclipse.org/Wire_EMF_Databinding_RCP"&gt;EMF+Databinding+RCP+iBatis&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you want to take a look at source code you can grab it from &lt;a href="http://publicsvn.bestsolution.at/repos/java/examples/EMF-Databinding/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There are some issues you need to be aware of when it comes to &lt;br /&gt;e.g. Master-Detail + Field-Dependencies. &lt;br /&gt;&lt;br /&gt;This is where &lt;a href="http://code.google.com/p/uface/"&gt;UFace&lt;/a&gt; comes into play which handles this kind of thing for you (and even more).&lt;br /&gt;&lt;br /&gt;Because I'm talking about UFace. We are making progress since the last blog entry the following things have happend:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;refactored Factory-API to get extensible and not cluttered with overloaded methods&lt;/li&gt;&lt;br /&gt;&lt;li&gt;started to think how UForm can be used by native implementators (UForm is an abstraction level above Databinding and your Model-Implementation-Technology)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;we added a new committer just today (Angelo Zerr) who develops some cool XML-UI things (See &lt;a href="http://akrogen.sourceforge.net/"&gt;Akrogen&lt;/a&gt;) and is enhancing our Swing-Binding and SWT-Bindings. Welcome Angelo.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Set up a &lt;a href="http://code.google.com/p/uface/wiki/CommitterAgreement"&gt;Committer&lt;/a&gt; and &lt;a href="http://code.google.com/p/uface/wiki/Contributing"&gt;Contributor&lt;/a&gt; policy. I hate this legal stuff and we want to keep it at minimum but this has to be the foundation of every project&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Received a code donation (SWT GridLayout for Swing) from Daniel Spiewak (See &lt;a href="http://code.google.com/p/uface/issues/detail?id=8&amp;can=1"&gt;Daniels Code contribution&lt;/a&gt;)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-269386033958125813?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/269386033958125813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=269386033958125813' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/269386033958125813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/269386033958125813'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/01/emf-databinding-im-adicted-to-this.html' title='EMF + Databinding - I&apos;m adicted to this stuff'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_cWFEe8uui9o/R5c35_leNRI/AAAAAAAAABg/VHOhdJ-hH98/s72-c/screen.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-4417648042808108788</id><published>2008-01-10T21:05:00.000+01:00</published><updated>2008-01-10T22:48:28.990+01:00</updated><title type='text'>One month of UFacekit-Development</title><content type='html'>A month ago &lt;a href="http://macstrac.blogspot.com/" target="_new"&gt;James Strachan&lt;/a&gt; and I started hacking on a project we named &lt;a href="http://code.google.com/p/uface/" target="_new"&gt;UFacekit&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;There are different things we are targeting with the project.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt; &lt;li&gt;Provide a uniform Facade above widget implementations (SWT,Swing,GWT,...)&lt;/li&gt;&lt;br /&gt; &lt;li&gt;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&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Provide reuseable Bundles which can be used independently &lt;ul&gt;&lt;li&gt;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&lt;/li&gt;&lt;li&gt;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&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Take a look at the following Screenshots they show what's already possible with the current sources.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/R4Z8QqR4CKI/AAAAAAAAABY/WP5fdoie7x0/s1600-h/Swing.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/R4Z8QqR4CKI/AAAAAAAAABY/WP5fdoie7x0/s400/Swing.png" alt="" id="BLOGGER_PHOTO_ID_5153943449241127074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_cWFEe8uui9o/R4Z8FaR4CJI/AAAAAAAAABQ/zF9hRLTfrjw/s1600-h/JFace.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_cWFEe8uui9o/R4Z8FaR4CJI/AAAAAAAAABQ/zF9hRLTfrjw/s400/JFace.png" alt="" id="BLOGGER_PHOTO_ID_5153943255967598738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://www.miglayout.com/" target="_new"&gt;Mig&lt;/a&gt;-Layout).&lt;br /&gt;&lt;br /&gt;They are full of features you need many lines code without a framework doing the nifity bits for you (e.g. MasterDetail + Field-Dependencies):&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Master-Detail support&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Model-UI-Binding&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Field-Dependencies (Country/Federalstate)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Setting up this UI needs:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;~ 80 Lines of Widget-Toolkit-Independent code&lt;/li&gt;&lt;br /&gt;&lt;li&gt;~ 20 Lines of Widget-Dependent code (= the start of the application which is currently not abstracted)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;The amazing thing is that both UIs are made up by the same source code:&lt;br /&gt;&lt;div class="java" style="border: 1px dotted #a0a0a0; font-family: 'Courier New', Courier, monospace; font-size: 8pt; background-color: #f0f0f0; margin: 0;padding: 0;overflow: scroll;"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    &lt;b style="color: #990066"&gt;public void&lt;/b&gt; createFormUI(UIComposite root) {&lt;br /&gt;        UIFactory ui = root.getFactory();&lt;br /&gt;&lt;br /&gt;        UBeanForm listForm = &lt;b style="color: #990066"&gt;new&lt;/b&gt; UBeanForm();&lt;br /&gt;        &lt;b style="color: #990066"&gt;final&lt;/b&gt; UBeanForm detailForm_1 = new UBeanForm();&lt;br /&gt;&lt;br /&gt;        UIComposite containerComposite = ui.newComposite(root, null, ui.newGridLayout(2));&lt;br /&gt;&lt;br /&gt;        TableColumn[] columns = {&lt;br /&gt;                &lt;b style="color: #990066"&gt;new&lt;/b&gt; TableColumn("People", &lt;b style="color: #990066"&gt;new&lt;/b&gt; NameLabelProvider())&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        UITable table = ui.newTable(listForm, containerComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(200, GridLayoutData.DEFAULT, GridLayoutData.ALIGN_BEGINNING, GridLayoutData.ALIGN_FILL, &lt;b style="color: #990066"&gt;false&lt;/b&gt;, &lt;b style="color: #990066"&gt;true&lt;/b&gt;), listForm.detailList(AddressBook.PEOPLE, &lt;b style="color: #990066"&gt;Collection&lt;/b&gt;.&lt;b style="color: #990066"&gt;class&lt;/b&gt;), columns);&lt;br /&gt;&lt;br /&gt;        // ---------------------&lt;br /&gt;&lt;br /&gt;        UIComposite detailComposite = ui.newComposite(containerComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, &lt;b style="color: #990066"&gt;true&lt;/b&gt;, &lt;b style="color: #990066"&gt;true&lt;/b&gt;), ui.newGridLayout(2));&lt;br /&gt;        ui.newLabel(detailComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "ID");&lt;br /&gt;        ui.newTextField(detailForm_1, detailComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, true, false), detailForm_1.detailValue(Person.ID, &lt;b style="color: #990066"&gt;int&lt;/b&gt;.&lt;b style="color: #990066"&gt;class&lt;/b&gt;));&lt;br /&gt;&lt;br /&gt;        ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "Name");&lt;br /&gt;        ui.newTextField(detailForm_1, detailComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, &lt;b style="color: #990066"&gt;true&lt;/b&gt;, &lt;b style="color: #990066"&gt;false&lt;/b&gt;), detailForm_1.detailValue(Person.NAME, String.&lt;b style="color: #990066"&gt;class&lt;/b&gt;));&lt;br /&gt;&lt;br /&gt;        ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "Location");&lt;br /&gt;        ui.newTextArea(detailForm_1, detailComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, &lt;b style="color: #990066"&gt;true&lt;/b&gt;, &lt;b style="color: #990066"&gt;false&lt;/b&gt;), detailForm_1.detailValue(Person.LOCATION, String.&lt;b style="color: #990066"&gt;class&lt;/b&gt;));&lt;br /&gt;&lt;br /&gt;        ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "Country");&lt;br /&gt;        UICombo combo = ui.newCombo(detailForm_1, detailComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, &lt;b style="color: #990066"&gt;true&lt;/b&gt;, &lt;b style="color: #990066"&gt;false&lt;/b&gt;), detailForm_1.detailValue(Person.COUNTRY, Country.&lt;b style="color: #990066"&gt;class&lt;/b&gt;), ModelHelper.createWritableList(getModel().getCountries(), Country.&lt;b style="color: #990066"&gt;class&lt;/b&gt;), &lt;b style="color: #990066"&gt;new&lt;/b&gt; CountryLabelProvider());&lt;br /&gt;&lt;br /&gt;        ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_BEGINNING), "Federalstate");&lt;br /&gt;        ui.newDependentListBox(detailForm_1, detailComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(GridLayoutData.DEFAULT,120,GridLayoutData.ALIGN_FILL, GridLayoutData.ALIGN_FILL, &lt;b style="color: #990066"&gt;true&lt;/b&gt;, &lt;b style="color: #990066"&gt;false&lt;/b&gt;), detailForm_1.detailValue(Person.FEDERAL_STATE, FederalState.&lt;b style="color: #990066"&gt;class&lt;/b&gt;), (IObservableList) detailForm_1.detailList(Country.FEDERAL_STATES, Collection.&lt;b style="color: #990066"&gt;class&lt;/b&gt;).createObservable(combo.getSelectionObservable()), &lt;b style="color: #990066"&gt;new&lt;/b&gt; FederalStateLabelProvider());&lt;br /&gt;&lt;br /&gt;        WritableValue value = ModelHelper.createWritableValue(getModel());&lt;br /&gt;        listForm.bind(value);&lt;br /&gt;&lt;br /&gt;        IObservableValue detailObservable = table.getSelectionObservable();&lt;br /&gt;        detailForm_1.bind(detailObservable);&lt;br /&gt;&lt;br /&gt;        UBeanForm detailForm_2 = &lt;b style="color: #990066"&gt;new&lt;/b&gt; UBeanForm();&lt;br /&gt;&lt;br /&gt;        columns = new TableColumn[] {&lt;br /&gt;          &lt;b style="color: #990066"&gt;new&lt;/b&gt; TableColumn("ID", &lt;b style="color: #990066"&gt;new&lt;/b&gt; IDLabelProvider()),&lt;br /&gt;                &lt;b style="color: #990066"&gt;new&lt;/b&gt; TableColumn("Name", &lt;b style="color: #990066"&gt;new&lt;/b&gt; NameLabelProvider()),&lt;br /&gt;                &lt;b style="color: #990066"&gt;new&lt;/b&gt; TableColumn("Location", &lt;b style="color: #990066"&gt;new&lt;/b&gt; LocationLabelProvider())&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        ui.newLabel(detailComposite, new GridLayoutData(GridLayoutData.ALIGN_END, GridLayoutData.ALIGN_CENTER), "");&lt;br /&gt;        ui.newTable(detailForm_2, detailComposite, &lt;b style="color: #990066"&gt;new&lt;/b&gt; GridLayoutData(GridLayoutData.ALIGN_FILL,GridLayoutData.ALIGN_FILL,true,true), detailForm_2.detailList(Person.FRIENDS, Collection.&lt;b style="color: #990066"&gt;class&lt;/b&gt;), columns);&lt;br /&gt;        detailForm_2.bind(detailObservable);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="java" style="border: 1px dotted #a0a0a0; font-family: 'Courier New', Courier, monospace; font-size: 8pt; background-color: #f0f0f0; margin: 0;padding: 0;overflow: scroll;"&gt;&lt;pre&gt;  &lt;b style="color: #990066"&gt;public void&lt;/b&gt; run(&lt;b style="color: #990066"&gt;final&lt;/b&gt; String uiMethod) {&lt;br /&gt;  Display display = &lt;b style="color: #990066"&gt;new&lt;/b&gt; Display();&lt;br /&gt;&lt;br /&gt;  Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {&lt;br /&gt;    &lt;b style="color: #990066"&gt;public void&lt;/b&gt; run() {&lt;br /&gt;      Shell shell = createUI(uiMethod);&lt;br /&gt;      shell.setSize(650, 500);&lt;br /&gt;      shell.setText("UFacekit - JFace-Demo ");&lt;br /&gt;      Display display = Display.getCurrent();&lt;br /&gt;        &lt;b style="color: #990066"&gt;while&lt;/b&gt; (!shell.isDisposed()) {&lt;br /&gt;          &lt;b style="color: #990066"&gt;if&lt;/b&gt; (!display.readAndDispatch()) {&lt;br /&gt;            display.sleep();&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;b style="color: #990066"&gt;private&lt;/b&gt; Shell createUI(String uiMethod) {&lt;br /&gt;    &lt;b style="color: #990066"&gt;final&lt;/b&gt; Shell shell = &lt;b style="color: #990066"&gt;new&lt;/b&gt; Shell();&lt;br /&gt;    SWTComposite composite = &lt;b style="color: #990066"&gt;new&lt;/b&gt; SWTComposite(shell,&lt;b style="color: #990066"&gt;new&lt;/b&gt; JFaceFactory().newFillLayout());&lt;br /&gt;    // generic code as shown above&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Did this spot your interest? Come and join our &lt;a href="http://groups.google.com/group/uface"&gt;google group&lt;/a&gt; and share your ideas with us.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-4417648042808108788?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/4417648042808108788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=4417648042808108788' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/4417648042808108788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/4417648042808108788'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/01/one-month-of-ufacekit-development.html' title='One month of UFacekit-Development'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_cWFEe8uui9o/R4Z8QqR4CKI/AAAAAAAAABY/WP5fdoie7x0/s72-c/Swing.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-7903017370881296831</id><published>2008-01-05T13:23:00.000+01:00</published><updated>2008-01-05T13:57:19.903+01:00</updated><title type='text'>EclipseCon: I'll be there</title><content type='html'>&lt;b&gt;News 1:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Just booked my flight and my room at the Hyatt. I'm excited to meet you all. &lt;br /&gt;&lt;br /&gt;There are so many interesting talks like &lt;a href="http://www.eclipsecon.org/2008/index.php?page=sub/&amp;id=9"&gt;Steve's talk about the future of SWT&lt;/a&gt; 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.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;News 2:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The other news I'd like to share with we you is that together with &lt;a href="http://macstrac.blogspot.com/"&gt;James Strachan&lt;/a&gt; I started a fairly interesting "experiment" called &lt;a href="http://code.google.com/p/uface/"&gt;UFaceKit&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Beside providing this generic API the project is split into many individual &lt;b&gt;plugins/bundles&lt;/b&gt; which can be used out of the uface-scope:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;A light weight JavaBean like implementation useable without any reflection-API the implementation is called UBean&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Observables for UBean like Eclipse provides an implementation for JavaBeans&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;UI-Observables for GWT/MyGWT/GWT-EXT&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;UI-Observables for Swing&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;As you see one of the "waste products" of this project is that Eclipse-Databinding is  can be used by Swing/GWT/... developers.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Primary targets currently are:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;   &lt;li&gt;SWT/JFace&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;GWT-implementations&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-7903017370881296831?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/7903017370881296831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=7903017370881296831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7903017370881296831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7903017370881296831'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2008/01/eclipsecon-ill-be-there.html' title='EclipseCon: I&apos;ll be there'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-1723412850769307023</id><published>2007-12-06T00:20:00.000+01:00</published><updated>2007-12-06T13:52:32.644+01:00</updated><title type='text'>ed4g - Eclipse Databinding for GWT-Widgets 0.0.1</title><content type='html'>I finally did it. Based upon the plugins I've ported over from Eclipse to compile under GWT I setup a project that provides Observable implementations for GWT and MyGWT widgets but it is open for any other GWT-compatible widget-lib.&lt;br /&gt;&lt;br /&gt;A missing thing currently is a 2nd light weight Model-Implementation that works on GWT, I thought about simply providing an Observable implemented ontop of a HashMap. EMF is available and working but I'd like to have a second very light weight implementation which can be used by people not familiar with EMF and only need some GWT related binding.&lt;br /&gt;&lt;br /&gt;You can find the project &lt;a href="http://code.google.com/p/ed4g/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-1723412850769307023?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/1723412850769307023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=1723412850769307023' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1723412850769307023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1723412850769307023'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/12/ed4g-eclipse-databinding-for-gwt.html' title='ed4g - Eclipse Databinding for GWT-Widgets 0.0.1'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-4665831585983803904</id><published>2007-11-19T02:23:00.000+01:00</published><updated>2007-11-19T02:48:19.910+01:00</updated><title type='text'>EMF + Databinding + GWT 1.5 - it works</title><content type='html'>Since the last time I blogged about the on going work to provide Eclipse-Core-Features for users of GWT some time has elapsed so I thought I should give you an update. &lt;br /&gt;&lt;br /&gt;Ed and Boris jumped on the train and try to help me with their indepth knowledge of EMF and Databinding. It's great to have them on board.&lt;br /&gt;&lt;br /&gt;Today I managed the first time to use EMF-Core-Modules (EMF-Common und EMF-Ecore) in a GWT-context. There are some rough edges and not everything is working but it's amazing that the newly developed EMF-Databinding-Integration developed in &lt;a  href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=75625"&gt;Bug 75625&lt;/a&gt; works nearly out-of-the box.&lt;br /&gt;&lt;br /&gt;My GWT-Code looks like this now:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;EMFDataBindingContext ctx = new EMFDataBindingContext();&lt;br /&gt;&lt;br /&gt;targetObservableValue = GWTObservables.observeText(&lt;br /&gt;   textBox, GWTObservables.Change);&lt;br /&gt;&lt;br /&gt;modelObservableValue = EMFObservables.observeDetailValue(&lt;br /&gt;   Realm.getDefault(),&lt;br /&gt;   value, &lt;br /&gt;   BrojectPackage.Literals.PROJECT__NAME);&lt;br /&gt;&lt;br /&gt;IConstants.BINDING_BUILDER.bindTextValue(&lt;br /&gt;   ctx, &lt;br /&gt;   targetObservableValue, &lt;br /&gt;   modelObservableValue);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've started an example project you can look at &lt;a href="http://oss.bestsolution.at/gwt-demo/Broject/0.0.1/Broject.html"&gt;Broject&lt;/a&gt; and get the sources from my &lt;a href="http://publicsvn.bestsolution.at/repos/java/gwt/example/"&gt;svn-repository&lt;/a&gt;, it's in a very very early stage but you should get the idea.&lt;br /&gt;&lt;br /&gt;If you are interested in the work then you should subscribe to the following bugs &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209434"&gt;EMF-Common&lt;/a&gt;, &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209435"&gt;EMF-Ecore&lt;/a&gt;, &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=207218"&gt;Extension to GWT-JRE-Emulation&lt;/a&gt;, &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209860"&gt;Core-Databinding&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-4665831585983803904?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/4665831585983803904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=4665831585983803904' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/4665831585983803904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/4665831585983803904'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/11/emf-databinding-gwt-15-it-works.html' title='EMF + Databinding + GWT 1.5 - it works'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-4331257386594130884</id><published>2007-10-09T13:48:00.000+02:00</published><updated>2007-10-09T14:06:34.803+02:00</updated><title type='text'>More details about Databinding and GWT</title><content type='html'>I promised in the morning that I'll blog more details about giving GWT-Developers access to concepts provided by Eclipse.&lt;br /&gt;&lt;br /&gt;Currently my port provides: &lt;br /&gt;- Core-Databinding + PEMF-Observables (for standard values (no lists at the moment))&lt;br /&gt;- Support for Perspectives (untested but available in code)&lt;br /&gt;- ViewPart-Implementation&lt;br /&gt;- Access to the low-level-bits of the Command-framework (AbstractHandler and friends)&lt;br /&gt;- A first draft implementation of ExtensionPointRegistry&lt;br /&gt;&lt;br /&gt;This is currently not a straight port and the API is in some situations different but I'll resolve this later on.&lt;br /&gt;&lt;br /&gt;Maybe some code example help you to understand the idea behind my work.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Starting up the application:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class DemoApplication extends Plugin {&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * This is the entry point method.&lt;br /&gt;  */&lt;br /&gt; public void start() {&lt;br /&gt;  super.start();&lt;br /&gt;  Workbench.createAndRunWorkbench(new WorkbenchAdvisor());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public String getPluginXML() {&lt;br /&gt;    return&lt;br /&gt;"&amp;lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n"+&lt;br /&gt;"&amp;lt;?eclipse version=\"3.2\"?&gt;\n"+&lt;br /&gt;"&amp;lt;plugin&gt;\n"+&lt;br /&gt;"    &amp;lt;extension\n"+&lt;br /&gt;"          point=\"org.eclipse.ui.views\"&gt;\n"+&lt;br /&gt;"       &amp;lt;view\n"+&lt;br /&gt;"             name=\"Range of Product\"\n"+&lt;br /&gt;"             allowMultiple=\"false\"\n"+&lt;br /&gt;"             class=\"at.bestsolution.gwt.demo.client.ui.views.ProductRangeViewPart\"\n"+&lt;br /&gt;"             id=\""+IConstants.PRODUCT_RANGE_VIEW_PART+"\"&gt;\n"+&lt;br /&gt;"       &amp;lt;/view&gt;\n"+&lt;br /&gt;"       &amp;lt;view\n"+&lt;br /&gt;"             name=\"Product\"\n"+&lt;br /&gt;"             allowMultiple=\"true\"\n"+&lt;br /&gt;"             class=\"at.bestsolution.gwt.demo.client.ui.views.ProductEditingViewPart\"\n"+&lt;br /&gt;"             id=\""+IConstants.PRODUCT_EDITING_VIEW_PART+"\"&gt;\n"+&lt;br /&gt;"       &amp;lt;/view&gt;\n"+&lt;br /&gt;"    &amp;lt;/extension&gt;\n"+&lt;br /&gt;"&amp;lt;/plugin&gt;\n"&lt;br /&gt;;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public String getPluginName() {&lt;br /&gt;  return "at.bestsolution.gwt.demo";&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Setting up a TreeViewer:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public Widget createPartControl() {&lt;br /&gt;&lt;br /&gt;    VerticalPanel panel = new VerticalPanel();&lt;br /&gt;    panel.setSize("100%", "100%");&lt;br /&gt;    Tree tree = new Tree();&lt;br /&gt;    tree.setSize("100%", "100%");&lt;br /&gt;    panel.add(tree);&lt;br /&gt;    panel.setCellHeight(tree, "100%");&lt;br /&gt;    panel.setCellWidth(tree, "100%");&lt;br /&gt;&lt;br /&gt;    final TreeViewer viewer = new TreeViewer(tree);&lt;br /&gt;    viewer.setContentProvider(new TreeContentProvider());&lt;br /&gt;    viewer.setLabelProvider(new LabelProvider());&lt;br /&gt;    viewer.setInput(Datasource.getDatasource().getProductRange());&lt;br /&gt;    viewer.addSelectionChangedListener(new SelectionChangedListener());&lt;br /&gt;    getSite().setSelectionProvider(viewer);&lt;br /&gt;// ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And finally binding a control to a model element:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;TextBox box = new TextBox();&lt;br /&gt;box.setEnabled(false);&lt;br /&gt;table.setWidget(0, 1, box);&lt;br /&gt;&lt;br /&gt;IObservableValue targetObservableValue = GWTObservables.observeText(box, GWTObservables.Change);&lt;br /&gt;IObservableValue modelObservableValue = PEMFObservablesFactory.observeValue(Realm.getDefault(), product, Product.ID);&lt;br /&gt;UpdateValueStrategy targetToModel = new UpdateValueStrategy();&lt;br /&gt;UpdateValueStrategy modelToTarget = new UpdateValueStrategy();&lt;br /&gt;modelToTarget.setConverter(new IntegerToStringConverter());&lt;br /&gt;ctx.bindValue(targetObservableValue, modelObservableValue, targetToModel, modelToTarget);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The final result looks like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/RwtuY-gQGNI/AAAAAAAAABI/GORdvCTmzxw/s1600-h/application.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/RwtuY-gQGNI/AAAAAAAAABI/GORdvCTmzxw/s400/application.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5119306776810887378" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-4331257386594130884?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/4331257386594130884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=4331257386594130884' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/4331257386594130884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/4331257386594130884'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/10/more-details-about-databinding-and-gwt.html' title='More details about Databinding and GWT'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_cWFEe8uui9o/RwtuY-gQGNI/AAAAAAAAABI/GORdvCTmzxw/s72-c/application.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-3175392144392946890</id><published>2007-10-09T07:43:00.000+02:00</published><updated>2007-10-09T07:54:27.144+02:00</updated><title type='text'>Doing RCP-Like programming with GWT</title><content type='html'>After having spent some time on GWT + Databinding I can now report success on porting over the Core-Databinding framework to GWT with fairly no changes from what is found in the Eclipse-CVS-Repository. &lt;br /&gt;&lt;br /&gt;But to do real programming in GWT there's more you need (Views, Editors, Commands, Actions, ...) so I've also taken over the other core ideas from Eclipse into a GWT-Lib I called gjface (it isn't a straight port of the Eclipse-API currently because of the lack of time but it's fairly usebable already).&lt;br /&gt;&lt;br /&gt;I've also created a Demo-Application you can find &lt;a href="http://oss.bestsolution.at/gwt-demo/current/DemoApplication.html"&gt;here&lt;/a&gt; and if you are interested how this Application is created you can get the source from &lt;a href="http://oss.bestsolution.at/gwt-demo/current/Demo-0.0.1.zip"&gt;here&lt;/a&gt;. I have only tested it on Firefox so it might be that it's not working on IE currently.&lt;br /&gt;&lt;br /&gt;I'll blog later today how this all works together but if you want to take an in depth look I'm at ESE!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-3175392144392946890?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/3175392144392946890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=3175392144392946890' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3175392144392946890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3175392144392946890'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/10/doing-rcp-like-programming-with-gwt.html' title='Doing RCP-Like programming with GWT'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-8328118888602637223</id><published>2007-09-29T00:17:00.000+02:00</published><updated>2007-09-29T00:40:05.477+02:00</updated><title type='text'>The marriage of GWT with Eclipse-Technologies</title><content type='html'>I'm currently on the track to explore GWT and started just this morning with it. The first thing I found missing is something like the Viewers-Concept from JFace.&lt;br /&gt;&lt;br /&gt;I don't want to learn new things if the one I'm familiar with would make my life much easier. JFace-Viewers is one of my main working areas in Eclipse-land. So I sat down and took a closer look and after 1 hour of work my GWT-code looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package at.bestsolution.eclipse.jface.example.client;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;&lt;br /&gt;import org.gwtwidgets.client.util.SimpleDateParser;&lt;br /&gt;&lt;br /&gt;import at.bestsolution.eclipse.jface.client.viewers.TreeViewer;&lt;br /&gt;import at.bestsolution.eclipse.jface.example.client.model.Family;&lt;br /&gt;import at.bestsolution.eclipse.jface.example.client.model.Person;&lt;br /&gt;import at.bestsolution.eclipse.jface.example.client.ui.MyContentProvider;&lt;br /&gt;import at.bestsolution.eclipse.jface.example.client.ui.MyLabelProvider;&lt;br /&gt;&lt;br /&gt;import com.google.gwt.core.client.EntryPoint;&lt;br /&gt;import com.google.gwt.user.client.ui.RootPanel;&lt;br /&gt;import com.google.gwt.user.client.ui.Tree;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Entry point classes define &lt;code&gt;onModuleLoad()&lt;/code&gt;.&lt;br /&gt; */&lt;br /&gt;public class JFaceExampleApp implements EntryPoint {&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * This is the entry point method.&lt;br /&gt;   */&lt;br /&gt;  public void onModuleLoad() {&lt;br /&gt;&lt;br /&gt;   Tree tree = new Tree();&lt;br /&gt;   TreeViewer viewer = new TreeViewer(tree);&lt;br /&gt;   viewer.setLabelProvider(new MyLabelProvider());&lt;br /&gt;   viewer.setContentProvider(new MyContentProvider());&lt;br /&gt;   viewer.setInput(createInput());&lt;br /&gt;&lt;br /&gt;   RootPanel.get().add(tree);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private ArrayList createInput() {&lt;br /&gt;   SimpleDateParser parser = new SimpleDateParser("yyyy-MM-dd");&lt;br /&gt;   ArrayList list = new ArrayList();&lt;br /&gt;&lt;br /&gt;   Family fam = new Family("Schindl");&lt;br /&gt;   Person p = new Person("Tom",parser.parse("1979-05-01"),fam);&lt;br /&gt;   p = new Person("Tina",parser.parse("1980-10-14"),fam);&lt;br /&gt;   p = new Person("Laura",parser.parse("1991-08-07"),fam);&lt;br /&gt;&lt;br /&gt;   list.add(fam);&lt;br /&gt;&lt;br /&gt;   fam = new Family("Hoppichler");&lt;br /&gt;   p = new Person("Andreas",parser.parse("1977-11-06"),fam);&lt;br /&gt;   p = new Person("Franzi",parser.parse("1978-11-02"),fam);&lt;br /&gt;&lt;br /&gt;   list.add(fam);&lt;br /&gt;&lt;br /&gt;   return list;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the respective Viewer-classes like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package at.bestsolution.eclipse.jface.example.client.ui;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;&lt;br /&gt;import at.bestsolution.eclipse.jface.client.viewers.ITreeContentProvider;&lt;br /&gt;import at.bestsolution.eclipse.jface.client.viewers.Viewer;&lt;br /&gt;import at.bestsolution.eclipse.jface.example.client.model.Family;&lt;br /&gt;import at.bestsolution.eclipse.jface.example.client.model.Person;&lt;br /&gt;&lt;br /&gt;public class MyContentProvider implements ITreeContentProvider {&lt;br /&gt;&lt;br /&gt; public Object[] getChildren(Object parentElement) {&lt;br /&gt;  if( parentElement instanceof Family ) {&lt;br /&gt;   return ((Family)parentElement).getList().toArray();&lt;br /&gt;  }&lt;br /&gt;  return new Object[0];&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object getParent(Object element) {&lt;br /&gt;  if( element instanceof Person ) {&lt;br /&gt;   return ((Person)element).getFamily();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return null;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean hasChildren(Object element) {&lt;br /&gt;  return getChildren(element).length &gt; 0;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object[] getElements(Object inputElement) {&lt;br /&gt;  return ((ArrayList)inputElement).toArray();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void dispose() {&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package at.bestsolution.eclipse.jface.example.client.ui;&lt;br /&gt;&lt;br /&gt;import org.gwtwidgets.client.util.SimpleDateFormat;&lt;br /&gt;&lt;br /&gt;import at.bestsolution.eclipse.jface.client.viewers.ILabelProvider;&lt;br /&gt;import at.bestsolution.eclipse.jface.example.client.model.Family;&lt;br /&gt;import at.bestsolution.eclipse.jface.example.client.model.Person;&lt;br /&gt;&lt;br /&gt;public class MyLabelProvider implements ILabelProvider {&lt;br /&gt; private SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");&lt;br /&gt;&lt;br /&gt; public String getText(Object element) {&lt;br /&gt;  if( element instanceof Family ) {&lt;br /&gt;   return ((Family)element).getName();&lt;br /&gt;  } else if( element instanceof Person ) {&lt;br /&gt;   return ((Person)element).getName() + " ("+format.format(((Person)element).getBirthday())+")";&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return "";&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you think this is cool? Because this was to trivial I thought I'll have to go further and after ~ 6h I had ported the the core-parts from the JFace-Databinding-Framework to GWT! So my UI-Binding-Code looks like this now:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// ....&lt;br /&gt;TextBox box = new TextBox();&lt;br /&gt;&lt;br /&gt;TextBoxObservableValue targetValue = new TextBoxObservableValue(box,TextBoxObservableValue.Change);&lt;br /&gt;IObservableValue modelValue = PEMFObservablesFactory.observeDetailValue(Realm.getDefault(), value, "id", String.class);&lt;br /&gt;&lt;br /&gt;DataBindingContext ctx = new DataBindingContext();&lt;br /&gt;UpdateValueStrategy targetToModel = new UpdateValueStrategy();&lt;br /&gt;targetToModel.setConverter(new IConverter() {&lt;br /&gt;&lt;br /&gt;    public Object convert(Object fromObject) {&lt;br /&gt;        return fromObject.toString();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Object getFromType() {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Object getToType() {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;UpdateValueStrategy modelToTarget = new UpdateValueStrategy();&lt;br /&gt;modelToTarget.setConverter(new IConverter() {&lt;br /&gt;&lt;br /&gt;    public Object convert(Object fromObject) {&lt;br /&gt;         return fromObject.toString();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Object getFromType() {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Object getToType() {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;ctx.bindValue(targetValue, modelValue, targetToModel, modelToTarget);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The GWT-Compiler translates all into JS-Code and because there's no Reflection-API available in this space I had to invent my own concept which I lend from EMF hence the name PEMF (for PoorEMF). Without question much of the Databinding-Framework is not working but at this stage I don't mind. The good thing is that all those low-level modules use fairly only classes already available from GWT so porting the whole framework is only a matter of time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-8328118888602637223?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/8328118888602637223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=8328118888602637223' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8328118888602637223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8328118888602637223'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/09/marriage-of-gwt-with-eclipse.html' title='The marriage of GWT with Eclipse-Technologies'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-3328651288086951082</id><published>2007-06-26T13:41:00.000+02:00</published><updated>2007-06-26T14:23:30.995+02:00</updated><title type='text'>Branding for Windows (How to create .ico files automatically)</title><content type='html'>After some time not having developed for Win32. I today had to brand a small RCP-application and once more completely forgot how to create this "Programm Launcher icon" using opensource tools.&lt;br /&gt;&lt;br /&gt;So I thought I have to restore this information somewhere I can find it later on:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;1. Get nice icons:&lt;/span&gt;&lt;br /&gt;The starting point for me is one of the open-source icon-collections (&lt;a href="http://www.icon-king.com/"&gt;www.icon-king.com/&lt;/a&gt;) or &lt;a href="http://websvn.kde.org/trunk/KDE/kdelibs/pics/oxygen/"&gt;oxygen&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;2. Boot you favorit Linux Distro (Sorry Win-Users for you this story ends here (or you grab CygWin)):&lt;/span&gt;&lt;br /&gt;Install the following tools:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;convert: Chances are high it's already installed&lt;/li&gt;&lt;br /&gt;&lt;li&gt;icotool: if not installed and not available for your distro (&lt;a href="http://www.nongnu.org/icoutils/"&gt;icoutils&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;3. Copy the images:&lt;/span&gt;&lt;br /&gt;Copy images the images the with the various sizes we need to a directory and given them eaually starting names. In my case these are:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;icon_16_16.png&lt;/li&gt;&lt;br /&gt;&lt;li&gt;icon_32_32.png&lt;/li&gt;&lt;br /&gt;&lt;li&gt;icon_48_48.png&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;4. Create .ico-File:&lt;/span&gt;&lt;br /&gt;The ico-File needed by RCP has to hold 6 images (32bit and 8bit).&lt;br /&gt;So we need to convert the images to 8bit ones:&lt;br /&gt;&lt;pre&gt;tom@vinea:icons&gt;&lt;br /&gt;&lt;br /&gt;mkdir target&lt;br /&gt;&lt;br /&gt;# Workaround because image magick doesn't seem to reduce colors when&lt;br /&gt;# converting from png to png&lt;br /&gt;convert -colors 256 icon_16_16.png target/tmp.gif&lt;br /&gt;convert -colors 256 target/tmp.gif target/icon_16_16_8bit.png&lt;br /&gt;&lt;br /&gt;convert -colors 256 icon_32_32.png target/tmp.gif&lt;br /&gt;convert -colors 256 target/tmp.gif target/icon_32_32_8bit.png&lt;br /&gt;&lt;br /&gt;convert -colors 256 icon_48_48.png target/tmp.gif&lt;br /&gt;convert -colors 256 target/tmp.gif target/icon_48_48_8bit.png&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Copy the original icons over to target-dir:&lt;br /&gt;&lt;pre&gt;tom@vinea:icons&gt;&lt;br /&gt;cp -f icon_16_16.png target&lt;br /&gt;cp -f icon_32_32.png target&lt;br /&gt;cp -f icon_48_48.png target&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Create the .ico-File using icotool:&lt;br /&gt;&lt;pre&gt;tom@vinea:icons&gt;&lt;br /&gt;icotool -c target/icon_16_16_8bit.png target/icon_16_16.png \&lt;br /&gt;target/icon_32_32_8bit.png target/icon_32_32.png \&lt;br /&gt;target/icon_48_48_8bit.png target/icon_48_48.png \&lt;br /&gt;&gt; target/icon.ico&lt;/pre&gt;&lt;br /&gt;Here's the full script for reference:&lt;br /&gt;&lt;pre&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;rm -rf target&lt;br /&gt;mkdir target&lt;br /&gt;&lt;br /&gt;# Workaround because image magick doesn't seem to reduce colors when&lt;br /&gt;# converting from png to png&lt;br /&gt;convert -colors 256 icon_16_16.png target/tmp.gif&lt;br /&gt;convert -colors 256 target/tmp.gif target/icon_16_16_8bit.png&lt;br /&gt;&lt;br /&gt;convert -colors 256 icon_32_32.png target/tmp.gif&lt;br /&gt;convert -colors 256 target/tmp.gif target/icon_32_32_8bit.png&lt;br /&gt;&lt;br /&gt;convert -colors 256 icon_48_48.png target/tmp.gif&lt;br /&gt;convert -colors 256 target/tmp.gif target/icon_48_48_8bit.png&lt;br /&gt;&lt;br /&gt;# Copy images&lt;br /&gt;cp -f icon_16_16.png target&lt;br /&gt;cp -f icon_32_32.png target&lt;br /&gt;cp -f icon_48_48.png target&lt;br /&gt;&lt;br /&gt;icotool -c target/icon_16_16_8bit.png target/icon_16_16.png \&lt;br /&gt;target/icon_32_32_8bit.png target/icon_32_32.png \&lt;br /&gt;target/icon_48_48_8bit.png target/icon_48_48.png \&lt;br /&gt;&gt; target/icon.ico&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-3328651288086951082?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/3328651288086951082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=3328651288086951082' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3328651288086951082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3328651288086951082'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/06/branding-for-windows-how-to-create-ico.html' title='Branding for Windows (How to create .ico files automatically)'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-8004692614027330290</id><published>2007-06-22T08:59:00.001+02:00</published><updated>2007-06-22T11:41:12.202+02:00</updated><title type='text'>Why do developers need Code-Snippets</title><content type='html'>Many of you may already have noticed that we started a Snippet collection for JFace-Elements like the one you know from SWT. Yesterday I updated the &lt;a href="http://wiki.eclipse.org/index.php/JFaceSnippets"&gt;wiki-page&lt;/a&gt; to show all snippets with a short description.&lt;br /&gt;&lt;br /&gt;Are Snippets only something we provide because we love our users soooo much? To me the answer is no.&lt;br /&gt;&lt;br /&gt;There are multiple reasons why snippets are a great thing:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Help for users to get started easily (Users)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Useful templates for users to log bugs (Users/Developers)&lt;br /&gt; Without a reproduceable testcase it is very hard to track bugs. Be prepared that JFace-Devs will insist even more on Snippets because now you have starting points to create Snippets easily. Insisting on snippets we often found out that we are not the one to blame but someone different (including the bugreporter itself)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Useful to mark bugs as invalid (Developers)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Useful to check no regressions are introduced (Developers)&lt;br /&gt; We also added snippets to our collection although their Classes are deprecated because this way we had an easy test case that we don't break any backwards contract. In our case we did this for TableTreeViewer&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Development example for new features (Developers)&lt;br /&gt; A good example is &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jface.snippets/Eclipse%20JFace%20Snippets/org/eclipse/jface/snippets/viewers/Snippet026TreeViewerTabEditing.java?view=markup"&gt;Snippet026&lt;/a&gt; which was used to develop Cell-Navigation and Editor-Activation throughout the whole 3.3 cycle. &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/Rnt3L5aoAiI/AAAAAAAAABA/UOjKfUBnvTk/s1600-h/snippet.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/Rnt3L5aoAiI/AAAAAAAAABA/UOjKfUBnvTk/s400/snippet.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5078784051065127458" /&gt;&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Advertise new API&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-8004692614027330290?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/8004692614027330290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=8004692614027330290' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8004692614027330290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8004692614027330290'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/06/why-do-we-devs-need-code-snippets.html' title='Why do developers need Code-Snippets'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_cWFEe8uui9o/Rnt3L5aoAiI/AAAAAAAAABA/UOjKfUBnvTk/s72-c/snippet.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-3594947812231165361</id><published>2007-06-12T23:29:00.000+02:00</published><updated>2007-06-13T00:19:16.833+02:00</updated><title type='text'>I'm perFLEXed</title><content type='html'>Yesterday Adobe released it's &lt;a href="http://labs.adobe.com/wiki/index.php/Flex_3"&gt;Flex 3&lt;/a&gt; and naturally I went there to see this new cool technology. I downloaded it and got an Eclipse with a GUI-Builder to create SWF-Applications. The nice thing is that Flex uses an XML-Format to store the GUI, ... . &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/Rm8Tg5aoAfI/AAAAAAAAAAo/zb6Y4l4UIy0/s1600-h/flex_1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/Rm8Tg5aoAfI/AAAAAAAAAAo/zb6Y4l4UIy0/s400/flex_1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5075296760959074802" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I guess you know what's coming now, don't you? I sat down and looked closer to find out that it would be fairly easy to write a Transformer to convert this in my custom EXSWT-Format used to build SWT/JFace-GUIs. After about 2 hours I now have a minimal XSLT-Stylesheet transforming MXML-Elements (currently mx:label, mx:combo, mx:button) to EXSWT and feeding it into my EXSWT-Lib. The only problem are different heights and widths needed by SWT and SWF but those are minor problems.&lt;br /&gt;&lt;br /&gt;Here's the original Flex-Project View one can export as an SWF-Application:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_cWFEe8uui9o/Rm8UdpaoAgI/AAAAAAAAAAw/gy7p3nlxACg/s1600-h/flex_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_cWFEe8uui9o/Rm8UdpaoAgI/AAAAAAAAAAw/gy7p3nlxACg/s400/flex_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5075297804636127746" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And here the one displayed using SWT-Widgets:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cWFEe8uui9o/Rm8U5ZaoAhI/AAAAAAAAAA4/G47v1iART-s/s1600-h/flex_3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cWFEe8uui9o/Rm8U5ZaoAhI/AAAAAAAAAA4/G47v1iART-s/s400/flex_3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5075298281377497618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is only a simple example but it shows how easy it is to define highlevel dialects on top of EXSWT which is a more or less lowlevel XML-Language.&lt;br /&gt;&lt;br /&gt;You can as always get the sources from my &lt;a href="http://publicsvn.bestsolution.at/repos/java"&gt;SVN&lt;/a&gt;-Repository and I have once more prepared a &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.exswt.examples/trunk/projectSet.psf"&gt;.psf&lt;/a&gt;-File for all Subclipse users.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-3594947812231165361?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/3594947812231165361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=3594947812231165361' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3594947812231165361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/3594947812231165361'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/06/im-perflexed.html' title='I&apos;m perFLEXed'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_cWFEe8uui9o/Rm8Tg5aoAfI/AAAAAAAAAAo/zb6Y4l4UIy0/s72-c/flex_1.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-7095710573411563946</id><published>2007-06-12T14:29:00.000+02:00</published><updated>2007-06-12T15:37:40.993+02:00</updated><title type='text'>Splash-Screen and Threads</title><content type='html'>Today I thought it would make my application look much more professional if the login-dialog is part of the splash-screen. The new extension point added in eclipse makes this possible and even provided an template implementation I could use without problem.&lt;br /&gt;&lt;br /&gt;The process is straight forward:&lt;ul&gt;&lt;li&gt;Create a Product Configuration (or use your existing one)&lt;/li&gt;&lt;li&gt;Switch to the Splash-Tab&lt;/li&gt;&lt;li&gt;Select in the Customization-Section the Interactive-Template&lt;/li&gt;&lt;li&gt;Switch to the Overview and "Launch an Eclipse application"&lt;/li&gt;&lt;/ul&gt;You are done. That was easy, wasn't it? To make this work you wouldn't need any help. The tricky thing I faced starts now. In my case I'm authentificating using a database-server and to not block the UI im doing this in a seperate thread and showing a ProgressBar in the mean while.&lt;br /&gt;&lt;br /&gt;When the application starts up the splash should look like this:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/Rm6XkJaoAdI/AAAAAAAAAAY/WHYB7CAJUHo/s1600-h/login.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/Rm6XkJaoAdI/AAAAAAAAAAY/WHYB7CAJUHo/s400/login.png" alt="" id="BLOGGER_PHOTO_ID_5075160477351805394" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;And while Logging into Database:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_cWFEe8uui9o/Rm6X05aoAeI/AAAAAAAAAAg/GcTbd5mac1Q/s1600-h/login2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_cWFEe8uui9o/Rm6X05aoAeI/AAAAAAAAAAg/GcTbd5mac1Q/s400/login2.png" alt="" id="BLOGGER_PHOTO_ID_5075160765114614242" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;So the first action is to add the "Check Login"-Label and the Progress bar like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private Label progressLabel;&lt;br /&gt;private ProgressBar progressBar;&lt;br /&gt;&lt;br /&gt;/** many lines of code */&lt;br /&gt;&lt;br /&gt;private void createProgressInfo() {&lt;br /&gt;    progressLabel = new Label(fCompositeLogin,SWT.NONE);&lt;br /&gt;    progressLabel.setText("Überprüfung läuft");&lt;br /&gt;    GridData data = new GridData();&lt;br /&gt;    data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT - 50;&lt;br /&gt;    progressLabel.setLayoutData(data);&lt;br /&gt;    progressLabel.setVisible(false);&lt;br /&gt;       &lt;br /&gt;    progressBar = new ProgressBar(fCompositeLogin,SWT.NONE|SWT.INDETERMINATE);&lt;br /&gt;    data = new GridData(SWT.NONE, SWT.NONE, false, false);&lt;br /&gt;    data.widthHint = F_TEXT_WIDTH_HINT;&lt;br /&gt;    data.horizontalSpan = 2;&lt;br /&gt;    progressBar.setLayoutData(data);&lt;br /&gt;    progressBar.setVisible(false);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void toggelCheckProgress(boolean state) {&lt;br /&gt;    progressLabel.setVisible(state);&lt;br /&gt;    progressBar.setVisible(state);&lt;br /&gt;    fCompositeLogin.layout();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We initially set the those two widgets invisible and show them later when we start the authentification. To make this easy we add helper method to turn the visibility on and off.&lt;br /&gt;&lt;br /&gt;The next part is to modify the handleButtonOKWidgetSelected()-method like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private volatile int loginStatus = -1;&lt;br /&gt;&lt;br /&gt;/** many lines of code */&lt;br /&gt;&lt;br /&gt;private void handleButtonOKWidgetSelected() {&lt;br /&gt;    final String username = fTextUsername.getText();&lt;br /&gt;    final String password = fTextPassword.getText();&lt;br /&gt;       &lt;br /&gt;    toggelCheckProgress(true);&lt;br /&gt;       &lt;br /&gt;    Thread t = new Thread() {&lt;br /&gt;&lt;br /&gt;        public void run() {&lt;br /&gt;            if( login(username,password) ) {&lt;br /&gt;                loginStatus = 1;&lt;br /&gt;            } else {&lt;br /&gt;                loginStatus = 2;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    t.start();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The content of the method is straight forward. It starts a thread and executes a potentially long running task in our case login(String,String). Our task is now to sync back to the gui-thread and:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Proceed with start up (hiding the login details from the splash-screen)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Display Login-Failure to the user&lt;/li&gt;&lt;/ol&gt;Normally you do this using Display#(a)syncExec() but that's not available in the splash-screen. The work-around I used as you see above is setting a special variable named loginStatus. The trick is now that you add checks for this variable to the Event-Loop method which looks like this afterwards:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private void doEventLoop() {&lt;br /&gt;    Shell splash = getSplash();&lt;br /&gt;    while (fAuthenticated == false) {&lt;br /&gt;        if (splash.getDisplay().readAndDispatch() == false) {&lt;br /&gt;            if( loginStatus == 1 ) {&lt;br /&gt;                loginSuccess();&lt;br /&gt;            } else if( loginStatus == 2 ) {&lt;br /&gt;                loginFailure();&lt;br /&gt;            }&lt;br /&gt;               &lt;br /&gt;            splash.getDisplay().sleep();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Your are nearly done now the only two methods missing are:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;private void loginSuccess() {&lt;br /&gt;    toggelCheckProgress(false);&lt;br /&gt;    fCompositeLogin.setVisible(false);&lt;br /&gt;    fAuthenticated = true;&lt;br /&gt;    loginStatus = -1;&lt;br /&gt;}&lt;br /&gt;   &lt;br /&gt;private void loginFailure() {&lt;br /&gt;    toggelCheckProgress(false);&lt;br /&gt;    loginStatus = -1;&lt;br /&gt;    MessageDialog.openError(&lt;br /&gt;        getSplash(),&lt;br /&gt;        "Authentification failed",&lt;br /&gt;        "Your username or password was wrong");&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Well that's all. You are done and have a splash screen who is authenticating without blocking the UI-thread without Display#(a)syncExec. I need to thank &lt;a href="http://eclipse.pookzilla.net/index.php"&gt;Kim&lt;/a&gt; for pointing me to this solution and she promised that there will be added API in 3.4 to make this more easier.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-7095710573411563946?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/7095710573411563946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=7095710573411563946' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7095710573411563946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/7095710573411563946'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/06/splash-screen-and-threads.html' title='Splash-Screen and Threads'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_cWFEe8uui9o/Rm6XkJaoAdI/AAAAAAAAAAY/WHYB7CAJUHo/s72-c/login.png' height='72' width='72'/><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-6170225661742382280</id><published>2007-06-09T19:31:00.000+02:00</published><updated>2007-06-11T08:03:21.972+02:00</updated><title type='text'>Things are evolving</title><content type='html'>It's been now a few months I started reworking my the first draft implementation which already provided many interesting things but there was still Java-Code needed to bind-POJOs and to interact with the Datasource.&lt;br /&gt;&lt;br /&gt;What's new:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;XBL (XmlBindingLanguage) to connect your model with the help of the databinding framework to SWT-Widgets&lt;/li&gt;&lt;li&gt;Switched to work on top of the Eclipse-Command-Framework&lt;/li&gt;&lt;li&gt;Added themeing framework&lt;br /&gt;&lt;/li&gt;&lt;li&gt;API cleanup&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Refactoring, refactoring&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I still see this as a research project which is not useable for production in the near future but if the community likes what I'm doing here these are the next things on my list:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;implement INSERT/UPDATE/DELETE on top of the COMMAND-Framework&lt;/li&gt;&lt;li&gt;evolve XBL (new features, refactoring, ...)&lt;/li&gt;&lt;li&gt;Transformer-Framework for EXSWT and XBL (use a highlevel dialect translated to those low-level ones)&lt;/li&gt;&lt;li&gt;Implement new provider which is able to fetch XBL and EXSWT files via HTTP. This would make changing the GUI without the need to redeploy your application to the client (what a cool feature RAP without the Browser :-)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Refactoring, Refactoring, ....&lt;/li&gt;&lt;/ul&gt;If you are interested you can checkout the current project from my companies &lt;a href="http://publicsvn.bestsolution.at/repos/"&gt;SVN-Repository&lt;/a&gt;. When using the Subclipse-Plugin I've added you a &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.dataforms.test/trunk/projectSet.psf"&gt;.psf&lt;/a&gt;-File to the project helping you to easily checkout all needed projects from SVN.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-6170225661742382280?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/6170225661742382280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=6170225661742382280' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/6170225661742382280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/6170225661742382280'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/06/things-are-evolveing.html' title='Things are evolving'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-5844203162928409875</id><published>2007-03-16T20:16:00.000+01:00</published><updated>2007-03-16T20:22:36.337+01:00</updated><title type='text'>New JFace API is in place</title><content type='html'>After ~8 months of work we checked in the new JFace-API with many exciting features in to CVS just a few hours ago. To see how powerful this new API is take a look at the this &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jface.snippets/Eclipse%20JFace%20Snippets/org/eclipse/jface/snippets/viewers/Snippet026TreeViewerTabEditing.java?view=markup"&gt;snippet&lt;/a&gt;. Test it and report us back problems if there are any.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-5844203162928409875?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/5844203162928409875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=5844203162928409875' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5844203162928409875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5844203162928409875'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/03/new-jface-api-is-in-place.html' title='New JFace API is in place'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-272010332394001919</id><published>2007-03-07T22:56:00.000+01:00</published><updated>2007-03-07T23:54:07.705+01:00</updated><title type='text'>XSWT, Databinding, ... =&gt; DataForms</title><content type='html'>It's sometime ago I started rewriting the current XSWT implementation from David Orme. Now I saw the &lt;a href="http://www.eclipsezone.com/eclipse/forums/t91164.rhtml"&gt;Blog&lt;/a&gt; from Alex about Databinding and thought it's time to let you all know that I'm working on a set of plugins which have the following focus:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use XSWT (or any other Definition Language) to create the GUI&lt;/li&gt;&lt;li&gt;Dynamically link together Forms (Master/Detail, ...) using Eclipse Extension Points&lt;/li&gt;&lt;li&gt;Provide an XML-Dialect to define the binding and data retrieval in XML&lt;/li&gt;&lt;/ul&gt;Although it's still a long way to go and many many things are not as smooth as they could be but I finally have something to present using a small application.&lt;br /&gt;&lt;br /&gt;Here's a screenshot of the small application. Currently you can only add items to it but that's working really fine.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cWFEe8uui9o/Re86rX7ap_I/AAAAAAAAAAM/Uv0O1klsUWw/s1600-h/screen.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_cWFEe8uui9o/Re86rX7ap_I/AAAAAAAAAAM/Uv0O1klsUWw/s400/screen.png" alt="" id="BLOGGER_PHOTO_ID_5039311024882886642" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The key point is how this all works technically and what should I say it simply works. There are still about 200 lines of code needed to make this work because the binding has to be done manually at the moment. Go and get the code from our companies &lt;a href="http://publicsvn.bestsolution.at/repos/java"&gt;SVN-Repository&lt;/a&gt; and give me feedback, I've added a &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.dataforms.test/trunk/projectSet.psf"&gt;projectSet.psf&lt;/a&gt; so you can easily check out all needed modules.&lt;br /&gt;&lt;br /&gt;The next things I want to address are the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Databinding:&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Adding missing features (Deletion, ...)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;XML-Language for Data-Retrieval and Binding (XBL)&lt;/li&gt;&lt;li&gt;Finishing Event System (= needed for scripting support)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Finalizing/Stabiallizing ExtensionPoints and API&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Adding API for a highly Configurable Privileges System&lt;/li&gt;&lt;li&gt;Provide XDOM (= DOM you know from Browsers to easily script Dataforms)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;EXSWT:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Transformation Chain (other highlevel dialects transformed to EXSWT which near to SWT/JFace)&lt;/li&gt;&lt;li&gt;Work on XSD-Schema and XML-Editor with Live-Preview&lt;/li&gt;&lt;li&gt;WYSIWYG-Editor&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Did I spark your interest? Give me your comments, I know there are other projects around with a fairly similar focus but some of the features are unique to this idea I think but are essential for datacentric applications.&lt;br /&gt;&lt;br /&gt;Oh in the end I have had written a &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.dataforms/trunk/design/"&gt;design document&lt;/a&gt; which is not up-to-date but provide informations where I'm coming from and where I'm going to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-272010332394001919?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/272010332394001919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=272010332394001919' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/272010332394001919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/272010332394001919'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/03/xswt-databinding-dataforms.html' title='XSWT, Databinding, ... =&gt; DataForms'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_cWFEe8uui9o/Re86rX7ap_I/AAAAAAAAAAM/Uv0O1klsUWw/s72-c/screen.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-5479857655616250126</id><published>2007-03-06T09:20:00.000+01:00</published><updated>2007-03-06T09:31:05.777+01:00</updated><title type='text'>EclipseCon community awards</title><content type='html'>I just read the &lt;a href="http://www.eclipsezone.com/eclipse/forums/t91124.rhtml"&gt;post&lt;/a&gt; from Alex about the community awards and couldn't believe finding my name under the ones finally winning the award. Thanks to everybody who voted for me. Now I'm even more disappointed that I couldn't afford attending the eclipse con but maybe I can make it to the &lt;a href="http://www.eclipsecon.org/2007/index.php?page=sub/&amp;id=4242"&gt;Eclipse Summit Europe&lt;/a&gt;.&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-5479857655616250126?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/5479857655616250126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=5479857655616250126' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5479857655616250126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/5479857655616250126'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/03/eclipsecon-community-awards.html' title='EclipseCon community awards'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-1384386285902362626</id><published>2007-03-03T12:25:00.000+01:00</published><updated>2007-03-03T12:30:43.883+01:00</updated><title type='text'>My first commit</title><content type='html'>What a great day my first commit to the eclipse cvs-repository. It's a small one patching JavaDoc for a not working API but it's a start. Here's the &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jface/src/org/eclipse/jface/viewers/TreeViewer.java?view=diff&amp;r1=text&amp;amp;tr1=1.77&amp;r2=1.78%3AHEAD&amp;amp;tr2=1.1&amp;amp;diff_format=h"&gt;patch&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-1384386285902362626?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/1384386285902362626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=1384386285902362626' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1384386285902362626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/1384386285902362626'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/03/my-first-commit.html' title='My first commit'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-46160309661596839</id><published>2007-01-26T00:36:00.000+01:00</published><updated>2007-01-26T00:58:32.832+01:00</updated><title type='text'>TableViewers and Nativelooking Checkboxes</title><content type='html'>Many of us have faced the same problem that if you needed to use checkboxes in your TableViewer/TreeViewer they look not native because they are pictures. I had some free minutes and thought that it's time to create a LabelProvider which is able to create platform look-and-feel images out of the box. It's not 100% native but it's not far away. The trick is to automatically create screenshots from CheckBox-Buttons and use them. This way the checkboxes look native on all platforms and correspond to the current look and feel of the platform.&lt;br /&gt;&lt;br /&gt;Here's the code if someone is interested:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package at.bestsolution.jface.viewers;&lt;br /&gt;&lt;br /&gt;import org.eclipse.jface.resource.JFaceResources;&lt;br /&gt;import org.eclipse.jface.viewers.ColumnLabelProvider;&lt;br /&gt;import org.eclipse.jface.viewers.ColumnViewer;&lt;br /&gt;import org.eclipse.swt.SWT;&lt;br /&gt;import org.eclipse.swt.graphics.GC;&lt;br /&gt;import org.eclipse.swt.graphics.Image;&lt;br /&gt;import org.eclipse.swt.graphics.Point;&lt;br /&gt;import org.eclipse.swt.widgets.Button;&lt;br /&gt;import org.eclipse.swt.widgets.Shell;&lt;br /&gt;&lt;br /&gt;public abstract class EmulatedNativeCheckBoxLabelProvider &lt;br /&gt;  extends ColumnLabelProvider &lt;br /&gt;{&lt;br /&gt;  private static final String CHECKED_KEY = "CHECKED";&lt;br /&gt;  private static final String UNCHECK_KEY = "UNCHECKED";&lt;br /&gt; &lt;br /&gt;  public EmulatedNativeCheckBoxLabelProvider(ColumnViewer viewer) {&lt;br /&gt;    if( JFaceResources.getImageRegistry().getDescriptor(CHECKED_KEY) == null ) {&lt;br /&gt;      JFaceResources.getImageRegistry().put(UNCHECK_KEY, &lt;br /&gt;        makeShot(viewer.getControl().getShell(),false));&lt;br /&gt;      JFaceResources.getImageRegistry().put(CHECKED_KEY,&lt;br /&gt;        makeShot(viewer.getControl().getShell(),true));&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  private Image makeShot(Shell shell, boolean type) {&lt;br /&gt;    Shell s = new Shell(shell,SWT.NO_TRIM);&lt;br /&gt;    Button b = new Button(s,SWT.CHECK);&lt;br /&gt;    b.setSelection(type);&lt;br /&gt;    Point bsize = b.computeSize(SWT.DEFAULT, SWT.DEFAULT);&lt;br /&gt;    b.setSize(bsize);&lt;br /&gt;    b.setLocation(0, 0);&lt;br /&gt;    s.setSize(bsize);&lt;br /&gt;    s.open();&lt;br /&gt;&lt;br /&gt;    GC gc = new GC(b);&lt;br /&gt;    Image image = new Image(shell.getDisplay(), bsize.x, bsize.y);&lt;br /&gt;    gc.copyArea(image, 0, 0);&lt;br /&gt;    gc.dispose();&lt;br /&gt;    &lt;br /&gt;    s.close();&lt;br /&gt;    &lt;br /&gt;    return image;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Image getImage(Object element) {&lt;br /&gt;    if( isChecked(element) ) {&lt;br /&gt;      return JFaceResources.getImageRegistry().&lt;br /&gt;               getDescriptor(CHECKED_KEY).createImage();&lt;br /&gt;    } else {&lt;br /&gt;      return JFaceResources.getImageRegistry().&lt;br /&gt;               getDescriptor(UNCHECK_KEY).createImage();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected abstract boolean isChecked(Object element);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I haven't really tested this (currently only on WinXP) but I suppose it's working on all platforms. You can also get the code from my &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.jface/branches/3_3_support/"&gt;svn-repository&lt;/a&gt; which holds some other interesting utilities and viewer classes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-46160309661596839?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/46160309661596839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=46160309661596839' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/46160309661596839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/46160309661596839'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/01/tableviewers-and-nativelooking.html' title='TableViewers and Nativelooking Checkboxes'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-8964544664550921189</id><published>2007-01-18T22:42:00.000+01:00</published><updated>2007-01-19T18:33:24.616+01:00</updated><title type='text'>The new faces of JFace (part2)</title><content type='html'>&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;The&lt;/span&gt; last &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;time&lt;/span&gt; I &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;showed&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;programming&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;model&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;we&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;introduce&lt;/span&gt;d &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;JFace&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;make&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;it&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;feel&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;like&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;programming&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;SWT&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;But&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;has&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;this&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;been&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;only&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;reason&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;that&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;we&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;decided&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;add&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;this&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;new&lt;/span&gt; API &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;beside&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;existing&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;one&lt;/span&gt; (&lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;ILabelProvider&lt;/span&gt;, &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;ITableLabelProvider&lt;/span&gt;, &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;IColorProvider&lt;/span&gt;, &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;ITableColorProvider&lt;/span&gt;, &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;IFontProvider&lt;/span&gt;, &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;ITableFontProvider&lt;/span&gt;&lt;/span&gt;) .&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;Sure&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;enough&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;it&lt;/span&gt; was &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;not&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;only&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;reason&lt;/span&gt;. First &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;of&lt;/span&gt; all &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;many&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;newcomers&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;have&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;been&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;confused&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;by&lt;/span&gt; all &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;those&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;NON&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;MANDATORY&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;interfaces&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;control&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;different&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;aspects&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;of&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_66"&gt;items&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_67"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_68"&gt;we&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_69"&gt;faced&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_70"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_71"&gt;problem&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_72"&gt;that&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_73"&gt;whenever&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_74"&gt;SWT&lt;/span&gt;-&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_75"&gt;Provided&lt;/span&gt; a &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_76"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_77"&gt;feature&lt;/span&gt; e.g. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_78"&gt;Owner&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_79"&gt;Draw&lt;/span&gt; Support in 3.2 &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_80"&gt;we&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_81"&gt;would&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_82"&gt;have&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_83"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_84"&gt;add&lt;/span&gt; a &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_85"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_86"&gt;interface&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_87"&gt;type&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_88"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_89"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_90"&gt;support&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_91"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_92"&gt;features&lt;/span&gt; e.g. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_93"&gt;ToolTip&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_94"&gt;support&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_95"&gt;for&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_96"&gt;table&lt;/span&gt;/&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_97"&gt;tree&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_98"&gt;cells&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_99"&gt;we&lt;/span&gt; also &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_100"&gt;had&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_101"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_102"&gt;provide&lt;/span&gt; a &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_103"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_104"&gt;interface&lt;/span&gt;. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_105"&gt;We&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_106"&gt;decided&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_107"&gt;that&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_108"&gt;this&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_109"&gt;is&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_110"&gt;not&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_111"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_112"&gt;way&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_113"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_114"&gt;go&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_115"&gt;for&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_116"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_117"&gt;future&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_118"&gt;we&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_119"&gt;sat&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_120"&gt;down&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_121"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_122"&gt;thought&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_123"&gt;about&lt;/span&gt; a &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_124"&gt;complete&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_125"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_126"&gt;structure&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_127"&gt;below&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_128"&gt;JFace&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_129"&gt;tree&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_130"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_131"&gt;table&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_132"&gt;support&lt;/span&gt;. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_133"&gt;We&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_134"&gt;added&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_135"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_136"&gt;idea&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_137"&gt;of&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_138"&gt;rows&lt;/span&gt; (&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_139"&gt;ViewerRow&lt;/span&gt;) &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_140"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_141"&gt;cells&lt;/span&gt; (&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_142"&gt;ViewerCell&lt;/span&gt;) &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_143"&gt;abstracting&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_144"&gt;common&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_145"&gt;things&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_146"&gt;provided&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_147"&gt;of&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_148"&gt;TreeItem&lt;/span&gt;&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_149"&gt;and&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_150"&gt;TableItem&lt;/span&gt;&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_151"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_152"&gt;completely&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_153"&gt;hiding&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_154"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_155"&gt;widget&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_156"&gt;specific&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_157"&gt;things&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_158"&gt;into&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_159"&gt;this&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_160"&gt;class&lt;/span&gt;. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_161"&gt;The&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_162"&gt;abstraction&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_163"&gt;level&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_164"&gt;this&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_165"&gt;provided&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_166"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_167"&gt;us&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_168"&gt;made&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_169"&gt;it&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_170"&gt;possible&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_171"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_172"&gt;provide&lt;/span&gt; a &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_173"&gt;common&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_174"&gt;class&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_175"&gt;named&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_176"&gt;ColumnViewer&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_177"&gt;what&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_178"&gt;have&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_179"&gt;we&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_180"&gt;learned&lt;/span&gt; so &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_181"&gt;far&lt;/span&gt;:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_182"&gt;We&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_183"&gt;don&lt;/span&gt;'t &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_184"&gt;need&lt;/span&gt; all &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_185"&gt;those&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_186"&gt;interfaces&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_187"&gt;any&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_188"&gt;more&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_189"&gt;We&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_190"&gt;have&lt;/span&gt; a &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_191"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_192"&gt;abstraction&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_193"&gt;level&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_194"&gt;for&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_195"&gt;column&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_196"&gt;based&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_197"&gt;viewers&lt;/span&gt; (&lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_198"&gt;ViewerRow&lt;/span&gt;&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_199"&gt;ViewerCell&lt;/span&gt;&lt;/span&gt;)&lt;/li&gt;&lt;li&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_200"&gt;We&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_201"&gt;have&lt;/span&gt; a &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_202"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_203"&gt;base&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_204"&gt;class&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_205"&gt;named&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_206"&gt;ColumnViewer&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;So &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_207"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_208"&gt;may&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_209"&gt;ask&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_210"&gt;what&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_211"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_212"&gt;should&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_213"&gt;use&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_214"&gt;if&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_215"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_216"&gt;can&lt;/span&gt;'t &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_217"&gt;use&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_218"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_219"&gt;old&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_220"&gt;interfaces&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_221"&gt;any&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_222"&gt;more&lt;/span&gt;. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_223"&gt;Well&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_224"&gt;the&lt;/span&gt; answer &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_225"&gt;is&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_226"&gt;ColumnLabelProvider&lt;/span&gt;&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_227"&gt;or&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_228"&gt;if&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_229"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_230"&gt;want&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_231"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_232"&gt;implement&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_233"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_234"&gt;whole&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_235"&gt;cell&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_236"&gt;behaviour&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_237"&gt;your&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_238"&gt;own&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_239"&gt;it&lt;/span&gt;'s &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_240"&gt;abstract&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_241"&gt;base&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_242"&gt;class&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_243"&gt;named&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_244"&gt;CellLabelProvider&lt;/span&gt;&lt;/span&gt;. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_245"&gt;The&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_246"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_247"&gt;ColumnLabelProvider&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_248"&gt;combines&lt;/span&gt; all &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_249"&gt;currently&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_250"&gt;know&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_251"&gt;interfaces&lt;/span&gt; (&lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_252"&gt;ILabelProvider&lt;/span&gt;&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_253"&gt;IFontProvider&lt;/span&gt;&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_254"&gt;IColorProvider&lt;/span&gt;&lt;/span&gt;). &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_255"&gt;There&lt;/span&gt;'s &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_256"&gt;no&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_257"&gt;base&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_258"&gt;class&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_259"&gt;visible&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_260"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_261"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_262"&gt;supporting&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_263"&gt;ITable&lt;/span&gt;*&lt;/span&gt;-&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_264"&gt;interfaces&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_265"&gt;because&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_266"&gt;those&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_267"&gt;interface&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_268"&gt;put&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_269"&gt;limitations&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_270"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_271"&gt;tables&lt;/span&gt; I'&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_272"&gt;ll&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_273"&gt;show&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_274"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_275"&gt;later&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_276"&gt;let&lt;/span&gt;'s &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_277"&gt;now&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_278"&gt;explore&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_279"&gt;how&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_280"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_281"&gt;use&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_282"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_283"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_284"&gt;ColumnLabelProvider&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_285"&gt;interface&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_286"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_287"&gt;how&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_288"&gt;it&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_289"&gt;is&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_290"&gt;used&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_291"&gt;TableViewer&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_292"&gt;viewer&lt;/span&gt; = &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_293"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_294"&gt;TableViewer&lt;/span&gt;(&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_295"&gt;parent&lt;/span&gt;,&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_296"&gt;SWT&lt;/span&gt;.&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_297"&gt;FULL&lt;/span&gt;_&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_298"&gt;SELECTION&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_299"&gt;TableViewerColumn&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_300"&gt;column&lt;/span&gt; = &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_301"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_302"&gt;TableViewerColumn&lt;/span&gt;(&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_303"&gt;viewer&lt;/span&gt;,&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_304"&gt;SWT&lt;/span&gt;.&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_305"&gt;NONE&lt;/span&gt;);&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_306"&gt;column&lt;/span&gt;.&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_307"&gt;setLabelProvider&lt;/span&gt;(&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_308"&gt;new&lt;/span&gt; StockNameProvider());&lt;br /&gt;column.getColumn().setText("Name");&lt;br /&gt;&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_309"&gt;TableViewerColumn&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_310"&gt;column&lt;/span&gt; = &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_311"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_312"&gt;TableViewerColumn&lt;/span&gt;(&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_313"&gt;viewer&lt;/span&gt;,&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_314"&gt;SWT&lt;/span&gt;.&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_315"&gt;NONE&lt;/span&gt;);&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_316"&gt;column&lt;/span&gt;.&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_317"&gt;setLabelProvider&lt;/span&gt;(&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_318"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_319"&gt;StockValueProvider&lt;/span&gt;());&lt;br /&gt;column.getColumn().setText("&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_320"&gt;Modification&lt;/span&gt;");&lt;br /&gt;&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_321"&gt;public&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_322"&gt;class&lt;/span&gt; StockNameProvider &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_323"&gt;extends&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_324"&gt;ColumnLableProvider&lt;/span&gt; {&lt;br /&gt; @&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_325"&gt;Override&lt;/span&gt;&lt;br /&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_326"&gt;public&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_327"&gt;String&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_328"&gt;getText&lt;/span&gt;(&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_348"&gt;Object&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_349"&gt;element&lt;/span&gt;) {&lt;br /&gt;    &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_329"&gt;return&lt;/span&gt; ((Stock)&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_349"&gt;element&lt;/span&gt;).&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_331"&gt;name&lt;/span&gt;;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_332"&gt;public&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_333"&gt;class&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_334"&gt;StockValueProvider&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_335"&gt;extends&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_336"&gt;ColumnLabelProvider&lt;/span&gt; {&lt;br /&gt;&lt;br /&gt; @&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_337"&gt;Override&lt;/span&gt;&lt;br /&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_338"&gt;public&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_339"&gt;String&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_340"&gt;getText&lt;/span&gt;(&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_348"&gt;Object&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_349"&gt;element&lt;/span&gt;) {&lt;br /&gt;    &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_341"&gt;return&lt;/span&gt; ((Stock)&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_349"&gt;element&lt;/span&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_342"&gt;&lt;/span&gt;).&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_342"&gt;modification.double&lt;/span&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_343"&gt;Value&lt;/span&gt;() + "%";&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_344"&gt;Override&lt;/span&gt;&lt;br /&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_345"&gt;public&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_346"&gt;Color&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_347"&gt;getForeground&lt;/span&gt;(&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_348"&gt;Object&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_349"&gt;element&lt;/span&gt;) {&lt;br /&gt;    &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_350"&gt;if&lt;/span&gt;( ((Stock)&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_351"&gt;element&lt;/span&gt;)&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_352"&gt;modiciation&lt;/span&gt;.&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_342"&gt;double&lt;/span&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_343"&gt;Value&lt;/span&gt;() &amp;lt; 0 ) {&lt;br /&gt;        &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_354"&gt;return&lt;/span&gt; getDisplay().getSystemColor(SWT.COLOR_RED);&lt;br /&gt;    } &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_355"&gt;else&lt;/span&gt; {&lt;br /&gt;        &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_356"&gt;return&lt;/span&gt; getDisplay().getSystemColor(SWT.COLOR_GREEN);&lt;br /&gt;    }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_357"&gt;You&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_358"&gt;may&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_359"&gt;now&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_360"&gt;argue&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_361"&gt;that&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_362"&gt;this&lt;/span&gt; was &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_363"&gt;easier&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_364"&gt;with&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_365"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_366"&gt;old&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_367"&gt;ITable&lt;/span&gt;*&lt;/span&gt;-API &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_368"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_369"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_370"&gt;are&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_371"&gt;true&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_372"&gt;but&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_373"&gt;from&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_374"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_375"&gt;point&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_376"&gt;of&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_377"&gt;reusability&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_378"&gt;this&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_379"&gt;version&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_380"&gt;is&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_381"&gt;much&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_382"&gt;more&lt;/span&gt; flexible &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_383"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_384"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_385"&gt;can&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_386"&gt;reuse&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_387"&gt;your&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_388"&gt;LabelProviders&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_389"&gt;for&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_390"&gt;many&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_391"&gt;different&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_392"&gt;TableViewers&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_393"&gt;because&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_394"&gt;they&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_395"&gt;don&lt;/span&gt;'t hold &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_396"&gt;any&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_397"&gt;index&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_398"&gt;informations&lt;/span&gt;. &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_399"&gt;Another&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_400"&gt;thing&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_401"&gt;is&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_402"&gt;that&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_403"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_404"&gt;needed&lt;/span&gt; a &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_405"&gt;bunch&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_406"&gt;of&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_407"&gt;custom&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_408"&gt;code&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_409"&gt;if&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_410"&gt;you&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_411"&gt;wanted&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_412"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_413"&gt;columns&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_414"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_415"&gt;be&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_416"&gt;reordable&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_417"&gt;with&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_418"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_419"&gt;old&lt;/span&gt; API &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_420"&gt;this&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_421"&gt;is&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_422"&gt;not&lt;/span&gt; an &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_423"&gt;issue&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_424"&gt;any&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_425"&gt;more&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_426"&gt;with&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_427"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_428"&gt;new&lt;/span&gt; API &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_429"&gt;because&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_430"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_431"&gt;LabelProvider&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_432"&gt;is&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_433"&gt;directly&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_434"&gt;connected&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_435"&gt;to&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_436"&gt;the&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_437"&gt;column&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_438"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_439"&gt;moves&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_440"&gt;with&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_441"&gt;it&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_442"&gt;Next&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_443"&gt;time&lt;/span&gt; I'&lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_444"&gt;ll&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_445"&gt;continue&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_446"&gt;with&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_447"&gt;some&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_448"&gt;nice&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_449"&gt;new&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_450"&gt;LabelProvider&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_451"&gt;features&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_452"&gt;like&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_453"&gt;ToolTip&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_454"&gt;support&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_455"&gt;and&lt;/span&gt; &lt;span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_456"&gt;OwnerDraw&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-8964544664550921189?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/8964544664550921189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=8964544664550921189' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8964544664550921189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/8964544664550921189'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/01/new-faces-of-jface-part2.html' title='The new faces of JFace (part2)'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-2234103666433588977</id><published>2007-01-05T11:15:00.000+01:00</published><updated>2007-01-05T12:00:15.076+01:00</updated><title type='text'>What items are visible in Table/Tree?</title><content type='html'>Have you often asked yourself which items are visibile in Table/Tree. Maybe you need these informations to dispose system-resources (e.g. if you have different images in every row you can easily run out of system resources).&lt;br /&gt;&lt;br /&gt;What to do? There's no SWT-API available to calculate this information. So we need a bunch of custom code to make this work. The following codefragements are only a first rough test case and they need JFace from 3.3M4 and a patch from &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=151295"&gt;bug 151295&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;Step 1: Setup the infrastructure&lt;br /&gt;- Event object to inform consumers about the change of visible rows&lt;br /&gt;&lt;pre&gt;public class ViewerRowStateChangedEvent extends EventObject {&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; public ArrayList itemsHidden;&lt;br /&gt;&lt;br /&gt; public ArrayList itemsVisible;&lt;br /&gt;&lt;br /&gt; public ViewerRowStateChangedEvent(Object source) {&lt;br /&gt;   super(source);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;- ViewerRowStateChangeListener for consumers to implement&lt;br /&gt;&lt;pre&gt;public interface ViewerRowStateChangeListener {&lt;br /&gt; public void itemStateChangedListener(ViewerRowStateChangedEvent event);&lt;br /&gt;}&lt;/pre&gt; Step 2: Create an AbstractClass implementing the visible row logic on base of ViewerRow and the new API whichn will hopefully added by &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=151295"&gt;bug 151295&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;public abstract class AbstractViewerRowVisibilityStateSupport {&lt;br /&gt; private ArrayList currentItems = new ArrayList();&lt;br /&gt;&lt;br /&gt; private ColumnViewer columnViewer;&lt;br /&gt;&lt;br /&gt; private ListenerList listenerList = new ListenerList();&lt;br /&gt; &lt;br /&gt; public AbstractViewerRowVisibilityStateSupport(ColumnViewer columnViewer) {&lt;br /&gt;   this.columnViewer = columnViewer;&lt;br /&gt;  &lt;br /&gt;   Listener l = new Listener() {&lt;br /&gt;     public void handleEvent(Event event) {&lt;br /&gt;       ArrayList list = recalculateVisibleItems();&lt;br /&gt;       ArrayList itemsVisible = new ArrayList();&lt;br /&gt;&lt;br /&gt;       Iterator it = list.iterator();&lt;br /&gt;       Object obj;&lt;br /&gt;&lt;br /&gt;       while( it.hasNext() ) {&lt;br /&gt;         obj = it.next();&lt;br /&gt;&lt;br /&gt;         if( ! currentItems.remove(obj) ) {&lt;br /&gt;           itemsVisible.add(obj);&lt;br /&gt;         }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       ArrayList hiddenItems = currentItems;&lt;br /&gt;       currentItems = list;&lt;br /&gt;&lt;br /&gt;       if( itemsVisible.size() &amp;gt; 0 || hiddenItems.size() &amp;gt; 0 ) {&lt;br /&gt;         if( ! listenerList.isEmpty() ) {&lt;br /&gt;           ColumnViewer v;&lt;br /&gt;           v = AbstractViewerRowVisibilityStateSupport.this.columnViewer;&lt;br /&gt;&lt;br /&gt;           ViewerRowStateChangedEvent ev = new ViewerRowStateChangedEvent(v);&lt;br /&gt;     ev.itemsHidden = hiddenItems;&lt;br /&gt;     ev.itemsVisible = itemsVisible;&lt;br /&gt;&lt;br /&gt;           Object[] listeners = listenerList.getListeners();&lt;br /&gt;           ViewerRowStateChangeListener l;&lt;br /&gt; &lt;br /&gt;     for( int i = 0; i &amp;lt; listeners.length; i++ ) {&lt;br /&gt;             l = (ViewerRowStateChangeListener)listeners[i];&lt;br /&gt;       l.itemStateChangedListener(ev);&lt;br /&gt;     }&lt;br /&gt;         }&lt;br /&gt;       }     &lt;br /&gt;     }&lt;br /&gt;   };&lt;br /&gt;   addListeners(getControl(),l);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected abstract void addListeners(Scrollable control, Listener l);&lt;br /&gt;&lt;br /&gt; protected abstract ViewerRow getTopRow();&lt;br /&gt;&lt;br /&gt; protected Scrollable getControl() {&lt;br /&gt;   return (Scrollable)columnViewer.getControl();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void addItemStateListener(ViewerRowStateChangeListener listener) {&lt;br /&gt;   listenerList.add(listener);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private ArrayList recalculateVisibleItems() {&lt;br /&gt;   ArrayList list = new ArrayList(100);&lt;br /&gt;   ViewerRow topRow = getTopRow();&lt;br /&gt;&lt;br /&gt;   if( topRow != null ) {&lt;br /&gt;     int totalHeight = getControl().getClientArea().height;&lt;br /&gt;     int itemHeight = topRow.getBounds().height;&lt;br /&gt;&lt;br /&gt;     list.add(topRow);&lt;br /&gt;&lt;br /&gt;     int tmp = topRow.getBounds().x+itemHeight;&lt;br /&gt;     // tmp += itemHeight;&lt;br /&gt;     // this would be more precise but half rows&lt;br /&gt;     // would be marked as non-visible&lt;br /&gt;   &lt;br /&gt;     // run until we reached the end of the client-area&lt;br /&gt;     while( tmp &amp;lt; totalHeight ) {&lt;br /&gt;       tmp += itemHeight;&lt;br /&gt;       topRow = topRow.getNeighbor(ViewerRow.BELOW, false);&lt;br /&gt;&lt;br /&gt;       if( topRow == null ) {&lt;br /&gt;         break;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       list.add(topRow);&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return list;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt; We simply listen to events who can change the items shown in the Scrollable make a diff to the last state and inform all consumers about the change.&lt;br /&gt;&lt;br /&gt;But what are the events how modify the items shown? This is delegated to specialized classes for Table and Tree because those may differ from control to control.&lt;br /&gt;&lt;br /&gt;Step 3: Provide specialized implementation for Tree and Table&lt;br /&gt;- An implementation for SWT-Table&lt;br /&gt;&lt;pre&gt;public class TableViewerRowVisibilityStateSupport extends&lt;br /&gt;     AbstractViewerRowVisibilityStateSupport {&lt;br /&gt; public TableViewerRowVisibilityStateSupport(TableViewer columnViewer) {&lt;br /&gt;   super(columnViewer);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected void addListeners(Scrollable control, Listener l) {&lt;br /&gt;   control.getVerticalBar().addListener(SWT.Selection, l);&lt;br /&gt;   control.addListener(SWT.Resize, l);&lt;br /&gt;   control.addListener(SWT.KeyUp, l);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected ViewerRow getTopRow() {&lt;br /&gt;   Table t = (Table)getControl();&lt;br /&gt;   int index = t.getTopIndex();&lt;br /&gt;   TableItem topItem = t.getItem(index);&lt;br /&gt;  &lt;br /&gt;   if( topItem != null ) {&lt;br /&gt;     return (ViewerRow) topItem.getData(ViewerRow.ROWPART_KEY);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return null;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;- An implementation for SWT-Tree&lt;br /&gt;&lt;pre&gt;public class TreeViewerRowVisibilityStateSupport extends&lt;br /&gt;     AbstractViewerRowVisibilityStateSupport {&lt;br /&gt; public TreeViewerRowVisibilityStateSupport(TreeViewer columnViewer) {&lt;br /&gt;   super(columnViewer);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected void addListeners(Scrollable control, Listener l) {&lt;br /&gt;   control.getVerticalBar().addListener(SWT.Selection, l);&lt;br /&gt;   control.addListener(SWT.Resize, l);&lt;br /&gt;   control.addListener(SWT.MouseUp, l);&lt;br /&gt;   control.addListener(SWT.KeyUp, l);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected ViewerRow getTopRow() {&lt;br /&gt;   TreeItem topItem = ((Tree)getControl()).getTopItem();&lt;br /&gt;   if( topItem != null ) {&lt;br /&gt;     return (ViewerRow) topItem.getData(ViewerRow.ROWPART_KEY);&lt;br /&gt;   }&lt;br /&gt;   return null;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;As said this is very rough first draft how this could work. I'll post this got some coments about possible issues this could provoke.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-2234103666433588977?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/2234103666433588977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=2234103666433588977' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/2234103666433588977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/2234103666433588977'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2007/01/what-items-are-visible-in-tabletree.html' title='What items are visible in Table/Tree?'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-116542023272014437</id><published>2006-12-06T16:30:00.000+01:00</published><updated>2006-12-12T12:20:41.456+01:00</updated><title type='text'>the new Faces of JFace (part 1)</title><content type='html'>Some of you may have noticed JFace provides new API to streamline JFace usage and to support new features like:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;custom owner draw&lt;/li&gt;&lt;li&gt;tooltips for tree/table-cells&lt;/li&gt;&lt;li&gt;keyboard editing support for viewers&lt;/li&gt;&lt;/ul&gt;To provide all those new features we (Tod Creasey, Boris Bokowski and me) decide to refactor the underling JFace code, provide new classes and to move things from specialized classes to more generice ones. The central of the whole refactoring brought up a whole bunch of new classes where the most important are the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ColumnViewer: Provides all things common to Viewers who deal with the concept of columns and rows&lt;/li&gt;&lt;li&gt;ViewerRow: Represents a row in the column viewer and wraps TableItem and TreeItem from SWT&lt;/li&gt;&lt;li&gt;ViewerCell: Represents one cell in the table/tree&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;We decide to create those new classe because it gives us the possibility to push as much code in the widget independent ColumnViewer instead of the widget centric classes derived from it.&lt;br /&gt;&lt;br /&gt;All the changes mentionned above might not be interesting to you because most of the time you want use them directly so let's take a look at the more interesting things from a user point of view.&lt;br /&gt;&lt;br /&gt;The most interesting thing to most of you might be that JFace has now adopted the programming style from SWT and JFace-Coding feels now much more like SWT-Coding. Look at the next few lines and you understand what I mean:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Composite parent = ...;&lt;br /&gt;TableViewer v = new TableViewer(parent);&lt;br /&gt;v.getTable().setLinesVisible(true);&lt;br /&gt;&lt;br /&gt;TableViewerColumn vColumn = new TableViewerColumn(v,SWT.NONE);&lt;br /&gt;vColumn.getColumn().setWidth(200);&lt;br /&gt;vColumn.setLabelProvider(new MyLabelProvider());&lt;br /&gt;&lt;br /&gt;v.setContentProvider(new MyContentProvider());&lt;br /&gt;v.setInput(model);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-116542023272014437?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/116542023272014437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=116542023272014437' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/116542023272014437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/116542023272014437'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2006/12/new-faces-of-jface-part-1.html' title='the new Faces of JFace (part 1)'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-116357912256587835</id><published>2006-11-15T09:08:00.000+01:00</published><updated>2006-11-17T18:34:49.746+01:00</updated><title type='text'>Are OS-ToolTips not flexible enough / Use JFace ToolTips</title><content type='html'>How often have you wished that OS-Tooltips would provide more functionalities like MultiLine-Text, Background-Color, Embedded Images, ... . The time you faced those problems is over since today where JFace ToolTips are available to the public.&lt;br /&gt;&lt;br /&gt;Usage is fairly straight forward:&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;Text text = new Text(parent,SWT.BORDER);&lt;br /&gt;text.setText("Hello World");&lt;br /&gt;DefaultToolTip toolTip = new DefaultToolTip(text);&lt;br /&gt;toolTip.setText("Hello World");&lt;br /&gt;toolTip.setBackgroundColor(parent.getDisplay().getSystemColor(SWT.COLOR_RED));&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Easy isn't it but there are many many more things available to you. You can add any control you want to the tooltip by subclassing &lt;span style="font-family:courier new;"&gt;org.eclipse.jface.window.ToolTip&lt;/span&gt; and providing your own implementation for &lt;span style="font-family:courier new;"&gt;createToolTipContentArea&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;public class MyToolTip extends ToolTip {&lt;br /&gt;    private Shell parentShell;&lt;br /&gt;&lt;br /&gt;    public MyToolTip(Control control) {&lt;br /&gt;        super(control);&lt;br /&gt;        this.parentShell = control.getShell();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected Composite createToolTipContentArea(Event event, Composite parent) {&lt;br /&gt;        Composite comp = new Composite(parent,SWT.NONE);&lt;br /&gt;        comp.setLayout(new FillLayout());&lt;br /&gt;&lt;br /&gt;        Button b = new Button(comp,SWT.PUSH);&lt;br /&gt;        b.setText("Say Hello");&lt;br /&gt;        b.addSelectionListener(new SelectionAdapter() {&lt;br /&gt;            public void widgetSelected(SelectionEvent e) {&lt;br /&gt;                hide();&lt;br /&gt;                MessageBox box = new MessageBox(parentShell,SWT.ICON_INFORMATION);&lt;br /&gt;                box.setMessage("Hello World!");&lt;br /&gt;                box.setText("Hello World");&lt;br /&gt;                box.open();&lt;br /&gt;            }&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Usage is the same than before:&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;Text text = new Text(parent,SWT.BORDER);&lt;br /&gt;text.setText("Hello World");&lt;br /&gt;&lt;br /&gt;MyToolTip myTooltipLabel = new MyToolTip(text);&lt;br /&gt;myTooltipLabel.setShift(new Point(-5, -5));&lt;br /&gt;myTooltipLabel.setHideOnMouseDown(false);&lt;br /&gt;myTooltipLabel.activate();&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;The small difference is that you configure the tip to not hide when the user clicks into the ToolTip the ToolTip-Code needs to ensure the hiding by its own by calling &lt;span style="font-family:courier new;"&gt;hide()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;There are other nice feature available to you:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;possibility to define delay before the ToolTip pops up&lt;/li&gt;&lt;br /&gt;&lt;li&gt;possibility to define delay how long the ToolTip is shown&lt;/li&gt;&lt;br /&gt;&lt;li&gt;possibility to define the pop up position &lt;/li&gt;&lt;br /&gt;&lt;li&gt;possibility to define a shift like shown in the code above&lt;/li&gt;&lt;br /&gt;&lt;li&gt;possibility to completely control the popup position by overloading &lt;span style="font-family:courier new;"&gt;ToolTip#getLocation(Point,Event)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;configure whether the bounds of the display and/or monitors should be:&lt;br /&gt;    &lt;ul&gt;&lt;br /&gt;    &lt;li&gt;&lt;span style="font-family:courier new;"&gt;setRespectDisplayBounds(boolean)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;&lt;span style="font-family:courier new;"&gt;setRespectMonitorBounds(boolean)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;    &lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-116357912256587835?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/116357912256587835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=116357912256587835' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/116357912256587835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/116357912256587835'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2006/11/are-os-tooltips-not-flexible-enough.html' title='Are OS-ToolTips not flexible enough / Use JFace ToolTips'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-115929734448425095</id><published>2006-09-26T20:58:00.000+02:00</published><updated>2006-09-26T21:04:00.496+02:00</updated><title type='text'>at.bestsolution.jface32-0.0.1 released</title><content type='html'>As promised I have released my JFace backport from  3.3 just a view days after 3.2 came out. You can get the ready plugin from my companies &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.jface32/releases/0.0.1/at.bestsolution.jface32_0.0.1.v20060925.zip"&gt;SVN-Repository&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-115929734448425095?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/115929734448425095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=115929734448425095' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115929734448425095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115929734448425095'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2006/09/atbestsolutionjface32-001-released.html' title='at.bestsolution.jface32-0.0.1 released'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-115841347056828306</id><published>2006-09-16T15:19:00.000+02:00</published><updated>2006-09-16T15:32:59.276+02:00</updated><title type='text'>JFace and features not part of Eclipse</title><content type='html'>Today I sit down and thought it is time to provide features JFace won't provide (some of them are marked as later or are refused) in an own project named &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.jface/trunk/"&gt;at.bestsolution.jface&lt;/a&gt;. Well 2 features I already had around somewhere in my workspaces:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;TableViewer working with multiple instances of the same object&lt;/li&gt;&lt;li&gt;Dialog which could restore it's values because it's only hidden&lt;/li&gt;&lt;/ul&gt;All people interested in the work could as always fetch the sources from my companies &lt;a href="http://publicsvn.bestsolution.at/"&gt;SVN&lt;/a&gt;-Server. At the moment this plugin only depends on JFace but it's likely that this will change in future and org.eclipse.swt.nebula and &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.jface32/trunk/"&gt;at.bestsolution.jface32&lt;/a&gt; will be added as dependencies. I haven't thoroughly tested because I never use it in my daily work so the QA is your part ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-115841347056828306?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/115841347056828306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=115841347056828306' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115841347056828306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115841347056828306'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2006/09/jface-and-features-not-part-of-eclipse.html' title='JFace and features not part of Eclipse'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-115807213016991645</id><published>2006-09-12T16:38:00.000+02:00</published><updated>2006-09-12T19:04:44.786+02:00</updated><title type='text'>How much can happen within one week?</title><content type='html'>Back from holiday I see JFace's new viewer API evolving from week to week and getting more stable and userfriendly but some parts are not as smooth as they should be some work has to spent. The most markable things changed is that the caching of column-indices is gone completely.&lt;br /&gt;&lt;br /&gt;Another important news is that &lt;a href="http://borisoneclipse.blogspot.com/"&gt;Boris&lt;/a&gt; sorted out some VIRTUAL-Table bugs. As of this writing I have integrated all those changes to &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.jface32/trunk"&gt;at.bestsolution.jface32&lt;/a&gt; project. Simply fetch all changes from my companies (BestSolution Systemhaus GmbH) public &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.jface32/trunk"&gt;SVN&lt;/a&gt;-Repository.&lt;br /&gt;&lt;br /&gt;At the moment all things from JFace HEAD are integrated and because &lt;a href="http://todcreaseyeclipse.blogspot.com/"&gt;Tod&lt;/a&gt;, Boris  and I all think that my widget-independency work can go in as is I've already integrated it. JFace integration will follow at the beginning 3.3M3 timeframe.&lt;br /&gt;&lt;br /&gt;And last but not less important a new API-function has been added to set multiple filters at once this should avoid us to use all those nasty hacks to avoid flickering, ... .&lt;br /&gt;&lt;br /&gt;I think I'll release a first version of the plugin with M2.&lt;br /&gt;&lt;br /&gt;Finally to a new JFace project providing snippets to all show common JFace. The new project has been approved by the eclipse PMC and can be found in eclipse's &lt;a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jface.snippets/"&gt;CVS&lt;/a&gt; with contribution from Tod and myself&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-115807213016991645?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/115807213016991645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=115807213016991645' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115807213016991645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115807213016991645'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2006/09/how-much-can-happen-within-one-week.html' title='How much can happen within one week?'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-115670460102025101</id><published>2006-08-27T20:41:00.000+02:00</published><updated>2006-08-28T00:41:06.026+02:00</updated><title type='text'>Viewer-Features form 3.3 in Eclipse-3.2</title><content type='html'>There are many many exciting features added in 3.3 cycle to jface but many people need a solution now and  not in 3.3-Timeframe. I myself have a need for some of those feature so I started back-porting them which is at the moment not really hard because at the moment JFace-Viewers doesn't use anything not available in 3.2-sources.&lt;br /&gt;&lt;br /&gt;I decided to make them publicly available because I think many also have a need for them. So for those who want to use exciting features added in 3.3 can fetch the sources at in my companies &lt;a href="http://publicsvn.bestsolution.at/repos/java/at.bestsolution.jface32/trunk"&gt;SVN-Directory&lt;/a&gt;. Don't forget to do your own QA to ensure everything is working as expected. If you find bugs you can file them to my companies bug-tracking system at &lt;a href="http://phpot.bestsolution.at/mantis/login_page.php"&gt;http://phpot.bestsolution.at/mantis/login_page.php&lt;/a&gt; and I'll try to incooperate them in eclipse bug-tracking system providing a patch for current HEAD-Trunk of CVS.&lt;br /&gt;&lt;br /&gt;Before releasing a first version I'm trying to get the patches to 3.3-CVS-HEAD:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=154329"&gt;Provide widget independent Table/TreeViewer  implementations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=87733"&gt;Double click behavior for tableviewer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=75114"&gt;TableViewer-Enhancement for Editing&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The current features/bug fixes against 3.2:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=149193"&gt;different cell-editors per row in same column&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=83200"&gt;custom-tooltip support&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=154755"&gt;VIRTUAL support in TableViewer&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This project will only continue until 3.3 is out afterwards people will need to recompile their code replacing at.bestsolution.jface32.* through org.eclipse.jface.*.&lt;br /&gt;&lt;br /&gt;At the end please note  the following things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;this is nothing official from Eclipse and I only thought that there are maybe others who have the same needs than I have.&lt;/li&gt;&lt;li&gt;There's a great likelihood that new API added in 3.3 at some point will change while 3.3 evolves so the API you find now is maybe a subject to change in the next release.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-115670460102025101?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/115670460102025101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=115670460102025101' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115670460102025101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115670460102025101'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2006/08/viewer-features-form-33-in-eclipse-32.html' title='Viewer-Features form 3.3 in Eclipse-3.2'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33274870.post-115642262004153977</id><published>2006-08-24T14:27:00.000+02:00</published><updated>2006-08-24T14:32:27.990+02:00</updated><title type='text'>Viewers-Refactoring</title><content type='html'>Banging my head against Viewers since about a month we finally reached a state where it's possible the first time to use viewers with different widget than org.eclipse.swt.widgets.Table. At the moment only TableViewer supports widget independency but once this is in head. TreeViewer is the next to come.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33274870-115642262004153977?l=tom-eclipse-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tom-eclipse-dev.blogspot.com/feeds/115642262004153977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33274870&amp;postID=115642262004153977' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115642262004153977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33274870/posts/default/115642262004153977'/><link rel='alternate' type='text/html' href='http://tom-eclipse-dev.blogspot.com/2006/08/viewers-refactoring.html' title='Viewers-Refactoring'/><author><name>Tom</name><uri>http://www.blogger.com/profile/06619033174219683085</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
