生物节律曲线的java实现

项目要求

根据生物节律曲线的定义,用户输入生日后,绘制生物节律曲线(使用JavaFX);能保存用户生日,并允许切换用户——即保存多个生日并进行切换。

解题思路描述:

  1. 首先设计输入出生年、月、日按钮和查询年、月下拉列表,实现基本的数据选择功能
  2. 其次设计选择用户下拉列表,能够选择三个不同的用户;设计切换用户按钮,单击后将当前年、月、日切换为该用户生日的年、月、日;设计保存按钮,单击后将当前的年、月、日设置为当前显示用户生日的年、月、日
  3. 最后编写绘制体力、情绪、智力节律曲线的方法;设计查询按钮,单击后出现显示曲线的场景

具体代码

首先奉上代码。

代码分为两个类,一个叫Birthday类,一个叫BioRhythmCalculator类。

Birthday类:

import javafx.scene.control.ComboBox;

public class Birthday {
    public ComboBox<Integer> yearComboBox;
    public ComboBox<Integer> monthComboBox;
    public ComboBox<Integer> dayComboBox;
    public Birthday(int year,int month,int day){
        yearComboBox = new ComboBox<>();
        monthComboBox = new ComboBox<>();
        dayComboBox = new ComboBox<>();
        yearComboBox.setValue(year);
        monthComboBox.setValue(month);;
        dayComboBox.setValue(day);
    }

}

 BioRhythmCalculator类:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class BioRhythmCalculator extends Application {
    //初始化三个用户生日实例和一个当前显示的生日实例
    public Birthday birthday = new Birthday(2000, 1, 1);
    public Birthday User1 = new Birthday(2001, 2, 2);
    public Birthday User2 = new Birthday(2002, 3, 3);
    public Birthday User3 = new Birthday(2003, 10, 24);
    //User记录当前是哪一个用户
    public String User = "用户一";


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

    // 下拉列表选项的年份
    private Integer[] getYearOptions() {
        return new Integer[]{2000, 2001, 2002, 2003, 2004,
                2005, 2006, 2007, 2008, 2009, 2010};
    }

    // 下拉列表选项的月份
    private Integer[] getMonthOptions() {
        return new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    }

    // 下拉列表选项的日期
    private Integer[] getDayOptions() {
        return new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
                21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
    }
    // 绘制人体生物节律曲线的方法
    private void drawBioRhythmCurve(long during1, long during2) {
        //创建坐标轴
        NumberAxis xAxis = new NumberAxis(during1, during2, 1);
        NumberAxis yAxis = new NumberAxis(-1.0, 1.0, 0.2);

        //创建线性图表
        LineChart<Number, Number> chart = new LineChart<>(xAxis, yAxis);

        //设置图表标题和轴标签
        chart.setTitle("人体生物节律曲线");
        xAxis.setLabel("天数");
        yAxis.setLabel("节律值");

        //创建身体节律数据系列
        XYChart.Series<Number, Number> physicalSeries = new XYChart.Series<>();
        physicalSeries.setName("身体节律");

        //创建情感节律数据系列
        XYChart.Series<Number, Number> emotionalSeries = new XYChart.Series<>();
        emotionalSeries.setName("情感节律");

        //创建智力节律数据系列
        XYChart.Series<Number, Number> intellectualSeries = new XYChart.Series<>();
        intellectualSeries.setName("智力节律");

        //添加数据点到数据系列中
        for (long i = during1; i <= during2; i++) {
            double t = i;
            double physicalValue = Math.sin(2 * Math.PI * t / 23);
            double emotionalValue = Math.sin(2 * Math.PI * t / 28);
            double intellectualValue = Math.sin(2 * Math.PI * t / 33);

            physicalSeries.getData().add(new XYChart.Data<>(i, physicalValue));
            emotionalSeries.getData().add(new XYChart.Data<>(i, emotionalValue));
            intellectualSeries.getData().add(new XYChart.Data<>(i, intellectualValue));
        }

        // 将数据系列添加到图表中
        chart.getData().addAll(physicalSeries, emotionalSeries, intellectualSeries);

        // 创建布局并显示图表
        VBox vbox = new VBox(chart);
        Scene scene = new Scene(vbox, 800, 400);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.show();
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("人体生物钟查询");

        // 网格布局
        GridPane grid = new GridPane();
        grid.setPadding(new Insets(20, 20, 20, 20));
        grid.setHgap(10);
        grid.setVgap(10);

        // 用户选择按钮
        ComboBox<String> userComboBox = new ComboBox<>();
        userComboBox.getItems().addAll("用户一", "用户二", "用户三");
        userComboBox.setValue("用户一");

        // 创建用户切换按钮
        Button switchUserButton = new Button("切换用户");

        switchUserButton.setOnAction(e -> {
            String selectedUser = userComboBox.getValue();
            User = selectedUser;
            switch (selectedUser) {
                case "用户一":
                    //当前显示的生日转换为用户一的生日
                    birthday.yearComboBox.setValue(User1.yearComboBox.getValue());
                    birthday.monthComboBox.setValue(User1.monthComboBox.getValue());
                    birthday.dayComboBox.setValue(User1.dayComboBox.getValue());
                    break;
                case "用户二":
                    //当前显示的生日转换为用户二的生日
                    birthday.yearComboBox.setValue(User2.yearComboBox.getValue());
                    birthday.monthComboBox.setValue(User2.monthComboBox.getValue());
                    birthday.dayComboBox.setValue(User2.dayComboBox.getValue());
                    break;
                case "用户三":
                    //当前显示的生日转换为用户三的生日
                    birthday.yearComboBox.setValue(User3.yearComboBox.getValue());
                    birthday.monthComboBox.setValue(User3.monthComboBox.getValue());
                    birthday.dayComboBox.setValue(User3.dayComboBox.getValue());
                    break;
            }
        });

        // 注明每行的信息
        Label birthDateLabel = new Label("请输入公历出生日期:");
        Label queryMonthLabel = new Label("请输入查询月份:");

        // 从这里输入出生日期 (年、月、日)
        birthday.yearComboBox.getItems().addAll(getYearOptions());
        birthday.monthComboBox.getItems().addAll(getMonthOptions());
        birthday.dayComboBox.getItems().addAll(getDayOptions());

        // 保存按钮
        Button saveButton = new Button("保存");
        saveButton.setOnAction(e -> {
            switch (User) {
                case "用户一":
                    User1.yearComboBox.setValue(birthday.yearComboBox.getValue());
                    User1.monthComboBox.setValue(birthday.monthComboBox.getValue());
                    User1.dayComboBox.setValue(birthday.dayComboBox.getValue());
                    break;
                case "用户二":
                    User2.yearComboBox.setValue(birthday.yearComboBox.getValue());
                    User2.monthComboBox.setValue(birthday.monthComboBox.getValue());
                    User2.dayComboBox.setValue(birthday.dayComboBox.getValue());
                    break;
                case "用户三":
                    User3.yearComboBox.setValue(birthday.yearComboBox.getValue());
                    User3.monthComboBox.setValue(birthday.monthComboBox.getValue());
                    User3.dayComboBox.setValue(birthday.dayComboBox.getValue());
                    break;
            }

            // 显示保存成功的提示对话框
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("提示");
            alert.setHeaderText(null);
            alert.setContentText( User + "生日保存成功!");
            alert.showAndWait();
        });

        // 从这里输入要查询的年份
        ComboBox<Integer> queryYearComboBox = new ComboBox<>();
        queryYearComboBox.getItems().addAll(2023, 2024, 2025, 2026);
        queryYearComboBox.setValue(2023);

        // 从这里输入要查询的月份
        ComboBox<Integer> queryMonthComboBox = new ComboBox<>();
        queryMonthComboBox.getItems().addAll(getMonthOptions());
        queryMonthComboBox.setValue(6);

        // 查询按钮
        Button submitButton = new Button("查询");
        submitButton.setOnAction(e -> {
            //获取用户选择的出生日期和查询年份
            int birthYear = birthday.yearComboBox.getValue();
            int birthMonth = birthday.monthComboBox.getValue();
            int birthDay = birthday.dayComboBox.getValue();
            int queryYear = queryYearComboBox.getValue();
            int queryMonth = queryMonthComboBox.getValue();

            //计算从当前生日到查询月份的第一天和最后一天之间的天数
            LocalDate birthDate = LocalDate.of(birthYear, birthMonth, birthDay);
            LocalDate queryFirstDay = LocalDate.of(queryYear, queryMonth, 1);
            LocalDate queryLastDay = queryFirstDay.withDayOfMonth(queryFirstDay.lengthOfMonth());
            long during1 = ChronoUnit.DAYS.between(birthDate, queryFirstDay);
            long during2 = ChronoUnit.DAYS.between(birthDate, queryLastDay);

            //绘制三条曲线
            drawBioRhythmCurve(during1, during2);
        });


        // 将组件添加到网格中
        grid.add(new Label("用户选择:"), 0, 0);
        grid.add(userComboBox, 1, 0);
        grid.add(switchUserButton, 3, 0);
        grid.add(birthDateLabel, 0, 1);
        grid.add(birthday.yearComboBox, 1, 1);
        grid.add(new Label("      年"), 2, 1);
        grid.add(birthday.monthComboBox, 3, 1);
        grid.add(new Label("      月      "), 4, 1);
        grid.add(birthday.dayComboBox, 5, 1);
        grid.add(new Label("      日      "), 6, 1);
        grid.add(queryMonthLabel, 0, 2);
        grid.add(queryYearComboBox, 1, 2);
        grid.add(new Label("      年  "), 2, 2);
        grid.add(queryMonthComboBox, 3, 2);
        grid.add(new Label("      月      "), 4, 2);
        grid.add(saveButton, 1, 3);
        grid.add(submitButton, 3, 3, 6, 1);

        Scene scene = new Scene(grid, 600, 200);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

接下来分别讲解上述各部分思路的实现。

第一部分的实现和调试:

设计下拉列表:

设计总的网格布局

 设计标签和下拉列表

 设计单击事件的处理程序

 将组件添加到网络中

 第一阶段效果图

每个下拉列表都有相应可供选择的标签,以“请输入公历出生日期”的“月”按钮为例:

以上是第一部分代码的效果。

第二部分的实现和调试

 将日期设计为一个叫Birthday的类,方便创建实例

 创建用户一、用户二、用户三和当前数据的生日实例,并用一个String记录当前是哪一个用户

 新增用户选择按钮

 设计用户切换按钮,单击后将当前显示的生日转换为该用户的生日

 修改之前输入生日的部分代码

 设计保存按钮,单击保存后就会将当前的生日保存到该用户的生日,单击后还会显示保存成果的窗口

 修改之前的代码,添加进刚刚设计的按钮

 第二部分效果展示

这是初始界面:

现在我们切换至用户三,并点击切换用户:

可以看到当前生日调整到了用户三的生日(默认设置的用户三生日)

接下来展示保存功能

首先将当前的生日改为2004年6月7日

然后单击保存:

为了验证是否真的保存了,我们先将用户切换为用户一:

接下来选择用户三,并单击切换用户:

可以看到和之前设置的生日一致,以上是第二阶段完成的效果。

第三部分的实现和调试:

 进一步设计查询按钮,使用java.time.LocalDate类和java.time.temporal.ChronoUnit类,便利与日期有关的操作和计算,计算从当前生日到查询月份的第一天和最后一天之间的天数,并调用绘制曲线的方法

 设计绘制曲线的方法,创建坐标轴,创建线性图表,设置图表标题和标签,常见身体节律、情感节律和智力节律数据系列,将数据系列添加到图表中,创建布局并显示图表

 第三部分效果展示

用户选择用户三,单击切换用户,将查询月份选择2023年7月,单击查询,显示以下新窗口:

为了验证准确性,我找到了类似的人体生物钟查询网站,可以看到和该网站的图像一致。

将查询月份设置为2023年8月,单击查询,显示窗口如下:

同样与该网站绘制的图像一致。

//家人们点个赞再走吧

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值