我正在尝试构建一个使用JTextPane来显示对话的聊天客户端。我在突出显示用户选择的聊天参与者的过去句子时遇到问题。在实现这一点时,我需要坚持使用HTMLDocument,因为一些内容必须是HTML。
最好的想法似乎是为参与对话的每个用户使用不同的命名样式。我的想法是,当需要突出某个人的文本时,我只是更新他的个人风格,他所说的一切都应该通过魔术突出显示。不幸的是,这不起作用。
所以要添加我使用的文字:
public void addMessage(String from, String message){
HTMLDocument doc = (HTMLDocument) textPane.getStyledDocument();
if(doc != null){
try {
String stylename = "from_" + from;
if(textPane.getStyle(stylename) == null){
LOG.debug("Did not find style. Adding new: " + stylename);
Style nameStyle = textPane.addStyle(stylename, null);
StyleConstants.setForeground(nameStyle, Color.black);
StyleConstants.setBold(nameStyle, true);
}else{
LOG.debug("Found existing style: " + textPane.getStyle(stylename));
}
doc.insertString(doc.getLength(), from + ": ", textPane.getStyle(stylename));
doc.insertString(doc.getLength(), message + "\n", null);
} catch (BadLocationException ble) {
LOG.error("Could not insert text to tab");
}
}
}
到目前为止一直都很好......文本按照我的意愿显示在textPane中。但是当我尝试在将来某个时候更新样式表并调用时:
public void highlight(String name, boolean highlight){
Style fromStyle = textPane.getStyle("from_" + name);
if(fromStyle != null){
LOG.debug("found style, changing color");
StyleConstants.setForeground(fromStyle, Color.red);
}else{
LOG.debug("fromStyle was NULL");
}
}
..我可以看到找到样式并且我的代码被执行 - 但屏幕上没有任何变化。
我想问一下您是否有任何关于我如何尝试解决此问题的建议。有没有办法让这个工作与命名样式或我应采取一些完全不同的方法?
谢谢
答案 0 :(得分:1)
您刚修改了Style
对象,仍然需要使用setCharacterAttributes
应用修改后的Style
。
答案 1 :(得分:1)
我已经创建了一个适合我的解决方案。我会在这里发布一个功能正常的测试用例。我最终得到了一个解决方案,我在StyleSheet中更新了样式类,然后为每个段落元素调用了htmlDocument.setParagraphAttributes。
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
public class StyleChangeTest extends JFrame {
public final static int APP_WIDTH = 640;
public final static int APP_HEIGHT = 400;
public JTextPane jTextPane;
public StyleSheet styleSheet;
public HTMLDocument htmlDocument;
public HTMLEditorKit htmlEditorKit;
public Element bodyElement;
public static StyleChangeTest jTextPaneApp;
public static void main(String[] args) throws InterruptedException, InvocationTargetException{
EventQueue.invokeAndWait(new Runnable() {
public void run() {
try {
jTextPaneApp = new StyleChangeTest();
jTextPaneApp.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
System.out.println("Started");
Thread.currentThread().sleep(1000);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
jTextPaneApp.change();
} catch (Exception e) {
e.printStackTrace();
}
}
});
System.out.println("Finished");
}
public StyleChangeTest(){
setSize(APP_WIDTH, APP_HEIGHT);
setResizable(false);
setTitle("JTextPane App");
styleSheet = new StyleSheet();
styleSheet.addRule(".someclass1 {color: blue;}");
styleSheet.addRule(".someclass2 {color: green;}");
htmlEditorKit = new HTMLEditorKit();
htmlEditorKit.setStyleSheet(styleSheet);
htmlDocument = (HTMLDocument) htmlEditorKit.createDefaultDocument();
jTextPane = new JTextPane();
jTextPane.setEditorKit(htmlEditorKit);
jTextPane.setDocument(htmlDocument);
try {
Element htmlElement = htmlDocument.getRootElements()[0];
bodyElement = htmlElement.getElement(0);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(jTextPane, BorderLayout.CENTER);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
addContent("<font class=someclass1>test 1</font><br>");
addContent("<font class=someclass2>test 2</font><br>");
} catch (Exception e) {
e.printStackTrace();
}
}
public void reapplyStyles() {
System.out.println("Reformating...");
Element sectionElem = bodyElement.getElement(bodyElement.getElementCount() - 1);
int paraCount = sectionElem.getElementCount();
for (int i=0; i<paraCount; i++) {
Element paraElem = sectionElem.getElement(i);
//System.out.println("\tParagraph: " + (i+1) + " - " + paraElem);
int rangeStart = paraElem.getStartOffset();
int rangeEnd = paraElem.getEndOffset();
htmlDocument.setParagraphAttributes(rangeStart, rangeEnd-rangeStart, paraElem.getAttributes(), true);
}
}
public void change() throws BadLocationException, IOException{
styleSheet = htmlEditorKit.getStyleSheet();
styleSheet.addRule(".someclass1 {color: red;}");
reapplyStyles();
addContent("<font class=someclass1>test 3</font><br>");
}
private void addContent(String content) throws BadLocationException, IOException{
Element contentElement = bodyElement.getElement(bodyElement.getElementCount() - 1);
StringBuffer sbHtml = new StringBuffer();
sbHtml.append("<font class=someclass>" + content + "</font><br>");
htmlDocument.insertBeforeEnd(contentElement, sbHtml.toString());
}
}