我在应用程序的文件夹中创建了一个图像缓存,并编写了下载图像和检查图像是否存在的代码。
但是,由于某种原因,我不能在src
属性中使用它们。
我读过这两篇文章:
jEditorPane handling local images
Display images using JEditorPane
然而,在第一个问题中,OP说他使用了另一种方法来设置图像源,这不适合我的情况。
第二篇文章假设file://
模式应该可以不带任何技巧地开箱即用,但不知何故,它在我的情况下不起作用。
A尝试将正斜杠替换为反斜杠,将空格替换为%20
并保持原样,尝试file://和file:///前缀-没有任何效果。我可以使用ImageIO读取我的文件,但JTextPane HTML渲染器找不到它们,因此屏幕上只有错误占位符。
图像路径的示例:
file:///D:/My%20Documents/NetBeansProjects/XMessenger/cache/http%3A%2F%2Fpopov654.pp.ru%2Fcopybox%2Fphoto.jpg
下面是代码:
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("/", "%2F").replaceAll(":", "%3A");
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(" ", "%20") + "\"");
}
}
}
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("%20", " ");
}
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) {}
}
1条答案
按热度按时间dw1jzc5e1#
找到问题了。似乎我应该转义文件名中的
%
符号,将其替换为%25
,但前提是我在URL字符串中使用该路径。当我使用File()
处理该文件时,不需要使用File()
。