JMonkeyEngine3——NiftyGui Chat Control

Chat Control

Nifty 聊天控件演示了如何组合多个控件以形成一个新控件。聊天控件由 Nifty 用户 ractoc 创建,代表一个典型的聊天窗口。有一个可滚动的聊天历史记录区域、一个聊天成员区域(在控件中称为玩家),以及一个文本字段和一个用于发送消息的按钮。

聊天控件应该与某种形式的网络协议一起使用来发送消息(这不包括在内)。

当用户输入新文本行时,将生成 Eventbus 事件。单个聊天行也可以包含可选图标。

chatControl分为三个面板:

  1. 消息面板
  2. 用户列表面板
  3. 聊天输入框

如下所示:

常用属性

Name Datatype Default Description
lines Integer 10 无需滚动即可在聊天历史区域看到的最大行数。此参数直接影响控件的高度。
sendLabel String "Send" 发送按钮文本。
chatLineIconWidth SizeValue 25px 每个聊天行都由一个图标和一段文本组成。chatLineIconWidth 参数决定聊天行图标的宽度。
chatLineIconHeight SizeValue 25px 每个聊天行都由一个图标和一段文本组成。chatLineIconHeight 参数决定聊天行图标的高度。
chatLineHeight SizeValue 25px 每个聊天行都由一个图标和一个文本组成。chatLineHeight 参数决定聊天行的高度。

EventBus Notification

当用户输入新行文本时,ChatTextSendEvent 会在 EventBus 上发布。

Java Builder 示例

1 // create the chat control allocating room to display 14 lines and change the send button text to "Send Message"
2 control(new ChatBuilder("chatId", 14) {{
3   sendLabel("Send Message");
4 }});

XML 示例

1 // create a chat control
2 <control id="chatId" name="nifty-chat" width="100%" height="100%" lines="14" sendLabel="Send Message" />

参考

https://github.com/nifty-gui/nifty-gui/wiki/Chat-Control

案例

创建一个NiftyGuiChatControl.xml,内容如下:

 1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 2 <nifty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://nifty-gui.lessvoid.com/nifty-gui" xsi:schemaLocation="https://gitee.com/JoyClm/nifty-gui/raw/1.4/nifty-core/src/main/resources/nifty.xsd https://gitee.com/JoyClm/nifty-gui/raw/1.4/nifty-core/src/main/resources/nifty.xsd">
 3     <useControls filename="nifty-default-controls.xml"/>
 4     <useStyles filename="nifty-default-styles.xml"/>
 5     <screen id="GScreen0" controller="mygame.NiftyGuiChatControl">
 6         <layer id="GLayer0" childLayout="center">
 7             <panel id="GPanel0" childLayout="center" width="80%" x="131px" y="220px" style="nifty-panel-simple" height="200px">
 8                 <control name="nifty-chat" id="chat0" width="*" x="8" y="9" lines="5" height="170px"/>
 9             </panel>
10         </layer>
11     </screen>
12 </nifty>

然后转到NiftyGuiChatControl.java代码,如下:

 1 import com.jme3.app.SimpleApplication;
 2 import com.jme3.math.ColorRGBA;
 3 import com.jme3.niftygui.NiftyJmeDisplay;
 4 import de.lessvoid.nifty.Nifty;
 5 import de.lessvoid.nifty.NiftyEventSubscriber;
 6 import de.lessvoid.nifty.controls.ChatTextSendEvent;
 7 import de.lessvoid.nifty.controls.chatcontrol.ChatControl;
 8 import de.lessvoid.nifty.render.NiftyImage;
 9 import de.lessvoid.nifty.screen.Screen;
