JMonkeyEngine3——NiftyGui Chat Control
Chat Control

Nifty 聊天控件演示了如何组合多个控件以形成一个新控件。聊天控件由 Nifty 用户 ractoc 创建,代表一个典型的聊天窗口。有一个可滚动的聊天历史记录区域、一个聊天成员区域(在控件中称为玩家),以及一个文本字段和一个用于发送消息的按钮。
聊天控件应该与某种形式的网络协议一起使用来发送消息(这不包括在内)。
当用户输入新文本行时,将生成 Eventbus 事件。单个聊天行也可以包含可选图标。
chatControl分为三个面板:
- 消息面板
- 用户列表面板
- 聊天输入框
如下所示:

常用属性
| 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程序,结果如下:

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

浙公网安备 33010602011771号