本文是仿微信聊天程序专栏的第四篇文章,主要记录了【主界面】的实现。
界面设计
仿微信聊天程序的主界面总体跟微信的主界面差不多,但是比微信的主界面简单得多,如下图所示:
界面布局
主界面整个界面采用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(); } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~