JavaFX作业

这篇具有很好参考价值的文章主要介绍了JavaFX作业。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

        在写这个作业之前,尝试在JavaFX中添加全局快捷键,测试了大概5个小时,到处找教程换版本,结果最后还是没找到支持Java8以上的(也有可能是我自己的问题),最后只能退而求其次,用jintellitype这个库来在原生swing里面添加了全局快捷键,算是圆了我对SAO Utils的一个执念吧,虽然实际上相差甚远。

作业:

1.安装向导

        提供一个setup.jar,模拟常见的软件安装交互特性。

        主要功能:上一步下一步的页面切换,按钮交互响应,页面创建

2.广播

        制作一个可以向子窗体同步信息的父窗体,内容由文本框输入,父窗体上放一个广播按钮和一个子窗体创建按钮,广播按钮点击后可以让父窗体输入文本显示到所有子窗体上,子窗体创建按钮点击后创建新的窗体(点击一次创建一次)。

        主要功能:文本输入,信息同步,按钮交互响应,窗体创建

3.监控

        制作一个可以收集自己创建的子窗体信息的父窗体,父窗体上有一个子窗体创建按钮和一个显示框,子窗体创建按钮点击后创建一个子窗体,显示框内显示当前已经创建的子窗体的名字(依次命名为1,2,3...)和每个子窗体上按钮被点击的次数;每个子窗体中心有一个点击按钮,点击后主窗体更新内容。

        主要功能:窗体创建,信息传递,按钮交互响应,计数计算

4.双向实时通讯

        创建一个主窗体和一个从窗体,主窗体上显示“已完成了   %”,从窗体上显示一个进度条(初始为0,在下方显示百分比)和两个按钮,一个增加按钮一个减少按钮,点击增加按钮,进度条增加1%,点击减少,进度条减少1%,从窗体的进度条和主窗体显示的  %相关联,同样的,主窗体上也有这两个按键。

        主要功能:按钮响应,信息双向同步,计数,线程安全(我在主窗体的按钮上加上了长按加速功能,方便调试,不然点来点去好难受)

5.微信群模拟

        用JavaFX模拟微信群聊功能。

        程序运行时可以动态创建多个窗体,也就是说先有一个主窗体,在创建从窗体时,用户可以选择一个群加入(相当于一个class来将从窗体分到不同的类别里,参见html的class),每个窗体代表一个用户(每个用户按照创建窗体的先后顺序有一个id),使用窗体背景色区分开各个群的成员。一个用户发送的消息只有他所属的群内的其他用户能看到。【我新加入了历史记录的模块,但是似乎效果并不是很好,当前的同步方式是一次性同步所有历史数据,显然当数据量较大时不太合适,而且太低效了(这个好改,但是懒)】

JavaFX学习记录

1.布局·

        VBox垂直布局,HBox水平布局

2.线程安全

        确保在多条线程访问的时候,我们的程序还能按照我们预期的行为去执行。

        关键字:synchronized,lock,volatile

完成(慢慢更新ing,注解有时间再写当做复习)

1.安装向导

package com.example.test10;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SetupWizard extends Application {
    private Stage stage;
    private int currentPage;
    private VBox pageContainer;
    private final Button backButton = new Button("Back");
    private final Button nextButton = new Button("Next");

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

    @Override
    public void start(Stage primaryStage) {
        stage = primaryStage;
        stage.setTitle("Setup Wizard");

        BorderPane root = new BorderPane();
        Scene scene = new Scene(root, 400, 300);

        // 创建页面容器
        pageContainer = new VBox();
        pageContainer.setPadding(new Insets(20));
        pageContainer.setAlignment(Pos.CENTER_LEFT);
        // 创建页面
        VBox page1 = createPage1();
        VBox page2 = createPage2();
        VBox page3 = createPage3();

        // 添加页面到容器
        pageContainer.getChildren().addAll(page1, page2, page3);

        // 设置当前页面
        currentPage = 0;
        showCurrentPage();

        // 创建按钮容器
        HBox buttonContainer = new HBox();
        buttonContainer.setPadding(new Insets(20));
        buttonContainer.setAlignment(Pos.BOTTOM_RIGHT);

        // 设置布局
        HBox.setMargin(backButton, new Insets(0, 10, 0, 0));
        backButton.setOnAction(event -> showPreviousPage());
        nextButton.setOnAction(event -> showNextPage());

        buttonContainer.getChildren().addAll(backButton, nextButton);
        root.setCenter(pageContainer);
        root.setBottom(buttonContainer);
        nextButton.setDisable(true);
        stage.setScene(scene);
        stage.show();
    }

    private VBox createPage1() {
        VBox page = new VBox();
        page.setSpacing(10);
        Label label = new Label("Please read and accept the agreement:");
        CheckBox checkBox = new CheckBox("I agree to the above terms and conditions");
        checkBox.setOnAction(event -> nextButton.setDisable(!checkBox.isSelected()));
        page.getChildren().addAll(label, checkBox);
        return page;
    }

    private VBox createPage2() {
        VBox page = new VBox();
        page.setSpacing(10);
        Label label = new Label("Please enter the installation directory:");
        TextField directoryField = new TextField();
        directoryField.textProperty().addListener((observable, oldValue, newValue) ->
                nextButton.setDisable(newValue.isEmpty()));
        page.getChildren().addAll(label, directoryField);
        return page;
    }

    private VBox createPage3() {
        VBox page = new VBox();
        page.setSpacing(10);
        Label label = new Label("Please select an option:");
        Button exitButton = new Button("Exit");
        exitButton.setOnAction(event -> stage.close());

        HBox buttonContainer = new HBox();
        buttonContainer.setAlignment(Pos.BOTTOM_RIGHT);
        buttonContainer.getChildren().addAll(backButton, exitButton);

        page.getChildren().addAll(label, buttonContainer);
        return page;
    }

    private void showPreviousPage() {
        if (currentPage > 0) {
            currentPage--;
            showCurrentPage();
        }
    }

    private void showNextPage() {
        if (currentPage < pageContainer.getChildren().size() - 1) {
            currentPage++;
            showCurrentPage();
            nextButton.setDisable(true);
        }
    }

    private void showCurrentPage() {
        pageContainer.getChildren().forEach(page -> page.setVisible(false));
        pageContainer.getChildren().get(currentPage).setVisible(true);

        backButton.setDisable(currentPage == 0);
        nextButton.setDisable(currentPage == pageContainer.getChildren().size() - 1);
    }
}

2. 广播

package com.example.test11;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;

public class ParentWindow extends Application {
    private final List<ChildWindow> childWindows = new ArrayList<>();
    private double childWindowOffsetY = 0;

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

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Parent Window");

        // 创建文本输入框
        TextField inputTextField = new TextField();
        inputTextField.setPromptText("输入要广播的文本");

        // 创建广播按钮
        Button broadcastButton = new Button("广播");
        broadcastButton.setOnAction(e -> broadcastMessage(inputTextField.getText()));

        // 创建子窗体创建按钮
        Button createChildButton = new Button("创建子窗体");
        createChildButton.setOnAction(e -> createChildWindow(primaryStage));

        // 创建按钮布局
        HBox buttonLayout = new HBox(10);
        buttonLayout.getChildren().addAll(broadcastButton, createChildButton);

        // 创建父窗体布局
        VBox parentLayout = new VBox(10);
        parentLayout.setPadding(new Insets(10));
        parentLayout.getChildren().addAll(inputTextField, buttonLayout);

        primaryStage.setScene(new Scene(parentLayout, 500, 350));
        primaryStage.show();
    }

    // 广播消息给所有子窗体
    private void broadcastMessage(String message) {
        for (ChildWindow childWindow : childWindows) {
            childWindow.showMessage(message);
        }
    }

    // 创建子窗体
    private void createChildWindow(Stage parentStage) {
        ChildWindow childWindow = new ChildWindow();
        childWindows.add(childWindow);
        
        // 为了方便观察效果
        // 我把子窗体放在了在父窗体的右侧
        // 并设置childWindowOffsetY作为子窗体的垂直偏移量
        double parentX = parentStage.getX();
        double parentY = parentStage.getY();
        double parentWidth = parentStage.getWidth();
        double parentHeight = parentStage.getHeight();
        childWindow.setX(parentX + parentWidth + 2);
        childWindow.setY(parentY-parentHeight/2+childWindowOffsetY);
        childWindowOffsetY += 120;

        childWindow.show();
    }

    // 子窗体类
    private static class ChildWindow extends Stage {
        private final TextArea messageArea;

        public ChildWindow() {
            setTitle("Child Window");

            // 消息显示区域
            messageArea = new TextArea();
            messageArea.setEditable(false);

            // 子窗体布局
            VBox childLayout = new VBox(10);
            childLayout.setPadding(new Insets(10));
            childLayout.getChildren().addAll(messageArea);

            setScene(new Scene(childLayout, 250, 180));
        }

        // 在子窗体上显示消息
        public void showMessage(String message) {
            Platform.runLater(() -> messageArea.appendText(message + "\n"));
        }
    }
}

