Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8097328

[SwingNode]: Swing Nodes have serious rendering artifacts when first displayed on the primary Stage

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3
    • 8u40
    • 8u5
    • javafx
    • OS: Windows 7
      Hardware: VMWare / Virtual Machine - GPU enabled (albeit via VMWare drivers)
      Java VM Settings: tried J2D_D3D=false and true. Same problems.

    Description

      Swing Nodes are not behaving well, even for simple JPanels.
      -A simple test which initializes 8 Swing Nodes on a StackPane will demonstrate varying results.
      -Sometimes the JPanels show up black, instead of rendering.
      -Sometimes there are black rectangular artifacts between JPanels.
      -Sometimes the JPanels appear (black again), but then vanish.
      -Sometimes resizing the window brings them back, up other times, they are never seen again.
      -Upon resizing the window, the JPanels will continue to render correctly (unless they don't come back).
      -Any attempt to resize the primary stage programmatically causes the stage to go black, and components will show up again one by one as you move the mouse over them, or will reappear if you manually resize with your mouse.

      I have tries, and have not been able to come up with any workaround for these problems. As such, I cannot progress with my conversion from Swing to JavaFX.

      --
      Simple, well commented example code below:
      --

      package fas.testing;


      import java.awt.Dimension;
      import java.awt.GraphicsEnvironment;
      import java.util.Random;

      import javax.swing.JPanel;
      import javax.swing.SwingUtilities;

      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.embed.swing.SwingNode;
      import javafx.geometry.Pos;
      import javafx.scene.Scene;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;

      public class Test2 extends Application{
      //XXX Use these flags to test different aspects of the swing node bugs
      private boolean USE_TOP_LEFT = false;
      private boolean WAIT_FOR_SWING = true;

      // instance variables, to allow configuring of the swing nodes in separate method
      private Stage primaryStage;
      private Scene scene;
      private StackPane root;

      // random used to place nodes
      private static final Random rand = new Random();

      private void initPresentation(){

      // add 8 randomly placed swing nodes of identical size
      for(int i = 0; i < 8; i++){

         // create the swing node
      SwingNode swingNode = new SwingNode();

      // set the location, randomly
         swingNode.setTranslateX(rand.nextDouble()*400);

         // IMPORTANT -- this test demonstrates noticeably different behavior when StackPane is TOP_LEFT aligned.
         // to compare, change USE_TOP_LEFT to false (we translate y values to be from the bottom in this case)
         if(USE_TOP_LEFT)
         swingNode.setTranslateY(rand.nextDouble()*400);
         else
         swingNode.setTranslateY(-rand.nextDouble()*400);
        
        
         // add the node to the parent
         root.getChildren().add(swingNode);

      final int myI = i; // we'll use this index to determine if its okay to display the primary stage yet

         // invoke all swing stuff on AWT EDT
         SwingUtilities.invokeLater(()->{
         // create a jpanel
         JPanel panel = new JPanel();
        
         // give it a random color
         panel.setBackground(new java.awt.Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)));
        
         // set the preferred / max size
         panel.setPreferredSize(new Dimension(100, 100));
         panel.setMaximumSize(new Dimension(100, 100));
        
         // assign this JPanel to the javafx swing node (method is supposedly safe to call from AWT EDT)
         swingNode.setContent(panel);
        
         // if we wait for swing to finish initializing all components before displaying, does this help? A little, but it does not fix the problems sufficiently to serve as workaround.
         if(myI == 7 && WAIT_FOR_SWING)
         Platform.runLater(()->primaryStage.show());
         });
      }
      }
      public void start(Stage primaryStage) throws Exception {
      // set our primary stage, and give it a title
      this.primaryStage = primaryStage;
      this.primaryStage.setTitle("Swing Node Test");

      // create our root stack pane, and make it so that nodes in it are top/left aligned
      this.root = new StackPane();
      if(USE_TOP_LEFT)
      this.root.setAlignment(Pos.TOP_LEFT); // align all components to top-left corner. This causes everything to go blank.
      else
      this.root.setAlignment(Pos.BOTTOM_LEFT); // align all components to bottom-left corner. This works better than TOP_LEFT, but still clearly has problems.

      // create a scene, which views our root stack pane. Make it the primaryStage's scene.
      this.scene = new Scene(root);
      this.primaryStage.setScene(scene);
      this.primaryStage.setWidth(400);
      this.primaryStage.setHeight(400);


      // create the randomly arranged swing nodes.
      initPresentation();

      // present the stage
      if(!WAIT_FOR_SWING)
      this.primaryStage.show();
      }
      public static void main(String... args){
      if(!GraphicsEnvironment.isHeadless())
      Application.launch(args);
      else
      System.err.println("Error: could not start TEST: this operating system is console based, and does not provide any means for displaying graphics to the screen.");
      }
      }

      Attachments

        Issue Links

          Activity

            People

              ant Anton Tarasov (Inactive)
              duke J. Duke
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported: