如何使用 JTextPane 在客户端和服务器之间进行颜色编码的聊天?

How to make color coded chats between client and server using JTextPane?

我有一个简单的客户端-服务器聊天系统,我想对它进行颜色编码,以便来自客户端的消息和来自服务器的消息以不同的颜色显示。我有以下内容:

       try {
            String messageout="";
           messageout=jTextField1.getText();
           jTextField1.setText("");

        appendToPane(jTextPane1,"\n"+"client: "+messageout,Color.BLUE);
        dos.writeUTF(messageout);
    } catch (IOException ex) {
        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
    }

dos为数据输出流

和:

private void appendToPane(JTextPane tp, String msg, Color c)
{
    StyleContext sc = StyleContext.getDefaultStyleContext();
    AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);

    aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
    aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);

    int len =tp.getDocument().getLength();
    tp.setCaretPosition(len);
    tp.setCharacterAttributes(aset, false);
    tp.replaceSelection(msg);
    tp.setText(tp.getText()+msg);

}

服务器具有将颜色设置为绿色而不是蓝色的类似代码。问题是我希望客户端消息显示为蓝色,服务器消息显示为绿色,而目前,在客户端中,所有消息都显示为蓝色,而在服务器中,所有消息都显示为绿色.我想要以下内容: 'client:blaablaa(in blue)' 'server:blaablaa(in green)'

有人能帮忙吗?

编辑:客户端从服务器读取(颜色已删除,直到我找到真正的解决方案)

        s=new Socket("localhost",1000);
        dis=new DataInputStream(s.getInputStream());
        dos=new DataOutputStream(s.getOutputStream());
        while(!msgin.equals("bye")){
            msgin=dis.readUTF();
           jTextPane1.setText(jTextPane1.getText()+"\n"+"server:"+msgin);

我想在最后一行代码中添加颜色上下文。

EdIT - 使用 appendToPane 而不是 setText(没有显示,当我从 appendToPane 中删除最后一个 setText 时:

    ss = new ServerSocket(1000);
    s = ss.accept();
    dis=new DataInputStream(s.getInputStream());
    dos=new DataOutputStream(s.getOutputStream());
    while(!msgin.equals("bye")){
        msgin=dis.readUTF();
         appendToPane(jTextPane1,"\n"+"client: "+msgin,Color.RED); 

并且:

        String messageout="";
        messageout=jTextField1.getText();


    jTextField1.setText("");
     appendToPane(jTextPane1,"\n"+"server:"+messageout,Color.BLUE);
     //jTextPane1.setText(jTextPane1.getText()+"\n"+"server:"+messageout);
        dos.writeUTF(messageout);

您可以 embed basic HTML 使用您的 Swing 组件。

b1 = new JButton("<html><center><b><u>D</u>isable</b><br>"
                 + "<font color=#ffffdd>middle button</font>",
                 leftButtonIcon);
Font font = b1.getFont().deriveFont(Font.PLAIN);
b1.setFont(font);
...
b2 = new JButton("middle button", middleButtonIcon);
b2.setFont(font);
b2.setForeground(new Color(0xffffdd));
...
b3 = new JButton("<html><center><b><u>E</u>nable</b><br>"
                 + "<font color=#ffffdd>middle button</font>",
                 rightButtonIcon);
b3.setFont(font);

代码取自链接页面。

如果您的 TextPane 设置为不可编辑(例如,您在某处有一个 tp.setEditable(false),则您不能使用编辑它的操作。方法 replaceSelection() 是一种编辑方法,因此,它没有做任何事情,只是发出哔哔声。

因此您选择了替换文本窗格的整个文本,这不被视为一种编辑方法。但是,你失去了造型。

在 non-editable 文本窗格中,您应该添加到支持文本窗格的文档中,而不是执行任何一个操作。因此,例如,像这样更改 appendToPane

private static void appendToPane(JTextPane tp, String msg, Color c)
{
    StyleContext sc = StyleContext.getDefaultStyleContext();
    AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);

    aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
    aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);

    // Get the TextPane's Document
    Document doc = tp.getDocument();
    int len = doc.getLength();
    try {
        doc.insertString(len, msg, aset);  // Use the `insertString` method of the document.
    } catch (BadLocationException e) {
        // Nothing. Using the doc length makes sure this exception isn't thrown
    }

}