如何基于JavaFX开发桌面程序

基于JavaFX开发桌面程序

注:我也是JAVA FX的初学者之一,自己在学习的时候踩了许多的坑,中文英文的资料查了不少,但是觉得FX技术和其他热门技术相比,教程还是太少了。这里就尽量做一点微小的贡献吧

使用环境

注:写这个只是为了说明我的环境,使用和我的不一样的环境在理解这篇教程的时候并没有什么问题,例如使用Windows平台、使用Oracle JDK(这样就不需要再单独安装FX组件了,可以不用MAVEN)、使用Oracle的SceneBuilder。可能唯一一个比较影响体验的就是不使用IDEA而是使用eclipse了

  • Ubuntu18.04LTS
  • OpenJDK 1.8
  • IDEA(with MAVEN):使用MAVEN安装FX环境(OpenJDK不附带FX环境)
  • SceneBuilder(glounhq):这是一个fxml可视化设计环境,使用上不如C#,但起码比纯命令设计强一百倍

搭建JAVA FX环境

下载IDEA、OpenJDK1.8、SceneBuilder(glounhq).

SceneBuilder下载地址:https://gluonhq.com/products/scene-builder/#download

在IDEA中关联SceneBuilder.关联的目的是为了之后可以从IDEA快速打开SceneBuilder来设计页面

IDEA->File->Settings->Language->Java FX->输入SceneBuilder的路径

如果是Linux环境,你会发现这个路径还不好找,我是使用locate SceneBuilder命令找到的,路径是: /opt/SceneBuilder/SceneBuilder

因为OpenJDK没有FX环境,需要我们自己安装。为了便于管理,我们在这里使用MAVEN

在IDEA中创建一个Java FX项目

在项目名上右键,选择'Add framework support',选择MAVEN

在pom.xml文件中加入以下依赖:

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-controls -->
    <dependency>
      <groupId>org.openjfx</groupId>
      <artifactId>javafx-controls</artifactId>
      <version>13</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-fxml -->
    <dependency>
      <groupId>org.openjfx</groupId>
      <artifactId>javafx-fxml</artifactId>
      <version>13</version>
    </dependency>
  </dependencies>

设计流程

这里只写一些我已经探索出来的设计流程,如果有不对的请指出~

先在Resources中创建fxml文件(之所以放在Resources文件夹下,是为了加载的时候方便,之后能看到),创建完成后在文件名上右击,选择'Open in SceneBuilder',之后就可以在SceneBuilder中进行可视化设计了。设计时要注意,对有响应的元素要在code栏下的fx:id中设置id,以便于之后的调用。设计完成后Ctrl+s保存文件

设计第一个加载的界面。这个可以放在入口的java类的main方法下,举个例子:

package sample;

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

public class Main extends Application {

  @Override
  public void start(Stage primaryStage) throws Exception{

    Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("Entry.fxml"));//从Resources中获取资源
    primaryStage.setTitle("Course Registration System");
    primaryStage.setScene(new Scene(root, 800, 600));
    primaryStage.show();
  }

设计触发器:

对于每一个Panel,我们要指定一个触发器类,这个是放在该fxml文件中的,例如IDEA中默认创建的就是AnchorPane对象,在它那一行就能找到:fx:controller="sample.MainController" ,这个MainController就是我创建的一个类

之后,我们可以对该panel下各个控件设计触发事件后的反映,这个可以在SceneBuilder中填写,在Code那一栏下面。设计了之后,它就会到我们指定的那个触发器类下寻找这个方法,如果没有的话IDEA会提示你创建

注意,触发器类可以创建多个,这样更便于管理,降低耦合度

在触发器中获取fxml中的控件对象

有时候,我们需要在事件相应中获取对象的值,例如设计登录页面时点击'提交'的按钮,我们需要知道输入框的字符串。这时候我们可以在触发器中获取这些元素,前提是我们为这些控件输入了fx:id,它是全局性的,不允许重复。例如我们可以通过声明:

  @FXML
  private TextField username;
  @FXML
  private TextField password;

获取两个TextField对象下的值:

usernameString=username.getText();
passwordString=password.getText();

页面跳转

我们需要为每一个页面设计一个Java类,例如我设计了一个SignIn_Student.java:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class SignIn_Student extends Application{
  private String usernameString;
  private String passwordString;
  @Override
  public void start(Stage stage) throws Exception{
    Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("SignIn_Student.fxml"));//加载页面
    Scene anotherScene=new Scene(root);
    stage.setTitle("Please log in");
    stage.setScene(anotherScene);
    stage.show();
  }
}

TableView的使用

这个控件用起来着实有点麻烦。折腾了好久。

我们肯定需要在某一个fxml页面中加入了这个TableView,并且输入了Table和它每一个TableColumn的fx:id.

我们需要为有TableView的fxml文件单独创建一个控制器类,之后会说为什么

我们需要创建一个类来表示要储存的数据,例如我这里创建了一个Courses.class:(下面的get和set方法是IDEA自动生成的)

package sample;
import javafx.beans.property.*;
import java.time.LocalDate;
import java.time.LocalTime;
public class Courses {
  private final StringProperty department;
  private final StringProperty lecturer;
  private final ObjectProperty<LocalDate> Time;
  private final StringProperty location;
  private final IntegerProperty ID;

  public Courses(String name, String department, String lecturer, LocalDate time, String location, Integer ID) {
    this.name = new SimpleStringProperty(name);
    this.department = new SimpleStringProperty(department);
    this.lecturer = new SimpleStringProperty(lecturer);
    this.Time = new SimpleObjectProperty<LocalDate>(time);
    this.location = new SimpleStringProperty(location);
    this.ID = new SimpleIntegerProperty(ID);
  }
  //String,String,String, Date,String,Integer
  private final StringProperty name;

  public String getName() {
    return name.get();
  }

  public StringProperty nameProperty() {
    return name;
  }

  public void setName(String name) {
    this.name.set(name);
  }

  public String getDepartment() {
    return department.get();
  }

  public StringProperty departmentProperty() {
    return department;
  }

  public void setDepartment(String department) {
    this.department.set(department);
  }

  public String getLecturer() {
    return lecturer.get();
  }

  public StringProperty lecturerProperty() {
    return lecturer;
  }

  public void setLecturer(String lecturer) {
    this.lecturer.set(lecturer);
  }

  public LocalDate getTime() {
    return Time.get();
  }

  public ObjectProperty<LocalDate> timeProperty() {
    return Time;
  }

  public void setTime(LocalDate time) {
    this.Time.set(time);
  }

  public String getLocation() {
    return location.get();
  }

  public StringProperty locationProperty() {
    return location;
  }

  public void setLocation(String location) {
    this.location.set(location);
  }

  public int getID() {
    return ID.get();
  }

  public IntegerProperty IDProperty() {
    return ID;
  }

  public void setID(int ID) {
    this.ID.set(ID);
  }
}

我们需要实现的效果是,在加载这个页面时,表格中自动加载数据。填写我们创建的控制器类如下:

package sample;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

import java.time.LocalDate;

