首页 > 编程语言 >仿微信聊天程序 - 04. 主界面

仿微信聊天程序 - 04. 主界面

时间:2023-07-16 13:44:48浏览次数:41  
标签:界面 04 fx void event FXContext 仿微信 public

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

界面设计

仿微信聊天程序的主界面总体跟微信的主界面差不多,但是比微信的主界面简单得多,如下图所示:

界面布局

主界面整个界面采用HBox布局,分为左中右三个部分,最左边是菜单栏,中间是联系人列表或对话信息列表,最右边是聊天窗口或设置信息窗口,完整的fxml如下:

<HBox prefHeight="640.0"
      prefWidth="860.0" stylesheets="@MainController.css" xmlns:fx="http://javafx.com/fxml"
      fx:controller="michong.javafx.wx.view.main.MainController">

    <children>
        <VBox alignment="CENTER" prefWidth="64.0" spacing="30.0" styleClass="left-menu">
            <children>
                <ImageView fx:id="avatarImageView" fitWidth="40" fitHeight="40"/>
                <ToggleButton fx:id="chatButton" selected="true" styleClass="chat-button"
                              onAction="#onChatClick"/>
                <ToggleButton fx:id="contactsButton" styleClass="contacts-button" onAction="#onContactsClick"/>
                <Pane VBox.vgrow="ALWAYS"/>
                <Button styleClass="setting-button"/>
            </children>
            <padding>
                <Insets bottom="20.0" top="20.0"/>
            </padding>
        </VBox>
        <VBox fx:id="listVBox" prefWidth="250.0" alignment="CENTER"/>
        <VBox HBox.hgrow="ALWAYS">
            <children>
                <HBox prefHeight="30.0" styleClass="top-menu">
                    <children>
                        <Pane HBox.hgrow="ALWAYS"/>
                        <Button onAction="#onMinimizeClick" styleClass="minimize-button"/>
                        <Button onAction="#onExitClick" styleClass="exit-button"/>
                    </children>
                </HBox>
                <Pane fx:id="mainPane" VBox.vgrow="ALWAYS">
                </Pane>
            </children>
        </VBox>
    </children>
</HBox>

样式优化

在界面设计的图中,可以看到主界面针对一些按钮进行了样式优化,采用图片代替原始的按钮样式,具体的css样式如下:

.contacts-button {
  -fx-cursor: hand;
  -fx-background-color: transparent;
  -fx-border-color: transparent;
  -fx-pref-width: 32px;
  -fx-pref-height: 32px;
  -fx-background-size: 32px 32px;
  -fx-background-image: url("/icon/contacts_0.png");
}
.contacts-button:selected {
  -fx-background-image: url("/icon/contacts_1.png");
}

事件处理

主界面的事件主要涉及两个部分,菜单的切换以及最小化和关闭事件处理,具体的处理代码如下:

public class MainController implements Initializable {

    public ImageView avatarImageView;
    public ToggleButton chatButton;
    public ToggleButton contactsButton;
    public VBox listVBox;
    public Pane mainPane;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        initializeUI();
        initializeEvent();
    }

    void initializeUI() {
        ToggleGroup leftMenuToggleGroup = new ToggleGroup();
        chatButton.setToggleGroup(leftMenuToggleGroup);
        contactsButton.setToggleGroup(leftMenuToggleGroup);
        onChatClick(null);
    }

    void initializeEvent() {
    }

    public void onChatClick(ActionEvent actionEvent) {
        listVBox.getChildren().clear();
        listVBox.getChildren().add(FXComponent.chatListController());
    }

    public void onContactsClick(ActionEvent actionEvent) {
        listVBox.getChildren().clear();
        listVBox.getChildren().add(FXComponent.contactsListController());
    }

    public void onMinimizeClick(ActionEvent actionEvent) {
        FXContext.getPrimaryStage().setIconified(true);
    }

    public void onExitClick(ActionEvent actionEvent) {
        Optional.ofNullable(FXContext.getPrimaryStage().getOnCloseRequest()).ifPresent(
                e -> e.handle(new WindowEvent(FXContext.getPrimaryStage(), WindowEvent.WINDOW_CLOSE_REQUEST)));
        FXContext.getPrimaryStage().close();
    }

}

拖动支持

从界面设计图中可以看出,主界面抛弃了JavaFX原始的窗体外壳,自定义了最小化和关闭按钮来实现这些功能,具体的窗体配置如下:

primaryStage.initStyle(StageStyle.TRANSPARENT);

将窗体设置为StageStyle.TRANSPARENT后,需要自己实现窗体的拖动功能:

Parent root = FX.fxml(MainController.class);
FX.drag(primaryStage, root);

