JavaFX实例:简单日历的实现

java的ui库分为三代,第一代是awt,第二代是swing,第三代就是javafx了,互相之间是替代关系。桌面开发现在一般用swing和javafx,今天用javafx开发一个简单的日历查询应用。

最终效果如下:
在这里插入图片描述
git地址:JavaFX日历实现


javafx开发

javafx开发界面开发有两种方式:
1.通过Java代码来编写。
所有的界面和逻辑都通过Java代码来实现,写的东西比较多。

2.通过JavaFX Scene Builder + Java代码来编写实现。
JavaFX Scene Builder是一种可视化设计工具,它允许通过拖放快速创建应用程序界面。 并且代码创建为XML格式的文件。通过JavaFX Scene Builder拖拽来开发界面,Java来实现逻辑比较简单快速。

下面的实例是通过JavaFX Scene Builder + Java实现的。


下载JavaFX Scene Builder

官网下载:JavaFX Scene Builder官网


创建项目

idea新建项目选择Java Fx。
(注意:尽量使用jdk8及8以上,jdk8以下是没有自带javafx的,需要自己引入jar包,自行百度)
在这里插入图片描述
建完后的结构如下,Main程序的入口,sample.fxml用于JavaFX Scene Builder拖拽生成界面,Controller用于绑定界面和和处理监听事件:
在这里插入图片描述

选择sample.fxml右键open in sceneBuilder,然后选择
在这里插入图片描述
然后选择安装好的JavaFX Scene Builder在这里插入图片描述

界面设计

从左上角选择相应的组件到中间进行布局,如图我选择了7个组件,左边是选择的所有组件信息。在中间选择任意一个组件右边都有组件的具体设置,比如长度、宽度、输入框默认提示,组件的名称等。
在这里插入图片描述
设置组件的名称,后面Java里会用到:
在这里插入图片描述
保存后sample.fxml内容变成如下:
要手动加上 fx:controller="sample.Controller"将sample.fxml文件和Controller文件关联绑定,这样下面写Java代码才能使用fxml里的东西。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="399.0" prefWidth="627.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <Button fx:id="id_1" layoutX="103.0" layoutY="120.0" mnemonicParsing="false" onAction="#buttonAction1" prefHeight="30.0" prefWidth="119.0" text="获取日历" textFill="#3a6f2e" />
      <TextField fx:id="text_1" layoutX="102.0" layoutY="61.0" promptText="请输入年份,如:2021" />
      <TextField fx:id="text_2" layoutX="380.0" layoutY="61.0" promptText="请输入月份,如:2" />
      <Text layoutX="48.0" layoutY="82.0" strokeType="OUTSIDE" strokeWidth="0.0" text=" 年:" wrappingWidth="35.0" />
      <Text layoutX="332.0" layoutY="82.0" strokeType="OUTSIDE" strokeWidth="0.0" text=" 月:" wrappingWidth="35.0" />
      <TextArea fx:id="text_3" layoutX="167.0" layoutY="197.0" prefHeight="146.0" prefWidth="274.0" />
   </children>
</AnchorPane>

代码:

Controller:

package sample;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {
    @FXML
    private Button id_1;
    @FXML
    private TextField text_1;//从fxml获取组件text_1,用于读取年
    @FXML
    private TextField text_2;//从fxml获取组件text_2,用于读取月
    @FXML
    private TextArea text_3;//从fxml获取组件text_3,用于输出

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

    //点击按钮时触发的事件
    public void buttonAction1(ActionEvent actionEvent)
    {
        String year = text_1.getText();//获取文本框输入的内容
        String month = text_2.getText();//获取文本框输入的内容
        String result=Service.calculationDate(year,month);
        text_3.setText(result);
    }
}

service:

package sample;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class Service {
    public static String calculationDate(String y, String m) {
        char[] yearChar = y.toCharArray();
        char[] monthChar = m.toCharArray();
        if(null==y||y.length()==0||null==m||m.length()==0){
            return "年份或月份不能输入为空。";
        }

        for (int i = 0; i < yearChar.length; i++) {
            boolean isOrNo = Character.isDigit(yearChar[i]);
            if (yearChar[0] == '0' || !isOrNo) {
                return "年份输入错误,请输入正确的年份。";
            }
        }

        for (int i = 0; i < monthChar.length; i++) {
            boolean isOrNo = Character.isDigit(monthChar[i]);
            if (yearChar[0] == '0' || !isOrNo) {
                return "月份输入错误,请输入正确的月份。";
            }
        }

        int year = Integer.parseInt(y);
        int month = Integer.parseInt(m);

        if (year < 1900||(year==1900&&month==1)) {
            return "年份需要大于等于1900。当年份是1900时,月份需要大于1。";
        }

        if (month > 12) {
            return "月份输入错误,请输入正确的月份。";
        }

        LocalDate endDate = LocalDate.of(year, month, 1);//设置输入的日期
        LocalDate startDate = LocalDate.of(1900, 1, 1);
        long sumDay = startDate.until(endDate, ChronoUnit.DAYS);//总相差的天数:3657
        /*以上代码计算1900年1月1号到输入的年月的总天数,如输入2018和8,则计算1900.1.1-2018.7.31的天数*/

        long xingQi = (sumDay + 1) % 7; //xingQi用来计算输入的月份1号星期几
        long everydayXingQi = sumDay + 1;
        int monthDay = endDate.lengthOfMonth();//用来接收输入的月份有几天

        String result = "日\t一\t二\t三\t四\t五\t六\n";
        for (int i = 0; i < xingQi; i++) {    //输出每月1号前的空格
            result += "\t";
        }
        for (int i = 1; i <= monthDay; i++) {  //输出每个月的天数和控制换行
            if (everydayXingQi % 7 == 6) {
                result += i + "\n";
            } else {
                result += i + "\t";
            }
            everydayXingQi++;
        }
        return result;
    }
}

Main:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        //引用sample.fxml页面布局
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        //设置窗口名称
        primaryStage.setTitle("日历");
        //设置窗口大小
        primaryStage.setScene(new Scene(root, 627, 399));
        //固定窗口大小使其无法最大化
        primaryStage.setResizable(false);
        //设置窗口的图标.
        primaryStage.getIcons().add(new Image("/sample/image/rili.jpg"));
        primaryStage.show();
    }

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

启动项目就ok了。


打成jar包:
在这里插入图片描述在这里插入图片描述

当然你也可以把写好的程序打成jar包或exe程序,打包如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
javaFxText下会生成一个exe文件
在这里插入图片描述
文件夹中打开后,双击就可以运行了
在这里插入图片描述
在这里插入图片描述
但是这个exe文件太难找了,一找找半天,本来想着创建个快捷方式,但是快捷方式只支持绝对路径,没办法,我们可以回到上层目录新建个txt文件输入:

start JavaFxTest\JavaFxTest.exe
exit

start 后面跟自己的文件夹名和exe名。
保存文件后把后缀改为bat

以后双击就能用了。
在这里插入图片描述


关于其他打包方式目前还没试,比如先打成jar包,再通过其他工具打成exe文件。
参考:将java打包成exe——在没有jdk或jre的机器上运行Java项目
java工具(一):在没有jdk环境的电脑上运行java项目,制作exe文件


如果你对 javaFX 感兴趣,你可以看下我 gitgub上使用 javaFX 开发的一个应用: XTool

在这里插入图片描述


Javafx教程:
Javafx教程
w3cschool-javafx教程
JavaFX概述和教程
javafxchina
JavaFX入门(一):我的第一个JavaFX程序
JavaFX Scene Builder的使用
如何在JavaFX中创建文本区域
javafx项目打包
使用exe4j将java文件打成exe文件运行详细教程
JavaFX 入门
JavaFX的几个新特性,让Swing彻底过时
JavaFX FXML教程
JavaFX FXML教程
JavaFX FXML教程
JavaFX FXML
JavaFX入门(四):JavaFX布局(一)
最通俗易懂——JavaFX可视化窗口如何插入图片
快速创建基于JavaFX的桌面App
JavaFx的那些坑
JavaFX 加载 fxml 文件 方法三 在 Controller 对 Stage 进行操作
Stage窗口介绍,打开新窗口
场景切换
fxml场景切换
JavaFX - 实现管理多个Stage窗口切换及源码解析
JavaFx的Stage管理实现切换案例——登录页面
scenebuilder教程-与Controller类进行绑定、scenebuilder生成Controller类
JavaFx教程第四部分:CSS 样式
JavaFx之整合JFoenix(十四)
JavaFX绑定
JavaFx2.0—Binding
JavaFX属性与绑定
场景切换
场景切换
JavaFX: FXML嵌套和子Controller(Sub-Controller)
JavaFx嵌套控制器
使用 JavaFx 示例将文本和图像复制到剪贴板

  • 3
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值