JAVA课程设计——聊天室(个人博客)

一、团队博客链接和项目Git地址

团队博客
项目Git地址

二、个人负责的模块

  1. 登录界面
  2. 注册界面
  3. 聊天窗口界面
    黄框为我负责的部分

三、Git提交记录



四、效果展示



五、我负责的关键部分代码

多任务实现实时更新聊天窗口关键代码

class MyScheduledServuce extends ScheduledService<Number>{
    @Override
    protected Task<Number> createTask() {
        int flag=0;
        Task<Number> task = new Task<Number>() {
            @Override
            protected Number call() throws Exception {
                //时间格式转换
                DateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

                    if(textMessageList.size()>1){
                        for(int i =1; i<textMessageList.size();i++){
                            String userName = textMessageList.get(i).getSender();
                            if (ChatStage.getChatViewMap().containsKey(userName)) {
                                GridPane messageBox = new GridPane();
                                Label userLabel = new Label(textMessageList.get(i).getSender()+":");
                                Label timeLabel = new Label(sdf.format(textMessageList.get(i).getTime()));
                                Text messageText = new Text(textMessageList.get(i).getText());
                                messageBox.setHgap(20);
                                messageBox.setVgap(5);
                                messageBox.add(userLabel, 0, 1);
                                messageBox.add(timeLabel, 1, 0);
                                messageBox.add(messageText, 1, 1);

                                ChatStage.getChatViewMap().get(userName).getChildren().add(messageBox);
                            }else{
                                VBox vBox2 = new VBox();
                                GridPane messageBox = new GridPane();
                                Label userLabel = new Label(textMessageList.get(i).getSender()+":");
                                Label timeLabel = new Label(sdf.format(textMessageList.get(i).getTime()));
                                Text messageText = new Text(textMessageList.get(i).getText());
                                messageBox.setHgap(20);
                                messageBox.setVgap(5);
                                messageBox.add(userLabel, 0, 1);
                                messageBox.add(timeLabel, 1, 0);
                                messageBox.add(messageText, 1, 1);
                                vBox2.getChildren().add(messageBox);
                                ChatStage.getChatViewMap().put(userName,vBox2);
                            }
                        }
                    }
                    textMessageList = new ArrayList<>();
                    return flag;
            }
        };
        return task;
    }
}
        MyScheduledServuce myScheduledServuce = new MyScheduledServuce();
        myScheduledServuce.setPeriod(Duration.seconds(0.5));
        myScheduledServuce.start();

实现多窗口关键代码

           userButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    currentUser = user.getUserName();
                    if(chatViewMap.containsKey(user.getUserName())){
                        chatNode[0] = chatViewMap.get(user.getUserName());
                    }else{
                        chatNode[0] = new VBox();
                        chatNode[0].setSpacing(20);
                        ChatStage.getChatViewMap().put(currentUser,chatNode[0]);
                    }
                    if(chatNode[0] !=null){
                        stackPane1.getChildren().clear();
                        stackPane1.getChildren().add(chatNode[0]);
                    }
                }
            });

登录界面

package client.gui;

import client.model.ClientController;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Rectangle2D;
import javafx.scene.ImageCursor;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import model.user.User;

/**
 * @author cjt
 */
public class LoginStage extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage loginStage) {


        //关闭窗口同时关闭后台
        loginStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                ClientController.logout();
            }
        });

        //设置窗口的标题和图标,并将窗口设置为不可拉伸
        loginStage.setTitle("JMU Chat Room");
        loginStage.getIcons().add(new Image("/client/gui/resource/stage-icon2.png"));
        loginStage.setResizable(false);

        //把窗口设置为屏幕居中
        Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
        loginStage.setWidth(556);
        loginStage.setHeight(458);
        loginStage.setX((screenBounds.getWidth()-loginStage.getWidth())/2);
        loginStage.setY((screenBounds.getHeight()-loginStage.getHeight())/2);

        //创建两个AnchorPane布局面板,并把achorPane2添加到anchorPane1里
        AnchorPane anchorPane1 = new AnchorPane();
        AnchorPane anchorPane2 = new AnchorPane();
        AnchorPane backgroundPane = new AnchorPane();
        anchorPane1.getChildren().add(anchorPane2);
        anchorPane1.getChildren().add(backgroundPane);

        //管理anchorPane2在anchorPane1中的位置
        AnchorPane.setTopAnchor(anchorPane2,158.0);
        AnchorPane.setBottomAnchor(anchorPane2,0.0);
        AnchorPane.setLeftAnchor(anchorPane2,0.0);
        AnchorPane.setRightAnchor(anchorPane2,0.0);

        //管理backgroundPane在anchorPane1中的位置
        AnchorPane.setTopAnchor(backgroundPane,0.0);
        AnchorPane.setBottomAnchor(backgroundPane,254.0);
        AnchorPane.setLeftAnchor(backgroundPane,0.0);
        AnchorPane.setRightAnchor(backgroundPane,0.0);

        //将anchorPane1作为scene的根节点,并设置scene的宽高
        Scene scene = new Scene(anchorPane1,538,412);
        loginStage.setScene(scene);

        //设置光标的图标
        scene.setCursor(new ImageCursor(new Image("/client/gui/resource/cursor-icon3.png")));

        //创建账号标签
        Label userNameLabel = new Label("User Name:");
        anchorPane2.getChildren().add(userNameLabel);
        AnchorPane.setTopAnchor(userNameLabel,60.0);
        AnchorPane.setLeftAnchor(userNameLabel,110.0);

        /* 创建账号文本输入框 */
        TextField userTextField = new TextField();
        userTextField.setTooltip(new Tooltip("请输入用户名"));
        userTextField.setPromptText("账号");
        anchorPane2.getChildren().add(userTextField);
        AnchorPane.setTopAnchor(userTextField,60.0);
        AnchorPane.setLeftAnchor(userTextField,240.0);

        /* 创建密码标签 */
        Label pwLabel = new Label("Password:");
        anchorPane2.getChildren().add(pwLabel);
        AnchorPane.setTopAnchor(pwLabel,102.0);
        AnchorPane.setLeftAnchor(pwLabel,110.0);

        /* 创建密码输入框 */
        PasswordField pwField = new PasswordField();
        pwField.setTooltip(new Tooltip("请输入密码"));
        pwField.setPromptText("密码");
        anchorPane2.getChildren().add(pwField);
        AnchorPane.setTopAnchor(pwField,102.0);
        AnchorPane.setLeftAnchor(pwField,240.0);

        /* 创建登录按钮 */
        Button loginButton = new Button("登录");
        loginButton.setCursor(new ImageCursor(new Image("/client/gui/resource/cursor-icon1.png")));
        anchorPane2.getChildren().add(loginButton);
        AnchorPane.setTopAnchor(loginButton,185.0);
        AnchorPane.setBottomAnchor(loginButton,24.0);
        AnchorPane.setLeftAnchor(loginButton,119.0);
        AnchorPane.setRightAnchor(loginButton,119.0);

        //创建注册按钮
        Button registerButton = new Button("注册账号");
        registerButton.setCursor(new ImageCursor(new Image("/client/gui/resource/cursor-icon1.png")));
        anchorPane2.getChildren().add(registerButton);
        AnchorPane.setTopAnchor(registerButton,140.0);
        AnchorPane.setBottomAnchor(registerButton,80.0);
        AnchorPane.setLeftAnchor(registerButton,349.0);
        AnchorPane.setRightAnchor(registerButton,103.0);


        /* 登录按钮点击事件 */
        loginButton.setOnAction(event -> {
            String userName = userTextField.getText();
            String password = pwField.getText();

            User user = new User(userName,password);

            if(ClientController.clientLogin(user)){
                loginStage.close();

                ChatStage chatStage = new ChatStage();
                chatStage.start(new Stage());


            }else{

                AlertDialog alertDialog = new AlertDialog("账号或密码错误");
                alertDialog.start(new Stage());

            }
        });

        //注册按钮点击事件
        registerButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                RegisterStage registerStage = new RegisterStage();
                registerStage.start(new Stage());
            }
        });

        //添加CSS样式表
        scene.getStylesheets().add(LoginStage.class.getResource("LoginCss.css").toExternalForm());
        anchorPane1.setId("anchor-Pane1");
        anchorPane2.setId("anchor-Pane2");
        backgroundPane.setId("background-Pane");
        loginButton.setId("login-Button");
        registerButton.setId("register-Button");

        loginStage.show();

    }
}

六、总结与反思

  该聊天系统仅完成了最基础的聊天功能,还有很多功能和细节尚未实现,比如标签设置图标、按钮设置图标、进度条等等因为实在没时间没能实现,最后只能草草收尾,在截止前的最后一天才勉强完成。                  
  因为从零开始学习JAVA FX,并且没有使用scene builder,纯手打实现图形界面,导致花费了前期大部分时间,赶不上进度。
  在课程设计结束后,我想进一步学习JAVA Fx技术以及前端技术,来更加完善聊天系统,同时实现多人聊天和文件传输。

七、学习参考资料

javafx中文网
B站的一门网课

原文地址:https://www.cnblogs.com/cjt0722/p/14342694.html