其中FX.drag的实现如下:

public static void drag(Stage stage, Parent root) {
    EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
        private double xOffset = 0;
        private double yOffset = 0;

        @Override
        public void handle(MouseEvent event) {
            if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
                xOffset = event.getSceneX();
                yOffset = event.getSceneY();
            } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
                stage.setX(event.getScreenX() - xOffset);
                if (event.getScreenY() - yOffset < 0) {
                    stage.setY(0);
                } else {
                    stage.setY(event.getScreenY() - yOffset);
                }
            }
        }
    };
    root.setOnMousePressed(eventHandler);
    root.setOnMouseDragged(eventHandler);
}

登录流程

调整原来的登录流程,登录成功后关闭登录窗口,显示主窗口:

public void onLoginClick(ActionEvent actionEvent) {
    form.getForm().persist();
    if (form.getForm().isValid()) {
        FXContext.getLoginStage().close();
        FXContext.getPrimaryStage().show();
    }
}

标签:界面,04,fx,void,event,FXContext,仿微信,public
From: https://www.cnblogs.com/michong2022/p/17557754.html

相关文章

  • 仿微信聊天程序 - 05. 聊天列表
    本文是仿微信聊天程序专栏的第五篇文章,主要记录了【聊天列表】的界面实现。界面设计聊天列表在主界面左边,主要显示最近的聊天记录,以及添加好友的信息等,总体界面设计如下:界面布局聊天列表的布局分为两部,列表布局和列表中的每一行的布局,其中列表布局的完整fxml如下:<HBoxprefH......
  • 仿微信聊天程序 - 07. 好友信息
    本文是仿微信聊天程序专栏的第七篇文章,主要记录了【好友信息】的界面实现。界面设计这里的好友信息界面没有处理复杂的功能,仅仅显示好友信息,支持在此界面中发起聊天而已,总体的界面设计如下图所示:界面布局好友信息仅仅只是信息展示,布局相对比较简单,这里采用VBox和HBox组合使用......
  • 仿微信聊天程序 - 06. 好友列表
    本文是仿微信聊天程序专栏的第六篇文章,主要记录了【好友列表】的界面实现。界面设计好友列表在主界面左边,界面UI风格跟聊天列表类似,只不过相比聊天列表更加简单,不需要显示聊天信息,时间等,总体界面设计如下:界面布局跟好友列表一样,聊天列表的布局也分为两部,列表布局和列表中的每......
  • 仿微信聊天程序 - 08. 聊天窗口
    本文是仿微信聊天程序专栏的第八篇文章,主要记录了【聊天窗口】的界面实现。界面设计聊天窗口是整个聊天程序的核心控件,比较复杂,大致可以分为上中下三个部分,上面显示用户昵称以及一些操作菜单,中间是聊天内容显示区域,下面的信息发送的区域,总体界面设计如下:界面布局根据界面设计......
  • CVE-2019-11043(PHP远程代码执行漏洞)复现
    一、漏洞介绍1、相关背景在web早期,页面都是以静态页面为主(如:HTML),没有动态页面的说法,所有还没有动态语言(如:PHP、JSP等)后来Ngnix为支持PHP语言就将有出现php页面的请求给PHP相关程序来进行处理,然后将处理后的结果反馈给用户。而解决PHP的相关程序就是cgi协议,有了cgi协议以后......
  • p1104 生日
    这道题目让我学会了sort函数()最后可以添加一个bool类型的cmp函数作为比较条件,其他就比较简单了#include<iostream>#include<algorithm>usingnamespacestd;structmember{stringname;intyear;intmonth;intday;intnum;}oi[105];intn;bo......
  • 力扣 904. 水果成篮 的解法
    分析题目原题如下:你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组fruits表示,其中fruits[i]是第i棵树上的水果种类。你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:你只有两个篮子,并且每个篮子只能装......
  • FeignClient服务端接口404问题
    自定义feignClient,服务端继承client接口,调用出现404异常。问题原因:feignClient接口的实现类上使用@Controller或@RestController的value属性中写入了公共url,导致接口方法404;因为feignClient是根据服务名在注册中心拉取到服务然后路由到feignClient接口的实现类上,跳过了类上的url......
  • ShardingJDBC 04_分库实战
    1创建数据库分别创建两个数据库,并在数据库中创建两个相同的表。这里创建的数据库是:shardingjdbc1,shardingjdbc2并在数据库下创建两张表:orders,order\_infoCREATETABLEorders(idINT(11)NOTNULLAUTO\_INCREMENT,customerVARCHAR(50)NULLDEFAULT'0'COLLATE'utf8mb4\_b......
  • Java学习day04: 方法和数组
    我在B站上大学......