10 import de.lessvoid.nifty.screen.ScreenController;
11 
12 /**
13  * @date 2024年7月17日15点36分
14  * @author JohnKkk
15  */
16 public class NiftyGuiChatControl extends SimpleApplication implements ScreenController{
17 
18     private Nifty m_Nifty;
19     private NiftyImage m_JohnKkkIcon;
20     private NiftyImage m_EdIcon;
21     
22     public static void main(String[] args) {
23         NiftyGuiChatControl niftyGuiLabel = new NiftyGuiChatControl();
24         niftyGuiLabel.start();
25     }
26     
27     @Override
28     public void simpleInitApp() {
29         // 设置默认背景色
30         getViewPort().setBackgroundColor(ColorRGBA.DarkGray);
31         
32         // 初始化Nifty
33         NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
34                 assetManager,
35                 inputManager,
36                 audioRenderer,
37                 guiViewPort);
38         m_Nifty = niftyDisplay.getNifty();
39         // 将NiftyGUI显示对象添加到JME3中
40         guiViewPort.addProcessor(niftyDisplay);
41         
42         m_Nifty.fromXml("Interface/NiftyGuiChatControl.xml", "GScreen0");
43         
44         // 禁用flyCam并显示鼠标
45         flyCam.setEnabled(false);
46         inputManager.setCursorVisible(true);
47     }
48     
49     @NiftyEventSubscriber(id="chat0")
50     public final void chatEvent(final String id, final ChatTextSendEvent chatTextSendEvent){
51         // 我们这边假设操作的client就是JohnKkk,所以输入消息后在这里插入到聊天窗口显示
52         chatTextSendEvent.getChatControl().receivedChatLine("JohnKkk:" + chatTextSendEvent.getText(), m_JohnKkkIcon);
53         // 同时往服务器发送这条JohnKkk的消息包...
54     }
55     
56     @Override
57     public void bind(Nifty nifty, Screen screen) {
58         ChatControl chatControl = screen.findControl("chat0", ChatControl.class);
59         // 添加两个用户到聊天用户面板
60         m_JohnKkkIcon = nifty.getRenderEngine().createImage(screen, "Textures/chat-icon-user.png", false);
61         chatControl.addPlayer("JohnKkk", m_JohnKkkIcon);
62         m_EdIcon = nifty.getRenderEngine().createImage(screen, "Textures/chat-icon-ninja.png", false);
63         chatControl.addPlayer("Ed", m_EdIcon);
64         
65         // 这里模拟从服务器收到Ed的消息,往聊天窗口插入Ed的消息
66         chatControl.receivedChatLine("Ed:Hello,John?", m_EdIcon);
67     }
68 
69     @Override
70     public void onStartScreen() {
71     }
72 
73     @Override
74     public void onEndScreen() {
75     }
76     
77 }

注意第58行,我们获取了ChatControl对象,这里需要解释一点,假设我们正在开发一个qq通讯软件,通过Socket登录了两个用户,那么我们就需要通过chatControl.addPlayer()来添加用户到聊天窗口的用户列表面板中,同理当某个用户离开时,我们可以通过chatControl.removePlayer()来移除对应用户从而用户展示面板不再显示该用户,代码如第60~63行,这里模拟了两个用户进了聊天;

当我们需要往聊天消息面板显示用户的消息,比如我们从服务器收到一条来自Ed用户的消息,我们可以通过第66行chatControl.receivedChatLine()来显示Ed的消息(第二个参数是显示头像),而当我们往聊天输入框输入消息并回车时,默认是不会显示出来的,因为我们不知道当前操作的是哪个用户,所以我们通过EventBus订阅,并假定当前操作的是JohnKkk这个用户,所以通过第52行(同样使用receivedChatLine()方法)往聊天消息面板插入JohnKkk的消息。

执行JME3程序,结果如下:

 当消息过长时,可以通过滚动鼠标滚轮来查看消息。

消息面板可以满足基本的聊天框架需求,可以通过修改样式来完成更好的消息面板,也可以通过自定义组件来制作自己的高级消息面板。

posted @ 2024-07-17 15:29  JhonKkk  阅读(53)  评论(0)    收藏  举报