Blog

Embedding Swing into SWT on Java8

If have have you ever faced the problem to embed Swing into your SWT application you know how nasty things get because you always have to synchronize between the SWT & Swing event loop. So if you have code like:

Display d = ...;
Shell s = ...;
JButton swingButton = new JButton("Swing");
Button swtButton = new Button("SWT");
swingButton.addActionListener( (e) -> 
   d.asyncExec( 
    () -> swtButton.setEnabled(!swtButton.getEnabled()) 
   ) 
);
swtButton.addListener( SWT.Selection, (e) -> 
 SwingUtilities.invokeLater( 
    () -> swingButton.setEnabled(!swingButton.isEnabled()) 
   )
);

// .....

while(!s.isDisposed()) {
  if(!d.readAndDispatch()) {
    d.sleep();
  }
}

You might not be suprised that this all can lead to fairly complex and unmaintainable code! Now let's see what we can do with our JavaFX8 knowledge to make SWT and Swing share the same event loop!

  1. JavaFX and SWT share the same event loop when we embedding JavaFX into SWT using FXCanvas
  2. in Java8 Swing can be forced to run on the same event loop as JavaFX

If we carefully study the above this means:

JavaFX-Event-Loop == SWT-Event-Loop
Swing-Event-Loop  == JavaFX-Event-Loop
----------------------------------------
Swing-Event-Loop == SWT-Event-Loop

Hm - that's interesting but how does this look like in code:

Display d = ...;
Shell s = ...;
// Make JavaFX run in embedded mode!
Shell dummy = new Shell(d);
FXCanvas c = new FXCanvas(dummy, SWT.NONE);
dummy.dispose();

JButton swingButton = new JButton("Swing");
Button swtButton = new Button("SWT");
swingButton.addActionListener( 
  (e) -> swtButton.setEnabled(!swtButton.getEnabled())
);
swtButton.addListener(SWT.Selection, 
  (e) -> swingButton.setEnabled(!swingButton.isEnabled())
);

// ...
while (!s.isDisposed()) {
  if (!d.readAndDispatch()) {
    d.sleep();
  }
}

d.dispose();
// Exit JavaFX-Platform
PlatformImpl.exit();

That's all from a source code point of view to get things working - the only extra thing you need to to as well is to launch your SWT-Application with "-Djavafx.embed.singleThread=true". I've recorded a short screencast on this to show you some SWT/Swing code in action! Video I've not extensively tested this code and I don't think it is officially supported by Oracle but the above sample runs fine on Win32 and MacOSX 10.9 - so it is hack but I wanted to get out this information - use it at your own risk!

published on
Previous
SWT on JavaFX is now at part of e(fx)clipse