JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
NewtCanvasJFX.java
Go to the documentation of this file.
1/**
2 * Copyright 2019 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.newt.javafx;
30
31import com.jogamp.common.util.PropertyAccess;
32import com.jogamp.common.util.locks.RecursiveLock;
33import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
34import com.jogamp.nativewindow.AbstractGraphicsScreen;
35import com.jogamp.nativewindow.Capabilities;
36import com.jogamp.nativewindow.CapabilitiesImmutable;
37import com.jogamp.nativewindow.GraphicsConfigurationFactory;
38import com.jogamp.nativewindow.NativeSurface;
39import com.jogamp.nativewindow.NativeWindow;
40import com.jogamp.nativewindow.NativeWindowException;
41import com.jogamp.nativewindow.NativeWindowFactory;
42import com.jogamp.nativewindow.NativeWindowHolder;
43import com.jogamp.nativewindow.SurfaceUpdatedListener;
44import com.jogamp.nativewindow.WindowClosingProtocol;
45import com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode;
46import com.jogamp.nativewindow.util.Insets;
47import com.jogamp.nativewindow.util.InsetsImmutable;
48import com.jogamp.nativewindow.util.Point;
49import com.jogamp.nativewindow.util.Rectangle;
50import com.jogamp.opengl.GLCapabilities;
51
52import javafx.beans.value.ChangeListener;
53import javafx.beans.value.ObservableValue;
54import javafx.event.EventHandler;
55import javafx.geometry.Bounds;
56import javafx.scene.Scene;
57import javafx.scene.canvas.Canvas;
58import jogamp.newt.Debug;
59import jogamp.newt.javafx.JFXEDTUtil;
60
61import com.jogamp.nativewindow.javafx.JFXAccessor;
62import com.jogamp.newt.Display;
63import com.jogamp.newt.Window;
64import com.jogamp.newt.event.WindowEvent;
65import com.jogamp.newt.util.EDTUtil;
66
67/**
68 * A NEWT based JFX {@link Canvas} specialization allowing a NEWT child {@link Window} to be attached using native parenting.
69 * <p>
70 * {@link NewtCanvasJFX} allows utilizing custom {@link GLCapabilities} settings independent from the JavaFX's window
71 * as well as independent rendering from JavaFX's thread.
72 * </p>
73 * <p>
74 * {@link NewtCanvasJFX} allows native parenting operations before and after
75 * it's belonging Group's Scene has been attached to the JavaFX {@link javafx.stage.Window Window}'s actual native window,
76 * i.e. becoming fully realized and visible.
77 * </p>
78 * <p>
79 * Note that {@link JFXAccessor#runOnJFXThread(boolean, Runnable)} is still used to for certain
80 * mandatory JavaFX lifecycle operation on the JavaFX thread.
81 * </p>
82 */
83public class NewtCanvasJFX extends Canvas implements NativeWindowHolder, WindowClosingProtocol {
84 private static final boolean DEBUG = Debug.debug("Window");
85 private static final boolean USE_JFX_EDT = PropertyAccess.getBooleanProperty("jogamp.newt.javafx.UseJFXEDT", true, true);
86 private volatile javafx.stage.Window parentWindow = null;
87 private volatile AbstractGraphicsScreen screen = null;
88
89 private WindowClosingMode newtChildClosingMode = WindowClosingMode.DISPOSE_ON_CLOSE;
91 private final Rectangle clientArea = new Rectangle();
92
93 private volatile JFXNativeWindow nativeWindow = null;
94 private volatile Window newtChild = null;
95 private volatile boolean newtChildReady = false; // ready if JFXEDTUtil is set and newtChild parented
96 private volatile boolean postSetSize = false; // pending resize
97 private volatile boolean postSetPos = false; // pending pos
98
99 private final EventHandler<javafx.stage.WindowEvent> windowClosingListener = new EventHandler<javafx.stage.WindowEvent>() {
100 @Override
101 public final void handle(final javafx.stage.WindowEvent e) {
102 if( DEBUG ) {
103 System.err.println("NewtCanvasJFX.Event.DISPOSE, "+e+", closeOp "+closingMode);
104 }
105 if( WindowClosingMode.DISPOSE_ON_CLOSE == closingMode ) {
106 NewtCanvasJFX.this.destroy();
107 } else {
108 // avoid JavaFX closing operation
109 e.consume();
110 }
111 } };
112 private final EventHandler<javafx.stage.WindowEvent> windowShownListener = new EventHandler<javafx.stage.WindowEvent>() {
113 @Override
114 public final void handle(final javafx.stage.WindowEvent e) {
115 if( DEBUG ) {
116 System.err.println("NewtCanvasJFX.Event.SHOWN, "+e);
117 }
118 repaintAction(true);
119 } };
120
121 /**
122 * Instantiates a NewtCanvas with a NEWT child.
123 *
124 * <p>
125 * Note: The NEWT child {@link Display}'s {@link EDTUtil} is being set to an JFX conform implementation
126 * via {@link Display#setEDTUtil(EDTUtil)}.
127 * </p>
128 * @param child optional preassigned {@link #Window}, maybe null
129 */
130 public NewtCanvasJFX(final Window child) {
131 super();
132
133 updateParentWindowAndScreen();
134
135 final ChangeListener<Number> sizeListener = new ChangeListener<Number>() {
136 @Override public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
137 if( DEBUG ) {
138 System.err.println("NewtCanvasJFX.Event.Size, "+oldValue.doubleValue()+" -> "+newValue.doubleValue()+", has "+getWidth()+"x"+getHeight());
139 }
140 updateSizeCheck((int)getWidth(), (int)getHeight());
141 repaintAction(isVisible());
142 } };
143 this.widthProperty().addListener(sizeListener);
144 this.heightProperty().addListener(sizeListener);
145 this.visibleProperty().addListener(new ChangeListener<Boolean>() {
146 @Override public void changed(final ObservableValue<? extends Boolean> observable, final Boolean oldValue, final Boolean newValue) {
147 if( DEBUG ) {
148 System.err.println("NewtCanvasJFX.Event.Visible, "+oldValue.booleanValue()+" -> "+newValue.booleanValue()+", has "+isVisible());
149 }
150 repaintAction(newValue.booleanValue());
151 }
152 });
153 this.sceneProperty().addListener(new ChangeListener<Scene>() {
154 @Override public void changed(final ObservableValue<? extends Scene> observable, final Scene oldValue, final Scene newValue) {
155 if( DEBUG ) {
156 System.err.println("NewtCanvasJFX.Event.Scene, "+oldValue+" -> "+newValue+", has "+getScene());
157 if(null != newValue) {
158 final javafx.stage.Window w = newValue.getWindow();
159 System.err.println("NewtCanvasJFX.Event.Scene window "+w+" (showing "+(null!=w?w.isShowing():0)+")");
160 }
161 }
162 if( updateParentWindowAndScreen() ) {
163 repaintAction(isVisible());
164 }
165 }
166 });
167
168 if(null != child) {
169 setNEWTChild(child);
170 }
171 }
172
173 private final void repaintAction(final boolean visible) {
174 if( visible && validateNative(true /* completeReparent */) ) {
175 if( newtChildReady ) {
176 if( postSetSize ) {
177 newtChild.setSize(clientArea.getWidth(), clientArea.getHeight());
178 postSetSize = false;
179 }
180 if( postSetPos ) {
181 newtChild.setPosition(clientArea.getX(), clientArea.getY());
182 postSetPos = false;
183 }
184 newtChild.windowRepaint(0, 0, clientArea.getWidth(), clientArea.getHeight());
185 }
186 }
187 }
188
189 private final void updatePosSizeCheck() {
190 final Bounds b = localToScene(getBoundsInLocal());
191 updatePosCheck((int)b.getMinX(), (int)b.getMinY());
192 updateSizeCheck((int)getWidth(), (int)getHeight());
193 }
194 private final void updatePosCheck(final int newX, final int newY) {
195 final boolean posChanged;
196 {
197 final Rectangle oClientArea = clientArea;
198 posChanged = newX != oClientArea.getX() || newY != oClientArea.getY();
199 if( posChanged ) {
200 clientArea.setX(newX);
201 clientArea.setY(newY);
202 }
203 }
204 if(DEBUG) {
205 final long nsh = newtChildReady ? newtChild.getSurfaceHandle() : 0;
206 System.err.println("NewtCanvasJFX.updatePosCheck: posChanged "+posChanged+", ("+Thread.currentThread().getName()+"): newtChildReady "+newtChildReady+", "+clientArea.getX()+"/"+clientArea.getY()+" "+clientArea.getWidth()+"x"+clientArea.getHeight()+" - surfaceHandle 0x"+Long.toHexString(nsh));
207 }
208 if( posChanged ) {
209 if( newtChildReady ) {
210 newtChild.setPosition(clientArea.getX(), clientArea.getY());
211 } else {
212 postSetPos = true;
213 }
214 }
215 }
216 private final void updateSizeCheck(final int newWidth, final int newHeight) {
217 final boolean sizeChanged;
218 {
219 final Rectangle oClientArea = clientArea;
220 sizeChanged = newWidth != oClientArea.getWidth() || newHeight != oClientArea.getHeight();
221 if( sizeChanged ) {
222 clientArea.setWidth(newWidth);
223 clientArea.setHeight(newHeight);
224 }
225 }
226 if(DEBUG) {
227 final long nsh = newtChildReady ? newtChild.getSurfaceHandle() : 0;
228 System.err.println("NewtCanvasJFX.updateSizeCheck: sizeChanged "+sizeChanged+", ("+Thread.currentThread().getName()+"): newtChildReady "+newtChildReady+", "+clientArea.getX()+"/"+clientArea.getY()+" "+clientArea.getWidth()+"x"+clientArea.getHeight()+" - surfaceHandle 0x"+Long.toHexString(nsh));
229 }
230 if( sizeChanged ) {
231 if( newtChildReady ) {
232 newtChild.setSize(clientArea.getWidth(), clientArea.getHeight());
233 } else {
234 postSetSize = true;
235 }
236 }
237 }
238
239 private final ChangeListener<javafx.stage.Window> sceneWindowChangeListener = new ChangeListener<javafx.stage.Window>() {
240 @Override public void changed(final ObservableValue<? extends javafx.stage.Window> observable, final javafx.stage.Window oldValue, final javafx.stage.Window newValue) {
241 if( DEBUG ) {
242 System.err.println("NewtCanvasJFX.Event.Window, "+oldValue+" -> "+newValue);
243 }
244 if( updateParentWindowAndScreen() ) {
245 repaintAction(isVisible());
246 }
247 } };
248
249 private boolean updateParentWindowAndScreen() {
250 final Scene s = this.getScene();
251 if( null != s ) {
252 final javafx.stage.Window w = s.getWindow();
253 if( DEBUG ) {
254 System.err.println("NewtCanvasJFX.updateParentWindowAndScreen: Scene "+s+", Window "+w+" (showing "+(null!=w?w.isShowing():0)+")");
255 }
256 if( w != parentWindow ) {
257 destroyImpl(false);
258 }
259 parentWindow = w;
260 if( null != w ) {
261 screen = JFXAccessor.getScreen(JFXAccessor.getDevice(parentWindow), -1 /* default */);
262 parentWindow.addEventHandler(javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST, windowClosingListener);
263 parentWindow.addEventHandler(javafx.stage.WindowEvent.WINDOW_SHOWN, windowShownListener);
264 return true;
265 } else {
266 s.windowProperty().addListener(sceneWindowChangeListener);
267 }
268 } else {
269 if( DEBUG ) {
270 System.err.println("NewtCanvasJFX.updateParentWindowAndScreen: Null Scene");
271 }
272 if( null != parentWindow ) {
273 destroyImpl(false);
274 }
275 }
276 return false;
277 }
278
279 /**
280 * Destroys this resource:
281 * <ul>
282 * <li> Make the NEWT Child invisible </li>
283 * <li> Disconnects the NEWT Child from this Canvas NativeWindow, reparent to NULL </li>
284 * <li> Issues {@link Window#destroy()} on the NEWT Child</li>
285 * <li> Remove reference to the NEWT Child</li>
286 * </ul>
287 * JavaFX will issue this call when sending out the {@link javafx.stage.WindowEvent#WINDOW_CLOSE_REQUEST} automatically,
288 * if the user has not overridden the default {@link WindowClosingMode#DISPOSE_ON_CLOSE} to {@link WindowClosingMode#DO_NOTHING_ON_CLOSE}
289 * via {@link #setDefaultCloseOperation(com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode)}.
290 * @see Window#destroy()
291 * @see #setDefaultCloseOperation(com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode)
292 */
293 public void destroy() {
294 destroyImpl(true);
295 }
296 private void destroyImpl(final boolean disposeNewtChild) {
297 if(DEBUG) {
298 System.err.println("NewtCanvasJFX.dispose: (has parent "+(null!=parentWindow)+", hasNative "+(null!=nativeWindow)+",\n\t"+newtChild);
299 }
300 if( null != newtChild ) {
301 if(DEBUG) {
302 System.err.println("NewtCanvasJFX.dispose.1: EDTUtil cur "+newtChild.getScreen().getDisplay().getEDTUtil());
303 }
304 if( null != nativeWindow ) {
305 configureNewtChild(false);
306 newtChild.setVisible(false);
307 newtChild.reparentWindow(null, -1, -1, 0 /* hint */);
308 }
309 if( disposeNewtChild ) {
310 newtChild.destroy();
311 newtChild = null;
312 }
313 }
314 if( null != parentWindow ) {
315 parentWindow.getScene().windowProperty().removeListener(sceneWindowChangeListener);
316 parentWindow.removeEventHandler(javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST, windowClosingListener);
317 parentWindow.removeEventHandler(javafx.stage.WindowEvent.WINDOW_SHOWN, windowShownListener);
318 parentWindow = null;
319 }
320 if( null != screen ) {
321 screen.getDevice().close();
322 screen = null;
323 }
324 nativeWindow = null;
325 }
326
327 private final boolean validateNative(final boolean completeReparent) {
328 if( null != nativeWindow ) {
329 return true; // already valid
330 }
331 if( null == parentWindow ) {
332 return false;
333 }
334 updatePosSizeCheck();
335 if(0 >= clientArea.getWidth() || 0 >= clientArea.getHeight()) {
336 return false;
337 }
338 final long nativeWindowHandle = JFXAccessor.getWindowHandle(parentWindow);
339 if( 0 == nativeWindowHandle ) {
340 return false;
341 }
342 screen.getDevice().open();
343
344 /* Native handle for the control, used to associate with GLContext */
345 final int visualID = JFXAccessor.getNativeVisualID(screen.getDevice(), nativeWindowHandle);
346 final boolean visualIDValid = NativeWindowFactory.isNativeVisualIDValidForProcessing(visualID);
347 if(DEBUG) {
348 System.err.println("NewtCanvasJFX.validateNative() windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", valid "+visualIDValid);
349 }
350 if( visualIDValid ) {
351 /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
352 * Note: JFX is owner of the native handle, hence no closing operation will be a NOP. */
353 final CapabilitiesImmutable caps = new Capabilities();
354 final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(screen.getDevice(), caps);
355 final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration( caps, caps, null, screen, visualID );
356 if(DEBUG) {
357 System.err.println("NewtCanvasJFX.validateNative() factory: "+factory+", windowHandle 0x"+Long.toHexString(nativeWindowHandle)+", visualID 0x"+Integer.toHexString(visualID)+", chosen config: "+config);
358 // Thread.dumpStack();
359 }
360 if (null == config) {
361 throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
362 }
363
364 nativeWindow = new JFXNativeWindow(config, nativeWindowHandle);
365 if( completeReparent ) {
366 reparentWindow( true );
367 }
368 }
369
370 return null != nativeWindow;
371 }
372
373 /**
374 * Sets a new NEWT child, provoking reparenting.
375 * <p>
376 * A previously detached <code>newChild</code> will be released to top-level status
377 * and made invisible.
378 * </p>
379 * <p>
380 * Note: When switching NEWT child's, detaching the previous first via <code>setNEWTChild(null)</code>
381 * produced much cleaner visual results.
382 * </p>
383 * <p>
384 * Note: The NEWT child {@link Display}'s {@link EDTUtil} is being set to an JFX conform implementation
385 * via {@link Display#setEDTUtil(EDTUtil)}.
386 * </p>
387 * @return the previous attached newt child.
388 */
389 public Window setNEWTChild(final Window newChild) {
390 final Window prevChild = newtChild;
391 if(DEBUG) {
392 System.err.println("NewtCanvasJFX.setNEWTChild.0: win "+newtWinHandleToHexString(prevChild)+" -> "+newtWinHandleToHexString(newChild));
393 }
394 // remove old one
395 if(null != newtChild) {
396 reparentWindow( false );
397 newtChild = null;
398 }
399 // add new one, reparent only if ready
400 newtChild = newChild;
401 if( null != newtChild && validateNative(false /* completeReparent */) ) {
402 reparentWindow( true );
403 }
404 return prevChild;
405 }
406
407 private void reparentWindow(final boolean add) {
408 if( null == newtChild ) {
409 return; // nop
410 }
411 if(DEBUG) {
412 System.err.println("NewtCanvasJFX.reparentWindow.0: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
413 }
414
415 newtChild.setFocusAction(null); // no AWT focus traversal ..
416 if(add) {
417 assert null != nativeWindow && null != parentWindow;
418 updatePosSizeCheck();
419 final int x = clientArea.getX();
420 final int y = clientArea.getY();
421 final int w = clientArea.getWidth();
422 final int h = clientArea.getHeight();
423
424 if(USE_JFX_EDT) {
425 // setup JFX EDT and start it
426 final Display newtDisplay = newtChild.getScreen().getDisplay();
427 final EDTUtil oldEDTUtil = newtDisplay.getEDTUtil();
428 if( ! ( oldEDTUtil instanceof JFXEDTUtil ) ) {
429 final EDTUtil newEDTUtil = new JFXEDTUtil(newtDisplay);
430 if(DEBUG) {
431 System.err.println("NewtCanvasJFX.reparentWindow.1: replacing EDTUtil "+oldEDTUtil+" -> "+newEDTUtil);
432 }
433 newEDTUtil.start();
434 newtDisplay.setEDTUtil( newEDTUtil );
435 }
436 }
437
438 newtChild.setSize(w, h);
439 newtChild.reparentWindow(nativeWindow, x, y, Window.REPARENT_HINT_BECOMES_VISIBLE);
440 newtChild.setPosition(x, y);
441 newtChild.setVisible(true);
442 configureNewtChild(true);
443 newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
444
445 // force this JFX Canvas to be focus-able,
446 // since it is completely covered by the newtChild (z-order).
447 // FIXME ??? super.requestFocus();
448 } else {
449 configureNewtChild(false);
450 newtChild.setVisible(false);
451 newtChild.reparentWindow(null, -1, -1, 0 /* hints */);
452 }
453 if(DEBUG) {
454 System.err.println("NewtCanvasJFX.reparentWindow.X: add="+add+", win "+newtWinHandleToHexString(newtChild)+", EDTUtil: cur "+newtChild.getScreen().getDisplay().getEDTUtil());
455 }
456 }
457
458 private void configureNewtChild(final boolean attach) {
459 newtChildReady = attach;
460 if( null != newtChild ) {
461 newtChild.setKeyboardFocusHandler(null);
462 if(attach) {
463 newtChildClosingMode = newtChild.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE);
464 } else {
465 newtChild.setFocusAction(null);
466 newtChild.setDefaultCloseOperation(newtChildClosingMode);
467 }
468 }
469 }
470
471 /** @return the current NEWT child */
473 return newtChild;
474 }
475
476 /**
477 * {@inheritDoc}
478 * @return this JFX Canvas {@link NativeWindow} representation, may be null in case it has not been realized
479 */
480 @Override
481 public NativeWindow getNativeWindow() { return nativeWindow; }
482
483 /**
484 * {@inheritDoc}
485 * @return this JFX Canvas {@link NativeSurface} representation, may be null in case it has not been realized
486 */
487 @Override
488 public NativeSurface getNativeSurface() { return nativeWindow; }
489
490 @Override
492 return closingMode;
493 }
494
495 @Override
497 final WindowClosingMode old = closingMode;
498 closingMode = op;
499 return old;
500 }
501
502
503 boolean isParent() {
504 return null!=newtChild ;
505 }
506
507 boolean isFullscreen() {
508 return null != newtChild && newtChild.isFullscreen();
509 }
510
511 private final void requestFocusNEWTChild() {
512 if( newtChildReady ) {
513 newtChild.setFocusAction(null);
514 newtChild.requestFocus();
515 }
516 }
517
518 @Override
519 public void requestFocus() {
521 requestFocusNEWTChild();
522 }
523
524 private class JFXNativeWindow implements NativeWindow {
525 private final AbstractGraphicsConfiguration config;
526 private final long nativeWindowHandle;
527 private final InsetsImmutable insets; // only required to allow proper client position calculation on OSX
528
529 public JFXNativeWindow(final AbstractGraphicsConfiguration config, final long nativeWindowHandle) {
530 this.config = config;
531 this.nativeWindowHandle = nativeWindowHandle;
532 this.insets = new Insets(0, 0, 0, 0);
533 }
534
535 @Override
536 public RecursiveLock getLock() { return null; }
537
538 @Override
539 public int lockSurface() throws NativeWindowException, RuntimeException {
540 return NativeSurface.LOCK_SUCCESS;
541 }
542
543 @Override
544 public void unlockSurface() { }
545
546 @Override
547 public boolean isSurfaceLockedByOtherThread() {
548 return false;
549 }
550
551 @Override
552 public Thread getSurfaceLockOwner() {
553 return null;
554 }
555
556 @Override
557 public boolean surfaceSwap() {
558 return false;
559 }
560
561 @Override
562 public void addSurfaceUpdatedListener(final SurfaceUpdatedListener l) { }
563
564 @Override
565 public void addSurfaceUpdatedListener(final int index, final SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
566 }
567
568 @Override
569 public void removeSurfaceUpdatedListener(final SurfaceUpdatedListener l) { }
570
571 @Override
572 public long getSurfaceHandle() {
573 return 0;
574 }
575
576 @Override
577 public int getX() {
578 return NewtCanvasJFX.this.clientArea.getX(); // FIXME: Use 'scale' or an actual window-width
579 }
580
581 @Override
582 public int getY() {
583 return NewtCanvasJFX.this.clientArea.getY(); // FIXME: Use 'scale' or an actual window-width
584 }
585
586 @Override
587 public int getWidth() {
588 return getSurfaceWidth(); // FIXME: Use 'scale' or an actual window-width
589 }
590
591 @Override
592 public int getHeight() {
593 return getSurfaceHeight(); // FIXME: Use 'scale' or an actual window-width
594 }
595
596 @Override
597 public final Rectangle getBounds() {
598 return new Rectangle(getX(), getY(), getWidth(), getHeight());
599 }
600
601 @Override
602 public final Rectangle getSurfaceBounds() {
603 return new Rectangle(getX(), getY(), // FIXME: 'scale' window -> pixel size
604 getSurfaceWidth(), getSurfaceHeight());
605 }
606
607 @Override
608 public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) {
609 return pixelUnitsAndResult; // FIXME HiDPI: use 'pixelScale'
610 }
611
612 @Override
613 public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) {
614 return windowUnitsAndResult; // FIXME HiDPI: use 'pixelScale'
615 }
616
617 @Override
618 public int getSurfaceWidth() {
619 return clientArea.getWidth();
620 }
621
622 @Override
623 public int getSurfaceHeight() {
624 return clientArea.getHeight();
625 }
626
627 @Override
628 public final NativeSurface getNativeSurface() { return this; }
629
630 @Override
631 public AbstractGraphicsConfiguration getGraphicsConfiguration() {
632 return config;
633 }
634
635 @Override
636 public long getDisplayHandle() {
637 return config.getScreen().getDevice().getHandle();
638 }
639
640 @Override
641 public int getScreenIndex() {
642 return config.getScreen().getIndex();
643 }
644
645 @Override
646 public void surfaceUpdated(final Object updater, final NativeSurface ns, final long when) { }
647
648 @Override
649 public void destroy() { }
650
651 @Override
652 public NativeWindow getParent() {
653 return null;
654 }
655
656 @Override
657 public long getWindowHandle() {
658 return nativeWindowHandle;
659 }
660
661 @Override
662 public InsetsImmutable getInsets() {
663 return insets;
664 }
665
666 @Override
667 public Point getLocationOnScreen(final Point point) {
668 final Point los = NativeWindowFactory.getLocationOnScreen(this); // client window location on screen
669 if(null!=point) {
670 return point.translate(los);
671 } else {
672 return los;
673 }
674 }
675
676 @Override
677 public boolean hasFocus() {
678 return isFocused();
679 }
680 };
681
682 static String newtWinHandleToHexString(final Window w) {
683 return null != w ? toHexString(w.getWindowHandle()) : "nil";
684 }
685 static String toHexString(final long l) {
686 return "0x"+Long.toHexString(l);
687 }
688}
689
Mutable insets representing rectangular window decoration insets on all four edges in window units.
Definition: Insets.java:35
final int getX()
x-position, left of rectangle.
Definition: Rectangle.java:68
final Rectangle setWidth(final int width)
Definition: Rectangle.java:92
final int getY()
y-position, top of rectangle.
Definition: Rectangle.java:70
final Rectangle setY(final int y)
Definition: Rectangle.java:91
final Rectangle setHeight(final int height)
Definition: Rectangle.java:93
final Rectangle setX(final int x)
Definition: Rectangle.java:90
abstract EDTUtil getEDTUtil()
abstract Display getDisplay()
A NEWT based JFX Canvas specialization allowing a NEWT child Window to be attached using native paren...
WindowClosingMode getDefaultCloseOperation()
NewtCanvasJFX(final Window child)
Instantiates a NewtCanvas with a NEWT child.
void destroy()
Destroys this resource:
NativeWindow getNativeWindow()
Returns the associated NativeWindow of this NativeWindowHolder, which is identical to getNativeSurfac...
WindowClosingMode setDefaultCloseOperation(final WindowClosingMode op)
Window setNEWTChild(final Window newChild)
Sets a new NEWT child, provoking reparenting.
NativeSurface getNativeSurface()
Returns the associated NativeSurface of this NativeSurfaceHolder.
Window closing mode if triggered by toolkit close operation.
DISPOSE_ON_CLOSE
Dispose resources on native window close operation.
A marker interface describing a graphics configuration, visual, or pixel format in a toolkit-independ...
AbstractGraphicsScreen getScreen()
Return the screen this graphics configuration is valid for.
boolean close()
Optionally closing the device if handle is not null.
long getHandle()
Returns the native handle of the underlying native device, if such thing exist.
boolean open()
Optionally [re]opening the device if handle is null.
A interface describing a graphics screen in a toolkit-independent manner.
int getIndex()
Returns the screen index this graphics screen is valid for.
AbstractGraphicsDevice getDevice()
Return the device this graphics configuration is valid for.
Provides low-level information required for hardware-accelerated rendering using a surface in a platf...
long getSurfaceHandle()
Returns the handle to the surface for this NativeSurface.
Accessor interface for implementing classes with ownership of a NativeWindow via an is-a or has-a rel...
Extend the NativeSurface interface with windowing information such as window-handle,...
Protocol for handling window closing events.
WindowClosingMode setDefaultCloseOperation(WindowClosingMode op)
Immutable insets representing rectangular window decoration insets on all four edges in window units.
Specifying NEWT's Window functionality:
Definition: Window.java:115
void sendWindowEvent(int eventType)
Send a WindowEvent to all WindowListener.
void setKeyboardFocusHandler(KeyListener l)
Sets a KeyListener allowing focus traversal with a covered window toolkit like AWT.
ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, int hints)
Change this window's parent window.
boolean windowRepaint(int x, int y, int width, int height)
Trigger window repaint while passing the dirty region in pixel units.
void requestFocus()
Request focus for this native window.
void setFocusAction(FocusRunnable focusAction)
Sets a FocusRunnable, which FocusRunnable#run() method is executed before the native focus is request...
void setSize(int width, int height)
Sets the size of the window's client area in window units, excluding decorations.
void setVisible(boolean visible)
Calls setVisible(true, visible), i.e.
void setPosition(int x, int y)
Sets the location of the window's client area excluding insets (window decorations) in window units.
void destroy()
Destroys this window incl.releasing all related resources.