3.监控

package com.example.text12;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;

public class ParentWindow extends Application {
    private int childWindowCount = 0;
    private double childWindowOffsetY = 0;
    private final List<ChildWindow> childWindows = new ArrayList<>();
    private Label infoLabel;

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

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Parent Window");

        // 创建子窗体创建按钮
        Button createChildButton = new Button("创建子窗体");
        createChildButton.setOnAction(e -> createChildWindow(primaryStage));

        // 创建信息显示标签
        infoLabel = new Label("已创建子窗体信息:");

        // 创建父窗体布局
        VBox parentLayout = new VBox(10);
        parentLayout.setPadding(new Insets(10));
        parentLayout.getChildren().addAll(createChildButton, infoLabel);

        primaryStage.setScene(new Scene(parentLayout, 500, 350));
        primaryStage.show();
    }

    // 创建子窗体
    private void createChildWindow(Stage parentStage) {
        childWindowCount++;
        String childWindowName = String.valueOf(childWindowCount);
        ChildWindow childWindow = new ChildWindow(childWindowName, this);

        childWindows.add(childWindow);

        double parentX = parentStage.getX();
        double parentY = parentStage.getY();
        double parentWidth = parentStage.getWidth();
        double parentHeight = parentStage.getHeight();
        childWindow.setX(parentX + parentWidth + 2);
        childWindow.setY(parentY-parentHeight/2+childWindowOffsetY);
        childWindowOffsetY += 180;

        childWindow.show();
        updateInfoLabel();
    }

    // 更新信息显示标签和父窗体的总点击次数
    private void updateInfoLabel() {
        StringBuilder sb = new StringBuilder();
        int totalClickCount = 0;
        for (ChildWindow childWindow : childWindows) {
            sb.append("子窗体").append(childWindow.getName()).append(": ").append(childWindow.getClickCount()).append("次点击\n");
            totalClickCount += childWindow.getClickCount();
        }
        sb.append("总点击次数: ").append(totalClickCount);

        Platform.runLater(() -> infoLabel.setText("已创建子窗体信息:\n" + sb));
    }

    // 子窗体类
    private static class ChildWindow extends Stage {
        private final String name;
        private int clickCount = 0;

        public ChildWindow(String name, ParentWindow parentWindow) {
            this.name = name;
            setTitle("Child Window " + name);

            // 创建点击按钮
            Button clickButton = new Button("点击");
            clickButton.setOnAction(e -> {
                clickCount++;
                parentWindow.updateInfoLabel();
            });

            // 创建子窗体布局
            VBox childLayout = new VBox(10);
            childLayout.setAlignment(Pos.CENTER);
            childLayout.setPadding(new Insets(10));
            childLayout.getChildren().addAll(clickButton);

            setScene(new Scene(childLayout, 250, 180));
        }

        // 获取子窗体名称
        public String getName() {
            return name;
        }

        // 获取子窗体的点击次数
        public int getClickCount() {
            return clickCount;
        }
    }
}

4. 双向实时通讯

package com.example.text13;

