1 Reply Latest reply on Nov 20, 2009 7:02 PM by 843807

    setAsynchronousLoadPriority on JTextPane does not seem to work in 1.6

    843806
      Hello,

      due to the nature of our app it needs to measure the height in pixels of the HTML content rendered in JTextPane (for correct pagination during printing - done from a different package) . So we used this code:

      (1)          sizeTestPane = new JTextPane();
      ((AbstractDocument)sizeTestPane.getDocument()).setAsynchronousLoadPriority(-1);
      ((HTMLDocument)sizeTestPane.getDocument()).setTokenThreshold(0);

      to make sure when HTML is set into it via setText() and there are images located on the local drive in the HTML (pointed to via IMG tags) - those images are loaded and rendered in JTextPane before we take the measurement (hence the setAsynchronousLoadPriority(-1) setting ) via

      (2) sizeTestPane.getPreferredSize().getHeight()

      This works nicely in 1.4.2_18 - the height of the JTextPane - correctly includes the height of the image. However after switching to 1.6.0 update 12 - the code in (2) above became unstable. It does sometimes produce correct height - but most of the time, the height is given without including the height of the image in the page.

      Same code .. different result. It seems the issue is that in 1.6.0_12 JTextPane in our scenario still performs asynchronous load of images and returns height too soon. To test this we added a button the we could click to perform final measurement after everything is rendered. Even after producing an incorrect height using code in (2) - taking a height measurement with Button click code in (3) - gave the correct height !!

      (3)     JButton control = new JButton("Check");
      control.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
      System.out.println("DEBUG G height: " + sizeTestPane.getPreferredSize().getHeight());
      }
      });

      Need help with this if anybody knows how this can be fixed - can JTextPane be forced to be synchronous in 1.6 ? is it a bug and I should report it? what am I missing..

      Paul

      edit1:
      actual code to illustrate the issue below, after further investigation the code also used to "wait" for JTextPane images to be loaded by spending time loading those images via ToolKit, and this ToolKit images loading functionality is different in 1.6 I guess (more buffering).

      So the real question is - what is the best way to wait for JTextPane images to get loaded or somehow force them be be synchronous.
           /*
            * loads HTML with image into the page and measures it 
            * JTextPane is made synchronous via setAsynchronousLoadPriority(-1)
            * but setText returns before images are loaded (this without waiting for images does not work in either 1.4.2 or 1.6.0
      
            * so this method also attempts to wait for image loading in JTextPain
            * loading those images simultaneously in the event dispatch thread via imageicon
            * in 1.4.2 - this works as the time spent equals the time it take JTextPane to load (so height comes back correct
            * in 1.6.0 - does not work - must be now the method returns "cached" images and time is not enough... 
            * tried using javax.imageio.ImageIO.read and PropertyListener of the JTextPage (for "page" event) - neither works
            * 
            * I guess need to find a way to wait for images to load in JTextPane - but cannot just do an arbitrary Thread.sleep 
            * - as #1 it actually does not work either (even with a 2sec delay)!!! 
            * and this measurement is a GUI inline process done to many HTML snippets
            * so needs to be fast.. 
            * 
            */
           public double calculateHTMLHeightWithToolKit(boolean useMT) {
                sizeTestPane.setSize(new Dimension(600,300));
                sizeTestPane.repaint();
      
                StringBuffer sbhtml = new StringBuffer();
                sbhtml.append("<HTML><HEAD>");
                sbhtml.append("</HEAD><BODY>");
                sbhtml.append(html);
                sbhtml.append("</BODY></HTML>");
      
                sizeTestPane.setText(sbhtml.toString());
      
                boolean bGraphic = false;
                int iindex = html.indexOf("src=\"");
                while (iindex >=0) {
                     bGraphic = true;
                     int eindex = html.indexOf("\"",iindex + 5);
                     if (eindex > iindex && eindex > 0) {
                          String imUrl = html.substring(iindex + 5,eindex);
                          try {
                               URL url = new URL(imUrl);
                               ImageIcon im = new ImageIcon();
                               JLabel label = new JLabel(im); 
                               Image img = Toolkit.getDefaultToolkit().getImage(url);
                               //Image img = javax.imageio.ImageIO.read(url);
                               im.setImage(img);
                               if (useMT) {
                                    MediaTracker mt = new MediaTracker (label);
                                    mt.addImage (img, 0);
                                    try {mt.waitForID (0);}catch (InterruptedException e) 
                                         {System.out.println("Cannot wait: " + e.getMessage());}
                               }
                          } catch (Exception e) {
                               System.out.println("Cannot load: " + e.getMessage());
                          }
                     } else {
                          break;
                     }
                     iindex = html.indexOf("src=\"", eindex+1);
                }
      
                double h = sizeTestPane.getPreferredSize().getHeight();
                return h;
           }
      }
      {code}
      
      Edited by: PaulCharo on Feb 23, 2009 9:55 PM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        • 1. Re: setAsynchronousLoadPriority on JTextPane does not seem to work in 1.6
          843807
          I came across this thread when I was searching for solutions to problems with the asynchronous loading of HTML pages by the JEditorPane.setPage method (JTextPane is essentially the same so far these problems are concerned). According to the API, you should be able to use a property-change listener to be informed of when loading of an HTML page is complete. However, when we tried this, it was clear that the listener was being called before all the images in the page had been loaded.

          It is possible to workaround this bug by forcing synchronous loading of the images. The following solutions are probably too late for PaulCharo, but may be of use to other people.

          To force synchronous loading of images you need to override methods in the HTMLEditor.HTMLFactory and HTMLEditorKit classes:
              static class MyViewFactory
                 extends HTMLEditorKit.HTMLFactory
              {
                  @Override
                  public View create (Element elem)
                  {
                      View view = super.create (elem);
                      if (view instanceof ImageView)
                              ((ImageView) view).setLoadsSynchronously (true);
                      return view;
                  }
              }
          
              static class MyHTMLEditorKit
                  extends HTMLEditorKit
              {
                  @Override
                  public ViewFactory getViewFactory ()
                  {
                      return new MyViewFactory ();
                  }
              }
          
              editorPane.setEditorKit (new MyHTMLEditorKit ());
          This should ensure that all images have been loaded by the time that the "page" property-change listener is called (see [JEditorPane.setPage API|http://java.sun.com/javase/6/docs/api/javax/swing/JEditorPane.html#setPage(java.net.URL)]), but there still seems to be something queued on the event dispatch queue that you need to wait for. This means that you have to use a property-change listener that looks something like:
          editorPane.addPropertyChangeListener (
              new PropertyChangeListener ()
              {
                  public void propertyChange (PropertyChangeEvent e)
                  {
                      if (e.getPropertyName ().equals ("page"))
                      {
                          EventQueue.invokeLater (
                             new Runnable ()
                             {
                                 public void run ()
                                 {
                                      // The page, including images, should now be loaded!
                                     .....
                                 }
                              });
                      }
                  }
              });
          If you don't want to use a property-change listener, you can force the loading of the HTML page itself to be synchronous by overriding the HTMLEditorKit.getDefaultDocument method. To do this, add the following method to the MyHTMLEditorKit class (this is in addition to the changes above for forcing synchronous loading of images):
              @Override
              public Document createDefaultDocument ()
              {
                  Document doc = super.createDefaultDocument ();
                  ((HTMLDocument) doc).setAsynchronousLoadPriority (-1);
                  return doc;
              }
          This should ensure that the HTML page and all its images have been loaded by the time that setPage returns. Unfortunately, there is still that mysterious task on the event dispatch queue that we have to wait for, so we need code that looks something like:
          editorPane.setPage (url);
          EventQueue.invokeLater (
              new Runnable ()
              {
                  public void run ()
                  {
                       // The HTML page and all its images should now be loaded!
                       .....
                  }
              });