摘要:創建窗口添加類為元素間空隙與主窗口創建過程相同,新建布局及控件,最后使用的方法顯示出來。設置主窗口中的按鈕事件,點擊按鈕后會顯示一個窗口。這時我們可以通過函數設置窗口關閉時觸發的事件在關閉窗口時,首先執行這一事件處理函數,再將窗口關閉。
前言
如今比較流行的桌面gui框架有WPF、WinForm、Qt、javafx等。其中WPF和WinForm目前還只能在運行Winsows上。Qt(widget)是一個很強大的跨平臺C++框架(不只是UI),但用C++寫界面實在有點蛋疼,且編譯出來的體積很大。
JavaFX是基于JAVA的開源桌面框架,筆者曾學習過Qt,打算嘗試使用Java寫桌面應用,現在網上關于JavaFX的教程不時很多,因此在這里記錄一下學習過程。
安裝和配置JavaFX11的環境不包括在JDK中,因此要在配置好JDK11的基礎上多帶帶配置,具體方法可以參考JavaFX官網。
窗口構成新建工程,在Main.java中輸入下列代碼:
public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception{ VBox layout = new VBox(); Label label = new Label("Hello world"); layout.getChildren().add(label); Scene scene = new Scene(layout, 300, 300); primaryStage.setTitle("Hello World"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
JavaFX中的Stage可以看作是窗口,Scene是窗口中的內容,調用Stage的setScene函數來設置窗口內容,窗口可以在運行時切換顯示的Scene,實現Tab頁面的效果。
VBox是JavaFX中的一種布局,其中的元素縱向排列,向VBox中添加元素需要調用vbox.getChildren().add(control),如上所示。
構造Scene時傳入頂層的布局(類似Qt中QMainWindow的CentralWidget)及大小。最后調用show函數將窗口顯示出來。
按鈕控件控件(Control)是GUI框架中最重要的部分,也是用戶與程序進行交互的媒介。
在JavaFX中使用控件需要導入包,例如
import javafx.scene.control.Label; import javafx.scene.control.*;
框架中不同控件的使用方法大同小異,這里用最常用的按鈕作為示例。
在窗口中添加按鈕構造一個Button對象并添加到VBox中:
Button button = new Button("Click me"); VBox layout = new VBox(); layout.getChildren().add(button); Scene scene = new Scene(layout, 300, 300); primaryStage.setScene(scene);處理按鈕點擊事件 使用EventHandler接口
創建Handler類實現EventHandler接口
class Handler implements EventHandler{ @Override public void handle(ActionEvent actionEvent) { if(actionEvent.getSource() instanceof Button) ((Button) actionEvent.getSource()).setText("Click me again"); } }
為按鈕注冊點擊方法
button.setOnAction(new Handler());
Button還有setOnMouseClicked,setOnTouchPressed等方法,這些是專門為處理鼠標事件及觸摸事件,setOnAction函數用來處理按鈕觸發事件(不管按鈕被哪種方式觸發,具體參考文檔)。
由代碼可以得出,setOnAction函數接收一個EventHandler接口,接口的handle方法用來處理事件。
使用匿名內部類與上一方法同理,我們可以使用匿名內部類創建接口
button.setOnAction(new EventHandler使用Lambda表達式() { @Override public void handle(ActionEvent actionEvent) { if(actionEvent.getSource() instanceof Button) ((Button) actionEvent.getSource()).setText("Click me again"); } });
Java中的一些接口可以由lambda表達式代替,因此可以在setOnAction中傳入lambda表達式:
button.setOnAction(actionEvent -> { if(actionEvent.getSource() instanceof Button){ ((Button) actionEvent.getSource()).setText("Click me again"); } });
這樣就可以在實現簡單的事件處理器時不必再特意實現接口。
其他控件使用其他控件的方法也都類似按鈕,使用時可以查詢文檔,或者根據IDE的代碼提示獲知函數簽名及使用方法。
多窗口在一個桌面程序中往往有多個窗口,下面介紹添加窗口的方法。
創建窗口添加MsgBox類
public class MsgBox { public static void show(String title) { Stage window = new Stage(); window.setTitle(title); Button trueButton = new Button("True"); Button falseButton = new Button("False"); HBox hBox = new HBox(10); //10為元素間空隙 hBox.getChildren().addAll(trueButton, falseButton); Scene scene = new Scene(hBox, 100, 100); window.setScene(scene); window.show(); } }
與主窗口創建過程相同,新建stage、Scene、布局及控件,最后使用Stage的show方法顯示出來。
調用MsgBox類的show方法即可顯示窗口,函數的參數為窗口的標題。
設置主窗口中的按鈕事件,點擊按鈕后會顯示一個MsgBox窗口。
button.setOnAction(actionEvent -> MsgBox.show("SubWindow"));窗口模態
Stage對象可以使用initModality方法設置窗口模態類型
window.initModality(Modality.WINDOW_MODAL);
類型包括 Modality.NONE, Modality.WINDOW_MODAL, Modality.APPLICATION_MODAL。
Modality.NONE: 不阻塞任何窗口
Modality.WINDOW_MODAL: 窗口級別的模態,僅僅阻塞與對話框關聯的窗口,用戶可以正常訪問其他窗口,適合用于多窗口的程序。
Modality.APPLICATION_MODAL(默認值): 應用程序級別的模態,窗口將阻塞整個程序,無法訪問程序中其他的窗口
返回子窗口的值有時我們需要得到用戶在子窗口中的操作,例如在本文的例子中,獲知用戶點了哪一個按鈕。
接下來實現這樣的功能——點擊True按鈕就在控制臺打印true,否則打印"false"。
更改MsgBox中的代碼
public static boolean show(String title) { Stage window = new Stage(); window.setTitle(title); Button trueButton = new Button("True"); Button falseButton = new Button("False"); trueButton.setOnAction(actionEvent -> { answer = true; window.close(); }); falseButton.setOnAction(actionEvent -> { answer = false; window.close(); }); HBox hBox = new HBox(10); hBox.getChildren().addAll(trueButton, falseButton); Scene scene = new Scene(hBox, 100, 100); window.setScene(scene); window.showAndWait(); return answer; }
show函數返回一個boolean類型的值,這個值是由點擊的按鈕決定的,按鈕點擊后會關閉窗口,返回布爾值。
設置主窗口中按鈕點擊事件
button.setOnAction(actionEvent -> { var result = MsgBox.show("SubWindow"); System.out.println(result); });showAndWait函數
這個函數會阻塞當前事件,直到窗口被關閉后才會返回,并執行接下類的語句。在上例中,我們顯示窗口并等待,直到點擊按鈕使窗口被關閉,才執行后面的return answer語句。
可以嘗試改為調用show方法,觀察返回的結果。
窗口的關閉有時在用戶關閉窗口時,需要執行一定的操作,例如保存設置、確認是否退出等。
這時我們可以通過setOnCloseRequest函數設置窗口關閉時觸發的事件
window.setOnCloseRequest(windowEvent -> { System.out.println("The window will be closed!"); });
JavaFX在關閉窗口時,首先執行這一事件處理函數,再將窗口關閉。但在某些情況下(例如確認是否關閉),我們需要在處理事件時取消窗口的關閉,這種情況下可以調用windowEvent的consume方法,告訴事件系統,此事件已經被處理完畢,不必再執行其他處理動作(如關閉窗口)。
將主窗口的代碼改為:
@Override public void start(Stage primaryStage) throws Exception { Button button = new Button("Click me"); button.setOnAction(actionEvent -> { var result = MsgBox.show("SubWindow"); System.out.println(result); }); VBox layout = new VBox(); layout.getChildren().add(button); Scene scene = new Scene(layout, 300, 300); primaryStage.setScene(scene); primaryStage.setTitle("Hello World"); primaryStage.setOnCloseRequest(windowEvent -> { var result = MsgBox.show("Do you want to CLOSE?"); if (result == false) { windowEvent.consume(); } }); primaryStage.show(); }
當用戶點擊關閉按鈕時,將會彈窗詢問是否關閉,若用戶點擊False按鈕窗口就不會被關閉。
鏈接推薦一個很好的JavaFX教程視頻:https://youtu.be/FLkOX4Eez6o
一個適合初學者的Qt教程:https://www.devbean.net/2012/...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77425.html
摘要:故可采用自定義控件的方式簡化外部的代碼調用。自定義控件的設計版本之后,提供寫法,此時要求必須繼承自節點對象,使用加載時,必須調用方法。 「博客搬家」 原地址: 簡書 原發表時間: 2017-05-21 有一個項目,需要模擬數千臺設備的工作情況,這數千個設備分為若干組,每組 100 臺。故需要設計一款 GUI 程序,包含 100 個自定義控件,模擬一組設備的工作情況,通過 List...
摘要:本文探討使用構建集成的可執行程序的方法,以及根節點問題。而使用后,可指導類作為根節點,避免了嵌套的情況。文件設計如下文件同時指明了根節點的類型,資源文件對應的設計如下此時可實現開始時,純代碼方式的自定義控件設計。 「博客搬家」 原地址: 簡書 原發表時間: 2017-05-22 上一篇文章探討了使用 IntelliJ IDEA 創建 JavaFX 工程,進而開發了所需應用程序。更...
摘要:中獲取并自定義窗口移動與縮放邏輯由于去掉了平臺自帶了標題欄,窗口就無法移動和縮放了,需要我們自己來實現。 JavaFx中Controller獲取Stage并自定義窗口移動與縮放邏輯 由于去掉了平臺自帶了標題欄,窗口就無法移動和縮放了,需要我們自己來實現。 去除窗口標題欄 public class Main extends Application { @Override ...
匿名類 匿名類可以使你代碼更簡潔,它們使你能夠同時聲明和實例化一個類,它們就像局部類,除了它們沒有名稱,如果你只需要使用局部類一次,請使用它們。 聲明匿名類 雖然局部類是類聲明,但匿名類是表達式,這意味著你在另一個表達式中定義該類,以下示例HelloWorldAnonymousClasses在局部變量frenchGreeting和spanishGreeting的初始化語句中使用匿名類,但使用局部類...
摘要:如果你想查看運行時模塊的加載過程輸出結果表示為模塊,由于我限制了不再往下輸出了,而我們模塊又沒有別的額外依賴,所以僅有這行輸出。 jdk9模塊快速入門 列出自帶模塊:java --list-modulesmac多版本jdk共存:http://adolphor.com/blog/2016...模塊規則示意圖:showImg(https://segmentfault.com/img/bVb...
閱讀 3019·2021-11-24 10:21
閱讀 1588·2021-10-11 10:57
閱讀 2803·2021-09-22 15:24
閱讀 2659·2021-09-22 14:58
閱讀 2331·2019-08-30 13:16
閱讀 3478·2019-08-29 13:05
閱讀 3411·2019-08-29 12:14
閱讀 3440·2019-08-27 10:55