--- /dev/null 2011-12-03 11:37:34.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/BufferedImageView.java 2011-12-03 11:37:34.000000000 +0100 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.image.BufferedImage; + +import javafx.application.Platform; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + +/** + * An {@link ImageView} that is able to render {@link BufferedImage}s. + */ +public class BufferedImageView extends ImageView { + + public BufferedImageView() { /* nothing to do */} + + public BufferedImageView(BufferedImage image) { + paintImage(image); + } + + public void paintImage(BufferedImage backBuffer) { + // use the internal API until we get a better alternative + @SuppressWarnings("deprecation") + final Image img = Image.impl_fromExternalImage(backBuffer); + Platform.runLater(new Runnable() { + @Override + public void run() { + setImage(img); + } + }); + } +} --- /dev/null 2011-12-03 11:37:35.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/FXSwingKeyboardFocusManagerPeer.java 2011-12-03 11:37:34.000000000 +0100 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.KeyboardFocusManager; +import java.awt.Window; +import java.awt.event.FocusEvent; +import java.awt.peer.KeyboardFocusManagerPeer; +import java.util.logging.Logger; + +import sun.awt.AppContext; +import sun.awt.CausedFocusEvent; +import sun.awt.CausedFocusEvent.Cause; +import sun.awt.SunToolkit; + +class FXSwingKeyboardFocusManagerPeer implements KeyboardFocusManagerPeer { + + private static Logger log = + Logger.getLogger(FXSwingKeyboardFocusManagerPeer.class.getName()); + + private static FXSwingKeyboardFocusManagerPeer instance; + + static FXSwingKeyboardFocusManagerPeer getInstance() { + if (instance == null) { + instance = new FXSwingKeyboardFocusManagerPeer(); + } + return instance; + } + + private FXSwingKeyboardFocusManagerPeer() { /* nothing to do */ } + + private Window currentFocusedWindow; + private Component currentFocusOwner; + + /** + * Returns the currently focused window. + * + * @return the currently focused window + * + * @see KeyboardFocusManager#getNativeFocusedWindow() + */ + @Override + public Window getCurrentFocusedWindow() { + return currentFocusedWindow; + } + + /** + * Sets the component that should become the focus owner. + * + * @param comp the component to become the focus owner + * + * @see KeyboardFocusManager#setNativeFocusOwner(Component) + */ + @Override + public void setCurrentFocusOwner(Component comp) { + currentFocusOwner = comp; + if (currentFocusOwner instanceof ProxyWindow) { + ((ProxyWindow) currentFocusOwner).getProxyView().requestFocus(); + } + } + + /** + * Returns the component that currently owns the input focus. + * + * @return the component that currently owns the input focus + * + * @see KeyboardFocusManager#getNativeFocusOwner() + */ + @Override + public Component getCurrentFocusOwner() { + return currentFocusOwner; + } + + /** + * Clears the current global focus owner. + * + * @param activeWindow + * + * @see KeyboardFocusManager#clearGlobalFocusOwner() + */ + @Override + public void clearGlobalFocusOwner(Window activeWindow) { + // TODO: Implement. + } + + public void setCurrentFocusedWindow(Window w) { + currentFocusedWindow = w; + if (currentFocusedWindow instanceof ProxyWindow) { + ((ProxyWindow) currentFocusedWindow).getProxyView().requestFocus(); + } + } + + boolean requestFocus(Component target, Component lightweightChild, boolean temporary, + boolean focusedWindowChangeAllowed, long time, Cause cause) { + + if (target instanceof ProxyWindow) { + ((ProxyWindow) target).getProxyView().requestFocus(); + } else { + log.warning("Cannot handle non-ProxyWindow component"); + } + return false; + } + + @SuppressWarnings("restriction") + private void postEvent(AWTEvent ev) { + SunToolkit.postEvent(AppContext.getAppContext(), ev); + } + + void focusGained(ProxyWindow w) { + log.fine("Focus gained: " + w); + @SuppressWarnings("restriction") + FocusEvent fg = new CausedFocusEvent(w, FocusEvent.FOCUS_GAINED, false, + currentFocusOwner, + Cause.NATIVE_SYSTEM); + postEvent(fg); + } + + void focusLost(ProxyWindow w) { + log.fine("Focus lost: " + w); + @SuppressWarnings("restriction") + FocusEvent fl = new CausedFocusEvent(w, FocusEvent.FOCUS_LOST, false, + null, Cause.NATIVE_SYSTEM); + postEvent(fl); + } + +} --- /dev/null 2011-12-03 11:37:35.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/KFMHelper.java 2011-12-03 11:37:35.000000000 +0100 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.Component; +import java.awt.KeyboardFocusManager; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +import sun.awt.CausedFocusEvent; + +class KFMHelper { + + static final int SNFH_FAILURE = 0; + static final int SNFH_SUCCESS_HANDLED = 1; + static final int SNFH_SUCCESS_PROCEED = 2; + + private static Method processSynchronousLightweightTransferMethod; + + private static Method shouldNativelyFocusHeavyweightMethod; + + static boolean processSynchronousLightweightTransfer(Component target, + Component lightweightChild, + boolean temporary, + boolean focusedWindowChangeAllowed, + long time) + { + try { + if (processSynchronousLightweightTransferMethod == null) { + processSynchronousLightweightTransferMethod = AccessController + .doPrivileged(new PrivilegedExceptionAction() { + public Method run() throws IllegalAccessException, + NoSuchMethodException { + Method m = KeyboardFocusManager.class + .getDeclaredMethod( + "processSynchronousLightweightTransfer", + new Class[] { Component.class, + Component.class, + Boolean.TYPE, + Boolean.TYPE, Long.TYPE }); + m.setAccessible(true); + return m; + } + }); + } + Object[] params = new Object[] { target, lightweightChild, + Boolean.valueOf(temporary), + Boolean.valueOf(focusedWindowChangeAllowed), + Long.valueOf(time) }; + return ((Boolean) processSynchronousLightweightTransferMethod + .invoke(null, params)).booleanValue(); + } catch (PrivilegedActionException pae) { + pae.printStackTrace(); + return false; + } catch (IllegalAccessException iae) { + iae.printStackTrace(); + return false; + } catch (IllegalArgumentException iaee) { + iaee.printStackTrace(); + return false; + } catch (InvocationTargetException ite) { + ite.printStackTrace(); + return false; + } + } + + static int shouldNativelyFocusHeavyweight(Component heavyweight, + Component descendant, + boolean temporary, + boolean focusedWindowChangeAllowed, + long time, + CausedFocusEvent.Cause cause) + { + if (shouldNativelyFocusHeavyweightMethod == null) { + Class[] arg_types = new Class[] { + Component.class, Component.class, + Boolean.TYPE, Boolean.TYPE, Long.TYPE, + CausedFocusEvent.Cause.class + }; + + try { + shouldNativelyFocusHeavyweightMethod = KeyboardFocusManager.class + .getDeclaredMethod("shouldNativelyFocusHeavyweight", + arg_types); + shouldNativelyFocusHeavyweightMethod.setAccessible(true); + + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } + } + Object[] args = new Object[] { + heavyweight, descendant, + Boolean.valueOf(temporary), + Boolean.valueOf(focusedWindowChangeAllowed), + Long.valueOf(time), cause + }; + + int result = SNFH_FAILURE; + if (shouldNativelyFocusHeavyweightMethod != null) { + try { + result = ((Integer) + shouldNativelyFocusHeavyweightMethod.invoke(null, args)).intValue(); + } catch (IllegalAccessException e) { + assert false; + + } catch (InvocationTargetException e) { + assert false; + } + } + + return result; + } + +} --- /dev/null 2011-12-03 11:37:35.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/KeyEventHandler.java 2011-12-03 11:37:35.000000000 +0100 @@ -0,0 +1,789 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javafx.embed.swing; + +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; +import java.awt.event.MouseEvent; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javafx.event.EventHandler; +import javafx.event.EventType; + +class KeyEventHandler implements EventHandler { + + private static final Map, Integer> keyEventMap; + static { + Map, Integer> map = new HashMap, Integer>(); + map.put(javafx.scene.input.KeyEvent.KEY_PRESSED, + java.awt.event.KeyEvent.KEY_PRESSED); + map.put(javafx.scene.input.KeyEvent.KEY_RELEASED, + java.awt.event.KeyEvent.KEY_RELEASED); + map.put(javafx.scene.input.KeyEvent.KEY_TYPED, + java.awt.event.KeyEvent.KEY_TYPED); + keyEventMap = Collections.unmodifiableMap(map); + } + + private Component component; + + KeyEventHandler(Component comp) { + component = comp; + } + + @Override + public void handle(javafx.scene.input.KeyEvent ke) { + Component focusOwner = + KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if (focusOwner == null) { + return; + } + + int id = getKeyEventId(ke); + long when = System.currentTimeMillis(); + int mods = getAWTModifiers(ke); + int keyCode = getAWTKeyCode(ke); + char keyChar = !ke.getCharacter().isEmpty() ? + ke.getCharacter().charAt(0) : + java.awt.event.KeyEvent.CHAR_UNDEFINED; + if (id == java.awt.event.KeyEvent.KEY_TYPED && + keyChar == java.awt.event.KeyEvent.CHAR_UNDEFINED) + { + return; + } + + final java.awt.event.KeyEvent kp = + new java.awt.event.KeyEvent(focusOwner, id, when, mods, keyCode, + keyChar); + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + component.dispatchEvent(kp); + } + }); + } + + private int getKeyEventId(javafx.scene.input.KeyEvent ke) { + return keyEventMap.get(ke.getEventType()); + } + + private int getAWTModifiers(javafx.scene.input.KeyEvent jfxKeyEvent) { + int mods = 0; + if (jfxKeyEvent.isAltDown()) { + mods |= MouseEvent.ALT_MASK | MouseEvent.ALT_DOWN_MASK; + } + if (jfxKeyEvent.isControlDown()) { + mods |= MouseEvent.CTRL_MASK | MouseEvent.CTRL_DOWN_MASK; + } + if (jfxKeyEvent.isShiftDown()) { + mods |= MouseEvent.SHIFT_MASK | MouseEvent.SHIFT_DOWN_MASK; + } + if (jfxKeyEvent.isMetaDown()) { + mods |= MouseEvent.META_MASK | MouseEvent.META_DOWN_MASK; + } + return mods; + } + + private int getAWTKeyCode(javafx.scene.input.KeyEvent jfxKeyEvent) { + int code = java.awt.event.KeyEvent.VK_UNDEFINED; + switch (jfxKeyEvent.getCode()) { + case A: + code = java.awt.event.KeyEvent.VK_A; + break; + case ACCEPT: + code = java.awt.event.KeyEvent.VK_ACCEPT; + break; + case ADD: + code = java.awt.event.KeyEvent.VK_ADD; + break; + case AGAIN: + code = java.awt.event.KeyEvent.VK_AGAIN; + break; + case ALL_CANDIDATES: + code = java.awt.event.KeyEvent.VK_ALL_CANDIDATES; + break; + case ALPHANUMERIC: + code = java.awt.event.KeyEvent.VK_ALPHANUMERIC; + break; + case ALT: + code = java.awt.event.KeyEvent.VK_ALT; + break; + case ALT_GRAPH: + code = java.awt.event.KeyEvent.VK_ALT_GRAPH; + break; + case AMPERSAND: + code = java.awt.event.KeyEvent.VK_AMPERSAND; + break; + case ASTERISK: + code = java.awt.event.KeyEvent.VK_ASTERISK; + break; + case AT: + code = java.awt.event.KeyEvent.VK_AT; + break; + case B: + code = java.awt.event.KeyEvent.VK_B; + break; + case BACK_QUOTE: + code = java.awt.event.KeyEvent.VK_BACK_QUOTE; + break; + case BACK_SLASH: + code = java.awt.event.KeyEvent.VK_BACK_SLASH; + break; + case BACK_SPACE: + code = java.awt.event.KeyEvent.VK_BACK_SPACE; + break; + case BEGIN: + code = java.awt.event.KeyEvent.VK_BEGIN; + break; + case BRACELEFT: + code = java.awt.event.KeyEvent.VK_BRACELEFT; + break; + case BRACERIGHT: + code = java.awt.event.KeyEvent.VK_BRACERIGHT; + break; + case C: + code = java.awt.event.KeyEvent.VK_C; + break; + case CANCEL: + code = java.awt.event.KeyEvent.VK_CANCEL; + break; + case CAPS: + code = java.awt.event.KeyEvent.VK_CAPS_LOCK; + break; + case CHANNEL_DOWN: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case CHANNEL_UP: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case CIRCUMFLEX: + code = java.awt.event.KeyEvent.VK_CIRCUMFLEX; + break; + case CLEAR: + code = java.awt.event.KeyEvent.VK_CLEAR; + break; + case CLOSE_BRACKET: + code = java.awt.event.KeyEvent.VK_CLOSE_BRACKET; + break; + case CODE_INPUT: + code = java.awt.event.KeyEvent.VK_CODE_INPUT; + break; + case COLON: + code = java.awt.event.KeyEvent.VK_COLON; + break; + case COLORED_KEY_0: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case COLORED_KEY_1: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case COLORED_KEY_2: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case COLORED_KEY_3: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case COMMA: + code = java.awt.event.KeyEvent.VK_COMMA; + break; + case COMPOSE: + code = java.awt.event.KeyEvent.VK_COMPOSE; + break; + case CONTEXT_MENU: + code = java.awt.event.KeyEvent.VK_CONTEXT_MENU; + break; + case CONTROL: + code = java.awt.event.KeyEvent.VK_CONTROL; + break; + case CONVERT: + code = java.awt.event.KeyEvent.VK_CONVERT; + break; + case COPY: + code = java.awt.event.KeyEvent.VK_COPY; + break; + case CUT: + code = java.awt.event.KeyEvent.VK_CUT; + break; + case D: + code = java.awt.event.KeyEvent.VK_D; + break; + case DEAD_ABOVEDOT: + code = java.awt.event.KeyEvent.VK_DEAD_ABOVEDOT; + break; + case DEAD_ABOVERING: + code = java.awt.event.KeyEvent.VK_DEAD_ABOVERING; + break; + case DEAD_ACUTE: + code = java.awt.event.KeyEvent.VK_DEAD_ACUTE; + break; + case DEAD_BREVE: + code = java.awt.event.KeyEvent.VK_DEAD_BREVE; + break; + case DEAD_CARON: + code = java.awt.event.KeyEvent.VK_DEAD_CARON; + break; + case DEAD_CEDILLA: + code = java.awt.event.KeyEvent.VK_DEAD_CEDILLA; + break; + case DEAD_CIRCUMFLEX: + code = java.awt.event.KeyEvent.VK_DEAD_CIRCUMFLEX; + break; + case DEAD_DIAERESIS: + code = java.awt.event.KeyEvent.VK_DEAD_DIAERESIS; + break; + case DEAD_DOUBLEACUTE: + code = java.awt.event.KeyEvent.VK_DEAD_DOUBLEACUTE; + break; + case DEAD_GRAVE: + code = java.awt.event.KeyEvent.VK_DEAD_GRAVE; + break; + case DEAD_IOTA: + code = java.awt.event.KeyEvent.VK_DEAD_IOTA; + break; + case DEAD_MACRON: + code = java.awt.event.KeyEvent.VK_DEAD_MACRON; + break; + case DEAD_OGONEK: + code = java.awt.event.KeyEvent.VK_DEAD_OGONEK; + break; + case DEAD_SEMIVOICED_SOUND: + code = java.awt.event.KeyEvent.VK_DEAD_SEMIVOICED_SOUND; + break; + case DEAD_TILDE: + code = java.awt.event.KeyEvent.VK_DEAD_TILDE; + break; + case DEAD_VOICED_SOUND: + code = java.awt.event.KeyEvent.VK_DEAD_VOICED_SOUND; + break; + case DECIMAL: + code = java.awt.event.KeyEvent.VK_DECIMAL; + break; + case DELETE: + code = java.awt.event.KeyEvent.VK_DELETE; + break; + case DIGIT0: + code = java.awt.event.KeyEvent.VK_0; + break; + case DIGIT1: + code = java.awt.event.KeyEvent.VK_1; + break; + case DIGIT2: + code = java.awt.event.KeyEvent.VK_2; + break; + case DIGIT3: + code = java.awt.event.KeyEvent.VK_3; + break; + case DIGIT4: + code = java.awt.event.KeyEvent.VK_4; + break; + case DIGIT5: + code = java.awt.event.KeyEvent.VK_5; + break; + case DIGIT6: + code = java.awt.event.KeyEvent.VK_6; + break; + case DIGIT7: + code = java.awt.event.KeyEvent.VK_7; + break; + case DIGIT8: + code = java.awt.event.KeyEvent.VK_8; + break; + case DIGIT9: + code = java.awt.event.KeyEvent.VK_9; + break; + case DIVIDE: + code = java.awt.event.KeyEvent.VK_DIVIDE; + break; + case DOLLAR: + code = java.awt.event.KeyEvent.VK_DOLLAR; + break; + case DOWN: + code = java.awt.event.KeyEvent.VK_DOWN; + break; + case E: + code = java.awt.event.KeyEvent.VK_E; + break; + case EJECT_TOGGLE: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case END: + code = java.awt.event.KeyEvent.VK_END; + break; + case ENTER: + code = java.awt.event.KeyEvent.VK_ENTER; + break; + case EQUALS: + code = java.awt.event.KeyEvent.VK_EQUALS; + break; + case ESCAPE: + code = java.awt.event.KeyEvent.VK_ESCAPE; + break; + case EURO_SIGN: + code = java.awt.event.KeyEvent.VK_EURO_SIGN; + break; + case EXCLAMATION_MARK: + code = java.awt.event.KeyEvent.VK_EXCLAMATION_MARK; + break; + case F: + code = java.awt.event.KeyEvent.VK_F; + break; + case F1: + code = java.awt.event.KeyEvent.VK_F1; + break; + case F10: + code = java.awt.event.KeyEvent.VK_F10; + break; + case F11: + code = java.awt.event.KeyEvent.VK_F11; + break; + case F12: + code = java.awt.event.KeyEvent.VK_F12; + break; + case F13: + code = java.awt.event.KeyEvent.VK_F13; + break; + case F14: + code = java.awt.event.KeyEvent.VK_F14; + break; + case F15: + code = java.awt.event.KeyEvent.VK_F15; + break; + case F16: + code = java.awt.event.KeyEvent.VK_F16; + break; + case F17: + code = java.awt.event.KeyEvent.VK_F17; + break; + case F18: + code = java.awt.event.KeyEvent.VK_F18; + break; + case F19: + code = java.awt.event.KeyEvent.VK_F19; + break; + case F2: + code = java.awt.event.KeyEvent.VK_F2; + break; + case F20: + code = java.awt.event.KeyEvent.VK_F20; + break; + case F21: + code = java.awt.event.KeyEvent.VK_F21; + break; + case F22: + code = java.awt.event.KeyEvent.VK_F22; + break; + case F23: + code = java.awt.event.KeyEvent.VK_F23; + break; + case F24: + code = java.awt.event.KeyEvent.VK_F24; + break; + case F3: + code = java.awt.event.KeyEvent.VK_F3; + break; + case F4: + code = java.awt.event.KeyEvent.VK_F4; + break; + case F5: + code = java.awt.event.KeyEvent.VK_F5; + break; + case F6: + code = java.awt.event.KeyEvent.VK_F6; + break; + case F7: + code = java.awt.event.KeyEvent.VK_F7; + break; + case F8: + code = java.awt.event.KeyEvent.VK_F8; + break; + case F9: + code = java.awt.event.KeyEvent.VK_F9; + break; + case FAST_FWD: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case FINAL: + code = java.awt.event.KeyEvent.VK_FINAL; + break; + case FIND: + code = java.awt.event.KeyEvent.VK_FIND; + break; + case FULL_WIDTH: + code = java.awt.event.KeyEvent.VK_FULL_WIDTH; + break; + case G: + code = java.awt.event.KeyEvent.VK_G; + break; + case GAME_A: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case GAME_B: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case GAME_C: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case GAME_D: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case GREATER: + code = java.awt.event.KeyEvent.VK_GREATER; + break; + case H: + code = java.awt.event.KeyEvent.VK_H; + break; + case HALF_WIDTH: + code = java.awt.event.KeyEvent.VK_HALF_WIDTH; + break; + case HELP: + code = java.awt.event.KeyEvent.VK_HELP; + break; + case HIRAGANA: + code = java.awt.event.KeyEvent.VK_HIRAGANA; + break; + case HOME: + code = java.awt.event.KeyEvent.VK_HOME; + break; + case I: + code = java.awt.event.KeyEvent.VK_I; + break; + case INFO: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case INPUT_METHOD_ON_OFF: + code = java.awt.event.KeyEvent.VK_INPUT_METHOD_ON_OFF; + break; + case INSERT: + code = java.awt.event.KeyEvent.VK_INSERT; + break; + case INVERTED_EXCLAMATION_MARK: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case J: + code = java.awt.event.KeyEvent.VK_J; + break; + case JAPANESE_HIRAGANA: + code = java.awt.event.KeyEvent.VK_JAPANESE_HIRAGANA; + break; + case JAPANESE_KATAKANA: + code = java.awt.event.KeyEvent.VK_JAPANESE_KATAKANA; + break; + case JAPANESE_ROMAN: + code = java.awt.event.KeyEvent.VK_JAPANESE_ROMAN; + break; + case K: + code = java.awt.event.KeyEvent.VK_K; + break; + case KANA: + code = java.awt.event.KeyEvent.VK_KANA; + break; + case KANA_LOCK: + code = java.awt.event.KeyEvent.VK_KANA_LOCK; + break; + case KANJI: + code = java.awt.event.KeyEvent.VK_KANJI; + break; + case KATAKANA: + code = java.awt.event.KeyEvent.VK_KATAKANA; + break; + case KP_DOWN: + code = java.awt.event.KeyEvent.VK_KP_DOWN; + break; + case KP_LEFT: + code = java.awt.event.KeyEvent.VK_KP_LEFT; + break; + case KP_RIGHT: + code = java.awt.event.KeyEvent.VK_KP_RIGHT; + break; + case KP_UP: + code = java.awt.event.KeyEvent.VK_KP_UP; + break; + case L: + code = java.awt.event.KeyEvent.VK_L; + break; + case LEFT: + code = java.awt.event.KeyEvent.VK_LEFT; + break; + case LEFT_PARENTHESIS: + code = java.awt.event.KeyEvent.VK_LEFT_PARENTHESIS; + break; + case LESS: + code = java.awt.event.KeyEvent.VK_LESS; + break; + case M: + code = java.awt.event.KeyEvent.VK_M; + break; + case META: + code = java.awt.event.KeyEvent.VK_META; + break; + case MINUS: + code = java.awt.event.KeyEvent.VK_MINUS; + break; + case MODECHANGE: + code = java.awt.event.KeyEvent.VK_MODECHANGE; + break; + case MULTIPLY: + code = java.awt.event.KeyEvent.VK_MULTIPLY; + break; + case MUTE: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case N: + code = java.awt.event.KeyEvent.VK_N; + break; + case NONCONVERT: + code = java.awt.event.KeyEvent.VK_NONCONVERT; + break; + case NUMBER_SIGN: + code = java.awt.event.KeyEvent.VK_NUMBER_SIGN; + break; + case NUMPAD0: + code = java.awt.event.KeyEvent.VK_NUMPAD0; + break; + case NUMPAD1: + code = java.awt.event.KeyEvent.VK_NUMPAD1; + break; + case NUMPAD2: + code = java.awt.event.KeyEvent.VK_NUMPAD2; + break; + case NUMPAD3: + code = java.awt.event.KeyEvent.VK_NUMPAD3; + break; + case NUMPAD4: + code = java.awt.event.KeyEvent.VK_NUMPAD4; + break; + case NUMPAD5: + code = java.awt.event.KeyEvent.VK_NUMPAD5; + break; + case NUMPAD6: + code = java.awt.event.KeyEvent.VK_NUMPAD6; + break; + case NUMPAD7: + code = java.awt.event.KeyEvent.VK_NUMPAD7; + break; + case NUMPAD8: + code = java.awt.event.KeyEvent.VK_NUMPAD8; + break; + case NUMPAD9: + code = java.awt.event.KeyEvent.VK_NUMPAD9; + break; + case NUM_LOCK: + code = java.awt.event.KeyEvent.VK_NUM_LOCK; + break; + case O: + code = java.awt.event.KeyEvent.VK_O; + break; + case OPEN_BRACKET: + code = java.awt.event.KeyEvent.VK_OPEN_BRACKET; + break; + case P: + code = java.awt.event.KeyEvent.VK_P; + break; + case PAGE_DOWN: + code = java.awt.event.KeyEvent.VK_PAGE_DOWN; + break; + case PAGE_UP: + code = java.awt.event.KeyEvent.VK_PAGE_UP; + break; + case PASTE: + code = java.awt.event.KeyEvent.VK_PASTE; + break; + case PAUSE: + code = java.awt.event.KeyEvent.VK_PAUSE; + break; + case PERIOD: + code = java.awt.event.KeyEvent.VK_PERIOD; + break; + case PLAY: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case PLUS: + code = java.awt.event.KeyEvent.VK_PLUS; + break; + case POUND: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case POWER: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case PREVIOUS_CANDIDATE: + code = java.awt.event.KeyEvent.VK_PREVIOUS_CANDIDATE; + break; + case PRINTSCREEN: + code = java.awt.event.KeyEvent.VK_PRINTSCREEN; + break; + case PROPS: + code = java.awt.event.KeyEvent.VK_PROPS; + break; + case Q: + code = java.awt.event.KeyEvent.VK_Q; + break; + case QUOTE: + code = java.awt.event.KeyEvent.VK_QUOTE; + break; + case QUOTEDBL: + code = java.awt.event.KeyEvent.VK_QUOTEDBL; + break; + case R: + code = java.awt.event.KeyEvent.VK_R; + break; + case RECORD: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case REWIND: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case RIGHT: + code = java.awt.event.KeyEvent.VK_RIGHT; + break; + case RIGHT_PARENTHESIS: + code = java.awt.event.KeyEvent.VK_RIGHT_PARENTHESIS; + break; + case ROMAN_CHARACTERS: + code = java.awt.event.KeyEvent.VK_ROMAN_CHARACTERS; + break; + case S: + code = java.awt.event.KeyEvent.VK_S; + break; + case SCROLL_LOCK: + code = java.awt.event.KeyEvent.VK_SCROLL_LOCK; + break; + case SEMICOLON: + code = java.awt.event.KeyEvent.VK_SEMICOLON; + break; + case SEPARATOR: + code = java.awt.event.KeyEvent.VK_SEPARATOR; + break; + case SHIFT: + code = java.awt.event.KeyEvent.VK_SHIFT; + break; + case SHORTCUT: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SLASH: + code = java.awt.event.KeyEvent.VK_SLASH; + break; + case SOFTKEY_0: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_1: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_2: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_3: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_4: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_5: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_6: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_7: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_8: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SOFTKEY_9: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case SPACE: + code = java.awt.event.KeyEvent.VK_SPACE; + break; + case STAR: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case STOP: + code = java.awt.event.KeyEvent.VK_STOP; + break; + case SUBTRACT: + code = java.awt.event.KeyEvent.VK_SUBTRACT; + break; + case T: + code = java.awt.event.KeyEvent.VK_T; + break; + case TAB: + code = java.awt.event.KeyEvent.VK_TAB; + break; + case TRACK_NEXT: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case TRACK_PREV: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case U: + code = java.awt.event.KeyEvent.VK_U; + break; + case UNDEFINED: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case UNDERSCORE: + code = java.awt.event.KeyEvent.VK_UNDERSCORE; + break; + case UNDO: + code = java.awt.event.KeyEvent.VK_UNDO; + break; + case UP: + code = java.awt.event.KeyEvent.VK_UP; + break; + case V: + code = java.awt.event.KeyEvent.VK_V; + break; + case VOLUME_DOWN: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case VOLUME_UP: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + break; + case W: + code = java.awt.event.KeyEvent.VK_W; + break; + case WINDOWS: + code = java.awt.event.KeyEvent.VK_WINDOWS; + break; + case X: + code = java.awt.event.KeyEvent.VK_X; + break; + case Y: + code = java.awt.event.KeyEvent.VK_Y; + break; + case Z: + code = java.awt.event.KeyEvent.VK_Z; + break; + default: + code = java.awt.event.KeyEvent.VK_UNDEFINED; + } + return code; + } + +} --- /dev/null 2011-12-03 11:37:36.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/ProxyGraphics.java 2011-12-03 11:37:36.000000000 +0100 @@ -0,0 +1,550 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.RenderingHints.Key; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; +import java.text.AttributedCharacterIterator; +import java.util.Map; + +import sun.awt.ConstrainableGraphics; + +class ProxyGraphics extends Graphics2D implements ConstrainableGraphics { + + private SwingView swingView; + + private Graphics2D proxy; + + ProxyGraphics(SwingView v, Graphics2D p) { + swingView = v; + proxy = p; + } + + @Override + public void draw3DRect(int x, int y, int width, int height, boolean raised) { + proxy.draw3DRect(x, y, width, height, raised); + commit(); + } + + @Override + public void drawBytes(byte[] data, int offset, int length, int x, int y) { + proxy.drawBytes(data, offset, length, x, y); + commit(); + } + + @Override + public void drawChars(char[] data, int offset, int length, int x, int y) { + proxy.drawChars(data, offset, length, x, y); + commit(); + } + + @Override + public Graphics create(int x, int y, int width, int height) { + Graphics2D copy = (Graphics2D) proxy.create(x, y, width, height); + ProxyGraphics graphics = new ProxyGraphics(swingView, copy); + return graphics; + } + + @Override + public void drawPolygon(Polygon p) { + proxy.drawPolygon(p); + commit(); + } + + @Override + public void fill3DRect(int x, int y, int width, int height, boolean raised) { + proxy.fill3DRect(x, y, width, height, raised); + commit(); + } + + @Override + public void drawRect(int x, int y, int width, int height) { + proxy.drawRect(x, y, width, height); + commit(); + } + + @Override + public void fillPolygon(Polygon p) { + proxy.fillPolygon(p); + commit(); + } + + @Override + public Rectangle getClipBounds(Rectangle r) { + return proxy.getClipBounds(r); + } + + @SuppressWarnings("deprecation") + @Override + public Rectangle getClipRect() { + return proxy.getClipRect(); + } + + @Override + public FontMetrics getFontMetrics() { + return proxy.getFontMetrics(); + } + + @Override + public boolean hitClip(int x, int y, int width, int height) { + return proxy.hitClip(x, y, width, height); + } + + @Override + public void draw(Shape s) { + proxy.draw(s); + commit(); + } + + @Override + public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { + boolean b = proxy.drawImage(img, xform, obs); + commit(); + return b; + } + + @Override + public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { + proxy.drawImage(img, op, x, y); + commit(); + } + + @Override + public void drawRenderedImage(RenderedImage img, AffineTransform xform) { + proxy.drawRenderedImage(img, xform); + commit(); + } + + @Override + public void drawRenderableImage(RenderableImage img, AffineTransform xform) { + proxy.drawRenderableImage(img, xform); + commit(); + } + + @Override + public void drawString(String str, int x, int y) { + proxy.drawString(str, x, y); + commit(); + } + + @Override + public void drawString(String str, float x, float y) { + proxy.drawString(str, x, y); + commit(); + } + + @Override + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + proxy.drawString(iterator, x, y); + commit(); + } + + @Override + public void drawString(AttributedCharacterIterator iterator, float x, + float y) { + proxy.drawString(iterator, x, y); + commit(); + } + + @Override + public void drawGlyphVector(GlyphVector g, float x, float y) { + proxy.drawGlyphVector(g, x, y); + commit(); + } + + @Override + public void fill(Shape s) { + proxy.fill(s); + commit(); + } + + @Override + public boolean hit(Rectangle rect, Shape s, boolean onStroke) { + return proxy.hit(rect, s, onStroke); + } + + @Override + public GraphicsConfiguration getDeviceConfiguration() { + return proxy.getDeviceConfiguration(); + } + + @Override + public void setComposite(Composite comp) { + proxy.setComposite(comp); + } + + @Override + public void setPaint(Paint paint) { + proxy.setPaint(paint); + } + + @Override + public void setStroke(Stroke s) { + proxy.setStroke(s); + } + + @Override + public void setRenderingHint(Key hintKey, Object hintValue) { + proxy.setRenderingHint(hintKey, hintValue); + } + + @Override + public Object getRenderingHint(Key hintKey) { + return proxy.getRenderingHint(hintKey); + } + + @Override + public void setRenderingHints(Map hints) { + proxy.setRenderingHints(hints); + } + + @Override + public void addRenderingHints(Map hints) { + proxy.addRenderingHints(hints); + } + + @Override + public RenderingHints getRenderingHints() { + return proxy.getRenderingHints(); + } + + @Override + public void translate(int x, int y) { + proxy.translate(x, y); + } + + @Override + public void translate(double tx, double ty) { + proxy.translate(tx, ty); + } + + @Override + public void rotate(double theta) { + proxy.rotate(theta); + } + + @Override + public void rotate(double theta, double x, double y) { + proxy.rotate(theta, x, y); + } + + @Override + public void scale(double sx, double sy) { + proxy.scale(sx, sy); + } + + @Override + public void shear(double shx, double shy) { + proxy.shear(shx, shy); + } + + @Override + public void transform(AffineTransform Tx) { + proxy.transform(Tx); + } + + @Override + public void setTransform(AffineTransform Tx) { + proxy.setTransform(Tx); + } + + @Override + public AffineTransform getTransform() { + return proxy.getTransform(); + } + + @Override + public Paint getPaint() { + return proxy.getPaint(); + } + + @Override + public Composite getComposite() { + return proxy.getComposite(); + } + + @Override + public void setBackground(Color color) { + proxy.setBackground(color); + } + + @Override + public Color getBackground() { + return proxy.getBackground(); + } + + @Override + public Stroke getStroke() { + return proxy.getStroke(); + } + + @Override + public void clip(Shape s) { + proxy.clip(s); + } + + @Override + public FontRenderContext getFontRenderContext() { + return proxy.getFontRenderContext(); + } + + @Override + public Graphics create() { + Graphics2D copy = (Graphics2D) proxy.create(); + ProxyGraphics graphics = new ProxyGraphics(swingView, copy); + return graphics; + } + + @Override + public Color getColor() { + return proxy.getColor(); + } + + @Override + public void setColor(Color c) { + proxy.setColor(c); + } + + @Override + public void setPaintMode() { + proxy.setPaintMode(); + } + + @Override + public void setXORMode(Color c1) { + proxy.setXORMode(c1); + } + + @Override + public Font getFont() { + return proxy.getFont(); + } + + @Override + public void setFont(Font font) { + proxy.setFont(font); + } + + @Override + public FontMetrics getFontMetrics(Font f) { + return proxy.getFontMetrics(f); + } + + @Override + public Rectangle getClipBounds() { + return proxy.getClipBounds(); + } + + @Override + public void clipRect(int x, int y, int width, int height) { + proxy.clipRect(x, y, width, height); + } + + @Override + public void setClip(int x, int y, int width, int height) { + proxy.setClip(x, y, width, height); + } + + @Override + public Shape getClip() { + return proxy.getClip(); + } + + @Override + public void setClip(Shape clip) { + proxy.setClip(clip); + } + + @Override + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + proxy.copyArea(x, y, width, height, dx, dy); + commit(); + } + + @Override + public void drawLine(int x1, int y1, int x2, int y2) { + proxy.drawLine(x1, y1, x2, y2); + commit(); + } + + @Override + public void fillRect(int x, int y, int width, int height) { + proxy.fillRect(x, y, width, height); + commit(); + } + + @Override + public void clearRect(int x, int y, int width, int height) { + proxy.clearRect(x, y, width, height); + commit(); + } + + @Override + public void drawRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) { + proxy.drawRoundRect(x, y, width, height, arcWidth, arcHeight); + commit(); + } + + @Override + public void fillRoundRect(int x, int y, int width, int height, + int arcWidth, int arcHeight) { + proxy.fillRoundRect(x, y, width, height, arcWidth, arcHeight); + commit(); + } + + @Override + public void drawOval(int x, int y, int width, int height) { + proxy.drawOval(x, y, width, height); + commit(); + } + + @Override + public void fillOval(int x, int y, int width, int height) { + proxy.fillOval(x, y, width, height); + commit(); + } + + @Override + public void drawArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { + proxy.drawArc(x, y, width, height, startAngle, arcAngle); + commit(); + } + + @Override + public void fillArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { + proxy.fillArc(x, y, width, height, startAngle, arcAngle); + commit(); + } + + @Override + public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { + proxy.drawPolyline(xPoints, yPoints, nPoints); + commit(); + } + + @Override + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { + proxy.drawPolygon(xPoints, yPoints, nPoints); + commit(); + } + + @Override + public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { + proxy.fillPolygon(xPoints, yPoints, nPoints); + commit(); + } + + @Override + public boolean drawImage(Image img, int x, int y, ImageObserver observer) { + boolean b = proxy.drawImage(img, x, y, observer); + commit(); + return b; + } + + @Override + public boolean drawImage(Image img, int x, int y, int width, int height, + ImageObserver observer) { + boolean b = proxy.drawImage(img, x, y, width, height, observer); + commit(); + return b; + } + + @Override + public boolean drawImage(Image img, int x, int y, Color bgcolor, + ImageObserver observer) { + boolean b = proxy.drawImage(img, x, y, bgcolor, observer); + commit(); + return b; + } + + @Override + public boolean drawImage(Image img, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) { + boolean b = proxy.drawImage(img, x, y, width, height, bgcolor, observer); + commit(); + return b; + } + + @Override + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { + boolean b = proxy.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer); + commit(); + return b; + } + + @Override + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, Color bgcolor, + ImageObserver observer) { + boolean b = proxy.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer); + commit(); + return b; + } + + @Override + public void dispose() { + proxy.dispose(); + commit(); + } + + private void commit() { + swingView.commit(); + } + + @Override + public void constrain(int x, int y, int w, int h) { + if (proxy instanceof ConstrainableGraphics) { + ((ConstrainableGraphics) proxy).constrain(x, y, w, h); + } else { + throw new UnsupportedOperationException(); + } + } +} --- /dev/null 2011-12-03 11:37:36.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/ProxyWindow.java 2011-12-03 11:37:36.000000000 +0100 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.Component; +import java.awt.Frame; +import java.lang.reflect.Field; + +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; + +class ProxyWindow extends Frame { + + private static Field peer; + + private static void initReflection() { + try { + peer = Component.class.getDeclaredField("peer"); + peer.setAccessible(true); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + static { + initReflection(); + } + + private SwingView proxyView; + + ProxyWindow(SwingView proxyView) { + this.proxyView = proxyView; + + try { + peer.set(this, new ProxyWindowPeer(this)); + + } catch (Exception e) { + e.printStackTrace(); + } + proxyView.focusedProperty().addListener(new ChangeListener() { + + @Override + public void changed(ObservableValue obs, + Boolean oldValue, Boolean newValue) { + FXSwingKeyboardFocusManagerPeer peer = + FXSwingKeyboardFocusManagerPeer.getInstance(); + if (newValue) { + peer.focusGained(ProxyWindow.this); + } else { + peer.focusLost(ProxyWindow.this); + } + } + }); + } + + @Override + public boolean isVisible() { + return proxyView.isVisible(); + } + @Override + public boolean isShowing() { + return proxyView.isVisible(); + } + + @Override + public boolean isFocusTraversable() { + return proxyView.isFocusTraversable(); + } + + SwingView getProxyView() { + return proxyView; + } +} --- /dev/null 2011-12-03 11:37:37.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/ProxyWindowPeer.java 2011-12-03 11:37:37.000000000 +0100 @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.BufferCapabilities; +import java.awt.BufferCapabilities.FlipContents; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Insets; +import java.awt.MenuBar; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.PaintEvent; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.image.VolatileImage; +import java.awt.peer.ComponentPeer; +import java.awt.peer.ContainerPeer; +import java.awt.peer.FramePeer; + +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.stage.Window; +import sun.awt.CausedFocusEvent.Cause; +import sun.java2d.pipe.Region; + +class ProxyWindowPeer implements FramePeer { + + private ProxyWindow window; + + ProxyWindowPeer(ProxyWindow w) { + window = w; + } + + @Override + public void toFront() { + throw new UnsupportedOperationException(); + } + + @Override + public void toBack() { + throw new UnsupportedOperationException(); + } + + @Override + public void setAlwaysOnTop(boolean alwaysOnTop) { + throw new UnsupportedOperationException(); + } + + @Override + public void updateFocusableWindowState() { + throw new UnsupportedOperationException(); + } + + // @Override No longer present in JDK6 + public boolean requestWindowFocus() { + throw new UnsupportedOperationException(); + } + + @Override + public void setModalBlocked(Dialog blocker, boolean blocked) { + throw new UnsupportedOperationException(); + } + + @Override + public void updateMinimumSize() { + throw new UnsupportedOperationException(); + } + + @Override + public void updateIconImages() { + throw new UnsupportedOperationException(); + } + + @Override + public void setOpacity(float opacity) { + throw new UnsupportedOperationException(); + } + + @Override + public void setOpaque(boolean isOpaque) { + // Noop. + } + + @Override + public void updateWindow() { + throw new UnsupportedOperationException(); + } + + @Override + public void repositionSecurityWarning() { + throw new UnsupportedOperationException(); + } + + @Override + public Insets getInsets() { + return new Insets(0, 0, 0, 0); + } + + @Override + public void beginValidate() { + // Nothing to do here. + } + + @Override + public void endValidate() { + // Nothing to do here. + } + + @Override + public void beginLayout() { + // Nothing to do here. + } + + @Override + public void endLayout() { + // Nothing to do here. + } + + // @Override Not present in JDK7 + public boolean isPaintPending() { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK7 + public void restack() { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK7 + public boolean isRestackSupported() { + return false; + } + + // @Override Not present in JDK7 + public Insets insets() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isObscured() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean canDetermineObscurity() { + return false; + } + + @Override + public void setVisible(boolean b) { + throw new UnsupportedOperationException(); + } + + @Override + public void setEnabled(boolean b) { + throw new UnsupportedOperationException(); + } + + @Override + public void paint(Graphics g) { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK7 + public void repaint(long tm, int x, int y, int width, int height) { + throw new UnsupportedOperationException(); + } + + @Override + public void print(Graphics g) { + throw new UnsupportedOperationException(); + } + + @Override + public void setBounds(int x, int y, int width, int height, int op) { + // Nothing to do here. + } + + @Override + public void handleEvent(AWTEvent e) { + // Nothing to do here. + } + + @Override + public void coalescePaintEvent(PaintEvent e) { + // Nothing to do here. + } + + @Override + public Point getLocationOnScreen() { + Point loc = new Point(); + Node node = window.getProxyView(); + while (true) { + loc.x += node.getLayoutX(); + loc.y += node.getLayoutY(); + Node parent = node.getParent(); + if (parent == null) { + break; + } + node = parent; + } + Scene scene = node.getScene(); + loc.x += scene.getX(); + loc.y += scene.getY(); + Window window = scene.getWindow(); + loc.x += window.getX(); + loc.y += window.getY(); + return loc; + } + + @Override + public Dimension getPreferredSize() { + throw new UnsupportedOperationException(); + } + + @Override + public Dimension getMinimumSize() { + throw new UnsupportedOperationException(); + } + + @Override + public ColorModel getColorModel() { + throw new UnsupportedOperationException(); + } + + @Override + public Toolkit getToolkit() { + return Toolkit.getDefaultToolkit(); + } + + @Override + public Graphics getGraphics() { + ProxyGraphics g = new ProxyGraphics(window.getProxyView(), (Graphics2D) + window.getProxyView().getBackBuffer().getGraphics()); + g.setColor(window.getForeground()); + g.setBackground(window.getBackground()); + g.setFont(window.getFont()); + return g; + } + + @Override + public FontMetrics getFontMetrics(Font font) { + throw new UnsupportedOperationException(); + } + + @Override + public void dispose() { + throw new UnsupportedOperationException(); + } + + @Override + public void setForeground(Color c) { + // Noop. + } + + @Override + public void setBackground(Color c) { + // Noop. + } + + @Override + public void setFont(Font f) { + // Noop. + } + + @Override + public void updateCursorImmediately() { + // TODO: Implement. + } + + @Override + public boolean requestFocus(Component lightweightChild, boolean temporary, + boolean focusedWindowChangeAllowed, long time, Cause cause) { + if (KFMHelper.processSynchronousLightweightTransfer(window, + lightweightChild, temporary, focusedWindowChangeAllowed, time)) { + return true; + } + + int result = KFMHelper.shouldNativelyFocusHeavyweight(window, + lightweightChild, temporary, focusedWindowChangeAllowed, time, + cause); + + switch (result) { + case KFMHelper.SNFH_FAILURE: + return false; + case KFMHelper.SNFH_SUCCESS_PROCEED: + return FXSwingKeyboardFocusManagerPeer.getInstance(). + requestFocus(window, lightweightChild, temporary, + focusedWindowChangeAllowed, time, cause); + case KFMHelper.SNFH_SUCCESS_HANDLED: + // Either lightweight or excessive request - all events are + // generated. + return true; + default: + return false; + } + } + + @Override + public boolean isFocusable() { + throw new UnsupportedOperationException(); + } + + @Override + public Image createImage(ImageProducer producer) { + throw new UnsupportedOperationException(); + } + + @Override + public Image createImage(int width, int height) { + return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + } + + @Override + public VolatileImage createVolatileImage(int width, int height) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean prepareImage(Image img, int w, int h, ImageObserver o) { + throw new UnsupportedOperationException(); + } + + @Override + public int checkImage(Image img, int w, int h, ImageObserver o) { + throw new UnsupportedOperationException(); + } + + @Override + public GraphicsConfiguration getGraphicsConfiguration() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean handlesWheelScrolling() { + throw new UnsupportedOperationException(); + } + + @Override + public void createBuffers(int numBuffers, BufferCapabilities caps) + throws AWTException { + throw new UnsupportedOperationException(); + } + + @Override + public Image getBackBuffer() { + throw new UnsupportedOperationException(); + } + + @Override + public void flip(int x1, int y1, int x2, int y2, FlipContents flipAction) { + throw new UnsupportedOperationException(); + } + + @Override + public void destroyBuffers() { + throw new UnsupportedOperationException(); + } + + @Override + public void reparent(ContainerPeer newContainer) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isReparentSupported() { + throw new UnsupportedOperationException(); + } + + @Override + public void layout() { + // Nothing to do here. + } + + // @Override Not present in JDK7 + public Rectangle getBounds() { + throw new UnsupportedOperationException(); + } + + @Override + public void applyShape(Region shape) { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK7 + public Dimension preferredSize() { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK7 + public Dimension minimumSize() { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK7 + public void show() { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK7 + public void hide() { + throw new UnsupportedOperationException(); + } + + // @Override no more present in JDK7 + public void enable() { + throw new UnsupportedOperationException(); + } + + // @Override no more present in JDK7 + public void disable() { + throw new UnsupportedOperationException(); + } + + // @Override no more present in JDK7 + public void reshape(int x, int y, int width, int height) { + throw new UnsupportedOperationException(); + } + + @Override + public void setTitle(String title) { + throw new UnsupportedOperationException(); + } + + @Override + public void setMenuBar(MenuBar mb) { + throw new UnsupportedOperationException(); + } + + @Override + public void setResizable(boolean resizeable) { + throw new UnsupportedOperationException(); + } + + @Override + public void setState(int state) { + throw new UnsupportedOperationException(); + } + + @Override + public int getState() { + return 0; + } + + @Override + public void setMaximizedBounds(Rectangle bounds) { + throw new UnsupportedOperationException(); + } + + @Override + public void setBoundsPrivate(int x, int y, int width, int height) { + throw new UnsupportedOperationException(); + } + + @Override + public Rectangle getBoundsPrivate() { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK6 + public void setZOrder(ComponentPeer above) { + throw new UnsupportedOperationException(); + } + + // @Override Not present in JDK6 + public boolean updateGraphicsData(GraphicsConfiguration gc) { + throw new UnsupportedOperationException(); + } + +} --- /dev/null 2011-12-03 11:37:37.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/SwingEventDispatcherHelper.java 2011-12-03 11:37:37.000000000 +0100 @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.AWTEvent; +import java.awt.Container; +import java.awt.event.KeyAdapter; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import javax.swing.JComponent; + +class SwingEventDispatcherHelper { + + private static final long MOUSE_MASK = AWTEvent.MOUSE_EVENT_MASK | + AWTEvent.MOUSE_MOTION_EVENT_MASK | + AWTEvent.MOUSE_WHEEL_EVENT_MASK; + + private static Field dispatcherField; + private static Constructor newLightweightDispatcher; + private static Method dispatchMethod; + private static Method enableEvents; + + // grab this idea from CacioCavallo + static void initReflection() { + try { + + // lightweight dispatcher + dispatcherField = Container.class.getDeclaredField("dispatcher"); + dispatcherField.setAccessible(true); + + Class dispatcherCls = Class.forName("java.awt.LightweightDispatcher"); + newLightweightDispatcher = + dispatcherCls.getDeclaredConstructor(new Class[] { + Container.class + }); + newLightweightDispatcher.setAccessible(true); + + dispatchMethod = dispatcherCls.getDeclaredMethod("dispatchEvent", + AWTEvent.class); + dispatchMethod.setAccessible(true); + + enableEvents = dispatcherCls.getDeclaredMethod("enableEvents", + new Class[] { + long.class + }); + enableEvents.setAccessible(true); + + } catch (Exception ex) { + + System.err.println(ex); + + InternalError err = new InternalError(); + err.initCause(ex); + throw err; + } + } + + static void setLightweightDispatcher(JComponent component) { + if (dispatcherField == null) { + initReflection(); + } + try { + Object dispatcher = newLightweightDispatcher.newInstance(component); + enableEvents.invoke(dispatcher, MOUSE_MASK | AWTEvent.KEY_EVENT_MASK); + dispatcherField.set(component, dispatcher); + component.addKeyListener(new KeyAdapter(){}); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Performs lightweight dispatching for the specified event on this window. + * This only calls the lightweight dispatcher. We cannot simply + * call dispatchEvent() because that would also send the event to the + * Toolkit dispatching mechanism (AWTEventListener, etc), which has ugly + * side effects, like popups closing too early. + * + * @param e the event to be dispatched + */ + static void dispatchEvent(AWTEvent awtEvent, JComponent component) { + + if (dispatcherField == null) { + initReflection(); + } + try { + Object dispatcher = dispatcherField.get(component); + if (dispatcher != null) { + dispatchMethod.invoke(dispatcher, awtEvent); + } + } catch (Exception ex) { + InternalError err = new InternalError(); + err.initCause(ex); + throw err; + } + + + } +} --- /dev/null 2011-12-03 11:37:38.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/SwingFX.java 2011-12-03 11:37:37.000000000 +0100 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.KeyboardFocusManager; +import java.lang.reflect.Field; + +import javax.swing.RepaintManager; + +/** + * Helper class for {@link SwingView}. The purpose of this class is to + * initialize the special {@link RepaintManager} needed to hook Swing components + * into JavaFX views.

+ * + * The {@link #init()} method must be called before initaliazing the graphics + * state of the application, typically within the main method before calling + * one of the {@link Application#launch(Class, String...))} methods. + */ +public class SwingFX { + + private static boolean initialized; + + /** + * Initializes and install the {@link RepaintManager} needed by + * {@link SwingView}. + */ + public static void init() { + System.setProperty("swing.volatileImageBufferEnabled", "false"); + + // workaround for Mac OS X JDK that cast Graphics to SunGraphics2D + // internally, not painting our components + // this workaround should not be needed from JDK 7 onward + String enableNativeBuffering = "true"; + if (System.getProperty("os.name").contains("Mac")) { + enableNativeBuffering = "false"; + } + System.setProperty("awt.nativeDoubleBuffering", enableNativeBuffering); + + new JFXPanel(); // needed as a trick to launch it on a Mac + + Class kfmCls = KeyboardFocusManager.class; + Field peer; + try { + peer = kfmCls.getDeclaredField("peer"); + peer.setAccessible(true); + peer.set(KeyboardFocusManager.getCurrentKeyboardFocusManager(), + FXSwingKeyboardFocusManagerPeer.getInstance()); + + } catch (Exception e) { + e.printStackTrace(); + } + initialized = true; + } + + static boolean isInitialized() { + return initialized; + } +} --- /dev/null 2011-12-03 11:37:38.000000000 +0100 +++ new/javafx-ui-controls/src/javafx/embed/swing/SwingView.java 2011-12-03 11:37:38.000000000 +0100 @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javafx.embed.swing; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Toolkit; +import java.awt.event.FocusEvent; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.EventHandler; +import javafx.event.EventType; +import javafx.geometry.Bounds; +import javafx.scene.control.Control; +import javafx.scene.input.MouseButton; + +import javax.swing.JComponent; +import javax.swing.SwingUtilities; + +/** + * A {@link Control} that allows embedding of Swing widgets. + * Before using this control, {@link SwingFX#init()} must be called before + * initializing the graphics state. + */ +public class SwingView extends Control { + + private static final Map, Integer> mouseEventMap; + static { + Map, Integer> map = new HashMap, Integer>(); + map.put(javafx.scene.input.MouseEvent.MOUSE_PRESSED, + MouseEvent.MOUSE_PRESSED); + map.put(javafx.scene.input.MouseEvent.MOUSE_RELEASED, + MouseEvent.MOUSE_RELEASED); + map.put(javafx.scene.input.MouseEvent.MOUSE_ENTERED, + MouseEvent.MOUSE_ENTERED); + map.put(javafx.scene.input.MouseEvent.MOUSE_EXITED, + MouseEvent.MOUSE_EXITED); + map.put(javafx.scene.input.MouseEvent.MOUSE_MOVED, + MouseEvent.MOUSE_MOVED); + map.put(javafx.scene.input.MouseEvent.MOUSE_DRAGGED, + MouseEvent.MOUSE_DRAGGED); + mouseEventMap = Collections.unmodifiableMap(map); + } + + private class MouseEventHandler implements + EventHandler { + + @Override + public void handle(javafx.scene.input.MouseEvent jfxMouseEvent) { + EventType type = jfxMouseEvent.getEventType(); + int id = mouseEventMap.get(type); + int button = getAWTButton(jfxMouseEvent.getButton()); + int modifiers = getAWTModifiers(jfxMouseEvent); + final MouseEvent awtEvent = + new MouseEvent(component, id, System.currentTimeMillis(), + modifiers, + (int) jfxMouseEvent.getX(), + (int) jfxMouseEvent.getY(), + (int) jfxMouseEvent.getScreenX(), + (int) jfxMouseEvent.getScreenY(), + jfxMouseEvent.getClickCount(), + false, + button); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + SwingEventDispatcherHelper.dispatchEvent(awtEvent, component); + } + }); + } + + private int getAWTModifiers(javafx.scene.input.MouseEvent jfxMouseEvent) { + int mods = 0; + if (jfxMouseEvent.isAltDown()) { + mods |= MouseEvent.ALT_MASK | MouseEvent.ALT_DOWN_MASK; + } + if (jfxMouseEvent.isControlDown()) { + mods |= MouseEvent.CTRL_MASK | MouseEvent.CTRL_DOWN_MASK; + } + if (jfxMouseEvent.isShiftDown()) { + mods |= MouseEvent.SHIFT_MASK | MouseEvent.SHIFT_DOWN_MASK; + } + if (jfxMouseEvent.isMetaDown()) { + mods |= MouseEvent.META_MASK | MouseEvent.META_DOWN_MASK; + } + if (jfxMouseEvent.isPrimaryButtonDown()) { + mods |= MouseEvent.BUTTON1_MASK | MouseEvent.BUTTON1_DOWN_MASK; + } + if (jfxMouseEvent.isSecondaryButtonDown()) { + mods |= MouseEvent.BUTTON2_MASK | MouseEvent.BUTTON2_DOWN_MASK; + } + if (jfxMouseEvent.isMiddleButtonDown()) { + mods |= MouseEvent.BUTTON3_MASK | MouseEvent.BUTTON3_DOWN_MASK; + } + + return mods; + } + + private int getAWTButton(MouseButton button) { + switch (button) { + case PRIMARY: + return MouseEvent.BUTTON1; + case SECONDARY: + return MouseEvent.BUTTON2; + case MIDDLE: + return MouseEvent.BUTTON3; + case NONE: + default: + return MouseEvent.NOBUTTON; + } + } + } + + private class PainterTask implements Runnable { + @Override + public void run() { + getImageView().paintImage(getBackBuffer()); + painterTaskFuture = null; + } + } + + private static final long COMMIT_DELAY = 30; + + private JComponent component; + + private ProxyWindow proxy; + private BufferedImageView imgView; + + private BufferedImage backBuffer; + + private static ScheduledExecutorService painterTimer = + Executors.newScheduledThreadPool(1); + + private Runnable painterTask = new PainterTask(); + private ScheduledFuture painterTaskFuture; + + public SwingView(JComponent comp) { + + if (!SwingFX.isInitialized()) { + throw new InternalError("SwingFX.init() must be called before"); + } + + this.component = comp; + + imgView = new BufferedImageView(); + getChildren().add(imgView); + + registerEvents(); + + layoutBoundsProperty().addListener(new ChangeListener() { + + @Override + public void changed(ObservableValue obs, + Bounds oldVal, final Bounds newVal) { + EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + proxy.setSize((int) newVal.getWidth(), + (int) newVal.getHeight()); + component.setSize((int) newVal.getWidth(), + (int) newVal.getHeight()); + component.validate(); + } + + }); + } + }); + + Dimension min = component.getMinimumSize(); + setMinSize(min.getWidth(), min.getHeight()); + Dimension pref = component.getPreferredSize(); + setMinSize(pref.getWidth(), pref.getHeight()); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + + JComponent component = SwingView.this.component; + proxy = new ProxyWindow(SwingView.this); + proxy.setForeground(component.getForeground()); + proxy.setBackground(component.getBackground()); + proxy.setFont(component.getFont()); + proxy.add(component); + component.addNotify(); + + SwingEventDispatcherHelper.setLightweightDispatcher(component); + component.setVisible(true); + component.doLayout(); + component.repaint(); + } + }); + } + + private void registerEvents() { + MouseEventHandler handler = new MouseEventHandler(); + setOnMousePressed(handler); + setOnMouseReleased(handler); + setOnMouseMoved(handler); + setOnMouseDragged(handler); + setOnMouseEntered(handler); + setOnMouseExited(handler); + KeyEventHandler keyHandler = new KeyEventHandler(component); + setOnKeyPressed(keyHandler); + setOnKeyReleased(keyHandler); + setOnKeyTyped(keyHandler); + focusedProperty().addListener(new ChangeListener() { + + @Override + public void changed(ObservableValue arg0, + Boolean oldValue, Boolean newValue) { + if (newValue == Boolean.FALSE) { + FocusEvent fl = new FocusEvent(component, + FocusEvent.FOCUS_LOST); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(fl); + } + } + }); + } + + Component getComponent() { + return component; + } + + BufferedImageView getImageView() { + return imgView; + } + + protected double computePrefWidth(double h) { + return component.getPreferredSize().getWidth(); + } + + protected double computePrefHeight(double w) { + return component.getPreferredSize().getHeight(); + } + + public synchronized void commit() { + + if (painterTaskFuture != null) { + painterTaskFuture.cancel(false); + } + + painterTaskFuture = painterTimer.schedule(painterTask, COMMIT_DELAY, + TimeUnit.MILLISECONDS); + } + + BufferedImage getBackBuffer() { + if (backBuffer == null || backBuffer.getWidth() < component.getWidth() || + backBuffer.getHeight() < component.getHeight()) + { + backBuffer = new BufferedImage(component.getWidth(), + component.getHeight(), + BufferedImage.TYPE_INT_ARGB); + } + return backBuffer; + } +}