2012-02-22 2 views
10

Java JEditorPane에 인 라인의 이미지를 표시하려고하고 있습니다. 아래의 코드는 Firefox에서 이미지를 올바르게 표시하는 HTML 컨텐트를 사용하지만 JEditorPane에서는 표시하지 않습니다. 어떤 아이디어? 감사.인 라인의 이미지를 가지는 JEditorPane

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();} 
} 

답변

15

"data :"에 대한 프로토콜 처리기를 추가해야 URL/URLConnection을 열 수 있습니다. 또는 클래스 경로 자원에 대한 일부 프로토콜 핸들러 "resource :"를 작성할 수 있습니다.

Handler (고정 된 이름 규칙!) 등급의 data 패키지가 필요합니다. 이것은 "data :"의 팩토리 클래스가되어 URLConnection을 리턴합니다. 이를 위해 DataConnection을 만듭니다.

프로토콜 처리기 설치는 System.setProperty를 통해 수행 할 수 있습니다. 여기서는 일반적인 방법으로이를 수행하기 위해 Handler.install();을 제공했습니다.

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); 
    } 

} 

여기 영리한 것은 표준 Java SE에 DatatypeConverter의 Base64로 디코딩을 사용하는 것입니다

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); 
     } 
    } 
} 

는 URLConnection의는 바이트 InputStream를 제공합니다.


P.S.

요즘 사람은 Base64.getEncoder().encode(...)을 사용합니다.

+0

* "여기 영리한 것"* 생각하게 만든 약 4 가지를 보았습니다. - 와우, 영리 하네! 오늘의 'learn item (s)'. :) –

+0

자세한 답변 해 주셔서 감사합니다! 나는 이것을 시도 할 것이다. – Mike

+0

매력처럼 일했습니다! 많은 감사합니다. 당신의 대답을 조사해 보면 하나의 질문이 제기되었습니다. java.protocol.handler.pkgs 등록 정보가 시작시 JVM에 의해 읽혀 지므로 처리기가 명령 줄 (예 : java -Djava.protocol.handler.pkgs = xxxxxx)에 제공되어야한다는 사실에 대한 여러 참조를 발견했습니다. 하지만 필자는 main() 메서드에서 test1.data.Handler.install()을 호출하고 작동했습니다. 새 버전의 Java에서 동작이 변경 되었습니까? 아니면 단순히 잘못 읽었습니까? – Mike