首页 > 编程语言 >仿微信聊天程序 - 08. 聊天窗口

仿微信聊天程序 - 08. 聊天窗口

时间:2023-07-16 13:44:06浏览次数:39  
标签:main fx 08 color 聊天 background 仿微信 button

本文是仿微信聊天程序专栏的第八篇文章,主要记录了【聊天窗口】的界面实现。

界面设计

聊天窗口是整个聊天程序的核心控件,比较复杂,大致可以分为上中下三个部分,上面显示用户昵称以及一些操作菜单,中间是聊天内容显示区域,下面的信息发送的区域,总体界面设计如下:

界面布局

根据界面设计的划分,将整个聊天窗口布局划分为上中下三个部分,中间使用WebView用于显示聊天内容,完整的fxml布局代码如下:

<StackPane prefHeight="610.0"
           prefWidth="546.0" stylesheets="@ChatMainController.css"
           xmlns:fx="http://javafx.com/fxml"
           fx:controller="michong.javafx.wx.view.chat.ChatMainController">
    <SplitPane dividerPositions="0.65" orientation="VERTICAL" styleClass="chat-main-pane">
        <items>
            <VBox>
                <children>
                    <HBox alignment="CENTER" prefHeight="40.0" styleClass="chat-main-menu">
                        <children>
                            <Label fx:id="nicknameLabel" styleClass="name-label"/>
                            <Pane HBox.hgrow="ALWAYS"/>
                            <MenuButton styleClass="chat-main-menu-more">
                                <items>
                                    <MenuItem text="清空" styleClass="chat-main-menu-item" onAction="#onClearClick"/>
                                    <MenuItem text="关闭" styleClass="chat-main-menu-item" onAction="#onCloseClick"/>
                                </items>
                            </MenuButton>
                        </children>
                        <padding>
                            <Insets left="20.0" right="5.0"/>
                        </padding>
                    </HBox>
                    <Separator styleClass="wx-separator"/>
                    <!--<Pane VBox.vgrow="ALWAYS"/>-->
                    <WebView fx:id="chatWebView" VBox.vgrow="ALWAYS"/>
                </children>
            </VBox>
            <VBox alignment="TOP_RIGHT" styleClass="chat-main-input">
                <children>
                    <HBox spacing="10.0">
                        <children>
                            <Button styleClass="face-button"/>
                            <Button styleClass="message-button"/>
                            <Pane HBox.hgrow="ALWAYS"/>
                            <Button styleClass="audio-button"/>
                            <Button styleClass="video-button"/>
                        </children>
                        <padding>
                            <Insets bottom="5.0" left="20.0" right="20.0" top="5.0"/>
                        </padding>
                    </HBox>
                    <StackPane VBox.vgrow="ALWAYS">
                        <children>
                            <TextArea fx:id="messageTextArea" wrapText="true"/>
                        </children>
                        <padding>
                            <Insets bottom="5.0" left="20.0" right="20.0" top="5.0"/>
                        </padding>
                    </StackPane>
                    <ButtonBar prefHeight="80.0">
                        <buttons>
                            <Button styleClass="wx-btn-send" text="发送(S)" onAction="#onSendClick"/>
                        </buttons>
                        <padding>
                            <Insets bottom="5.0" right="20.0" top="5.0"/>
                        </padding>
                    </ButtonBar>
                </children>
            </VBox>
        </items>
    </SplitPane>
</StackPane>

样式美化

跟其他界面一样,JavaFX默认提供的控件样式风格跟聊天程序并不搭,所以聊天窗口仍需要进行样式美化,完整的CSS代码如下:

.chat-main-pane {
  -fx-background-color: #fafafa;
  -fx-border-color: transparent;
}

.chat-main-pane .button {
  -fx-cursor: hand;
  -fx-background-color: transparent;
  -fx-border-color: transparent;
  -fx-pref-width: 30px;
  -fx-pref-height: 30px;
  -fx-background-size: 30px 30px;
}

