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

ImageView incorrectly calculates size when synchronously loaded

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      When forced to load image synchronously class javax.swing.text.html.ImageView incorrectly calculates image width and height, which results in images of <img> HTML tags not being shown.

      Works correctly in Oracle JDK 1.8.0_152.
      Work incorrectly in Oracle JDK 1.8.0_212.
      Also checked on third party Zulu JDK 1.8.0_202, which suggests that ImageView in Oracle JDK 1.8.0_202 is probably also broken.

      REGRESSION : Last worked in version 8u192

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create JTextPane with a custom HTMLEditorKit, with ViewFactory which forces synchronous loading of images.
      Set HTML code into created JTextPane with some <img> tags, where attribute "src" points to an existing image file.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      HTML tags <img> show corresponding images in the JTextPane component.
      ACTUAL -
      HTML tags <img> do not show corresponding images in the JTextPane component.

      ---------- BEGIN SOURCE ----------
      package swing;

      import javax.swing.*;
      import javax.swing.text.Element;
      import javax.swing.text.View;
      import javax.swing.text.ViewFactory;
      import javax.swing.text.html.HTMLEditorKit;
      import javax.swing.text.html.ImageView;
      import javax.swing.text.html.StyleSheet;
      import java.awt.*;

      /**
       * <a href="https://github.com/rybak/foobar/blob/master/baz/src/main/java/swing/SynchronousImageLoading.java">
       * Available on Github with image.png resource.</a>
       * <p>
       * Demo of a bug in JDK 202+.
       * <p>
       * <em>Actual result:</em>
       * <p>
       * Images in the window are not shown.
       * </p>
       *
       * <em>Expected result:</em>
       * <p>
       * Images in the window are shown.
       * </p>
       *
       * <em>Notes</em>
       * <p>
       * Works correctly in Oracle JDK 1.8.0_152.
       * Work incorrectly in Zulu JDK 1.8.0_202.
       * Work incorrectly in Oracle JDK 1.8.0_212.
       * </p>
       *
       * @author Andrei Rybak
       */
      public class SynchronousImageLoading {

      private final JFrame mainWindow;
      private final JTextPane htmlDisplay;
      private final JTextPane rawHtml;

      private SynchronousImageLoading() {
      mainWindow = new JFrame();
      mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      mainWindow.setTitle(String.format("Swing HTML image loading bug (%s) (%s)",
      System.getProperty("java.version"),
      System.getProperty("java.vendor")
      ));
      JPanel content = new JPanel(new BorderLayout());

      JCheckBox synchronousLoading = new JCheckBox("load synchronously", true);
      HTMLEditorKit htmlEditorKit = new HTMLEditorKit() {
      private final ViewFactory syncedImageLoadingFactory = new HTMLFactory() {
      @Override
      public View create(Element elem) {
      View view = super.create(elem);
      //force that icons loaded synchronously.
      if (view instanceof ImageView)
      ((ImageView) view).setLoadsSynchronously(synchronousLoading.isSelected());
      return view;
      }
      };

      @Override
      public ViewFactory getViewFactory() {
      return syncedImageLoadingFactory;
      }
      };
      StyleSheet css = htmlEditorKit.getStyleSheet();
      css.addRule("a { color: red; }");

      rawHtml = new JTextPane();
      rawHtml.setEditable(false);
      rawHtml.setBorder(BorderFactory.createLineBorder(Color.BLACK));

      htmlDisplay = new JTextPane();
      htmlDisplay.setEditorKit(htmlEditorKit);
      htmlDisplay.setEditable(false);

      setHtml();
      content.add(htmlDisplay, BorderLayout.CENTER);
      content.add(rawHtml, BorderLayout.NORTH);
      {
      JPanel bottomPanel = new JPanel();
      bottomPanel.add(synchronousLoading);
      JButton refreshButton = new JButton("Refresh");
      bottomPanel.add(refreshButton);
      refreshButton.addActionListener(ignored -> setHtml());
      content.add(bottomPanel, BorderLayout.SOUTH);
      }
      mainWindow.setContentPane(content);
      }

      private void setHtml() {
      String imageUrl = SynchronousImageLoading.class.getResource("image.png").toString();
      System.err.println(imageUrl);
      String html = String.format("<html><body>\n" +
      "Just an image: <img src=\"%s\" /><br/>\n" +
      "<a href=\"https://example.net\">A link</a><br/>\n" +
      "Image inside link:<a href=\"https://example.net\"><img src=\"%s\"></a><br/>\n" +
      "Image with big border:<img src=\"%s\" border=\"10\"><br/>\n" +
      "Image with workaround:<img src=\"%s\" width=\"64\" height=\"64\">\n" +
      "</body></html>",
      imageUrl,
      imageUrl,
      imageUrl,
      imageUrl
      );
      htmlDisplay.setText(html);
      rawHtml.setText(html);
      }

      private void run() {
      mainWindow.setResizable(false);
      mainWindow.setSize(800, 600);
      mainWindow.setVisible(true);
      }

      public static void main(String... args) {
      new SynchronousImageLoading().run();
      }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Explicitly provide width and height inside HTML tag <img>, as shown for the fourth <img> tag in the source code.

      FREQUENCY : always


            pbansal Pankaj Bansal (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: