2012-02-22 34 views
10

Tôi đang cố hiển thị hình ảnh nội dòng trong Java JEditorPane. Mã bên dưới sử dụng nội dung HTML hiển thị đúng hình ảnh trong Firefox, nhưng không hiển thị trong JEditorPane. Bất kỳ ý tưởng tại sao? Cảm ơn.JEditorPane với hình ảnh nội dòng

import javax.swing.*; 
import java.awt.*; 

public class InlineImage { 

    public InlineImage() { 
     JFrame frame=new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JEditorPane edit=new JEditorPane(); 
     frame.getContentPane().add(edit); 
     edit.setContentType("text/html"); 

     String html = "<html><body>Local image<br><img src=\"data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAyCAYAAACqNX6+AAACeklEQVR42u1bHZBCURgNgiBYCINgIVhYCIKFhSBYCIIgCIKFxSBoZpsJgjAIgmAhCIIgCIKFIAiChSAIF4IgCL7d82abnWl69Xq9+7r1Dhyp93PfOff7ufd+n8/nEyF0AkmgIAQFoSDEjQgSCn1LPD6SbPZDSqWKNBqv0m5nZDh8lsnkUebziIH1OiC/d+wF/tteN50+GPfiGbVaQcrld8nnm8Y78C4K8odAYC3R6Jfkci2pVosGaYtFWDYbvynRKgDx8G4Ij7FgTBjbzQuC2ZhOd4wZCgIOzfBLYysSxooxh8OL2xAEH4KPGo3irs98pwF3CZcXi42vS5CtCPiAaxfBDLPZvRQKNUWW49CDEomBdDrpmxXBDN1uSlKprvj9m8sLgkHAx47HMU+JYObSkBmenxDYvDGTaRum63UhdoFUG9maa4IgW4KZkvzD6PVebMaYEy6GSS6XdyTcIlaroA1rsRgr6vU3zwVsp4BFZzC4ckYQBCmYH4k9D4NBwmLAP2IZFMNZUY6nxwf+rFRKJNJhYLVvSxAs9Bgz1ADcniQIzIprDLVbL+aua8+PyWSfxCkGOLYsSKuVI2mKAY4tC4LlP0lTv8ViWRAS5g4oyLUKQpelmctiUNcsqDPt1Szt5cJQs4Uht0402zrh5qKGm4tb19XvJ0mkq2ciPKC6ngOq3SNcEms/xXXsCJdFDhoWOeyWAdGFWSsDikTm7hXKwVq4VjEvlLNfWnpmKSkqGFlK+l9Kaj1WuFBs7cWKRrgmbYqtvdyOUCxW9W5HOCQOXBobdtjSxpY2J5o+L0W+55o+7bZFN5t5JW3RT0+fbIsmKAgFISgIBSHU4QdCoO0W7Xd4AwAAAABJRU5ErkJggg==\"></body></html>"; 
     edit.setText(html); 

     frame.setSize(500,300); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) {new InlineImage();} 
} 

Trả lời

15

Bạn cần thêm trình xử lý giao thức cho "dữ liệu:" để URL/URLConnection có thể mở được. Ngoài ra, bạn có thể tạo một số trình xử lý giao thức "resource:" cho tài nguyên đường dẫn lớp.

Bạn cần gói data với lớp học Handler (quy ước tên cố định!). Đây sẽ là lớp nhà máy cho "dữ liệu:" trả về một URLConnection. Chúng tôi sẽ tạo DataConnection cho điều đó.

Cài đặt trình xử lý giao thức có thể được thực hiện thông qua System.setProperty. Ở đây tôi đã cung cấp Handler.install(); để thực hiện điều đó một cách chung chung.

package test1.data; 

import java.io.IOException; 
import java.net.URL; 
import java.net.URLConnection; 
import java.net.URLStreamHandler; 

public class Handler extends URLStreamHandler { 

    @Override 
    protected URLConnection openConnection(URL u) throws IOException { 
     return new DataConnection(u); 
    } 

    public static void install() { 
     String pkgName = Handler.class.getPackage().getName(); 
     String pkg = pkgName.substring(0, pkgName.lastIndexOf('.')); 

     String protocolHandlers = System.getProperty("java.protocol.handler.pkgs", ""); 
     if (!protocolHandlers.contains(pkg)) { 
      if (!protocolHandlers.isEmpty()) { 
       protocolHandlers += "|"; 
      } 
      protocolHandlers += pkg; 
      System.setProperty("java.protocol.handler.pkgs", protocolHandlers); 
     } 
    } 
} 

Các URLConnection cho một InputStream để các byte:

package test1.data; 

import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.URL; 
import java.net.URLConnection; 
import javax.xml.bind.DatatypeConverter; 

public class DataConnection extends URLConnection { 

    public DataConnection(URL u) { 
     super(u); 
    } 

    @Override 
    public void connect() throws IOException { 
     connected = true; 
    } 

    @Override 
    public InputStream getInputStream() throws IOException { 
     String data = url.toString(); 
     data = data.replaceFirst("^.*;base64,", ""); 
     System.out.println("Data: " + data); 
     byte[] bytes = DatatypeConverter.parseBase64Binary(data); 
     return new ByteArrayInputStream(bytes); 
    } 

} 

Điều thông minh ở đây là sử dụng Base64 giải mã DatatypeConverter trong tiêu chuẩn Java SE.


P.S.

Ngày nay, người dùng sẽ sử dụng Base64.getEncoder().encode(...).

+0

* "Điều thông minh ở đây" * Tôi đã thấy khoảng 4 điều khiến tôi nghĩ - Wow, thật thông minh! 'Tìm hiểu (các) mục' của tôi trong ngày. :) –

+0

Cảm ơn bạn đã trả lời chi tiết! Tôi sẽ thử. – Mike

+0

Làm việc như một sự quyến rũ! Cảm ơn nhiều. Nghiên cứu câu trả lời của bạn đã đặt ra một câu hỏi. Tôi tìm thấy một số tham chiếu đến thực tế là thuộc tính java.protocol.handler.pkgs được JVM đọc khi khởi động, do đó các trình xử lý phải được cung cấp trên dòng lệnh (ví dụ: java -Djava.protocol.handler.pkgs = xxxxxx). Nhưng tôi chỉ đơn giản gọi là test1.data.Handler.install() trong phương thức main() của tôi và nó hoạt động. Hành vi có thay đổi trong các phiên bản Java mới hơn không, hoặc tôi có đọc sai nó không? – Mike

Các vấn đề liên quan