summaryrefslogtreecommitdiffstats
path: root/com
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2010-07-08 07:44:30 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2010-07-08 07:44:30 +0200
commit3d75736bb30623c5858fec33ad8c0a3419d35c52 (patch)
tree766f0f5b7db7f175b5578d8c4c79798119d04d3d /com
Replicate the repo...HEADmaster
Diffstat (limited to 'com')
-rw-r--r--com/trolltech/research/qtjambiawtbridge/QComponentHost.java149
-rw-r--r--com/trolltech/research/qtjambiawtbridge/QWidgetHost.java128
-rw-r--r--com/trolltech/research/qtjambiawtbridge/QWidgetWrapper.java69
-rw-r--r--com/trolltech/research/qtjambiawtbridge/QtJambiAwtBridge.java18
-rw-r--r--com/trolltech/research/qtjambiawtbridge/RedirectContainer.java104
-rw-r--r--com/trolltech/research/qtjambiawtbridge/examples/AwtInQt.java67
-rw-r--r--com/trolltech/research/qtjambiawtbridge/examples/QtInAwt.java88
7 files changed, 623 insertions, 0 deletions
diff --git a/com/trolltech/research/qtjambiawtbridge/QComponentHost.java b/com/trolltech/research/qtjambiawtbridge/QComponentHost.java
new file mode 100644
index 0000000..9da0640
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/QComponentHost.java
@@ -0,0 +1,149 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import com.trolltech.research.qtjambiawtbridge.generated.QComponentHostNative;
+import com.trolltech.qt.gui.*;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.core.QEvent;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class QComponentHost extends QComponentHostNative {
+ static {
+ Toolkit.getDefaultToolkit();
+ javax.swing.UIManager.getDefaults();
+ }
+
+ private Component component;
+ private Frame container;
+ public QComponentHost(final Component hostedComponent, QWidget parent) {
+ super(parent);
+ component = hostedComponent;
+ setFocusPolicy(Qt.FocusPolicy.TabFocus);
+ }
+
+ @Override
+ public void resizeEvent(QResizeEvent e) {
+ if (container == null)
+ return;
+ container.setBounds(0, 0, e.size().width(), e.size().height());
+ }
+
+ @Override
+ public boolean event(QEvent e) {
+ return super.event(e);
+ }
+
+ @Override
+ protected void focusInEvent(QFocusEvent e) {
+ final boolean backwards = (e.reason() == Qt.FocusReason.BacktabFocusReason);
+
+ if (!backwards && e.reason() != Qt.FocusReason.TabFocusReason)
+ return;
+
+ try {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ focusAwt(backwards);
+ }
+ });
+ } catch (Exception f) {
+ f.printStackTrace();
+ }
+ }
+
+ @Override
+ public void showEvent(QShowEvent e) {
+ // By trial and error, the only way to get the window handle is
+ // to put the component inside a Frame (which gets a window handle)
+ // and retrieving this in the paint method. Also, we need to make
+ // sure the Qt window is visible (if you attach prior to this
+ // then showing the window will hang indefinitely) hence we do
+ // this in the showEvent
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ container = RedirectContainer.embedComponent(QComponentHost.this, component);
+ container.setVisible(true);
+ }
+ });
+ } catch (Throwable f) { f.printStackTrace(); }
+ }
+
+ public QComponentHost(Component hostedComponent) {
+ this(hostedComponent, null);
+ }
+
+ @Override
+ protected void closeEvent(QCloseEvent e) {
+ container.setVisible(false);
+ }
+
+ @Override
+ public QSize minimumSizeHint() {
+ if (container == null)
+ return new QSize();
+
+ Dimension dim = container.getMinimumSize();
+ return new QSize(dim.width, dim.height);
+ }
+
+ @Override
+ public QSize sizeHint() {
+ if (container == null)
+ return new QSize();
+
+ Dimension d = component.getPreferredSize();
+ return new QSize((int) d.getWidth(), (int) d.getHeight());
+ }
+
+ private void setFocusInQt(QWidget w, Qt.FocusReason reason) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ w.window().activateWindow();
+ w.setFocus(reason);
+ w.update();
+ }
+
+ private void focusAwt(final boolean backwards) {
+ container.toFront();
+
+ Component c = null;
+ if (component instanceof Container) {
+ c = !backwards
+ ? container.getFocusTraversalPolicy().getFirstComponent((Container) component)
+ : container.getFocusTraversalPolicy().getLastComponent((Container) component);
+ } else {
+ c = component;
+ }
+
+ if (c != null)
+ c.requestFocus();
+
+ }
+
+
+ void focusQt(final boolean backwards) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ QWidget startWidget = backwards ? QtJambiAwtBridge.previousInFocusChain(QComponentHost.this)
+ : nextInFocusChain();
+ QWidget w = startWidget;
+ while (w.focusPolicy() != Qt.FocusPolicy.TabFocus
+ && w.focusPolicy() != Qt.FocusPolicy.StrongFocus) {
+ w = backwards ? QtJambiAwtBridge.previousInFocusChain(w) : w.nextInFocusChain();
+
+ if (w == startWidget)
+ break;
+ }
+
+ if (w.focusPolicy() == Qt.FocusPolicy.TabFocus
+ || w.focusPolicy() == Qt.FocusPolicy.StrongFocus) {
+ w.window().setAttribute(Qt.WidgetAttribute.WA_KeyboardFocusChange, true);
+ setFocusInQt(w, backwards ? Qt.FocusReason.BacktabFocusReason : Qt.FocusReason.TabFocusReason);
+ }
+ }
+ });
+ }
+
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/QWidgetHost.java b/com/trolltech/research/qtjambiawtbridge/QWidgetHost.java
new file mode 100644
index 0000000..421fdb7
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/QWidgetHost.java
@@ -0,0 +1,128 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import java.awt.*;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QWidget;
+
+public class QWidgetHost extends Canvas {
+ private static final long serialVersionUID = 1L;
+
+ private void focusQt(final boolean backwards) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ QWidget startWidget = backwards ? QtJambiAwtBridge.previousInFocusChain(QWidgetHost.this.containedWidget)
+ : QWidgetHost.this.containedWidget.nextInFocusChain();
+ QWidget w = startWidget;
+ while (w.focusPolicy() != Qt.FocusPolicy.TabFocus
+ && w.focusPolicy() != Qt.FocusPolicy.StrongFocus) {
+ w = backwards ? QtJambiAwtBridge.previousInFocusChain(w) : w.nextInFocusChain();
+
+ if (w == startWidget)
+ break;
+ }
+
+ if (w.focusPolicy() == Qt.FocusPolicy.TabFocus
+ || w.focusPolicy() == Qt.FocusPolicy.StrongFocus) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ w.window().activateWindow();
+ w.window().setAttribute(Qt.WidgetAttribute.WA_KeyboardFocusChange, true);
+ w.setFocus(backwards ? Qt.FocusReason.BacktabFocusReason : Qt.FocusReason.TabFocusReason);
+ w.update();
+ }
+ }
+ });
+ }
+
+ /**
+ * Constructs a binding layer between AWT and a QWidget.
+ *
+ * @param containedWidget This widget will become a child of the QWidgetHost on the first AWT paint event.
+ */
+ public QWidgetHost(QWidget containedWidget) {
+ QApplication.setQuitOnLastWindowClosed(false);
+ setFocusable(true);
+
+ childWidget = containedWidget;
+ sizeHint = new QSize();
+ minimumSizeHint = new QSize();
+
+ addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ if (e.getOppositeComponent() == null) {
+ return ;
+ }
+
+ Container focusCycleRoot = getFocusCycleRootAncestor();
+ boolean backwards = (e.getOppositeComponent() == focusCycleRoot.getFocusTraversalPolicy().getComponentAfter(focusCycleRoot, QWidgetHost.this));
+ focusQt(backwards);
+ }
+
+ });
+ }
+
+ private QWidget childWidget;
+ private QWidgetWrapper containedWidget;
+
+ @Override
+ public void paint(Graphics g) {
+ if (containedWidget == null) {
+ setVisible(false);
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ containedWidget = new QWidgetWrapper(childWidget, QWidgetHost.this);
+ sizeHint = containedWidget.sizeHint();
+ minimumSizeHint = containedWidget.minimumSizeHint();
+ }
+ });
+ setVisible(true);
+ }
+
+ super.paint(g);
+ }
+
+ @Override
+ public void setBounds(final int x, final int y, final int width, final int height) {
+ if (containedWidget != null) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ containedWidget.move(0, 0);
+ containedWidget.resize(width, height);
+ }
+ });
+ }
+
+ super.setBounds(x, y, width, height);
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ if (containedWidget != null) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ sizeHint = containedWidget.sizeHint();
+ }
+ });
+ }
+ return new Dimension(sizeHint.width(), sizeHint.height());
+ }
+ QSize sizeHint;
+
+ @Override
+ public Dimension getMinimumSize() {
+ if (containedWidget != null) {
+ QApplication.invokeAndWait(new Runnable() {
+ public void run() {
+ minimumSizeHint = containedWidget.minimumSizeHint();
+ }
+ });
+ }
+ return new Dimension(minimumSizeHint.width(), minimumSizeHint.height());
+ }
+ private QSize minimumSizeHint;
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/QWidgetWrapper.java b/com/trolltech/research/qtjambiawtbridge/QWidgetWrapper.java
new file mode 100644
index 0000000..9bcd82d
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/QWidgetWrapper.java
@@ -0,0 +1,69 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import com.trolltech.research.qtjambiawtbridge.generated.QWidgetHostNative;
+import com.trolltech.qt.gui.*;
+import com.trolltech.qt.core.Qt;
+
+import javax.swing.*;
+import java.awt.*;
+
+class QWidgetWrapper extends QWidgetHostNative {
+ private QWidgetHost host;
+
+ public QWidgetWrapper(QWidget child, QWidgetHost host) {
+ super(host);
+
+ // Call this to make sure the widget is connected to a native window
+ winId();
+
+ this.host = host;
+ child.setParent(this);
+
+ // Make sure widget fills entire parent rect
+ QHBoxLayout layout = new QHBoxLayout(this);
+ layout.setMargin(0);
+ layout.setContentsMargins(0, 0, 0, 0);
+ layout.setSpacing(0);
+ layout.addWidget(child);
+
+ setFocusPolicy(Qt.FocusPolicy.TabFocus);
+ setVisible(true);
+ }
+
+ @Override
+ public void closeEvent(QCloseEvent e) {
+ e.setAccepted(false);
+ }
+
+ private void focusAwt(final boolean backwards) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ Container c = host.getFocusCycleRootAncestor();
+
+ if (c != null) {
+ host.requestFocus();
+ Component component = backwards
+ ? c.getFocusTraversalPolicy().getComponentBefore(c, host)
+ : c.getFocusTraversalPolicy().getComponentAfter(c, host);
+
+ component.requestFocus();
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void showEvent(QShowEvent e) {
+ move(0, 0);
+ resize(host.getBounds().width, host.getBounds().height);
+ }
+
+ @Override
+ protected synchronized void focusInEvent(QFocusEvent event) {
+ if (event.reason() == Qt.FocusReason.BacktabFocusReason) {
+ focusAwt(true);
+ } else if (event.reason() == Qt.FocusReason.TabFocusReason) {
+ focusAwt(false);
+ }
+ }
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/QtJambiAwtBridge.java b/com/trolltech/research/qtjambiawtbridge/QtJambiAwtBridge.java
new file mode 100644
index 0000000..943f8ff
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/QtJambiAwtBridge.java
@@ -0,0 +1,18 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import com.trolltech.qt.gui.QWidget;
+
+import java.awt.*;
+
+class QtJambiAwtBridge {
+ public static QWidget previousInFocusChain(QWidget w ) {
+ QWidget prev = null, next = w.nextInFocusChain();
+ while (next != w) {
+ prev = next;
+ next = next.nextInFocusChain();
+ }
+ return prev;
+ }
+
+ static native Frame getEmbeddedFrame(long widgetNativeId);
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/RedirectContainer.java b/com/trolltech/research/qtjambiawtbridge/RedirectContainer.java
new file mode 100644
index 0000000..424c955
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/RedirectContainer.java
@@ -0,0 +1,104 @@
+package com.trolltech.research.qtjambiawtbridge;
+
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.gui.QApplication;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+
+// sun.awt.x11.embeddedFrame on Linux
+// see text file for osx info
+class RedirectContainer {
+
+ private static class FocusComponent extends Component {
+ private static final long serialVersionUID = 1L;
+ private QComponentHost host;
+
+ public FocusComponent(final boolean isFocusIn, final QComponentHost host) {
+ this.host = host;
+
+ setFocusable(true);
+ setBounds(0, 0, 1, 1);
+
+ addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+
+ if (e.getOppositeComponent() == null) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ return ;
+ }
+
+ if (isFocusIn) {
+ host.focusQt(true);
+ } else {
+ host.focusQt(false);
+ }
+ }
+
+ });
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(1, 1);
+ }
+
+ @Override
+ public Dimension getMaximumSize() {
+ return new Dimension(1, 1);
+ }
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ static Frame embedComponent(QComponentHost parent, Component component) {
+ Frame f = QtJambiAwtBridge.getEmbeddedFrame(parent.nativeId());
+ if (f != null) {
+ // Connect the frame to its window handle, since it's no longer
+ // handled by Swing (for event processing)
+ f.addNotify();
+
+ GridBagLayout layout = new GridBagLayout();
+
+ f.setLayout(layout);
+ f.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
+ f.setFocusTraversalPolicyProvider(true);
+
+ GridBagConstraints focusConstraints = new GridBagConstraints();
+ focusConstraints.ipadx = 0;
+ focusConstraints.ipady = 0;
+ focusConstraints.anchor = GridBagConstraints.CENTER;
+ focusConstraints.fill = GridBagConstraints.NONE;
+ focusConstraints.insets.left = 0;
+ focusConstraints.insets.right = 0;
+ focusConstraints.insets.bottom = 0;
+ focusConstraints.insets.top = 0;
+
+ FocusComponent focusIn = new FocusComponent(true, parent);
+
+ layout.setConstraints(focusIn, focusConstraints);
+ f.add(focusIn);
+
+ {
+ GridBagConstraints constraints = (GridBagConstraints) focusConstraints.clone();
+ constraints.fill = GridBagConstraints.BOTH;
+ constraints.weightx = 1;
+ constraints.weighty = 1;
+
+ f.add(component);
+ }
+
+ FocusComponent focusOut = new FocusComponent(false, parent);
+ layout.setConstraints(focusOut, focusConstraints);
+ f.add(focusOut);
+
+ f.pack();
+ }
+
+ return f;
+ }
+
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/examples/AwtInQt.java b/com/trolltech/research/qtjambiawtbridge/examples/AwtInQt.java
new file mode 100644
index 0000000..6a2f2eb
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/examples/AwtInQt.java
@@ -0,0 +1,67 @@
+package com.trolltech.research.qtjambiawtbridge.examples;
+
+import com.trolltech.qt.gui.*;
+import com.trolltech.research.qtjambiawtbridge.QComponentHost;
+
+import javax.swing.*;
+import java.awt.*;
+
+public class AwtInQt extends QWidget {
+
+ public AwtInQt() {
+ QGridLayout layout = new QGridLayout(this);
+
+ // A few Qt widgets
+ layout.addWidget(new QLabel("First name:"), 0, 0);
+ layout.addWidget(new QLineEdit(), 0, 1);
+ layout.addWidget(new QLabel("Last name:"), 1, 0);
+ layout.addWidget(new QLineEdit(), 1, 1);
+
+ // The AWT part of the GUI
+ {
+ JPanel panel = new JPanel();
+
+ panel.setLayout(new GridLayout(1, 2));
+
+ panel.add(new JLabel("Social security number:"));
+ panel.add(new JTextField());
+
+ // Add the AWT panel to Qt's layout
+ layout.addWidget(new QComponentHost(panel), 2, 0, 1, 2);
+ }
+
+ {
+ JPanel panel = new JPanel();
+
+ panel.setLayout(new GridLayout(2, 4));
+
+ panel.add(new JLabel("Phone number:"));
+ panel.add(new JTextField());
+
+ panel.add(new JLabel("Address:"));
+ panel.add(new JTextField());
+
+ panel.add(new JLabel("Credit card #:"));
+ panel.add(new JTextField());
+
+ panel.add(new JLabel("Expiration date:"));
+ panel.add(new JTextField());
+
+ // Add the AWT panel to Qt's layout
+ layout.addWidget(new QComponentHost(panel), 4, 0, 1, 2);
+ }
+
+ }
+
+ public static void main(String[] args) {
+ QApplication.initialize(args);
+
+ AwtInQt awtInQt = new AwtInQt();
+ awtInQt.show();
+
+ QApplication.exec();
+
+ System.exit(0);
+ }
+
+}
diff --git a/com/trolltech/research/qtjambiawtbridge/examples/QtInAwt.java b/com/trolltech/research/qtjambiawtbridge/examples/QtInAwt.java
new file mode 100644
index 0000000..bef356e
--- /dev/null
+++ b/com/trolltech/research/qtjambiawtbridge/examples/QtInAwt.java
@@ -0,0 +1,88 @@
+package com.trolltech.research.qtjambiawtbridge.examples;
+
+import java.awt.GridLayout;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QGridLayout;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QLineEdit;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.research.qtjambiawtbridge.QWidgetHost;
+
+public class QtInAwt extends JFrame {
+
+ private static final long serialVersionUID = 1L;
+
+ public QtInAwt() {
+ setLayout(new GridLayout(4, 1));
+
+ {
+ JPanel row = new JPanel();
+ row.setLayout(new GridLayout(1, 2));
+ row.add(new JLabel("First name:"));
+ row.add(new JTextField());
+
+ add(row);
+ }
+
+ {
+ JPanel row = new JPanel();
+ row.setLayout(new GridLayout(1, 2));
+ row.add(new JLabel("Last name:"));
+ row.add(new JTextField());
+
+ add(row);
+ }
+
+ // The Qt part of the GUI
+ {
+ QWidget row = new QWidget();
+ QGridLayout layout = new QGridLayout(row);
+ layout.addWidget(new QLabel("Social security number:"), 0, 0);
+ layout.addWidget(new QLineEdit(), 0, 1);
+
+ // Add the Qt widget to AWT's layout
+ add(new QWidgetHost(row));
+ }
+
+ {
+ QWidget row = new QWidget();
+ QGridLayout layout = new QGridLayout(row);
+ layout.addWidget(new QLabel("Phone number:"), 0, 0);
+ layout.addWidget(new QLineEdit(), 0, 1);
+
+ layout.addWidget(new QLabel("Address:"), 1, 0);
+ layout.addWidget(new QLineEdit(), 1, 1);
+
+ layout.addWidget(new QLabel("Credit card #:"), 0, 2);
+ layout.addWidget(new QLineEdit(), 0, 3);
+
+ layout.addWidget(new QLabel("Expiration date:"), 1, 2);
+ layout.addWidget(new QLineEdit(), 1, 3);
+
+ // Add the Qt widget to AWT's layout
+ add(new QWidgetHost(row));
+ }
+
+ }
+
+ public static void main(String args[]) {
+ // We have to initialize Qt Jambi in order to use its widgets
+ QApplication.initialize(args);
+
+ QtInAwt qtInAwt = new QtInAwt();
+ qtInAwt.setVisible(true);
+ qtInAwt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ qtInAwt.setSize(640, 480);
+
+ // We need to run a Qt Jambi event loop in this thread in order
+ // for its widgets to receive events
+ QApplication.exec();
+ }
+
+}