iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
Software Development

玩轉ABCL Lisp!用奇怪偏門的方式學習JavaFX系列 第 16 篇

lesson 7: 第一個互動元件,按鈕:Hello Button & MessageBox & Action

  • 分享至 

  • xImage
  •  

TL;DR

這篇介紹如何建立 JavaFX Button、套用按鈕風格,以及透過 EventHandler 回應點擊事件。最後也會將事件結果顯示在 JavaFX 的訊息對話框中。

建立 Button

最簡單的互動元件應該就是按鈕了,建立一個按鈕加入到畫面:

(defun create-java-info-scene ()
  (prog* (......
          (btn-hello (new "javafx.scene.control.Button" "Hello")) ; 建立Button物件
          (box (new +VBox+ 50.5 (jnew-array-from-list "javafx.scene.Node"
                                 `(,label-java-version
                                   ,label-javafx-version
                                   ,btn-hello))))  ;; 將Button加入到畫面
          (scene-style (get-system-resource "res/style.css"))
          (result (new +scene+ box 640 480)))
     ......
     (return result)))

設定 Button 風格

在 res/style.css 加入按鈕的預設風格:

/* Style for all buttons */
.button {
    -fx-background-color: #34c669;
    -fx-text-fill: white;
    -fx-font-size: 14px;
    -fx-font-family: "Arial";
    -fx-font-weight: bold;
    -fx-background-radius: 5px;
    -fx-padding: 8px 16px;
}

/* Style when hovering over the button */
.button:hover {
    -fx-background-color: #28a745;
    -fx-cursor: hand;
}

/* Style when the button is clicked/pressed */
.button:pressed {
    -fx-background-color: #1e7e34;
}

綁定 Button 事件

要綁定事件處理,需要透過 Node.setOnAction(handler) 進行:

(#"setOnAction" btn-hello *hello-btn-handler*)

*hello-btn-handler*是javafx.event.EventHandler的實現物件,在ABCL可以透過#'jinterface-implementation建立:

(defvar *hello-btn-handler*
  (jinterface-implementation
   "javafx.event.EventHandler"
   "handle" (lambda (event)
              (format t "Action for Event ~A~%" event))))

因為 JavaFX 的事件處理幾乎都會用到 javafx.event.EventHandler,可以為此建立一個巨集:

(defmacro make-event-handler (args &body body)
  `(jinterface-implementation
   "javafx.event.EventHandler"
   "handle" (lambda ,args
              ,@body)))

如此可以簡化建立EventHandler物件的方式:

(make-event-handler (event)
  (format t "Action for Event ~A~%" event))
Action for Event #<javafx.event.ActionEvent javafx.event.ActionEvent[source=.... {6DF3D250}>
Action for Event #<javafx.event.ActionEvent javafx.event.ActionEvent[source=.... {CE29DC7}>
Action for Event #<javafx.event.ActionEvent javafx.event.ActionEvent[source=.... {7F70AF59}>
Action for Event #<javafx.event.ActionEvent javafx.event.ActionEvent[source=.... {7A3564DC}>
Action for Event #<javafx.event.ActionEvent javafx.event.ActionEvent[source=.... {642E6C0D}>

顯示點擊結果

讓應用不只是在終端機顯示訊息,進一步跳出一個訊息對話框,讓使用者知道已經點擊了按鈕:

(prog ((alert (make-messagebox "Clicked Button")))
   (#"show" alert))

#'make-messagebox是依照個人習慣建立的函式,實際上建立的是javafx.scene.control.Alert:

(defun make-messagebox (msg)
  (new +Alert+ +AlertType.INFORMATION+
       msg
       (jarray-from-list
        `(,+ButtonType.OK+))))

為簡化寫法,定義的一些常數:

(defconstant +Alert+ "javafx.scene.control.Alert")
(defconstant +AlertType+ "javafx.scene.control.Alert$AlertType")
(defconstant +AlertType.INFORMATION+
  (jfield +AlertType+ "INFORMATION"))
(defconstant +ButtonType+ "javafx.scene.control.ButtonType")
(defconstant +ButtonType.OK+
  (jfield +ButtonType+ "OK"))

畢竟我最早接觸的視窗程式是 VB6,在 JAVA-calculator 也使用 Swing 的 MessageDialog()。

執行結果

按下按鈕後,程式會觸發事件處理器,並顯示點擊結果:

https://ithelp.ithome.com.tw/upload/images/20260929/20112470uvFMvyMP7T.png

這篇完成了第一個 JavaFX 互動元件。後續可以再延伸處理更多 Dialog 類型與互動情境。


上一篇
lesson 6: 怎麼設定個別元素風格? 用Style ID & Style Class設定場景風格
下一篇
lesson 8: 資料雙向綁定:Hello {Name}!發揮 ABCL 的威力
系列文
玩轉ABCL Lisp!用奇怪偏門的方式學習JavaFX 共 18 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言