I'm making an image cache in the folder of my application. I made code for downloading images and checking for their existence.
However, I cannot use them in src
attributes for some reason.
I have read these two posts:
jEditorPane handling local images
Display images using JEditorPane
However, in the first question the OP said that he used another method for setting image source, that is not suitable in my case.
And the second article assumes that file://
scheme should be working out of the box without any tricks. But somehow it's not working in my case.
A tried replacing forward slashes with backslashes, replacing spaces with
and leaving them as they are, tried file:// and file:/// prefix - nothing is working. I can read my files using ImageIO, but JTextPane HTML renderer does not find them, so I have just error placeholders on screen.
The example of the path to an image:
file:///D:/My Documents/NetBeansProjects/XMessenger/cache/http://popov654.pp.ru/copybox/photo.jpg
Here is the code:
private int last_width = 0;
private HashMap<String, Image> imgCache = new HashMap<String, Image>();
private void createTestMessageContent(final JComponent parent) {
String html = "Some <i>text</i><br>And more,<br>And more...<br>And more...<br>And more...<br>And more...<br>And more...<br>"
"<img src=\"http://popov654.pp.ru/copybox/photo.jpg\" width=\"390\" height=\"260\">"
"<img src=\"http://popov654.pp.ru/copybox/DSCN2155.jpg\" width=\"390\" height=\"260\">"
"<img src=\"http://popov654.pp.ru/copybox/DSCN2157.jpg\" width=\"390\" height=\"260\">";
html = "<div style=\"padding: 0px; font-size: 14px; font-family: Tahoma\">" html "</div>";
final String orig_html = html;
Matcher m = Pattern.compile("((<img src=\"[^\"] \")( width=\"\\d \")?( height=\"\\d \")?([^>]*>)\\s*) ").matcher(orig_html);
while (m.find()) {
String str = m.group();
Matcher m2 = Pattern.compile("src=\"([^\"] )\"").matcher(str);
while (m2.find()) {
File f = new File("cache");
if (!f.exists()) {
f.mkdir();
}
String src = m2.group(1);
String cached_name = src.replaceAll("/", "/").replaceAll(":", ":");
File img = new File("cache/" cached_name);
System.err.println(img.getAbsolutePath());
if (!img.exists()) {
InputStream in = null;
BufferedInputStream b_in = null;
FileOutputStream fileOutputStream = null;
try {
in = new URL(src).openStream();
b_in = new BufferedInputStream(in);
fileOutputStream = new FileOutputStream("cache/" cached_name);
byte dataBuffer[] = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
fileOutputStream.write(dataBuffer, 0, bytesRead);
}
//Files.copy(in, Paths.get("cache/" cached_name), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
in.close();
b_in.close();
fileOutputStream.close();
} catch (IOException ex) {}
}
} else {
html = html.replaceFirst("src=\"" src "\"", "src=\"file:///" img.getAbsolutePath().replaceAll("\\\\", "/").replaceAll(" ", " ") "\"");
}
}
}
final String cached_html = html;
html = html.replaceAll("(<img src=\"[^\"] \")( width=\"\\d \")?( height=\"\\d \")?([^>]*>)", "<a href=\"#\" style=\"display: inline-block; margin-right: 10px\">$1 width=\"390\" height=\"260\" hspace=\"2\" vspace=\"8\" border=\"0\"$4</a>");
System.out.println(html);
msgContent.setText(html);
addHyperlinkListener(msgContent);
//msgContent.setMinimumSize(new Dimension(msgContent.getWidth(), msgContent.getPreferredSize().height 20));
//setMinimumSize(new Dimension(getWidth(), msgContent.getPreferredSize().height 160));
setPreferredSize(new Dimension(getWidth(), msgContent.getPreferredSize().height 148));
initImages();
updateSize();
content2.addComponentListener(new java.awt.event.ComponentListener() {
@Override
public void componentResized(ComponentEvent e) {
int new_width = ((JPanel)e.getSource()).getWidth();
if (new_width != last_width) updateImages(cached_html);
last_width = new_width;
}
@Override
public void componentMoved(ComponentEvent e) {}
@Override
public void componentShown(ComponentEvent e) {}
@Override
public void componentHidden(ComponentEvent e) {}
});
}
private void initImages() {
HTMLDocument doc = (HTMLDocument) msgContent.getStyledDocument();
Element[] imgs = getElementsByTagName(HTML.Tag.IMG, doc);
for (Element img: imgs) {
Element a = img.getParentElement();
try {
String src = (String) img.getAttributes().getAttribute(HTML.Attribute.SRC);
System.out.println("src=" src);
System.out.println();
Image image = null;
if (!src.startsWith("http://") && !src.startsWith("https://")) {
String path = src;
if (src.startsWith("file:///")) {
path = path.substring(8).replaceAll(" ", " ");
}
image = ImageIO.read(new File(path));
} else {
image = ImageIO.read(new URL(src));
}
imgCache.put(src, image);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
private void updateImages(String orig_html) {
int width = XMessengerApp.getMainWindow().getMessagePaneWidth() - 108;
double default_ratio = 16f / 9;
int img_width = (int) (width * 0.65);
int img_height = (int) ((double)img_width / default_ratio);
int margin = (int) (width * 0.005);
String html = orig_html;
Matcher m = Pattern.compile("((<img src=\"[^\"] \")( width=\"\\d \")?( height=\"\\d \")?([^>]*>)\\s*) ").matcher(orig_html);
while (m.find()) {
String str = m.group();
String str_new = str;
String[] img_strs = str.split(">\\s*<");
if (img_strs.length > 1) {
System.err.println("Image series found of " img_strs.length " images");
}
if (img_strs.length > 1) {
img_width = (int)((width - margin * img_strs.length) / img_strs.length * 0.95);
img_height = (int)((double)img_width / default_ratio);
}
for (int i = 0; i < img_strs.length; i ) {
if (i > 0) img_strs[i] = "<" img_strs[i];
if (i < img_strs.length-1) img_strs[i] = img_strs[i] ">";
Matcher m2 = Pattern.compile("src=\"([^\"] )\"").matcher(img_strs[i]);
m2.find();
String src = m2.group(1);
double ratio = default_ratio;
if (imgCache.containsKey(src)) {
Image img = imgCache.get(src);
ratio = (double) img.getWidth(null) / img.getHeight(null);
//System.out.println("Aspect ratio: " ratio);
}
if (img_strs.length == 1) {
img_height = (int)((double)img_width / ratio);
} else {
img_width = (int)((double)img_height * ratio);
}
//System.out.println("Src: " src);
String replace = img_strs[i].replaceAll("(<img src=\"[^\"] \")( width=\"\\d \")?( height=\"\\d \")?([^>]*>)", "<a href=\"#\" style=\"display: inline-block; margin-right: " margin "px\">$1 width=\"" img_width "\" height=\"" img_height "\" hspace=\"" margin "\"vspace=\"8\" border=\"0\"$4</a>");
str_new = str_new.replaceFirst(img_strs[i], replace);
}
if (img_strs.length > 1) {
str_new = "<div style=\"float: left; margin-left: -10px\">" str_new "</div>";
}
html = html.replaceFirst(str, str_new);
}
msgContent.setText(html);
}
private void updateSize() {
try {
Dimension d = msgContent.getPreferredSize();
Rectangle r = msgContent.modelToView(msgContent.getDocument().getLength());
d.height = r.y r.height;
msgContent.setPreferredSize(d);
Dimension d2 = content2.getPreferredSize();
d2.height = r.y r.height 200;
content2.setPreferredSize(d2);
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
topFrame.getContentPane().validate();
} catch (Exception ex) {}
}
CodePudding user response:
Found the problem. It seems that I should escape %
symbols in my filenames, replacing it with %
, but only if I use that path inside a URL string. When I'm using File()
to work with that file it is not needed.