public class MainController {
  @FXML
  private TextField username;
  @FXML
  private TextField password;
  @FXML
  private TableView<Courses> allCoursesTable;
  @FXML
  private TableColumn<Courses,String> CourseNameAttribute;
  @FXML
  private TableColumn<Courses,String> DepartmentAttribute;
  @FXML
  private TableColumn<Courses,String> LectureAttribute;
  @FXML
  private TableColumn<Courses, LocalDate> TimeAttribute;
  @FXML
  private TableColumn<Courses,String> LocationAttribute;
  @FXML
  private TableColumn<Courses,Number> CourseIDAttribute;
  @FXML
  private void initialize() {
    ObservableList<Courses> data= FXCollections.observableArrayList(new Courses("MACHINE LEARNING","COMPUTER","ZHANGYI",LocalDate.of(2012,01,01),"A101",4011));//创建ObservableList对象,将数据装进去
    CourseNameAttribute.setCellValueFactory(cellData->cellData.getValue().nameProperty());
    DepartmentAttribute.setCellValueFactory(cellData->cellData.getValue().departmentProperty());
    LectureAttribute.setCellValueFactory(cellData->cellData.getValue().lecturerProperty());
    TimeAttribute.setCellValueFactory(cellData->cellData.getValue().timeProperty());
    LocationAttribute.setCellValueFactory(cellData->cellData.getValue().locationProperty());
    CourseIDAttribute.setCellValueFactory(cellData->cellData.getValue().IDProperty());
    allCoursesTable.setItems(data);//加载数据
  }
}

这就是为什么要用单独的控制器类了,否则initialize方法会在每次创建页面的时候都加载一次,而只有某一个页面有我们说的这些Tabel和Column对象,会报错的。

写一个方法来跳转到这个页面。

如何实现页面之间的传参呢?

对于要传参的页面,我们就不能直接获取parent对象了,而是先要获取FXMLLoader对象:

FXMLLoader fxmlLoader = new FXMLLoader(getClass().getClassLoader().getResource("MainPanel.fxml"));
Parent root = fxmlLoader.load();
MainController mc=fxmlLoader.getController();

注意这个MainController是我为这个页面写的控制器类

获取了Controller对象后,我们就可以调用方法,将参数传进去了:

    mc.setPassword(pass);
    mc.setUsername(user);
    mc.handleAllCourses();

我在MainController这个类中是这样写的:

  public void setUsername(String username){
    usernameString=username;
  }
  public void setPassword(String password){
    passwordString=password;
  }

