JDK-8226274 : NPE in WinWindow.notifyMoving when Stage with no Scene is shown on 2nd monitor
  • Type: Bug
  • Component: javafx
  • Sub-Component: window-toolkit
  • Affected Version: 8u281,openjfx11
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2019-06-17
  • Updated: 2021-01-13
  • Resolved: 2019-06-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 Other
8u291Fixed openjfx13Fixed
Related Reports
Duplicate :  
Relates :  
Description
I'm creating two stages, one as a child of the primary one.  The child stage is given a Scene, but the parent isn't.  I then move both stages to my second monitor programmatically.

The bug occurs when I try to show the two Stages.  Sample code and stack trace below.  Uncommenting the "stage.setScene" line works around the problem.

import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class NotifyMovingBug extends Application {

  public static void main(String[] args) {
    Application.launch(args);
  }

  @Override
  public void start(Stage stage) throws Exception {
    Stage childStage = new Stage(StageStyle.TRANSPARENT);

    childStage.initOwner(stage);

    Screen screen = Screen.getScreens().stream()
      .filter(s -> !s.equals(Screen.getPrimary()))
      .findFirst()
      .orElseThrow(() -> new IllegalArgumentException("Must have two screens!"));

    setupStageLocation(stage, screen);
    setupStageLocation(childStage, screen);

    // stage.setScene(new Scene(new Label("Bla")));
    childStage.setScene(new Scene(new Label("Some text")));

    stage.show();  // <<<< NPE here
    childStage.show(); 
  }

  private static void setupStageLocation(Stage stage, Screen screen) {
    Rectangle2D bounds = screen.getBounds();

    stage.setX(bounds.getMinX());
    stage.setY(bounds.getMinY());
    stage.setWidth(bounds.getWidth());
    stage.setHeight(bounds.getHeight());
  }
}

Stack trace:

Exception in Application start method
java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
	at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
	at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
	at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NullPointerException
	at javafx.graphics/com.sun.glass.ui.win.WinWindow.notifyMoving(WinWindow.java:205)
	at javafx.graphics/com.sun.glass.ui.win.WinWindow.setBounds(WinWindow.java:129)
	at javafx.graphics/com.sun.javafx.tk.quantum.WindowStage.setBounds(WindowStage.java:336)
	at javafx.graphics/javafx.stage.Window$TKBoundsConfigurator.apply(Window.java:1550)
	at javafx.graphics/javafx.stage.Window.applyBounds(Window.java:1412)
	at javafx.graphics/javafx.stage.Window$12.invalidated(Window.java:1117)
	at javafx.base/javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
	at javafx.base/javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:145)
	at javafx.graphics/javafx.stage.Window.setShowing(Window.java:1174)
	at javafx.graphics/javafx.stage.Window.show(Window.java:1189)
	at javafx.graphics/javafx.stage.Stage.show(Stage.java:273)
	at NotifyMovingBug.start(NotifyMovingBug.java:32)
	at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
	at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
	at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
	at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
	at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
	... 1 more
Exception running application NotifyMovingBug

The line of code where this fails in WinWindow is:

                    view.updateLocation();

Where "view" is null.

Comments
Changeset: 0dd97a3b7cb6 Author: kcr Date: 2019-06-21 09:27 -0700 URL: http://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/0dd97a3b7cb6 8226274: NPE in WinWindow.notifyMoving when Stage with no Scene is shown on 2nd monitor Reviewed-by: arapte, jhendrikx
21-06-2019

This is a regression introduced by the fix for JDK-8146920. On the Windows platform, when a Stage is moved (or initially shown) on a screen other than the one it was one (or other than the default when first showing the Stage), the View associated with the Stage is notified via a call to `view.updateLocation()`. However, the `view` is null until a scene is set on the stage. The simple, and correct fix is to add a null check. I will send out a review request shortly.
18-06-2019

This will be a simple fix, so I'll target it for JavaFX 13. I will also add a test for this.
18-06-2019

See JDK-8226283 for another test case.
18-06-2019

As suggested by the bug description, an easy workaround is to attach a dummy Scene before showing a Stage.
17-06-2019