There and back again

A common question I get when I'm doing talks on Qt Jambi is how well it plays with other toolkits, specifically Swing and AWT. There's a lot of code out there written in either or both, and people who want to port their projects to Jambi or build new components on top of existing legacy code require some sort of migration layer.

So far, our answer to the question has been that top level windows in Qt Jambi and Swing play well together, while window components are more reluctant to partake in any sort of social activity.

It has, however, been our goal all along to change this, and implement migration classes that allow a Qt Jambi widget to be adopted by a AWT/Swing component, vice versa, and in general make it even more convenient to use Qt Jambi together with existing Java code.

Yesterday I had some time to sit down and sketch up a crude solution for part of this migration layer. It currently works on Windows and Linux, only supports putting Jambi into AWT (not the other way around), and is not at all perfect. It's quite functional already, though.

On the technical side, it uses JAWT to access OS specific data about a Canvas-subclass that I've called QAwtWidget. The QAwtWidget also takes a reference to a QWidget, which is the Qt component it will bind into AWT/Swing. It will then use all this information to have the operating system reparent the Qt widget to the QAwtWidget-canvas. This means that all event handling is automatically delegated to the correct widget, so the widget will immediately be fully operational.

There are snags, however, and a solution like this will never be completely perfect. I'm not sure if we will ever be able to make it work on Mac, and there will be some oddities in focus handling, window activation, etc. that I don't think we'll be able to remove entirely. But it'll be a great tool for parts of a project where it's unnoticable, and it will definitely be a great tool to have for porting existing AWT/Swing-code to Qt Jambi.

Here's an example of the image viewer demo running on Windows inside a GridLayout with a couple of buttons for extra evidence.

Qt and Awt running side by side

The code for making this happen:

public static void main(String args[]) {

JFrame f = new JFrame();
f.setBounds(0, 0, 500, 100);

GridLayout flayout = new GridLayout(2, 2);

// The widget to embed
QWidget w = new com.trolltech.demos.ImageViewer();

// The migration layer
QAwtWidget awtWidget = new QAwtWidget(w);

JButton swingButton = new JButton();
swingButton.setText("Swing button");

Button awtButton = new Button();
awtButton.setLabel("AWT button");


// Run Qt event loop in main thread

Blog Topics: