Pregunta

I am making a java chat application. I have already made the basics, & its working fine. Now I wanted to add the ability to change fonts & insert smilies. I also wanted to add a little Time stamp next to each message.

For the time stamp, its obvious that we need to use tables for nice alignments. But couldn't find an easy solution to have them. After a bit of googleing,

  • I learned that it can be achieved using HTML. So I tried the HTML Editor Kit & it worked pretty well. Smilies, fonts & time was inserted.
    • However, I also have a requirement to save that chat conversation into a file (for chat history purposes). I know there is a Document behind all this. I tried using its methods to save/load, but having some problems. Code is below.
    • Additionally the font size is a problem, since it's range is 1-7 & I would like having the normal ranges like in MS Word.
    • Lastly, my HTML knowledge is very basic, and these days, HTML is used with CCS which I have no knowledge of. Most websites discourage the use of HTML tags, since the latest version doesn't even support them. Is that going to create a problem for my application? If so, I would like another method to achieve the above - don't want to use deprecated stuff even though this is for a simple college project.

CODE: I created these general variables:

HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument HTMLdoc = new HTMLDocument();
jTextPane1.setEditorKit(kit);
jTextPane1.setDocument(HTMLdoc);

In a JButton, I have the following code to insert text/chat:

kit.insertHTML(HTMLdoc, HTMLdoc.getLength(), "<tr>"
+ "<td width=\"50\" valign=\"top\">NAME:</td>"
+ "<td width=\"250\"><font size=\"3\" face=\"Monospaced\">" + addSmiles(JOptionPane.showInputDialog(null)) + "</font></td>"
+ "<td width=\"100\" valign=\"top\"><font size=\"1\">"
+ new SimpleDateFormat("hh:mm a").format(Calendar.getInstance().getTime()).toString() + "</font></td>"
+ "</tr>", 0, 0, null);

The addSmiles method just goes through each word, & replaces a ':)' with the img tag.

To save/reload the conversation, I used this basic code:

kit.read(new FileReader("asd.htm"), HTMLdoc, 0);
kit.write(new FileWriter("asd.htm"), HTMLdoc, 0, HTMLdoc.getLength());

It writes fine, but read produces an error.

java.lang.RuntimeException: Must insert new content into body element

I feel that I have used the insertHTML method wrongly. Can anybody give me a nice link which shows its usage? Especially the last three arguments (pop & pushDepth, insertTag) with examples. Oracle docs, don't explain it to my satisfaction. :/

  • I have used the standard StyledDocuemnt with SimpleAttributeSet to support multiple fonts. I used the RTFEditorKit & successfully saved/loaded chats. But couldn't insert smilies nor the table for timestamps. I did come across one link here. It tries to draw tables into the JTextPane. Found it tough to understand, but if you guys recommend it, then I will look into it seriously.

I hope I explained my problem decently & not too lengthily! :D Looking forward to your answers.

---------EDIT :---------

I changed my code slightly:

The initializations:

HTMLEditorKit kit = new HTMLEditorKit();
jTextPane1.setEditorKit(kit);
HTMLDocument HTMLdoc = (HTMLDocument) jTextPane1.getDocument();
HTMLdoc.putProperty("IgnoreCharsetDirective", true);

I insert the initial lines into the doc, with appropriate try-catch:

kit.insertHTML(HTMLdoc, 0, "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">", 0, 0, null);
kit.insertHTML(HTMLdoc, HTMLdoc.getLength(), "<table id=\"TBL\"></table>", 0, 0, null);

Any chat, I use the same HTML String as before, just changed the method used to insert:

HTMLdoc.insertBeforeEnd(HTMLdoc.getElement("TBL"), "<tr>"
+ "<td width=\"50\" valign=\"top\">NAME:</td>"
+ "<td width=\"250\"><font size=\"3\" face=\"Monospaced\">" + addSmiles(JOptionPane.showInputDialog(null)) + "</font></td>"
+ "<td width=\"100\" valign=\"top\">" + new SimpleDateFormat("hh:mm a").format(Calendar.getInstance().getTime()).toString() + "</td>"
+ "</tr>");

Finally, to save a chat:

OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("asd"), "UTF-8");
kit.write(out, HTMLdoc, 0, HTMLdoc.getLength());
out.close();

Until this point, everything works beautifully. When I open file "asd", it shows the HTML correctly. I can even open it in a browser & view the data correctly.

To retrieve the data & insert it back into the JTextPane/Document:

InputStreamReader in = new InputStreamReader(new FileInputStream("asd"), "UTF-8");
kit.read(in, HTMLdoc, 0);
in.close();

In this case, I get an error:

Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: Must insert new content into body element-
at javax.swing.text.html.HTMLDocument$HTMLReader.generateEndsSpecsForMidInsert(HTMLDocument.java:2353)
at javax.swing.text.html.HTMLDocument$HTMLReader.<init>(HTMLDocument.java:2300)
at javax.swing.text.html.HTMLDocument$HTMLReader.<init>(HTMLDocument.java:2174)
at javax.swing.text.html.HTMLDocument$HTMLReader.<init>(HTMLDocument.java:2169)
at javax.swing.text.html.HTMLDocument.getReader(HTMLDocument.java:326)
at javax.swing.text.html.HTMLEditorKit.read(HTMLEditorKit.java:260)
at ChatGUI.NewJFrame.jBtnRWActionPerformed(NewJFrame.java:157)

Where line 157 points to the kit.read statement. Can anybody tell me what I am doing wrong here?

EDIT AGAIN------------------------

I realized my mistake :). Had to clear the Document before reading into it: HTMLdoc.remove(0, HTMLdoc.getLength()); Now it works!!

¿Fue útil?

Solución

Here reading the Javadoc is very helpful.

Best to hold the table element somewhere. Then

// Assuming the table has attribute id="TBL":
Element tableElement = htmlDoc.getElement("TBL");
htmlDoc.insertBeforeEnd(tableElement, "<tr>...</tr>");

I would indeed advise to use a StyleSheet which can shorten the HTML. Maybe as <style type="text/css"> in the HTML (for storing).

Smileys can also be done with images; as alt attribute the ":)".

Best use Unicode, UTF-8, not the current operating system encoding.

new InputStreamReader(new FileInputStream(file), "UTF-8")
new OutputStreamWriter(new FileOutputStream(file), "UTF-8")

With an encoding specified in the file:

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top