这就是入门的FX教程了,有了这些基本的方法,相信设计一个稍微复杂一点的桌面应用程序已经不是问题了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • JavaFx UI控件与代码间的绑定方法

    JavaFx初探一,UI控件的使用,具体内容如下 方式一:使用纯代码直接new view控件,这样就不涉及到与fxml文件之间的交互了 方式二:使用fxml编写界面文件,用可视化工具scene builder 来构建交互界面. 分两种方式绑定控件,可以用Android的方法在java中直接调用类似findviewbyId的方法,先在xml文件中设置fxid,然后根据id去找这个控件,代码如下 @Override public void start(Stage primaryStage) thro

  • Javafx实现国际象棋游戏

    本文实例为大家分享了Javafx实现国际象棋游戏的具体代码,供大家参考,具体内容如下 基本规则 棋子马设计"日"的移动方式 兵设计只能向前直走,每次只能走一格.但走第一步时,可以走一格或两格的移动方式 请为后设计横.直.斜都可以走,步数不受限制,但不能越子的移动方式. 车只能横向或者竖向行走 国王是在以自己为中心的九宫格内行走 骑士只能走对角线 项目目录结构 UML类图关系 以骑士为例 实现基本功能 吃子 不能越子 游戏结束提示 基本移动策略 背景音乐 效果 控制器 PressedAc

  • JavaFX之TableView的使用详解

    TableView,算是一个很重要的控件,几乎随处可见,而且功能强大,数据展示效果良好.所以,在JavaFX中,我们自然而然也应该学习一下TableView的使用. 下面我们先看看TableView的效果图: 每一列都是一个TableColumn,我们可以直接创建也可以在JavaFX Scene Builder中创建好. TableView的数据填充,需要一个ObservableList.其中需要一个类来做数据填充. 下面看看我们数据填充的类: 复制代码 代码如下: import javafx.

  • javafx tableview鼠标触发更新属性详解

    本文实例为大家分享了javafx tableview鼠标触发更新属性,供大家参考,具体内容如下 public class HoverCell extends TableCell<Person, String> { public HoverCell(StringProperty hoverProperty) { setOnMouseEntered(e -> hoverProperty.set(getItem())); setOnMouseExited(e -> hoverProper

  • 详解JavaFX桌面应用开发-Group(容器组)

    1:Group的功能 Group可以管理一组节点 Group可以对管理的节点进行增删改查的操作 Group可以管理节点的属性 1.2:看看JDKSE1.9的API Group类有下列可以调用的方法 2:Group的使用 代码如下: package application; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.

  • JavaFX 监听窗口关闭事件实例详解

    1.写在前面 在JavaFX的程序开发的时候,在使用多线程的时候,默认情况下在程序退出的时候,新开的线程依然在后台运行. 在这种情况下,可以监听窗口关闭事件,在里面关闭子线程. 2.具体实现的样例 package sample; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import java

  • JavaFX Metro UI 和 开发库使用简介

    Metro UI For JavaFX! 这是一个Windows设计风格的UI库,使用非常简单,只要一行代码就可以实现整体UI风格的替换! new JMetro(JMetro.Style.LIGHT).applyTheme(scene);  例子 Switch Button 案例: 可以看到,非常的美观! 作者博客 : https://pixelduke.com/java-javafx-theme-jmetro 可以在他的博客中查看 Jmetro 项目的说明和使用方式. ConsrolsFX 这

  • javafx实现五子棋游戏

    需求描述 一个五子棋游戏,能实现双方黑白对决,当一方获胜时给出提示信息,利用GUI界面实现 项目结构如下图 一.实体 FiveChess类 提供五子棋实体包含的所有信息 判断游戏是否结束 play方法改变chess[][]棋盘中的数据 package entity; import javafx.scene.control.Alert; public class FiveChess{ public double getWidth() { return width; } public void se

  • 如何基于JavaFX开发桌面程序

    基于JavaFX开发桌面程序 注:我也是JAVA FX的初学者之一,自己在学习的时候踩了许多的坑,中文英文的资料查了不少,但是觉得FX技术和其他热门技术相比,教程还是太少了.这里就尽量做一点微小的贡献吧 使用环境 注:写这个只是为了说明我的环境,使用和我的不一样的环境在理解这篇教程的时候并没有什么问题,例如使用Windows平台.使用Oracle JDK(这样就不需要再单独安装FX组件了,可以不用MAVEN).使用Oracle的SceneBuilder.可能唯一一个比较影响体验的就是不使用IDE

  • 详解基于Wepy开发小程序插件(推荐)

    开发 wepy-plugin-autopages 使用 wepy 开发项目时不需要手动配置 app.wpy 下的 config.pages,autopages 插件会自动监控 pages 目录下文件的变化,自动生成更新对应 app.json 下的 pages. 注意:该插件只会对编译文件dist里配置添加,源文件是不会改动的. 注意:我还发现有个问题是他是按命名顺序添加的,所以开发阶段可以用客户端指定路径,但是发布的话还是乖乖手动添加吧 这插件看情况使用吧,如果是个人项目的话我觉得还是值得用的,

  • 基于Electron实现桌面应用开发代码实例

    Electron是一个可以使用 JavaScript,HTML 和 CSS 构建跨平台桌面应用程序的开源框架. 本文主要分享一下采用vue + electron开发桌面程序的搭建过程. 1. 环境准备 这里采用的是vue-cli3.x,可以通过下面的指令查看当前vue-cli的版本: vue --version# 3.9.3 这里我用的是3.9.3 如果没有装vue-cli可以通过下面的命令安装: npm install -g @vue/cli 如果是vue-cli还是2.x可以先卸载2.x然后

  • Python开发桌面小程序功能

    当使用桌面应用程序的时候,有没有那么一瞬间,想学习一下桌面应用程序开发?建议此次课程大家稍作了解不要浪费太多时间,因为没有哪家公司会招聘以为Python程序员开发桌面程序吧? 开发环境: Python 3.6 Pycharm 代码 界面设置 导入模块 import tkinter as tk 实例化一个窗体对象 root = tk.Tk() 标题 root.title('计算器') 大小以及出现的位置 root.geometry("295x280+150+150") 透明度 root.

  • 基于.net开发的遵循web标准的个人站点程序包下载

    基本信息 程序包名称:基于.net开发的遵循web标准的个人站点程序包下载 开发者主页:www.ceocio.net 软件大小:1.84mb 安装环境:Windows 2000/xp ;ASP.Net+SQL Server 版本:1.0 格式:RAR 软件说明 本程序包是www.ceocio.net站长liuwei友情提供,供有兴趣用.net开发符合web标准的网站的程序员参考. 作者关于本程序包的说明 该软件大家可自行修改源代码,如果可以的话请在您站点上打上我的连接:) 搞这个东东,最初是给自

  • 基于vue开发微信小程序mpvue-docs跳转页面功能

    打开github,把项目克隆下来https://github.com/F-loat/mpvue-quickstart 跳转页面,废话不多说直接点... 打开pages.js 默认是有两个页面的, 现在新添加一个newpage的页面 这样加就行了! 然后是 用模版上的方法去跳转页面已测试OK, 虽然是很简单的问题,但是没找到在哪写的,所以给记录下来!希望对你有用 总结 以上所述是小编给大家介绍的基于vue开发微信小程序mpvue-docs跳转页面功能,希望对大家有所帮助,如果大家有任何疑问请给我留

  • c#基于opencv,开发摄像头播放程序

    前言 Windows下实现摄像视频捕捉有多种实现方式:各种方式的优劣,本文不做对比.但是,opencv是一款老牌开发库,在图像处理领域声名显赫.采用opencv来处理摄像视频,在性能和稳定性上,是有保障的.并且,opencv包含很多图像处理函数,可以更方便的对视频处理. 执行程序是用wpf开发的,所以先将opencv封装成c语言接口,以供调用.opencv也不可能提供现成的控件供wpf使用,两种不同的开发语言"沟通"起来有些困难.其实稍作变通,就可以实现摄像头播放功能. 1 对open

  • 基于XML的桌面应用

    前面已经提到,通过XSL,我们可以把相同的数据以不同的数据形式提交给终端客户,一个XSL文件描述了数据的显示方式,你可以把许多XSL和同一个XML文档相连来提供不同的基于HTML的表示,这样事实上,我们就可以建立基于XML的桌面应用程序.基于Windows体系结构的一个图形表示如下所示: 采用这种方法主要有两个优点,首先,你可以以平台和语言独立的方式来操作数据,其次,不需要编程你就可以实现对同样数据的不同的视图表示. 实际上,你需要一个工具能够把原始的数据转化为XML格式化的形式,然后用HTML

  • ComposeDesktop开发桌面端多功能APK工具

    目录 前言 功能一览 多渠道打包 对齐和签名 配置签名 对齐 签名 其他内容 桌面端开发 弹窗 文件选择器 文件拖拽 数据的保存 资源的拷贝 打包MSI 总结 前言 终于算是忙完了一个阶段!!!从4月份开始,工作内容以及职务上都进行了较大的变动,最直接的就是从海外项目组调到了国内项目组. 国内项目组目前有两个应用在同时跑着,而且还有几个马甲包也要维护,不知道大家发版的时候复杂不复杂,反正我们每次发版的时候都需要经历--打包.加固.对齐.重签名.打渠道包.上传云存储.生成渠道推广链接.生成内更SQ

  • C# Windows API应用之基于GetDesktopWindow获得桌面所有窗口句柄的方法

    本文实例讲述了C# Windows API应用之基于GetDesktopWindow获得桌面所有窗口句柄的方法.分享给大家供大家参考,具体如下: Windows API Windows 这个多作业系统除了协调应用程序的执行.分配内存.管理资源-之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程式达到开启视窗.描绘图形.使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便称之为 Application Pro

随机推荐