Я делаю приложение чата Java. Я уже сделал основы, и все работает нормально. Теперь я хотел добавить возможность менять шрифты и вставлять смайлики. Я также хотел добавить небольшую метку времени рядом с каждым сообщением.
Для метки времени очевидно, что нам нужно использовать таблицы для хорошего выравнивания. Но не мог найти простого решения, чтобы иметь их. Немного погуглив,
- 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.
- Кроме того, размер шрифта является проблемой, так как его диапазон составляет 1-7, и я хотел бы иметь нормальные диапазоны, как в MS Word.
- Наконец, мои знания HTML очень базовые, и в наши дни HTML используется с CCS, о которой я ничего не знаю. Большинство веб-сайтов не рекомендуют использовать HTML-теги, поскольку последняя версия их даже не поддерживает. Это создаст проблему для моего приложения? Если это так, я хотел бы использовать другой метод для достижения вышеизложенного - не хочу использовать устаревшие вещи, даже если это для простого проекта колледжа.
КОД: я создал эти общие переменные:
HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument HTMLdoc = new HTMLDocument();
jTextPane1.setEditorKit(kit);
jTextPane1.setDocument(HTMLdoc);
В JButton у меня есть следующий код для вставки текста/чата:
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);
Метод addSmiles просто перебирает каждое слово и заменяет «:)» тегом img.
Чтобы сохранить/перезагрузить беседу, я использовал этот базовый код:
kit.read(new FileReader("asd.htm"), HTMLdoc, 0);
kit.write(new FileWriter("asd.htm"), HTMLdoc, 0, HTMLdoc.getLength());
Пишет нормально, а чтение выдает ошибку.
java.lang.RuntimeException: Must insert new content into body element
Я чувствую, что неправильно использовал метод insertHTML. Может ли кто-нибудь дать мне хорошую ссылку, которая показывает его использование? Особенно последние три аргумента (pop & pushDepth, insertTag) с примерами. Документы Oracle, не объясняйте это к моему удовольствию. :/
- Я использовал стандартный StyledDocuemnt с SimpleAttributeSet для поддержки нескольких шрифтов. Я использовал RTFEditorKit и успешно сохранил/загрузил чаты. Но не мог вставить смайлики и таблицу для временных меток. Я наткнулся на одну ссылку здесь. Он пытается рисовать таблицы в JTextPane. Было трудно понять, но если вы, ребята, порекомендуете это, я серьезно рассмотрю это.
Надеюсь, я объяснил свою проблему прилично и не слишком долго! :D С нетерпением жду ваших ответов.
--------- РЕДАКТИРОВАТЬ :---------
Я немного изменил свой код:
Инициализации:
HTMLEditorKit kit = new HTMLEditorKit();
jTextPane1.setEditorKit(kit);
HTMLDocument HTMLdoc = (HTMLDocument) jTextPane1.getDocument();
HTMLdoc.putProperty("IgnoreCharsetDirective", true);
Я вставляю в документ начальные строки с соответствующим 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);
В любом чате я использую ту же строку HTML, что и раньше, просто изменил метод, используемый для вставки:
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>");
Наконец, чтобы сохранить чат:
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("asd"), "UTF-8");
kit.write(out, HTMLdoc, 0, HTMLdoc.getLength());
out.close();
До этого момента все работает прекрасно. Когда я открываю файл «asd», он правильно отображает HTML. Я даже могу открыть его в браузере и правильно просмотреть данные.
Чтобы получить данные и вставить их обратно в JTextPane/Document:
InputStreamReader in = new InputStreamReader(new FileInputStream("asd"), "UTF-8");
kit.read(in, HTMLdoc, 0);
in.close();
В этом случае я получаю сообщение об ошибке:
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)
Где строка 157 указывает на инструкцию kit.read. Может ли кто-нибудь сказать мне, что я делаю неправильно здесь?
ПОВТОРИТЬ ИЗМЕНЕНИЕ---------------------------------------
Я понял свою ошибку :). Пришлось очистить документ перед чтением: HTMLdoc.remove(0, HTMLdoc.getLength());
Теперь все работает!!