.chat-main-menu {
  -fx-background-color: #fafafa;
}

.name-label {
  -fx-font-size: 20px;
  -fx-text-fill: black;
}

.chat-main-menu-more {
  -fx-cursor: hand;
  -fx-background-color: transparent;
  -fx-border-color: transparent;
  -fx-pref-width: 44px;
  -fx-pref-height: 30px;
  -fx-background-size: 44px 30px;
  -fx-background-image: url("/icon/more.png");
}
.chat-main-menu-item {
  -fx-padding: 5 0 5 5;
}
.chat-main-menu-item:hover,
.chat-main-menu-item:focused {
  -fx-cursor: hand;
  -fx-background-color: #dbd9d8;
}
.chat-main-menu-item:hover .label,
.chat-main-menu-item:focused .label {
  -fx-text-fill: black;
}

.separator .line {
  -fx-border-color: derive(#eee9e9, 20%);
  -fx-border-width: 1;
}

.chat-main-input > * {
  -fx-background-color: #ffffff;
}

.face-button {
  -fx-background-image: url("/icon/face_0.png");
}
.face-button:hover {
  -fx-background-image: url("/icon/face_1.png");
}
.message-button {
  -fx-background-image: url("/icon/message_0.png");
}
.message-button:hover {
  -fx-background-image: url("/icon/message_1.png");
}
.audio-button {
  -fx-background-image: url("/icon/audio_0.png");
}
.audio-button:hover {
  -fx-background-image: url("/icon/audio_0.png");
}
.video-button {
  -fx-background-image: url("/icon/video_0.png");
}
.video-button:hover {
  -fx-background-image: url("/icon/video_0.png");
}

.send-button {
  -fx-padding: 5px 10px;
  -fx-font-size: 12px;
  -fx-background-color: #f5f5f5;
}
.send-button:hover {
  -fx-cursor: hand;
  -fx-text-fill: #ffffff;
  -fx-background-color: #5cb85c;
  -fx-border-color: #4cae4c;
}
.text-area {
  -fx-font-size: 14px;
  -fx-padding: 0;
  -fx-cursor: default;
  -fx-background-color: #ffffff;
}
.text-area .content {
  -fx-cursor: text;
  -fx-background-color: #ffffff;
}
.text-area:focused .content {
  -fx-background-color: #ffffff;
}

逻辑控制

调整原来聊天列表的事件控制逻辑,当单击聊天列表项时显示聊天信息界面,这里只是静态显示,动态拉取聊天信息后续功能将继续完善,控制代码如下:

void initializeEvent() {
    chatListView.getSelectionModel().selectedItemProperty().addListener((obj, ov, nv) -> {
        if (Objects.nonNull(nv)) {
            Pane main = FXComponent.mainComponent();
            main.getChildren().clear();
            main.getChildren().add(FXComponent.chatMainComponent(nv.getId()));
        }
    });
}

数据填充

跟好友信息的处理方式类似,这里直接给出Controller的代码:

/**
 * @author michong
 */
public class ChatMainController implements UserDataController {
    public Label nicknameLabel;
    public WebView chatWebView;
    public TextArea messageTextArea;

    private Long contactsId;

    @Override
    public void initialize(Object data) {
        contactsId = (Long) data;
        initializeUI();
        initializeEvent();
        renderDebugData();
    }

    void initializeUI() {
    }

    void initializeEvent() {
    }

    void renderDebugData() {
        nicknameLabel.setText("WxID: " + contactsId);
    }

    public void onClearClick(ActionEvent actionEvent) {
    }

    public void onCloseClick(ActionEvent actionEvent) {
    }

    public void onSendClick(ActionEvent actionEvent) {
    }
}

更多细节,可以查看第7节【好友信息】的实现。

标签:main,fx,08,color,聊天,background,仿微信,button
From: https://www.cnblogs.com/michong2022/p/17557759.html

相关文章

  • abc089 <前缀和>
    题目D-PracticalSkillTest思路计算出所有结点在跳转过程中的前缀和,从而O1查询根据数据范围,实际上不需要二分,直接开相同大小的数组即可(代码中使用二分)代码Code//https://atcoder.jp/contests/abc089/tasks/abc089_d#include<iostream>#include<algorith......
  • abc088 <bfs 最短路>
    题目D-GridRepainting思路bfs找到从起点到终点的最短路,+1(起点),即为至少留下的白色块的个数则答案=总白色块数-(最短路+1)代码Code//https://atcoder.jp/contests/abc088/tasks/abc088_d#include<iostream>#include<algorithm>#include<vector>#incl......
  • abc086d <二维前缀和 同余>
    题目D-Checker思路坐标对2k取余,通过二维前缀和计算满足条件的个数;也可对k取余,参考;代码Code//https://atcoder.jp/contests/abc086/tasks/arc089_b//二维前缀和同余#include<iostream>#include<algorithm>#include<vector>#include<cstring>usi......
  • abc085d <贪心>
    题目D-KatanaThrower思路关键:连续使用ai与投掷bi并无冲突,可先使用ai再投掷bi找到ai中的最大值maxa;首先从大到小使用bi中比maxa大的元素,而后不足h再重复使用maxa(虽然按照先b后a的顺序分析计算,但实际上应是先用a后用b)代码Code//https://atcoder.jp/conte......
  • abc084d <素数筛 前缀和>
    题目D-2017-likeNumber思路筛出数据范围1e5范围内的素数检查每个素数是否为2017-like对1~1e5内的2017-like求前缀和,回答询问总结如果数据范围允许,进行预处理,查表回答询问代码Code//https://atcoder.jp/contests/abc084/tasks/abc084_d#include<iostre......
  • abc083d <思维 贪心>
    题目D-WideFlip思路参考live4m的博客其实全0和全1是无所谓的,只需要全部相同就行了,因为每次操作是令一个>=k区间的翻转,如果是全1,令[1,n]再翻转一次即可.考虑[1,i]已经相同,s[i]!=s[i+1]时如何操作,要使得[1,i+1]相同,要么[1,i]翻转,要么[i+1,n]翻转,为了使k最大,显......
  • abc082d <bitset 状压dp>
    题目D-FTRobot思路动态规划的方式记录每次行动后,机器人在坐标系中所有可能位置通过bitset对状态进行压缩,即每个位置有机器人trueor没有false因为机器人仅按坐标轴方向前进,因而可将xy坐标状态分开存储,进一步降低计算量,也方便使用bitset通过bitset的移位......
  • ASEMI快恢复二极管MUR2080CT参数, MUR2080CT规格
    编辑-ZMUR2080CT参数描述:型号:MUR2080CT最大峰值反向电压(VRRM):800V最大RMS电压(VRMS):430V最大直流阻断电压VR(DC):800V平均整流正向电流(IF):20A非重复峰值浪涌电流(IFSM):150A工作接点温度和储存温度(TJ,Tstg):-55to+150℃最大热阻(RθJC):3℃/W正向电压(VF):2V最大瞬时......
  • ASEMI快恢复二极管MUR2080CTR资料,MUR2080CTR参数
    编辑-ZMUR2080CTR是一种高压、超快恢复整流二极管。它通常用于各种电子应用,如电源、逆变器和电机控制电路。该二极管设计用于处理高压和高频开关,适用于需要快速高效整流的应用。 MUR2080CTR二极管的一个关键特性是其超快的恢复时间。这意味着它可以非常快地从导通状态切换到非......
  • Oracle学习笔记:parallel并行处理 --转载 https://blog.csdn.net/w892824196/article/
    在使用oracel查询时,可以通过并行提高查询速度。例如:select/*+parallel(a,6)*/count(1)fromtable_namea;强行启用并行度来执行当前SQL。加上这个说明之后,可以强行启用Oracle的多线程处理功能,提高效率。但本身启动这个功能,也是要消耗资源与性能的。所有,一般都会在返回记......