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