如何基于JavaFX開發(fā)桌面程序
基于JavaFX開發(fā)桌面程序
注:我也是JAVA FX的初學者之一,自己在學習的時候踩了許多的坑,中文英文的資料查了不少,但是覺得FX技術和其他熱門技術相比,教程還是太少了。這里就盡量做一點微小的貢獻吧
使用環(huán)境
注:寫這個只是為了說明我的環(huán)境,使用和我的不一樣的環(huán)境在理解這篇教程的時候并沒有什么問題,例如使用Windows平臺、使用Oracle JDK(這樣就不需要再單獨安裝FX組件了,可以不用MAVEN)、使用Oracle的SceneBuilder??赡芪ㄒ灰粋€比較影響體驗的就是不使用IDEA而是使用eclipse了
- Ubuntu18.04LTS
- OpenJDK 1.8
- IDEA(with MAVEN):使用MAVEN安裝FX環(huán)境(OpenJDK不附帶FX環(huán)境)
- SceneBuilder(glounhq):這是一個fxml可視化設計環(huán)境,使用上不如C#,但起碼比純命令設計強一百倍
搭建JAVA FX環(huán)境
下載IDEA、OpenJDK1.8、SceneBuilder(glounhq).
SceneBuilder下載地址:https://gluonhq.com/products/scene-builder/#download
在IDEA中關聯(lián)SceneBuilder.關聯(lián)的目的是為了之后可以從IDEA快速打開SceneBuilder來設計頁面
IDEA->File->Settings->Language->Java FX->輸入SceneBuilder的路徑
如果是Linux環(huán)境,你會發(fā)現(xiàn)這個路徑還不好找,我是使用locate SceneBuilder命令找到的,路徑是: /opt/SceneBuilder/SceneBuilder
因為OpenJDK沒有FX環(huán)境,需要我們自己安裝。為了便于管理,我們在這里使用MAVEN
在IDEA中創(chuàng)建一個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>
設計流程
這里只寫一些我已經(jīng)探索出來的設計流程,如果有不對的請指出~
先在Resources中創(chuàng)建fxml文件(之所以放在Resources文件夾下,是為了加載的時候方便,之后能看到),創(chuàng)建完成后在文件名上右擊,選擇'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();
}
設計觸發(fā)器:
對于每一個Panel,我們要指定一個觸發(fā)器類,這個是放在該fxml文件中的,例如IDEA中默認創(chuàng)建的就是AnchorPane對象,在它那一行就能找到:fx:controller="sample.MainController" ,這個MainController就是我創(chuàng)建的一個類
之后,我們可以對該panel下各個控件設計觸發(fā)事件后的反映,這個可以在SceneBuilder中填寫,在Code那一欄下面。設計了之后,它就會到我們指定的那個觸發(fā)器類下尋找這個方法,如果沒有的話IDEA會提示你創(chuàng)建
注意,觸發(fā)器類可以創(chuàng)建多個,這樣更便于管理,降低耦合度
在觸發(fā)器中獲取fxml中的控件對象
有時候,我們需要在事件相應中獲取對象的值,例如設計登錄頁面時點擊'提交'的按鈕,我們需要知道輸入框的字符串。這時候我們可以在觸發(fā)器中獲取這些元素,前提是我們?yōu)檫@些控件輸入了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文件單獨創(chuàng)建一個控制器類,之后會說為什么
我們需要創(chuàng)建一個類來表示要儲存的數(shù)據(jù),例如我這里創(chuàng)建了一個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);
}
}
我們需要實現(xiàn)的效果是,在加載這個頁面時,表格中自動加載數(shù)據(jù)。填寫我們創(chuàng)建的控制器類如下:
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));//創(chuàng)建ObservableList對象,將數(shù)據(jù)裝進去
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);//加載數(shù)據(jù)
}
}
這就是為什么要用單獨的控制器類了,否則initialize方法會在每次創(chuàng)建頁面的時候都加載一次,而只有某一個頁面有我們說的這些Tabel和Column對象,會報錯的。
寫一個方法來跳轉到這個頁面。
如何實現(xiàn)頁面之間的傳參呢?
對于要傳參的頁面,我們就不能直接獲取parent對象了,而是先要獲取FXMLLoader對象:
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getClassLoader().getResource("MainPanel.fxml"));
Parent root = fxmlLoader.load();
MainController mc=fxmlLoader.getController();
注意這個MainController是我為這個頁面寫的控制器類
獲取了Controller對象后,我們就可以調用方法,將參數(shù)傳進去了:
mc.setPassword(pass);
mc.setUsername(user);
mc.handleAllCourses();
我在MainController這個類中是這樣寫的:
public void setUsername(String username){
usernameString=username;
}
public void setPassword(String password){
passwordString=password;
}
這就是入門的FX教程了,有了這些基本的方法,相信設計一個稍微復雜一點的桌面應用程序已經(jīng)不是問題了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
詳解 Java中日期數(shù)據(jù)類型的處理之格式轉換的實例
這篇文章主要介紹了詳解 Java中日期數(shù)據(jù)類型的處理之格式轉換的實例的相關資料,日期以及時間格式處理,在Java中時間格式一般會涉及到的數(shù)據(jù)類型包括Calendar類和Date類,需要的朋友可以參考下2017-08-08
Spring Data JPA結合Mybatis進行分頁查詢的實現(xiàn)
本文主要介紹了Spring Data JPA結合Mybatis進行分頁查詢的實現(xiàn)2024-03-03
maven在settings.xml和pom.xml中指定jdk版本編譯的方法
在開發(fā)Java應用時,通常需要指定要使用的Java版本,下面這篇文章主要給大家介紹了關于maven在settings.xm和pom.xml中指定jdk版本編譯的方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-05-05
Spring?Boot項目中使用OpenAI-Java的示例詳解
Spring?Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發(fā)過程,這篇文章主要介紹了Spring?Boot項目中使用OpenAI-Java的示例詳解,需要的朋友可以參考下2023-04-04
springboot yml中profiles的巧妙用法(小白必看多環(huán)境配置)
這篇文章主要介紹了springboot yml中profiles的巧妙用法,非常適合多環(huán)境配置場景,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
springboot項目中引入本地依賴jar包并打包到lib文件夾中
這篇文章主要介紹了springboot項目中引入本地依賴jar包,如何打包到lib文件夾中,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04

