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

Tooltip based on graphic contented only show less than 1 out of 10 times

    XMLWordPrintable

Details

    • web
    • b127
    • 9
    • generic
    • generic

    Description

      FULL PRODUCT VERSION :
      java 9
      Java(TM) SE Runtime Environment (build 9+181)
      Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Windows 10.0.15063 (10 Pro 64-bit)

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      NVidia GForce GT 730

      A DESCRIPTION OF THE PROBLEM :
      Tooltips with graphic contect only show up black without any content being shown with the exception of maybe the first tooltip that you pop-up) in Java 9.

      This wasn't an issue with any of the Java 8 runtime engines that were released for at least the passed year.

      REGRESSION. Last worked in version 8u144

      ADDITIONAL REGRESSION INFORMATION:
      I don't have Java 8 installed anymore, but was 8 Update 144, and all the versions before it in the passed year or so. In all those versions I never had any problem when using setGraphic straight instead of having to use a workaround (see below)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Put a WebTooltip (see class below) on a few JavaFX controls (no CSS, just the CSS defaults for a .tooltip already trigger this).
      Usually when hovering over the first control, you see the tooltip pop-up as expected, but thereafter on a second or 3 control it goes wrong consistently.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Expectation: Tooltips should always show.
      ACTUAL -
      Tooltips show up black without any content, with a possible exception of the first tooltip that you are trying to see.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javafx.beans.value.ChangeListener;
      import javafx.beans.value.ObservableValue;
      import javafx.concurrent.Worker;
      import javafx.concurrent.Worker.State;
      import javafx.event.EventHandler;
      import javafx.scene.CacheHint;
      import javafx.scene.control.ContentDisplay;
      import javafx.scene.control.Tooltip;
      import javafx.scene.text.FontSmoothingType;
      import javafx.scene.web.WebView;
      import javafx.stage.WindowEvent;
      import javafx.util.Duration;

      public class WebTooltip extends Tooltip {

      //Only create WebToolTip on demand using MouseListener and discard after being shown. Underlying JavaFX WebView control burns memory
          //continuously, even when Tooltip is not visible (a couple of hundred of these will result in 5..10MB heap-space being claimed). This
      //results in high CPU load, and frequent garbage collections that also generate large spikes due to the number of objects that need
          //freeing (180 ->80MB free if System.gc() is run every 10 seconds):
      public WebTooltip(String text) {
      setShowDuration(new Duration(30000)); //unit is ms
      final WebView webView = new WebView();
      webView.setPrefSize(1024, -1);
      webView.setFontSmoothingType(FontSmoothingType.GRAY);
      //webView.setDisable(true);
      webView.setMouseTransparent(true);
      webView.setCache(true);
      webView.setCacheHint(CacheHint.QUALITY);
      webView.getEngine().loadContent("<html><head><style>td {white-space: nowrap;} body white-space: nowrap; overflow-x: hidden; overflow-y: hidden;}</style></head><body><div id='mydiv' style='overflow:hidden'>" + text + "</div></body></html>"); //This does not immediately trigger the above changed handler
      //webView.getEngine().loadContent("<html><head></head><body><div id='mydiv'>testText</div></body></html>"); //This does not immediately trigger the above changed handler
      //Switch this label over to display it's content as graphic only: The graphic will be provided by the WebView component:
      webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
      @Override
      public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
      if (newState == Worker.State.SUCCEEDED) { //This adjustsize has different 'margins' then the one in WebLabel!
      Object result = webView.getEngine().executeScript("document.getElementById('mydiv').offsetHeight");
      if (result instanceof Integer)
      webView.setPrefHeight((Integer)result+15);
      // offsetWidth can not be used for the next command in WebKit, but scrollWidth seems to do the trick:
      result = webView.getEngine().executeScript("document.getElementById('mydiv').scrollWidth");
      if (result instanceof Integer)
      webView.setPrefWidth((Integer)result + 25);
      }
      }
      });
      setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
         setGraphic(webView);
      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Change the setGraphic() line to:
      setOnShown(new EventHandler<WindowEvent>(){
      @Override
      public void handle(WindowEvent arg0) {
      setGraphic(webView);
      }
      });
      Now the tootlips show 100% of the time again.

      Attachments

        1. tooltip_screenshots.png
          27 kB
          Priyanka Mangal
        2. ToolTipTest.java
          2 kB
          Priyanka Mangal
        3. WebTooltip.java
          3 kB
          Priyanka Mangal

        Issue Links

          Activity

            People

              mbilla Murali Billa
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: