< prev index next >

modules/javafx.swing/src/main/java/javafx/embed/swing/JFXPanel.java

Print this page




  60 
  61 import javafx.application.Platform;
  62 import javafx.scene.Scene;
  63 
  64 import javax.swing.JComponent;
  65 import javax.swing.SwingUtilities;
  66 
  67 import com.sun.javafx.application.PlatformImpl;
  68 import com.sun.javafx.cursor.CursorFrame;
  69 import com.sun.javafx.embed.AbstractEvents;
  70 import com.sun.javafx.embed.EmbeddedSceneInterface;
  71 import com.sun.javafx.embed.EmbeddedStageInterface;
  72 import com.sun.javafx.embed.HostInterface;
  73 import com.sun.javafx.stage.EmbeddedWindow;
  74 import com.sun.javafx.tk.Toolkit;
  75 import com.sun.javafx.PlatformUtil;
  76 import java.awt.event.InvocationEvent;
  77 
  78 import java.lang.reflect.Method;
  79 import java.util.concurrent.atomic.AtomicInteger;
  80 import sun.awt.AppContext;
  81 import sun.awt.SunToolkit;
  82 import sun.java2d.SunGraphics2D;
  83 import sun.java2d.SurfaceData;
  84 import com.sun.javafx.logging.PlatformLogger;
  85 import com.sun.javafx.logging.PlatformLogger.Level;
  86 


  87 /**
  88 * {@code JFXPanel} is a component to embed JavaFX content into
  89  * Swing applications. The content to be displayed is specified
  90  * with the {@link #setScene} method that accepts an instance of
  91  * JavaFX {@code Scene}. After the scene is assigned, it gets
  92  * repainted automatically. All the input and focus events are
  93  * forwarded to the scene transparently to the developer.
  94  * <p>
  95  * There are some restrictions related to {@code JFXPanel}. As a
  96  * Swing component, it should only be accessed from the event
  97  * dispatch thread, except the {@link #setScene} method, which can
  98  * be called either on the event dispatch thread or on the JavaFX
  99  * application thread.
 100  * <p>
 101  * Here is a typical pattern how {@code JFXPanel} can used:
 102  * <pre>
 103  *     public class Test {
 104  *
 105  *         private static void initAndShowGUI() {
 106  *             // This method is invoked on Swing thread


 433 
 434     /**
 435      * Overrides the {@link java.awt.Component#processMouseEvent(MouseEvent)}
 436      * method to dispatch the mouse event to the JavaFX scene attached to this
 437      * {@code JFXPanel}.
 438      *
 439      * @param e the mouse event to dispatch to the JavaFX scene
 440      */
 441     @Override
 442     protected void processMouseEvent(MouseEvent e) {
 443         if ((e.getID() == MouseEvent.MOUSE_PRESSED) &&
 444             (e.getButton() == MouseEvent.BUTTON1)) {
 445             if (!hasFocus()) {
 446                 requestFocus();
 447                 // this focus request event goes to eventqueue and will be
 448                 // asynchronously handled so MOUSE_PRESSED event will not be
 449                 // honoured by FX immediately due to lack of focus in fx
 450                 // component. Fire the same MOUSE_PRESSED event after
 451                 // requestFocus() so that 2nd mouse press will be honoured
 452                 // since now fx have focus
 453                 AppContext context = SunToolkit.targetToAppContext(this);
 454                 if (context != null) {
 455                     SunToolkit.postEvent(context, e);
 456                 }
 457             }
 458         }
 459 
 460         sendMouseEventToFX(e);
 461         super.processMouseEvent(e);
 462     }
 463 
 464     /**
 465      * Overrides the {@link java.awt.Component#processMouseMotionEvent(MouseEvent)}
 466      * method to dispatch the mouse motion event to the JavaFX scene attached to
 467      * this {@code JFXPanel}.
 468      *
 469      * @param e the mouse motion event to dispatch to the JavaFX scene
 470      */
 471     @Override
 472     protected void processMouseMotionEvent(MouseEvent e) {
 473         sendMouseEventToFX(e);
 474         super.processMouseMotionEvent(e);
 475     }
 476 


 553         }
 554         super.processComponentEvent(e);
 555     }
 556 
 557     // called on EDT only
 558     private void updateComponentSize() {
 559         int oldWidth = pWidth;
 560         int oldHeight = pHeight;
 561         // It's quite possible to get negative values here, this is not
 562         // what JavaFX embedded scenes/stages are ready to
 563         pWidth = Math.max(0, getWidth());
 564         pHeight = Math.max(0, getHeight());
 565         if (getBorder() != null) {
 566             Insets i = getBorder().getBorderInsets(this);
 567             pWidth -= (i.left + i.right);
 568             pHeight -= (i.top + i.bottom);
 569         }
 570         double newScaleFactorX = scaleFactorX;
 571         double newScaleFactorY = scaleFactorY;
 572         Graphics g = getGraphics();
 573         if (g instanceof SunGraphics2D) {
 574             SurfaceData sd = ((SunGraphics2D) g).surfaceData;
 575             newScaleFactorX = sd.getDefaultScaleX();
 576             newScaleFactorY = sd.getDefaultScaleY();
 577         }
 578         if (oldWidth != pWidth || oldHeight != pHeight ||
 579             newScaleFactorX != scaleFactorX || newScaleFactorY != scaleFactorY)
 580         {
 581             createResizePixelBuffer(newScaleFactorX, newScaleFactorY);
 582             if (scenePeer != null) {
 583                 scenePeer.setPixelScaleFactors((float) newScaleFactorX,
 584                                                (float) newScaleFactorY);
 585             }
 586             scaleFactorX = newScaleFactorX;
 587             scaleFactorY = newScaleFactorY;
 588             sendResizeEventToFX();
 589         }
 590     }
 591 
 592     // This methods should only be called on EDT
 593     private boolean updateScreenLocation() {
 594         synchronized (getTreeLock()) {
 595             if (isShowing()) {
 596                 Point p = getLocationOnScreen();
 597                 screenX = p.x;


 748         if (!scenePeer.getPixels(buf, pWidth, pHeight)) {
 749             // In this case we just render what we have so far in the buffer.
 750         }
 751 
 752         Graphics gg = null;
 753         try {
 754             gg = g.create();
 755             if ((opacity < 1.0f) && (gg instanceof Graphics2D)) {
 756                 Graphics2D g2d = (Graphics2D)gg;
 757                 AlphaComposite c = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);
 758                 g2d.setComposite(c);
 759             }
 760             if (getBorder() != null) {
 761                 Insets i = getBorder().getBorderInsets(this);
 762                 gg.translate(i.left, i.top);
 763             }
 764             gg.drawImage(pixelsIm, 0, 0, pWidth, pHeight, null);
 765 
 766             double newScaleFactorX = scaleFactorX;
 767             double newScaleFactorY = scaleFactorY;
 768             if (g instanceof SunGraphics2D) {
 769                 SurfaceData sd = ((SunGraphics2D)g).surfaceData;
 770                 newScaleFactorX = sd.getDefaultScaleX();
 771                 newScaleFactorY = sd.getDefaultScaleY();
 772             }
 773             if (scaleFactorX != newScaleFactorX || scaleFactorY != newScaleFactorY) {
 774                 createResizePixelBuffer(newScaleFactorX, newScaleFactorY);
 775                 // The scene will request repaint.
 776                 scenePeer.setPixelScaleFactors((float) newScaleFactorX,
 777                                                (float) newScaleFactorY);
 778                 scaleFactorX = newScaleFactorX;
 779                 scaleFactorY = newScaleFactorY;
 780             }
 781         } catch (Throwable th) {
 782             th.printStackTrace();
 783         } finally {
 784             if (gg != null) {
 785                 gg.dispose();
 786             }
 787         }
 788     }
 789 
 790     /**
 791      * Returns the preferred size of this {@code JFXPanel}, either
 792      * previously set with {@link #setPreferredSize(Dimension)} or


 811         if (!enabled) {
 812             if (disableCount.incrementAndGet() == 1) {
 813                 if (dnd != null) {
 814                     dnd.removeNotify();
 815                 }
 816             }
 817         } else {
 818             if (disableCount.get() == 0) {
 819                 //should report a warning about an extra enable call ?
 820                 return;
 821             }
 822             if (disableCount.decrementAndGet() == 0) {
 823                 if (dnd != null) {
 824                     dnd.addNotify();
 825                 }
 826             }
 827         }
 828     }
 829 
 830     private transient  AWTEventListener ungrabListener = event -> {
 831         if (event instanceof sun.awt.UngrabEvent) {
 832             SwingFXUtils.runOnFxThread(() -> {
 833                 if (JFXPanel.this.stagePeer != null &&
 834                         getScene() != null &&
 835                         getScene().getFocusOwner() != null &&
 836                         getScene().getFocusOwner().isFocused()) {
 837                     JFXPanel.this.stagePeer.focusUngrab();
 838                 }
 839             });
 840         }
 841         if (event instanceof MouseEvent) {
 842             // Synthesize FOCUS_UNGRAB if user clicks the AWT top-level window
 843             // that contains the JFXPanel.
 844             if (event.getID() == MouseEvent.MOUSE_PRESSED && event.getSource() instanceof Component) {
 845                 final Window jfxPanelWindow = SwingUtilities.getWindowAncestor(JFXPanel.this);
 846                 final Component source = (Component)event.getSource();
 847                 final Window eventWindow = source instanceof Window ? (Window)source : SwingUtilities.getWindowAncestor(source);
 848 
 849                 if (jfxPanelWindow == eventWindow) {
 850                     SwingFXUtils.runOnFxThread(() -> {
 851                         if (JFXPanel.this.stagePeer != null) {


 860                         }
 861                     });
 862                 }
 863             }
 864         }
 865     };
 866 
 867     /**
 868      * Notifies this component that it now has a parent component. When this
 869      * method is invoked, the chain of parent components is set up with
 870      * KeyboardAction event listeners.
 871      */
 872     @Override
 873     public void addNotify() {
 874         super.addNotify();
 875 
 876         registerFinishListener();
 877 
 878         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
 879             JFXPanel.this.getToolkit().addAWTEventListener(ungrabListener,
 880                 SunToolkit.GRAB_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
 881             return null;
 882         });
 883         updateComponentSize(); // see RT-23603
 884         SwingFXUtils.runOnFxThread(() -> {
 885             if ((stage != null) && !stage.isShowing()) {
 886                 stage.show();
 887                 sendMoveEventToFX();
 888             }
 889         });
 890     }
 891 
 892     @Override
 893     public InputMethodRequests getInputMethodRequests() {
 894         EmbeddedSceneInterface scene = scenePeer;
 895         if (scene == null) {
 896             return null;
 897         }
 898         return new InputMethodSupport.InputMethodRequestsAdapter(scene.getInputMethodRequests());
 899     }
 900 


 911         });
 912 
 913         pixelsIm = null;
 914         pWidth = 0;
 915         pHeight = 0;
 916 
 917         super.removeNotify();
 918 
 919         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
 920             JFXPanel.this.getToolkit().removeAWTEventListener(ungrabListener);
 921             return null;
 922         });
 923 
 924         /* see CR 4867453 */
 925         getInputContext().removeNotify(this);
 926 
 927         deregisterFinishListener();
 928     }
 929 
 930     private void invokeOnClientEDT(Runnable r) {
 931         AppContext context = SunToolkit.targetToAppContext(this);
 932         if (context == null) {
 933             if (log.isLoggable(Level.FINE)) log.fine("null AppContext encountered!");
 934             return;
 935         }
 936         SunToolkit.postEvent(context, new InvocationEvent(this, r));
 937     }
 938 
 939     private class HostContainer implements HostInterface {
 940 
 941         @Override
 942         public void setEmbeddedStage(EmbeddedStageInterface embeddedStage) {
 943             stagePeer = embeddedStage;
 944             if (stagePeer == null) {
 945                 return;
 946             }
 947             if (pWidth > 0 && pHeight > 0) {
 948                 stagePeer.setSize(pWidth, pHeight);
 949             }
 950             invokeOnClientEDT(() -> {
 951                 if (stagePeer != null && JFXPanel.this.isFocusOwner()) {
 952                     stagePeer.setFocused(true, AbstractEvents.FOCUSEVENT_ACTIVATED);
 953                 }
 954             });
 955             sendMoveEventToFX();
 956         }


1037                 return cachedPlatformCursor;
1038             }
1039 
1040             // platform cursor not cached yet
1041             final Cursor platformCursor =
1042                     SwingCursors.embedCursorToCursor(cursorFrame);
1043             cursorFrame.setPlatforCursor(Cursor.class, platformCursor);
1044 
1045             return platformCursor;
1046         }
1047 
1048         @Override
1049         public boolean grabFocus() {
1050             // On X11 grab is limited to a single XDisplay connection,
1051             // so we can't delegate it to another GUI toolkit.
1052             if (PlatformUtil.isLinux()) return true;
1053 
1054             invokeOnClientEDT(() -> {
1055                 Window window = SwingUtilities.getWindowAncestor(JFXPanel.this);
1056                 if (window != null) {
1057                     if (JFXPanel.this.getToolkit() instanceof SunToolkit) {
1058                         ((SunToolkit)JFXPanel.this.getToolkit()).grab(window);
1059                     }
1060                 }
1061             });
1062 
1063             return true; // Oh, well...
1064         }
1065 
1066         @Override
1067         public void ungrabFocus() {
1068             // On X11 grab is limited to a single XDisplay connection,
1069             // so we can't delegate it to another GUI toolkit.
1070             if (PlatformUtil.isLinux()) return;
1071 
1072             invokeOnClientEDT(() -> {
1073                 Window window = SwingUtilities.getWindowAncestor(JFXPanel.this);
1074                 if (window != null) {
1075                     if (JFXPanel.this.getToolkit() instanceof SunToolkit) {
1076                         ((SunToolkit)JFXPanel.this.getToolkit()).ungrab(window);
1077                     }
1078                 }
1079             });
1080         }
1081     }
1082 }


  60 
  61 import javafx.application.Platform;
  62 import javafx.scene.Scene;
  63 
  64 import javax.swing.JComponent;
  65 import javax.swing.SwingUtilities;
  66 
  67 import com.sun.javafx.application.PlatformImpl;
  68 import com.sun.javafx.cursor.CursorFrame;
  69 import com.sun.javafx.embed.AbstractEvents;
  70 import com.sun.javafx.embed.EmbeddedSceneInterface;
  71 import com.sun.javafx.embed.EmbeddedStageInterface;
  72 import com.sun.javafx.embed.HostInterface;
  73 import com.sun.javafx.stage.EmbeddedWindow;
  74 import com.sun.javafx.tk.Toolkit;
  75 import com.sun.javafx.PlatformUtil;
  76 import java.awt.event.InvocationEvent;
  77 
  78 import java.lang.reflect.Method;
  79 import java.util.concurrent.atomic.AtomicInteger;
  80 



  81 import com.sun.javafx.logging.PlatformLogger;
  82 import com.sun.javafx.logging.PlatformLogger.Level;
  83 
  84 import jdk.swing.interop.SwingInterOpUtils;
  85 
  86 /**
  87 * {@code JFXPanel} is a component to embed JavaFX content into
  88  * Swing applications. The content to be displayed is specified
  89  * with the {@link #setScene} method that accepts an instance of
  90  * JavaFX {@code Scene}. After the scene is assigned, it gets
  91  * repainted automatically. All the input and focus events are
  92  * forwarded to the scene transparently to the developer.
  93  * <p>
  94  * There are some restrictions related to {@code JFXPanel}. As a
  95  * Swing component, it should only be accessed from the event
  96  * dispatch thread, except the {@link #setScene} method, which can
  97  * be called either on the event dispatch thread or on the JavaFX
  98  * application thread.
  99  * <p>
 100  * Here is a typical pattern how {@code JFXPanel} can used:
 101  * <pre>
 102  *     public class Test {
 103  *
 104  *         private static void initAndShowGUI() {
 105  *             // This method is invoked on Swing thread


 432 
 433     /**
 434      * Overrides the {@link java.awt.Component#processMouseEvent(MouseEvent)}
 435      * method to dispatch the mouse event to the JavaFX scene attached to this
 436      * {@code JFXPanel}.
 437      *
 438      * @param e the mouse event to dispatch to the JavaFX scene
 439      */
 440     @Override
 441     protected void processMouseEvent(MouseEvent e) {
 442         if ((e.getID() == MouseEvent.MOUSE_PRESSED) &&
 443             (e.getButton() == MouseEvent.BUTTON1)) {
 444             if (!hasFocus()) {
 445                 requestFocus();
 446                 // this focus request event goes to eventqueue and will be
 447                 // asynchronously handled so MOUSE_PRESSED event will not be
 448                 // honoured by FX immediately due to lack of focus in fx
 449                 // component. Fire the same MOUSE_PRESSED event after
 450                 // requestFocus() so that 2nd mouse press will be honoured
 451                 // since now fx have focus
 452                 SwingInterOpUtils.postEvent(this, e);



 453             }
 454         }
 455 
 456         sendMouseEventToFX(e);
 457         super.processMouseEvent(e);
 458     }
 459 
 460     /**
 461      * Overrides the {@link java.awt.Component#processMouseMotionEvent(MouseEvent)}
 462      * method to dispatch the mouse motion event to the JavaFX scene attached to
 463      * this {@code JFXPanel}.
 464      *
 465      * @param e the mouse motion event to dispatch to the JavaFX scene
 466      */
 467     @Override
 468     protected void processMouseMotionEvent(MouseEvent e) {
 469         sendMouseEventToFX(e);
 470         super.processMouseMotionEvent(e);
 471     }
 472 


 549         }
 550         super.processComponentEvent(e);
 551     }
 552 
 553     // called on EDT only
 554     private void updateComponentSize() {
 555         int oldWidth = pWidth;
 556         int oldHeight = pHeight;
 557         // It's quite possible to get negative values here, this is not
 558         // what JavaFX embedded scenes/stages are ready to
 559         pWidth = Math.max(0, getWidth());
 560         pHeight = Math.max(0, getHeight());
 561         if (getBorder() != null) {
 562             Insets i = getBorder().getBorderInsets(this);
 563             pWidth -= (i.left + i.right);
 564             pHeight -= (i.top + i.bottom);
 565         }
 566         double newScaleFactorX = scaleFactorX;
 567         double newScaleFactorY = scaleFactorY;
 568         Graphics g = getGraphics();
 569         newScaleFactorX = SwingInterOpUtils.getDefaultScaleX(g);
 570         newScaleFactorY = SwingInterOpUtils.getDefaultScaleY(g);



 571         if (oldWidth != pWidth || oldHeight != pHeight ||
 572             newScaleFactorX != scaleFactorX || newScaleFactorY != scaleFactorY)
 573         {
 574             createResizePixelBuffer(newScaleFactorX, newScaleFactorY);
 575             if (scenePeer != null) {
 576                 scenePeer.setPixelScaleFactors((float) newScaleFactorX,
 577                                                (float) newScaleFactorY);
 578             }
 579             scaleFactorX = newScaleFactorX;
 580             scaleFactorY = newScaleFactorY;
 581             sendResizeEventToFX();
 582         }
 583     }
 584 
 585     // This methods should only be called on EDT
 586     private boolean updateScreenLocation() {
 587         synchronized (getTreeLock()) {
 588             if (isShowing()) {
 589                 Point p = getLocationOnScreen();
 590                 screenX = p.x;


 741         if (!scenePeer.getPixels(buf, pWidth, pHeight)) {
 742             // In this case we just render what we have so far in the buffer.
 743         }
 744 
 745         Graphics gg = null;
 746         try {
 747             gg = g.create();
 748             if ((opacity < 1.0f) && (gg instanceof Graphics2D)) {
 749                 Graphics2D g2d = (Graphics2D)gg;
 750                 AlphaComposite c = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);
 751                 g2d.setComposite(c);
 752             }
 753             if (getBorder() != null) {
 754                 Insets i = getBorder().getBorderInsets(this);
 755                 gg.translate(i.left, i.top);
 756             }
 757             gg.drawImage(pixelsIm, 0, 0, pWidth, pHeight, null);
 758 
 759             double newScaleFactorX = scaleFactorX;
 760             double newScaleFactorY = scaleFactorY;
 761             newScaleFactorX = SwingInterOpUtils.getDefaultScaleX(g);
 762             newScaleFactorY = SwingInterOpUtils.getDefaultScaleY(g);



 763             if (scaleFactorX != newScaleFactorX || scaleFactorY != newScaleFactorY) {
 764                 createResizePixelBuffer(newScaleFactorX, newScaleFactorY);
 765                 // The scene will request repaint.
 766                 scenePeer.setPixelScaleFactors((float) newScaleFactorX,
 767                                                (float) newScaleFactorY);
 768                 scaleFactorX = newScaleFactorX;
 769                 scaleFactorY = newScaleFactorY;
 770             }
 771         } catch (Throwable th) {
 772             th.printStackTrace();
 773         } finally {
 774             if (gg != null) {
 775                 gg.dispose();
 776             }
 777         }
 778     }
 779 
 780     /**
 781      * Returns the preferred size of this {@code JFXPanel}, either
 782      * previously set with {@link #setPreferredSize(Dimension)} or


 801         if (!enabled) {
 802             if (disableCount.incrementAndGet() == 1) {
 803                 if (dnd != null) {
 804                     dnd.removeNotify();
 805                 }
 806             }
 807         } else {
 808             if (disableCount.get() == 0) {
 809                 //should report a warning about an extra enable call ?
 810                 return;
 811             }
 812             if (disableCount.decrementAndGet() == 0) {
 813                 if (dnd != null) {
 814                     dnd.addNotify();
 815                 }
 816             }
 817         }
 818     }
 819 
 820     private transient  AWTEventListener ungrabListener = event -> {
 821         if (SwingInterOpUtils.isUngrabEvent(event)) {
 822             SwingFXUtils.runOnFxThread(() -> {
 823                 if (JFXPanel.this.stagePeer != null &&
 824                         getScene() != null &&
 825                         getScene().getFocusOwner() != null &&
 826                         getScene().getFocusOwner().isFocused()) {
 827                     JFXPanel.this.stagePeer.focusUngrab();
 828                 }
 829             });
 830         }
 831         if (event instanceof MouseEvent) {
 832             // Synthesize FOCUS_UNGRAB if user clicks the AWT top-level window
 833             // that contains the JFXPanel.
 834             if (event.getID() == MouseEvent.MOUSE_PRESSED && event.getSource() instanceof Component) {
 835                 final Window jfxPanelWindow = SwingUtilities.getWindowAncestor(JFXPanel.this);
 836                 final Component source = (Component)event.getSource();
 837                 final Window eventWindow = source instanceof Window ? (Window)source : SwingUtilities.getWindowAncestor(source);
 838 
 839                 if (jfxPanelWindow == eventWindow) {
 840                     SwingFXUtils.runOnFxThread(() -> {
 841                         if (JFXPanel.this.stagePeer != null) {


 850                         }
 851                     });
 852                 }
 853             }
 854         }
 855     };
 856 
 857     /**
 858      * Notifies this component that it now has a parent component. When this
 859      * method is invoked, the chain of parent components is set up with
 860      * KeyboardAction event listeners.
 861      */
 862     @Override
 863     public void addNotify() {
 864         super.addNotify();
 865 
 866         registerFinishListener();
 867 
 868         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
 869             JFXPanel.this.getToolkit().addAWTEventListener(ungrabListener,
 870                 SwingInterOpUtils.GRAB_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
 871             return null;
 872         });
 873         updateComponentSize(); // see RT-23603
 874         SwingFXUtils.runOnFxThread(() -> {
 875             if ((stage != null) && !stage.isShowing()) {
 876                 stage.show();
 877                 sendMoveEventToFX();
 878             }
 879         });
 880     }
 881 
 882     @Override
 883     public InputMethodRequests getInputMethodRequests() {
 884         EmbeddedSceneInterface scene = scenePeer;
 885         if (scene == null) {
 886             return null;
 887         }
 888         return new InputMethodSupport.InputMethodRequestsAdapter(scene.getInputMethodRequests());
 889     }
 890 


 901         });
 902 
 903         pixelsIm = null;
 904         pWidth = 0;
 905         pHeight = 0;
 906 
 907         super.removeNotify();
 908 
 909         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
 910             JFXPanel.this.getToolkit().removeAWTEventListener(ungrabListener);
 911             return null;
 912         });
 913 
 914         /* see CR 4867453 */
 915         getInputContext().removeNotify(this);
 916 
 917         deregisterFinishListener();
 918     }
 919 
 920     private void invokeOnClientEDT(Runnable r) {
 921         SwingInterOpUtils.postEvent(this, new InvocationEvent(this, r));





 922     }
 923 
 924     private class HostContainer implements HostInterface {
 925 
 926         @Override
 927         public void setEmbeddedStage(EmbeddedStageInterface embeddedStage) {
 928             stagePeer = embeddedStage;
 929             if (stagePeer == null) {
 930                 return;
 931             }
 932             if (pWidth > 0 && pHeight > 0) {
 933                 stagePeer.setSize(pWidth, pHeight);
 934             }
 935             invokeOnClientEDT(() -> {
 936                 if (stagePeer != null && JFXPanel.this.isFocusOwner()) {
 937                     stagePeer.setFocused(true, AbstractEvents.FOCUSEVENT_ACTIVATED);
 938                 }
 939             });
 940             sendMoveEventToFX();
 941         }


1022                 return cachedPlatformCursor;
1023             }
1024 
1025             // platform cursor not cached yet
1026             final Cursor platformCursor =
1027                     SwingCursors.embedCursorToCursor(cursorFrame);
1028             cursorFrame.setPlatforCursor(Cursor.class, platformCursor);
1029 
1030             return platformCursor;
1031         }
1032 
1033         @Override
1034         public boolean grabFocus() {
1035             // On X11 grab is limited to a single XDisplay connection,
1036             // so we can't delegate it to another GUI toolkit.
1037             if (PlatformUtil.isLinux()) return true;
1038 
1039             invokeOnClientEDT(() -> {
1040                 Window window = SwingUtilities.getWindowAncestor(JFXPanel.this);
1041                 if (window != null) {
1042                     SwingInterOpUtils.grab(JFXPanel.this.getToolkit(), window);


1043                 }
1044             });
1045 
1046             return true; // Oh, well...
1047         }
1048 
1049         @Override
1050         public void ungrabFocus() {
1051             // On X11 grab is limited to a single XDisplay connection,
1052             // so we can't delegate it to another GUI toolkit.
1053             if (PlatformUtil.isLinux()) return;
1054 
1055             invokeOnClientEDT(() -> {
1056                 Window window = SwingUtilities.getWindowAncestor(JFXPanel.this);
1057                 if (window != null) {
1058                     SwingInterOpUtils.ungrab(JFXPanel.this.getToolkit(), window);


1059                 }
1060             });
1061         }
1062     }
1063 }
< prev index next >