I have the following issue, that I am using a JTextPane with a HTMLEditorKit, and dynamically adding content to the pane. The content can be over several lines, also containing lots of images (small icons). The problem now is, if I insert for example a bunch of text with icons, via:
editorKit.insertHTML(doc, doc.getLength(), htmlCode, 0, 0, null);
The result is, that the images in the html code taking a long time to appear on the screen (~1second):
Question: Is there a way, to buffer the images shown in the pane if it's html code via:
imgsrc = "file:/" + imgSRCOnHDD;
imgsrc = imgsrc.replace("\\", "/");
imgSub = "<img height=\"18\" width=\"18\" style=\"vertical-align:middle;\" src='" + imgsrc + "'></img>";
I cant use pane.insertIcon because of the HTMLEditor. Is there maybe to have some sort of container setting it to invisible, adding the content to the pane, and afterwards setting the container visible?
Comment by @StanislavL led to me solving the problem, though not the link he provided, it didnt work and I couldnt find out why, the URLs were correct I double checked, but after setting the Cache, the Pane always would show "broken link" picture for every image. So I found this post, with the knowledge of the cache mechanism of HTMLEditorKit:
https://stackoverflow.com/a/27669916/7377320
The mentioned code:
public class ImageCache extends Hashtable {
public Object get(Object key) {
Object result = super.get(key);
if (result == null){
result = Toolkit.getDefaultToolkit().createImage((URL) key);
put(key, result);
}
return result;
}
}
...
Dictionary cache = (Dictionary) pane.getDocument().getProperty("imageCache");
if (cache == null) {
cache = new ImageCache();
pane.getDocument().putProperty("imageCache", cache);
}
Worked flawless, and it is working now. I also made this change to ImageView for the HTMLEditorKit:
public class MyImageView extends ImageView {
public MyImageView(Element elem) {
super(elem);
}
@Override
public Icon getNoImageIcon() {
return null;
}
@Override
public Icon getLoadingImageIcon() {
return null;
}
}
This wont show any broken link pictures anymore in the pane, also no "pre loading" broken link picture too.
HTMLEditorKit:
public class MyHTMLEditorKit extends HTMLEditorKit {
@Override
public ViewFactory getViewFactory() {
return new HTMLEditorKit.HTMLFactory() {
public View create(Element e) {
View v = super.create(e);
Object o = e.getAttributes().getAttribute(StyleConstants.NameAttribute);
if (o instanceof HTML.Tag) {
HTML.Tag kind = (HTML.Tag) o;
if (kind == HTML.Tag.IMG) {
return new MyImageView(e);
}
}
if (v instanceof InlineView) {
return new InlineView(e) {
public int getBreakWeight(int axis, float pos, float len) {
return View.GoodBreakWeight;
}
public View breakView(int axis, int p0, float pos, float len) {
if (axis == View.X_AXIS) {
checkPainter();
int p1 = getGlyphPainter().getBoundedPosition(this, p0, pos, len);
if (p0 == getStartOffset() && p1 == getEndOffset()) {
return this;
}
return createFragment(p0, p1);
}
return this;
}
};
} else if (v instanceof ParagraphView) {
return new ParagraphView(e) {
protected javax.swing.SizeRequirements calculateMinorAxisRequirements(int axis, javax.swing.SizeRequirements r) {
if (r == null) {
r = new javax.swing.SizeRequirements();
}
float pref = layoutPool.getPreferredSpan(axis);
float min = layoutPool.getMinimumSpan(axis);
// Don't include insets, Box.getXXXSpan will include them.
r.minimum = (int) min;
r.preferred = Math.max(r.minimum, (int) pref);
r.maximum = Integer.MAX_VALUE;
r.alignment = 0.5f;
return r;
}
};
}
return v;
}
};
}
}