<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # JavaFX 事件 > 原文: [http://zetcode.com/gui/javafx/events/](http://zetcode.com/gui/javafx/events/) GUI 應用是事件驅動的。 應用會對在其生命周期內生成的不同事件類型做出反應。 事件是由用戶(單擊鼠標),應用(計時器)或系統(時鐘)生成的。 事件是有關更改的通知。 它將狀態更改封裝在事件源中。 應用中已注冊的事件過濾器和事件處理器將接收事件并提供響應。 JavaFX 中的每個事件都具有三個屬性: * 事件來源 * 事件目標 * 事件類型 事件源是狀態更改的對象; 它產生事件。事件目標是事件的目的地。事件類型為相同`Event`類的事件提供了額外的分類。 事件源對象將處理事件的任務委托給事件處理器。 當事件發生時,事件源創建一個事件對象,并將其發送到每個注冊的處理器。 ## 事件處理器 `EventHandler`處理特定類或類型的事件。 事件處理器設置為事件源。 它具有`handle()`方法,在該方法中,我們將為響應生成的事件而調用的代碼放入其中。 `EventHandlerEx.java` ```java package com.zetcode; import javafx.application.Application; import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program uses two EventHandlers for * two different Events. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class EventHandlerEx extends Application { @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { HBox root = new HBox(); ContextMenu conMenu = new ContextMenu(); MenuItem noopMi = new MenuItem("No op"); MenuItem exitMi = new MenuItem("Exit"); conMenu.getItems().addAll(noopMi, exitMi); exitMi.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { Platform.exit(); } }); root.setOnMousePressed(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (event.isSecondaryButtonDown()) { conMenu.show(root, event.getScreenX(), event.getScreenY()); } } }); Scene scene = new Scene(root, 300, 250); stage.setTitle("EventHandler"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } } ``` 該示例將兩個`EventHandlers`用于兩個不同的`Events`。 ```java ContextMenu conMenu = new ContextMenu(); ``` `ContextMenu`是一個包含菜單項列表的彈出控件。 ```java MenuItem noop = new MenuItem("No op"); MenuItem exit = new MenuItem("Exit"); conMenu.getItems().addAll(noop, exit); ``` 將創建兩個`MenuItems`并將其添加到上下文菜單。 ```java exitMi.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { Platform.exit(); } }); ``` 使用`setOnAction()`方法,我們為`ActionEvent`設置了一個事件處理器。 `EventHandler`的`handle()`方法以`Platform.exit()`方法退出應用。 ```java root.setOnMousePressed(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (event.isSecondaryButtonDown()) { conMenu.show(root, event.getScreenX(), event.getScreenY()); } } }); ``` 使用`setOnMousePressed()`方法,我們為`MouseEvent`設置了一個事件處理器。 當我們單擊第二個鼠標按鈕(通常是右按鈕)時,上下文菜單將顯示在屏幕上。 它顯示在鼠標單擊的 x 和 y 坐標下方。 ## 事件屬性 以下程序探討了`MouseEvent`的屬性。 這是由于用戶與鼠標交互而發生的事件。 `EventSourceEx.java` ```java package com.zetcode; import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Pane; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program explores the properties of * an event. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class EventSourceEx extends Application { @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { Pane root = new Pane(); Rectangle rect = new Rectangle(30, 30, 80, 80); rect.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent e) { System.out.println(e.getSource()); System.out.println(e.getTarget()); System.out.println(e.getEventType()); System.out.format("x:%f, y:%f%n", e.getSceneX(), e.getSceneY()); System.out.format("x:%f, y:%f%n", e.getScreenX(), e.getScreenY()); } }); root.getChildren().addAll(rect); Scene scene = new Scene(root, 300, 250); stage.setTitle("Event properties"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } } ``` 在示例中,我們有一個矩形。 我們將事件處理器添加到鼠標單擊的事件類型。 ```java rect.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent e) { ... } }); ``` `setOnMouseClicked()`將事件處理器添加到鼠標單擊的事件類型。 處理器是一個匿名內部類。 當在矩形上檢測到鼠標單擊時,將調用其`handle()`方法。 ```java System.out.println(e.getSource()); System.out.println(e.getTarget()); System.out.println(e.getEventType()); ``` 這三個是通用屬性,可用于所有事件。 `getSource()`方法返回最初發生事件的對象。 `getTarget()`方法返回此事件的事件目標。 在我們的例子中,事件源和事件目標是相同的-矩形。 `getEventType()`方法返回`MouseEvent`的事件類型。 在我們的情況下,它返回`MOUSE_CLICKED`值。 ```java System.out.format("x:%f, y:%f%n", e.getSceneX(), e.getSceneY()); System.out.format("x:%f, y:%f%n", e.getScreenX(), e.getScreenY()); ``` 這四個屬性特定于此事件。 我們打印相對于場景和屏幕的鼠標單擊的 x 和 y 坐標。 ## Lambda 表達式 從 JDK 8 開始,可以使用 lambda 表達式替換匿名內部類。 ```java rect.setOnMouseClicked((MouseEvent e) -> { System.out.println(e.getSource()); System.out.println(e.getTarget()); System.out.println(e.getEventType()); System.out.format("x:%f, y:%f%n", e.getSceneX(), e.getSceneY()); System.out.format("x:%f, y:%f%n", e.getScreenX(), e.getScreenY()); }); ``` 這是使用 lambda 表達式重寫的上一個示例中的事件處理代碼。 ## 通用處理器 在下一個示例中,我們創建一個監聽所有類型事件的通用事件處理器。 `GenericHandlerEx.java` ```java package com.zetcode; import javafx.application.Application; import javafx.event.Event; import javafx.event.EventHandler; import javafx.event.EventType; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.StackPane; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program adds a generic event * handler to a button control. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class GenericHandlerEx extends Application { @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { StackPane root = new StackPane(); Button btn = new Button("Button"); btn.addEventHandler(EventType.ROOT, new GenericHandler()); root.getChildren().add(btn); Scene scene = new Scene(root, 300, 250); stage.setTitle("Generic handler"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } private class GenericHandler implements EventHandler<Event> { @Override public void handle(Event event) { System.out.println(event.getEventType()); } } } ``` 本示例具有一個按鈕控件。 通用處理器已插入按鈕。 ```java Button btn = new Button("Button"); btn.addEventHandler(EventType.ROOT, new GenericHandler()); ``` `addEventHandler()`方法將事件處理器注冊到指定事件類型的按鈕節點。 `EventType.ROOT`代表所有事件類型。 ```java private class GenericHandler implements EventHandler<Event> { @Override public void handle(Event event) { System.out.println(event.getEventType()); } } ``` 處理器使用其`handle()`方法將事件類型打印到控制臺。 ## 多種來源 可以將單個事件處理器添加到多個源。 可以使用`getSource()`方法確定事件的來源。 `MultipleSourcesEx.java` ```java package com.zetcode; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program plugs an EventHandler to multiple * controls. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class MultipleSourcesEx extends Application { private Label lbl; @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { AnchorPane root = new AnchorPane(); VBox vbox = new VBox(5); Button btn1 = new Button("Close"); Button btn2 = new Button("Open"); Button btn3 = new Button("Find"); Button btn4 = new Button("Save"); MyButtonHandler mbh = new MyButtonHandler(); btn1.setOnAction(mbh); btn2.setOnAction(mbh); btn3.setOnAction(mbh); btn4.setOnAction(mbh); vbox.getChildren().addAll(btn1, btn2, btn3, btn4); lbl = new Label("Ready"); AnchorPane.setTopAnchor(vbox, 10d); AnchorPane.setLeftAnchor(vbox, 10d); AnchorPane.setBottomAnchor(lbl, 10d); AnchorPane.setLeftAnchor(lbl, 10d); root.getChildren().addAll(vbox, lbl); Scene scene = new Scene(root, 350, 200); stage.setTitle("Multiple sources"); stage.setScene(scene); stage.show(); } private class MyButtonHandler implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent event) { Button btn = (Button) event.getSource(); lbl.setText(String.format("Button %s fired", btn.getText())); } } public static void main(String[] args) { launch(args); } } ``` 該示例有四個按鈕和一個標簽。 一個事件處理器將添加到所有四個按鈕。 觸發按鈕的名稱顯示在標簽中。 ```java Button btn1 = new Button("Close"); Button btn2 = new Button("Open"); Button btn3 = new Button("Find"); Button btn4 = new Button("Save"); ``` 這四個按鈕將共享一個事件處理器。 ```java MyButtonHandler mbh = new MyButtonHandler(); ``` 創建一個`MyButtonHandler`的實例。 它作為內部命名類實現。 ```java btn1.setOnAction(mbh); btn2.setOnAction(mbh); btn3.setOnAction(mbh); btn4.setOnAction(mbh); ``` 使用`setOnAction()`方法將處理器添加到四個不同的按鈕。 ```java private class MyButtonHandler implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent event) { Button btn = (Button) event.getSource(); lbl.setText(String.format("Button %s fired", btn.getText())); } } ``` 在`MyButtonHandler`的`handle()`方法內部,我們確定事件的來源并使用來源的文本標簽構建消息。 該消息通過`setText()`方法設置為標簽控件。 ![Multiple sources](https://img.kancloud.cn/f7/ba/f7ba0ef8c388d2af2037af2d25b19f95_352x226.jpg) 圖:多個來源 ## `java.util.Timer` `java.util.Timer`計劃任務以供將來在后臺線程中執行。 `TimerTask`是可以計劃為一次性執行或由計時器重復執行的任務。 `TimerEx.java` ```java package com.zetcode; import java.util.Timer; import java.util.TimerTask; import javafx.application.Application; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.Spinner; import javafx.scene.layout.HBox; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program uses a java.util.Timer to * schedule a task. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class TimerEx extends Application { int delay = 0; @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { HBox root = new HBox(10); root.setPadding(new Insets(10)); Timer timer = new java.util.Timer(); Spinner spinner = new Spinner(1, 60, 5); spinner.setPrefWidth(80); Button btn = new Button("Show message"); btn.setOnAction(event -> { delay = (int) spinner.getValue(); timer.schedule(new MyTimerTask(), delay*1000); }); root.getChildren().addAll(btn, spinner); stage.setOnCloseRequest(event -> { timer.cancel(); }); Scene scene = new Scene(root); stage.setTitle("Timer"); stage.setScene(scene); stage.show(); } private class MyTimerTask extends TimerTask { @Override public void run() { Platform.runLater(() -> { Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("Information dialog"); alert.setHeaderText("Time elapsed information"); String contxt; if (delay == 1) { contxt = "1 second has elapsed"; } else { contxt = String.format("%d seconds have elapsed", delay); } alert.setContentText(contxt); alert.showAndWait(); }); } } public static void main(String[] args) { launch(args); } } ``` 該示例有兩個控件:一個按鈕和一個微調器。 該按鈕將啟動計時器,延遲后將顯示一個消息對話框。 延遲由微調控件選擇。 ```java Timer timer = new java.util.Timer(); ``` 創建`java.util.Timer`的實例。 ```java Spinner spinner = new Spinner(1, 60, 5); ``` `Spinner`控件用于選擇延遲量。 它的參數是最小值,最大值和當前值。 該值以毫秒為單位。 ```java btn.setOnAction(event -> { delay = (int) spinner.getValue(); timer.schedule(new MyTimerTask(), delay*1000); }); ``` 在按鈕的事件處理器中,我們使用`getValue()`方法獲取微調框的當前值,并使用計時器的`schedule()`方法安排任務。 ```java stage.setOnCloseRequest(event -> { timer.cancel(); }); ``` 當使用計時器的`cancel()`方法終止應用時,我們將取消計時器。 ```java private class MyTimerTask extends TimerTask { @Override public void run() { Platform.runLater(() -> { Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("Information dialog"); alert.setHeaderText("Time elapsed information"); String contxt; if (delay == 1) { contxt = "1 second has elapsed"; } else { contxt = String.format("%d seconds have elapsed", delay); } alert.setContentText(contxt); alert.showAndWait(); }); } } ``` `runLater()`方法在 JavaFX 應用線程上執行任務。 我們顯示一個消息對話框,通知您經過的時間。 ![Time elapsed](https://img.kancloud.cn/17/9f/179f95531c7a39ab485034b958571e4c_362x178.jpg) 圖:經過的時間 ## 移動窗口 以下示例顯示了應用窗口在屏幕上的位置。 `MovingWindowEx.java` ```java package com.zetcode; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.VBox; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program shows the screen coordinates * of the application window in two labels. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class MovingWindowEx extends Application { int x = 0; int y = 0; Label lblx; Label lbly; @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { VBox root = new VBox(10); root.setPadding(new Insets(10)); String txt1 = String.format("x: %d", x); lblx = new Label(txt1); String txt2 = String.format("y: %d", y); lbly = new Label(txt2); root.getChildren().addAll(lblx, lbly); stage.xProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { doChange(newValue); } private void doChange(Number newValue) { x = newValue.intValue(); updateXLabel(); } }); stage.yProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { doChange(newValue); } private void doChange(Number newValue) { y = newValue.intValue(); updateYLabel(); } }); Scene scene = new Scene(root, 300, 250); stage.setTitle("Moving window"); stage.setScene(scene); stage.show(); } private void updateXLabel() { String txt = String.format("x: %d", x); lblx.setText(txt); } private void updateYLabel() { String txt = String.format("y: %d", y); lbly.setText(txt); } public static void main(String[] args) { launch(args); } } ``` 該示例顯示了兩個標簽控件中的當前窗口坐標。 為了獲得窗口位置,我們監聽舞臺的`xProperty`和`yProperty`的變化。 ```java String txt1 = String.format("x: %d", x); lblx = new Label(txt1); String txt2 = String.format("y: %d", y); lbly = new Label(txt2); ``` 這兩個標簽顯示了應用窗口左上角的 x 和 y 坐標。 ```java stage.xProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { doChange(newValue); } private void doChange(Number newValue) { x = newValue.intValue(); updateXLabel(); } }); ``` `xProperty`將舞臺的水平位置存儲在屏幕上。 我們添加一個`ChangeListener`來監聽屬性的更改。 每次修改屬性時,我們都會檢索新值并更新標簽。 ![Moving a window](https://img.kancloud.cn/0a/ad/0aadc563c2d2a30ef076e6ca91156a80_302x276.jpg) 圖:移動窗口 JavaFX 教程的這一部分專門討論 JavaFX 事件。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看