import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

    private static Main instance; // 单例实例
    private int progress = 0; // 进度值
    private final Object lock = new Object(); // 同步锁对象
    private Label progressLabel; // 主窗体的进度文本标签
    private PauseTransition increaseTimer; // 增加定时器
    private PauseTransition decreaseTimer; // 减少定时器

    public static Main getInstance() {
        return instance;
    }

    public int getProgress() {
        return progress;
    }

    public Object getLock() {
        return lock;
    }

    public void increaseProgress() {
        if (progress < 100) {
            progress++;
        }
    }

    public void decreaseProgress() {
        if (progress > 0) {
            progress--;
        }
    }

    @Override
    public void start(Stage primaryStage) {
        instance = this; // 设置单例实例

        // 创建主窗体
        primaryStage.setTitle("主窗体");
        progressLabel = new Label("已完成了 0%");
        progressLabel.setAlignment(Pos.CENTER);

        Button increaseButton = new Button("增加");
        Button decreaseButton = new Button("减少");

        increaseButton.setOnAction(e -> {
            increaseProgress();
            updateProgressLabel();
        });

        decreaseButton.setOnAction(e -> {
            decreaseProgress();
            updateProgressLabel();
        });

        increaseButton.setOnMousePressed(e -> increaseTimer.playFromStart());

        increaseButton.setOnMouseReleased(e -> increaseTimer.stop());

        decreaseButton.setOnMousePressed(e -> decreaseTimer.playFromStart());

        decreaseButton.setOnMouseReleased(e -> decreaseTimer.stop());

        increaseTimer = createTimer(increaseButton, true);
        decreaseTimer = createTimer(decreaseButton, false);

        HBox buttonLayout = new HBox(10);
        buttonLayout.setAlignment(Pos.CENTER);
        buttonLayout.getChildren().addAll(increaseButton, decreaseButton);

        VBox mainLayout = new VBox(10);
        mainLayout.setAlignment(Pos.CENTER);
        mainLayout.getChildren().addAll(progressLabel, buttonLayout);
        Scene mainScene = new Scene(mainLayout, 450, 300);
        primaryStage.setScene(mainScene);
        primaryStage.show();

        // 创建从窗体
        Thread syncThread = getThread(primaryStage);
        syncThread.start();
    }

    private Thread getThread(Stage primaryStage) {
        ProgressBarWindow progressBarWindow = new ProgressBarWindow();
        Stage secondaryStage = getStage(primaryStage, progressBarWindow);
        secondaryStage.show();

        // 同步主窗体和从窗体的进度
        Thread syncThread = new Thread(() -> {
            try {
                while (true) {
                    synchronized (lock) {
                        Platform.runLater(() -> {
                            progressBarWindow.updateProgress(progress);
                            progressBarWindow.updatePercentage(progress);
                            updateProgressLabel();
                        });
                        lock.wait(100);
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        syncThread.setDaemon(true);
        return syncThread;
    }

    private static Stage getStage(Stage primaryStage, ProgressBarWindow progressBarWindow) {
        Stage secondaryStage = new Stage();
        secondaryStage.setTitle("从窗体");
        Scene secondaryScene = new Scene(progressBarWindow.getLayout(), 250, 180);
        secondaryStage.setScene(secondaryScene);

        double primaryX = primaryStage.getX();
        double primaryY = primaryStage.getY();
        double primaryWidth = primaryStage.getWidth();
        double primaryHeight = primaryStage.getHeight();
        secondaryStage.setX(primaryX + primaryWidth + 2);
        secondaryStage.setY((primaryY+primaryHeight)/2);
        return secondaryStage;
    }

    private void updateProgressLabel() {
        progressLabel.setText("已完成了 " + progress + "%");
    }

    private PauseTransition createTimer(Button button, boolean increase) {
        PauseTransition timer = new PauseTransition(Duration.millis(100));
        timer.setOnFinished(e -> {
            synchronized (lock) {
                if (increase) {
                    increaseProgress();
                } else {
                    decreaseProgress();
                }
                updateProgressLabel();
            }
            timer.playFromStart();
        });
        button.setOnMouseClicked(e -> {
            if (e.getClickCount() > 1) {
                timer.stop();
            }
        });
        return timer;
    }

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

class ProgressBarWindow {
    private final VBox layout;
    private final ProgressBar progressBar;
    private final Label percentageLabel;

    public ProgressBarWindow() {
        progressBar = new ProgressBar(0);
        percentageLabel = new Label("0%");

        VBox.setMargin(progressBar, new javafx.geometry.Insets(10));
        VBox.setMargin(percentageLabel, new javafx.geometry.Insets(10));

        Button increaseButton = new Button("增加");
        Button decreaseButton = new Button("减少");
        increaseButton.setOnAction(e -> {
            synchronized (Main.getInstance().getLock()) {
                Main.getInstance().increaseProgress();
                updateProgress(Main.getInstance().getProgress());
                updatePercentage(Main.getInstance().getProgress());
            }
        });
        decreaseButton.setOnAction(e -> {
            synchronized (Main.getInstance().getLock()) {
                Main.getInstance().decreaseProgress();
                updateProgress(Main.getInstance().getProgress());
                updatePercentage(Main.getInstance().getProgress());
            }
        });

        HBox buttonLayout = new HBox(10);
        buttonLayout.setAlignment(Pos.CENTER);
        buttonLayout.getChildren().addAll(increaseButton, decreaseButton);

        layout = new VBox(10);
        layout.setAlignment(Pos.CENTER);
        layout.getChildren().addAll(progressBar, percentageLabel, buttonLayout);
    }

    public VBox getLayout() {
        return layout;
    }

    public void updateProgress(int progress) {
        progressBar.setProgress(progress / 100.0);
    }

    public void updatePercentage(int progress) {
        percentageLabel.setText(progress + "%");
    }
}

5.微信群模拟

        今天上了课,感觉我这个的设计思路不是很好。应该建一个group类来存储成员ID,这样在功能拓展开发上更灵活,比如退群这种功能只需要将group类中的memberID的集合中的对应ID删除即可。同样地,历史记录也可以存储到group类的history中,这样新成员加入历史记录同步就直接通过ID找到群内的history即可。文章来源地址https://www.toymoban.com/news/detail-743668.html

package com.example.test14;

import javafx.scene.control.Alert;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;

public class WeChatGroupSimulation extends Application {
    private static List<GroupChatMember> groupChatMembers; // 存储群聊成员
    private double childWindowOffsetY = 0; // 用来调节新窗体位置

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

    @Override
    public void start(Stage primaryStage) {
        groupChatMembers = new ArrayList<>();//创建一个空的ArrayList对象,用于存储群聊成员。
        // 创建主窗体
        createMainWindow(primaryStage);
        primaryStage.setTitle("WeChat Group Simulation");
        primaryStage.show();
    }

    private void createMainWindow(Stage primaryStage) {
        VBox root = new VBox();//垂直布局
        root.setAlignment(Pos.CENTER); // 居中对齐
        root.setSpacing(10); // 垂直间距10像素
        root.setPadding(new Insets(10)); // 内边距10像素

        Button addButton1 = new Button("加入1群");
        addButton1.setOnAction(event -> createGroupChatMember("1群", Color.RED, primaryStage));
        root.getChildren().add(addButton1);

        Button addButton2 = new Button("加入2群");
        addButton2.setOnAction(event -> createGroupChatMember("2群", Color.GREEN, primaryStage));
        root.getChildren().add(addButton2);

        // 加入群组3的按钮
        Button addButton3 = new Button("加入3群");
        addButton3.setOnAction(event -> createGroupChatMember("3群", Color.BLUE, primaryStage));
        root.getChildren().add(addButton3);

        Scene scene = new Scene(root, 300, 200);
        primaryStage.setScene(scene);
    }

    // 创建群聊成员窗口
    private void createGroupChatMember(String groupName, Color backgroundColor, Stage parentStageStage) {
        GroupChatMember member = new GroupChatMember(groupName);

        // 将已存在的群聊成员的历史消息合并到新成员的历史消息中
        for (GroupChatMember existingMember : groupChatMembers) {
            if (existingMember.getGroupName().equals(groupName)) {
                member.getHistory().addAll(existingMember.getHistory());
                break;
            }
        }
        Stage stage = new Stage();
        stage.setTitle(groupName);

        VBox root = new VBox();
        root.setStyle("-fx-background-color: " + toRGBCode(backgroundColor)); // 背景颜色
        root.setSpacing(10);
        root.setPadding(new Insets(10));

        TextArea historyArea = new TextArea(); // 创建文本区域用于显示历史消息
        historyArea.setPrefHeight(500);
        historyArea.setEditable(false);

        ListView<String> messageList = new ListView<>(); // 创建列表视图用于显示消息列表

        TextArea inputArea = new TextArea(); // 创建文本区域作为输入框
        inputArea.setPromptText("Enter your message..."); // 输入框提示文本
        inputArea.setPrefHeight(60);

        root.getChildren().addAll(historyArea, messageList, inputArea); // 将历史消息区域、消息列表和输入框添加到root中

        Scene scene = new Scene(root, 300, 400);

        // 新窗口初始位置(主要是为了自己方便一点,懒得动鼠标)
        double primaryX = parentStageStage.getX();
        double primaryY = parentStageStage.getY();
        double primaryWidth = parentStageStage.getWidth();
        double primaryHeight = parentStageStage.getHeight();
        stage.setX(primaryX + primaryWidth );
        stage.setY(primaryY-primaryHeight/2+ childWindowOffsetY);
        childWindowOffsetY += 100;

        stage.setScene(scene);

        // 模拟发送消息
        inputArea.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) {
                String message = inputArea.getText().trim();
                inputArea.clear();
                if (!message.isEmpty()) {
                    member.sendMessage(message); // 发送消息给成员对象
                    broadcastMessage(member, message); // 通过当前成员对象,广播消息给其他成员
                    messageList.scrollTo(messageList.getItems().size() - 1); // 聚焦到最后一条消息
                } else {
                    showErrorAlert();
                }
            }
        });

        // 监听新消息
        member.setOnMessageReceived(new MessageReceivedListener() {
            @Override
            public void onMessageReceived(String message) {
                // 更新消息列表
                Platform.runLater(() -> messageList.getItems().add(message));
            }
            @Override
            public void onHistoryUpdated(String historyText) {
                // 更新历史消息
                Platform.runLater(() -> historyArea.setText(historyText));
            }
        });

        groupChatMembers.add(member);

        stage.show();
    }

    // 错误提示窗口
    private void showErrorAlert() {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("Error");
        alert.setHeaderText(null);
        alert.setContentText("Message cannot be empty");
        alert.showAndWait();
    }

    // 广播消息给同一群组的其他成员,也就是其他成员获得sender的message
    private void broadcastMessage(GroupChatMember sender, String message) {
        for (GroupChatMember member : groupChatMembers) {
            if (member != sender && member.getGroupName().equals(sender.getGroupName())) {
                member.receiveMessage(sender.getUsername(), message);
            }
        }
    }

    // 颜色转换:RGB
    private String toRGBCode(Color color) {
        int r = (int) (color.getRed() * 255);
        int g = (int) (color.getGreen() * 255);
        int b = (int) (color.getBlue() * 255);
        return String.format("#%02x%02x%02x", r, g, b);
    }
}

// 群聊成员类
class GroupChatMember {
    private static int memberID = 0;
    private final String groupName;
    private final String username;
    private final List<String> history;
    private MessageReceivedListener listener;

    public GroupChatMember(String groupName) {
        this.groupName = groupName;
        this.username = "成员" + getNextMemberID();
        this.history = new ArrayList<>();
    }

    private static synchronized int getNextMemberID() {
        return ++memberID;
    }

    public String getGroupName() {
        return groupName;
    }
    public String getUsername() {
        return username;
    }
    public List<String> getHistory() {
        return history;
    }
    public void setOnMessageReceived(MessageReceivedListener listener) {
        this.listener = listener;
        updateHistory();
    }

    public void sendMessage(String message) {
        history.add(username + ": " + message);
        if (listener != null) {
            listener.onMessageReceived(username + ": " + message);
            updateHistory();
        }
    }

    public void receiveMessage(String sender, String message) {
        history.add(sender +": "+ message);
        if (listener != null) {
            listener.onMessageReceived(sender +": "+ message);
            updateHistory();
        }
    }

    private void updateHistory() {
        StringBuilder builder = new StringBuilder();
        for (String message : history) {
            builder.append(message).append("\n");
        }
        if (listener != null) {
            listener.onHistoryUpdated(builder.toString());
        }
    }
}

// 监听消息接收和历史消息更新的接口
interface MessageReceivedListener {
    void onMessageReceived(String message);
    void onHistoryUpdated(String historyText);
}

到了这里,关于JavaFX作业的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java的Swing被JavaFX取代了

    JavaFX是Oracle在Java平台上推出的一种富客户端应用程序开发框架,它在功能和外观方面更加先进和强大,逐渐取代了过时的Swing框架。JavaFX提供了丰富的用户界面控件、布局容器、图形绘制、媒体播放和动画等功能,使得开发者能够更加轻松地构建现代化、交互式的桌面应用程

    2024年02月04日
    浏览(26)
  • 【面向对象程序设计】账户类(Java、JavaFX)

    目录 版本1: 设计Account1类,包含: 设计测试类ATMMachine1: 版本2: 扩展Account1类为Account2类:   设计测试类ATMMachine2,其主菜单如下: 版本3: uml啥的找不到了,太久远了,有什么不懂得评论或者私聊问我吧。 ■ 一个名为id 的int 类型的私有数据域(默认值为0),长度为6位

    2024年02月08日
    浏览(32)
  • Java 17 中找不到 JavaFX 的解决方法

    最近在学习 Paul Deitel 和 Harvey Deitel 编写的 Java 编程入门教材《Java: How to Program - Early Objects 11th Edition》 本书豆瓣页面链接 其中第 1 章第 1.10 节给出一个简易画板示例程序,是一个 JavaFX GUI 程序 其目录结构如下 按书上给的命令 javac *.java 编译时出现如下错误,编译失败 以上错

    2024年02月09日
    浏览(42)
  • 详解Java实现2048小游戏(JavaFX,完整源码+注释说明)

    刚刚完成的一个小游戏,写文章记录一下,如果有任何错误或者可以改进的代码请提出 另一方面也是方便自己几个月或几年后忘记时,来这里翻一翻回顾思路 目录 基本界面: 类的组织: _CardPane: _CardMatrixPane: _CardColor: _GameMenuBar: _2048Demo: 基本思路: 卡片: 卡片矩阵:

    2024年02月03日
    浏览(40)
  • GraalVM详细安装及打包springboot、java、javafx使用教程(环境安装篇)

    下一篇:GraalVM详细安装及打包springboot、java、javafx使用教程(打包普通JAVA项目篇) GraalVM是一款由Oracle公司开发的一款具有高效性能、降低基础设施成本、支持Java发展、与其他编程语言无缝集成、创建本机镜像等优点的跨平台虚拟机。它支持多种编程语言,如Java、JavaScript、Rub

    2024年04月26日
    浏览(29)
  • 开发语言漫谈-Java

            由于C++过于复杂,Java诞生了。与C++相比,Java更易于学习和使用,它去掉C++中的指针和解决了内存管理问题。Java提供了垃圾自动回收机制,自动管理不再使用的内存。Python又进一步简化,使得语法更简洁,更易于阅读和编写。当然随着简化,性能就越来越低。    

    2024年04月10日
    浏览(37)
  • 海康威视相机SDK二次开发(JAVA语言)

    前言 有个项目需要使用java程序读取海康威视的相机图片。相机通过以太网连接服务器,部署在服务器上的java程序将相机拍摄的画面保存在指定路径下。 海康威视提供了sdk开发包,可以在官网中下载,windows和linux系统都有。但是开发包中给出的示例代码,无法满足实际需要,

    2024年04月29日
    浏览(35)
  • BsinCopilot:Java版端到端大语言模型开发框架

    BsinCopilot是基于BsinPaaS开源框架构建的大语言模型应用SaaS服务,借鉴langchain的框架思想,引入  langchian4j组件,微前端微服务的架构设计,可快速助您构建和体验端到端的AI应用。 概念 说明 Bsin 毕昇缩写,毕昇,中国北宋发明家,活字印刷术的发明者。毕昇出身平民,长期在

    2024年03月13日
    浏览(42)
  • Android 安卓开发语言kotlin与Java该如何选择

            如今在Android开发中,应用层开发语言主要是Java和Kotlin,Kotlin是后来加入的,主导的语言还是Java。kotlin的加入仿佛让会kotlin语言的开发者更屌一些,其实不然。         有人说kotlin的引入是解决开发者复杂的逻辑,并且对空指针控制的比较友好,但是我们在开

    2024年02月11日
    浏览(33)
  • C语言课程作业

    本科期间c语言课程作业代码整理: Josephus链表实现 Josephus 层序遍历树 二叉树的恢复 哈夫曼树 链表的合并 中缀表达式 链接:https://pan.baidu.com/s/1Q7d-LONauNLi7nJS_h0jtw?pwd=swit 提取码:swit

    2024年02月09日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包