Archive

Archive for the ‘SWT’ Category

Java FX HTML Editor in Eclipse!

I did not care about JavaFX, Because It did not support OSX, and there was no legal OSGi bundle for it.

Now, JDK7 shipped with JavaFX, So there is no bundle problem anymore. JDK7 for OSX is also available now. And I heard that Oracle provides Embedding API for SWT.

So I’v tried to make a HTML Editor for Eclipse using JavaFX.

I could make a HTML WYSIWYG Edtior which supports HTML5/CSS3. Codes were unbelievably easy and short.

See in HD to improve readability.

 

Source codes(part):

</span>
<pre>public class HtmlEditor extends EditorPart {
	...

	@Override
	public void createPartControl(Composite parent) {
		canvas = new FXCanvas(parent, SWT.NONE);
		editor = new HTMLEditor();
		Scene scene = new Scene(editor);
		canvas.setScene(scene);

		IDocument doc = documentProvider.getDocument(getEditorInput());
		editor.setHtmlText(doc.get());

		editor.setOnKeyPressed(new EventHandler() {
			@Override
			public void handle(KeyEvent event) {
				setDirty(true);
			}
		});
	}
}

I think we can use JavaFX Scene graph as a view of GEF too. It must be cool! It provides very high quality rendering results with performance. I will challenge this later.

Categories: JavaFX, SWT

Dark Side of SWT, #1 Peer Communication

2012/10/22 1 comment

I began JAVA since 1995, And I loved Swing then SWT.

Now I am a big fan of SWT since 2002. And I have some worries about SWT that I want to share with you.

Why SWT

For long time, SWT is best solution for Java UI. The primary reasons are:

  • Native Look & Feel, Performance
  • JFace

Native Look&Feel, Performance

In early stage of Java, Standard UI for Java, AWT was very ugly and slow.

There was a big war around Java UI. Primary topic in the war was Unified Experience VS Native Experience.

  • Unified Experience, Same Look&Feel in all kind of platform: Swing
  • Native Experience, Native Look&Feel in each platform: AWT, SWT

Since one of primary philosophy in Java is “Write once run everywhere(in same way!)”, Sun raised hand of Amy Fowler who is leader of Swing, and denied standard proposal of SWT. (I think actual reason is little bit different. Hint: Sun developed NetBeans.)

All UI Objects in SWT are just proxies to OS’s UI Objects. So application looks very harmonious with their native OS because all UIs are actually native. It is why do we have to dispose SWT Resources and Widgets.

In other words, It is working slightly different for each platform. ex:

  • In OSX, Closing shell not dispatching focus out or modify event from text field in shell
  • In OSX, Buttons can’t take keyboard focus, So what if some wizard page contains only buttons, it can’t have context help.
  • In windows 95, Adavnaced Graphics may not work
  • … and so many things …

You have to test every platform what if you have choose SWT.

Behavior of widgets are handled by Native OS, ex: expanding/collapsing tree. So it is very fast. SWT translates Native Events to SWT Events(Display#readAndDispatch), So developer can extend behavior of widgets using Java.

JFace

JFace is most elegant and easy, and well designed library for UI. JFace provides awesome MVC patterns for SWT. So SWT can stay very simple and low-level. Most good experience of Eclipse Application are came with JFace. Swing is much more complex then SWT because there is nothing likes JFace.

JFace is also good tutorial or guide about how to use SWT smart. It’s big heritage.

Peer communication: Is it really fast?

SWT translates messages between Java and OS world. It called as “Peer Communication”. In General, Peer communications between different machine are very slow since it requires:

  • Synchronization
  • Data conversion

When you commit a command through SWT, SWT translate it and send to OS. OS will work what you ordered. What if amount of work is larger than cost of peer communication, It’s Okay. In other case, It’s not.

In general, OS doing not much since almost controllers are written with Java in SWT. When you click the button, OS generate event, SWT will translate it and dispatch, Java Listener will do some job.

AWT’s Peer communication uses same strategy, buy it is very buggy and slow because they tried to accomplish Write Once Run Everywhere. So communications costs much than SWT. But, Natives are natives, differents are differents. So it was failed.

Example of terrible peer communication performance

public class Example {
   public static void main(String[] args) {
      long start = System.currentTimeMillis();
 
      Display display = Display.getDefault();
      Image image = new Image(display, 640, 480);
      GC gc = new GC(image);
      gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
 
      for(int x=0; x<640; x++){
         for(int y=0; y<480; y++){
            gc.drawPoint(x, y);
         }
      }
 
      long elpasedTime = System.currentTimeMillis() - start;
      System.out.println("done:" + elpasedTime);
   }
}

It fills red pixels into a 640*480 image using SWT. It costs more then 2000 milliseconds! Because Line 12 cause Peer Communication 307,200 times!

How about this, Let replace line 10~14 to below:

gc.fillRectangle(0, 0, 640, 480);

It costs about 300 milliseconds now. They are semantically same task but peer communications are reduced. There was a big difference in performance.

Someone may think first example is too inefficient to compare, see next.

Remove Peer Communication

public class Example {
   public static void main(String[] args) {
      long start = System.currentTimeMillis();
 
      PaletteData palette = new PaletteData(0xff0000, 0xff00, 0xff);
      ImageData data = new ImageData(640, 480, 32, palette);
      RGB red = new RGB(255, 0, 0);
 
      for (int x = 0; x < 640; x++) {
         for (int y = 0; y < 480; y++) {
            data.setPixel(x, y, palette.getPixel(red));
         }
      }
 
      long elapsed = System.currentTimeMillis() - start;
      System.out.println("done:" + elapsed);
   }
}

This codes are exactly same with first example except there is no peer communication since PaletteData, RGB and ImageData are pure java objects.

It costs only 193 milliseconds. And this code can be executed in Non-UI thread. So we don’t have to block UI when we create images.

We know Reducing peer communication or eliminating peer communication is very important topic to develop UI Applications with SWT now. However, in many case, We can’t reduce peer communication. Consider situation that we have to update all TreeItems by it’s model change. We have to perform below codes for all TreeItems:

TreeItem item = ...;
Model model = item.getData();
 
item.setText(model.getLabel());
item.setImage(model.getImage());

Number of peer communications are increased as count of tree items. It’s a reason for that why TreeViewer#refresh() is so slow.

In this case, We can use Deferred Update Strategy, Lazy Content Providing or Virtual FLAG to improve performance. But these techniques are pretty tough to developers.

Lightweight UI

In these days, Swing is super fast since it uses GPU. Native performance is not important anymore since native behavior is tend to be smaller than actual business task or rendering codes. And almost machine has it’s own GPU.

For instance, GEF needs to manipulate very complex UI without Peer Cost, So they developed Draw2d(light-weight, Pure Java UI Library which is rendered on FigureCanvas). So we can use various UIs without loosing performance in GEF Editors.

Figures in Draw2D are almost same with Swing. Swing UIs are rendered by JVM, Figures in Draw2d are rendered by FigureCanvas(LightWeightSystem). So there are no peer cost.

(Actually Figure Canvas uses Native GC when it render, So it uses peer communications. But Figure Updater optimizes this context to reduce peer communication. Defining or manipulating UI elements are toll free! not like SWT)

For same purpose, Nebula provides some widgets like Grid. It can takes massive amount of model and massive number of UI elements.

Conclusion

SWT is fast? Yes! and No!! You have to care about peer communication to make your application support massive scale.

Categories: SWT Tags: