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!

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!

About these ads

3 Responses to “Embedding Swing into SWT on Java8”

  1. You can do it without JavaFx:

    AWTAccessor.getEventQueueAccessor().setFwDispatcher(getEventQueue(),
    new SWTDispatcher());

    private static EventQueue getEventQueue() {
    return AccessController
    .doPrivileged(new PrivilegedAction() {
    @Override
    public EventQueue run() {
    return java.awt.Toolkit.getDefaultToolkit()
    .getSystemEventQueue();
    }
    });
    }

    public class SWTDispatcher implements FwDispatcher {

    @Override
    public SecondaryLoop createSecondaryLoop() {
    return null;
    }

    @Override
    public boolean isDispatchThread() {
    return getDisplay().getThread() == Thread.currentThread();
    }

    @Override
    public void scheduleDispatch(Runnable runnable) {
    getDisplay().asyncExec(runnable);
    }

    private static Display getDisplay()
    {
    final Display display = Display.getCurrent();
    return (display != null) ? display : Display.getDefault();
    }
    }

Trackbacks/Pingbacks

  1. JavaFX links of the week, February 17 // JavaFX News, Demos and Insight // FX Experience - February 16, 2014

    […] Schindl has an interesting blog post on embedding Swing into SWT by making use of changes in Java 8.0 to make better allowances for […]

  2. Java desktop links of the week, February 17 « Jonathan Giles - February 16, 2014

    […] Schindl has an interesting blog post on embedding Swing into SWT by making use of changes in Java 8.0 to make better allowances for […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 675 other followers

%d bloggers like this: