-
Bug
-
Resolution: Fixed
-
P4
-
1.4.0, 1.4.1
-
b24
-
x86
-
windows_nt
Name: ddT132432 Date: 01/17/2002
C:\>java -version
java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1
Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)
This also happens on 1.4-Beta3
I am trying to read(inputStream, object) into a JEditorPane, I have a string of
html (for what it is worth I am displaying multipart alternative email, so I
won't have url). If the string of HTML triggers a ChangedCharSetException
(caught in JEditorPane.read()) and the HTMLDocument passes in does not have an
associated url, a NullPointerException is thrown.
The following code shows this problem, and the workaround. If I extend
JEditorPane and reimplemnt the read method it can make it work.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import java.io.*;
public class PaneTest extends JDialog {
public String htmlString = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0
Transitional//EN\"><HTML><HEAD><META http-equiv=Content-Type
content=\"text/html; charset=iso-8859-1\"><META content=\"MSHTML
5.50.4522.1800\" name=GENERATOR><STYLE></STYLE></HEAD><BODY
bgColor=#ffffff><DIV><FONT size=4>Thank you for the quote you sent
reguarding account #99999999999999. I just have a couple of questions.
Please let me know. </FONT></DIV><DIV><FONT size=4>
Thank you, we look forward to hearing from you.</FONT></DIV></BODY></HTML>";
public JEditorPane pane = new JEditorPane();
public FixedJEditorPane fixedPane = new FixedJEditorPane();
public PaneTest() {
super();
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
JPanel jp = new JPanel(new BorderLayout(10,10));
pane.setPreferredSize(new Dimension(200,200));
pane.setBorder(BorderFactory.createLineBorder(Color.black));
fixedPane.setPreferredSize(new Dimension(200,200));
fixedPane.setBorder(BorderFactory.createLineBorder(Color.black));
jp.add(pane,BorderLayout.WEST);
jp.add(fixedPane,BorderLayout.EAST);
getContentPane().add(jp);
updateJEditorPane();
updateFIXEDJEditorPane();
}
public void updateJEditorPane (){
try {
HTMLEditorKit myKit =
(HTMLEditorKit)pane.getEditorKitForContentType("text/html");
pane.setEditorKit(myKit);
HTMLDocument inputDoc = (HTMLDocument)
myKit.createDefaultDocument();
pane.read(new
ByteArrayInputStream(htmlString.getBytes()),(Object)inputDoc);
}
catch (Exception ex) {
pane.setText("Error");
ex.printStackTrace();
}
}
public void updateFIXEDJEditorPane (){
try {
HTMLEditorKit myKit = (HTMLEditorKit)fixedPane.getEditorKitForContentType("text/html");
fixedPane.setEditorKit(myKit);
HTMLDocument inputDoc = (HTMLDocument)myKit.createDefaultDocument();
fixedPane.read(new ByteArrayInputStream(htmlString.getBytes()),(Object)inputDoc);
}
catch (Exception ex) {
fixedPane.setText("Error");
ex.printStackTrace();
}
}
public class FixedJEditorPane extends JEditorPane{
public FixedJEditorPane(){
super();
}
public void read(InputStream in, Object desc) throws IOException {
EditorKit kit = this.getEditorKit();
if (desc instanceof HTMLDocument &&
kit instanceof HTMLEditorKit) {
HTMLDocument hdoc = (HTMLDocument) desc;
setDocument(hdoc);
read(in, hdoc);
} else {
String charset = (String) getClientProperty("charset");
Reader r = (charset != null) ? new InputStreamReader(in, charset):
new InputStreamReader(in);
super.read(r, desc);
}
}
void read(InputStream in, Document doc) throws IOException {
try {
System.out.println("my pane");
EditorKit kit = this.getEditorKit();
String charset = (String) getClientProperty("charset");
Reader r = (charset != null) ? new InputStreamReader(in, charset) :
new InputStreamReader(in);
kit.read(r, doc, 0);
} catch (BadLocationException e) {
throw new IOException(e.getMessage());
} catch (ChangedCharSetException e1) {
String charSetSpec = e1.getCharSetSpec();
if (e1.keyEqualsCharSet()) {
putClientProperty("charset", charSetSpec);
} else {
setCharsetFromContentTypeParameters(charSetSpec);
}
//++++++++++++++++++++
// change this
//
// in.close();
// URL url = (URL)doc.getProperty(Document.StreamDescriptionProperty);
// URLConnection conn = url.openConnection();
// in = conn.getInputStream();
in.reset();
//++++++++++++++++++++
try {
doc.remove(0, doc.getLength());
} catch (BadLocationException e) {}
doc.putProperty("IgnoreCharsetDirective", new Boolean(true));
read(in, doc);
}
}
private void setCharsetFromContentTypeParameters(String paramlist) {
String charset = null;
try {
// paramlist is handed to us with a leading ';', strip it.
int semi = paramlist.indexOf(';');
if (semi > -1 && semi < paramlist.length()-1) {
paramlist = paramlist.substring(semi + 1);
}
if (paramlist.length() > 0) {
// parse the paramlist into attr-value pairs & get the
// charset pair's value
HeaderParser hdrParser = new HeaderParser(paramlist);
charset = hdrParser.findValue("charset");
if (charset != null) {
putClientProperty("charset", charset);
}
}
}
catch (IndexOutOfBoundsException e) {
// malformed parameter list, use charset we have
}
catch (NullPointerException e) {
// malformed parameter list, use charset we have
}
catch (Exception e) {
// malformed parameter list, use charset we have; but complain
System.err.println("JEditorPane.getCharsetFromContentTypeParametersfailed
on: " + paramlist);
e.printStackTrace();
}
}
} // end of corrected jeditorpane
static class HeaderParser {
/* table of key/val pairs - maxes out at 10!!!!*/
String raw;
String[][] tab;
public HeaderParser(String raw) {
this.raw = raw;
tab = new String[10][2];
parse();
}
private void parse() {
if (raw != null) {
raw = raw.trim();
char[] ca = raw.toCharArray();
int beg = 0, end = 0, i = 0;
boolean inKey = true;
boolean inQuote = false;
int len = ca.length;
while (end < len) {
char c = ca[end];
if (c == '=') { // end of a key
tab[i][0] = new String(ca, beg, end-beg).toLowerCase();
inKey = false;
end++;
beg = end;
} else if (c == '\"') {
if (inQuote) {
tab[i++][1]= new String(ca, beg, end-beg);
inQuote=false;
do {
end++;
} while (end < len && (ca[end] == ' ' || ca[end] == ','));
inKey=true;
beg=end;
} else {
inQuote=true;
end++;
beg=end;
}
} else if (c == ' ' || c == ',') { // end key/val, of
//whatever we're in
if (inQuote) {
end++;
continue;
} else if (inKey) {
tab[i++][0] = (new String(ca, beg,end-beg)).toLowerCase();
} else {
tab[i++][1] = (new String(ca, beg, end-beg));
}
while (end < len && (ca[end] == ' ' || ca[end] == ',')) {
end++;
}
inKey = true;
beg = end;
} else {
end++;
}
}
// get last key/val, if any
if (--end > beg) {
if (!inKey) {
if (ca[end] == '\"') {
tab[i++][1] = (new String(ca, beg, end-beg));
} else {
tab[i++][1] = (new String(ca, beg, end-beg+1));
}
} else {
tab[i][0] = (new String(ca, beg,end-beg+1)).toLowerCase();
}
} else if (end == beg) {
if (!inKey) {
if (ca[end] == '\"') {
tab[i++][1] = String.valueOf(ca[end-1]);
} else {
tab[i++][1] = String.valueOf(ca[end]);
}
} else {
tab[i][0] = String.valueOf(ca[end]).toLowerCase();
}
}
}
}
public String findKey(int i) {
if (i < 0 || i > 10)
return null;
return tab[i][0];
}
public String findValue(int i) {
if (i < 0 || i > 10)
return null;
return tab[i][1];
}
public String findValue(String key) {
return findValue(key, null);
}
public String findValue(String k, String Default) {
if (k == null)
return Default;
k.toLowerCase();
for (int i = 0; i < 10; ++i) {
if (tab[i][0] == null) {
return Default;
} else if (k.equals(tab[i][0])) {
return tab[i][1];
}
}
return Default;
}
public int findInt(String k, int Default) {
try {
return Integer.parseInt(findValue(k,String.valueOf(Default)));
} catch (Throwable t) {
return Default;
}
}
}
public static void main(String[] args) {
PaneTest paneTest = new PaneTest();
paneTest.pack();
paneTest.setVisible(true);
}
}
(Review ID: 136901)
======================================================================
- duplicates
-
JDK-4759915 Unexpected ChangedCharSetException in JTextPane
-
- Closed
-