亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何正確設置自定義事件

如何正確設置自定義事件

茅侃侃 2022-12-15 16:19:49
好的 - 我已經為此奮斗了很久,閱讀了一百萬篇文章、教程等。它們似乎都沒有直接解決我在這里想做的事情。我有這個小代碼示例來說明?;旧希蚁M軌驈陌粹o引發/觸發自定義事件并讓標簽響應該事件。(請注意,除了我在這里嘗試使用實際的 Event 對象之外,我沒有興趣尋找其他方法來做到這一點。我非常清楚如何使用更改偵聽器等來做到這一點,但我想學習如何這樣做。)這是代碼,您可以看到它沒有得到我正在尋找的結果。其中大部分來自一些示例(對我來說并沒有真正起作用),我承認這里有些部分讓我“呼呼”。如果有人可以幫助我讓它工作,我可以稍后對其進行剖析以確保我了解到底發生了什么。這是代碼:import javafx.application.Application;import javafx.beans.property.ObjectProperty;import javafx.beans.property.SimpleObjectProperty;import javafx.event.Event;import javafx.event.EventHandler;import javafx.event.EventType;import javafx.geometry.Insets;import javafx.geometry.Pos;import javafx.scene.Scene;import javafx.sene.control.Button;import javafx.scene.control.Label;import javafx.scene.layout.VBox;import javafx.stage.Stage;//-------------------------------------------------------------------public class MyDemo extends Application {    public static void main(String[] args) {    launch(args);    }    @Override    public void start(Stage primaryStage) {    // label that should receive the event and react to it    MyLabel lblReceiver = new MyLabel("And I Should Receive & React");    // button to firs the event    Button btnSender = new Button("Initate Event");    btnSender.setPrefWidth(200);    btnSender.setOnAction(e -> {        MyEvent.fireEvent(lblReceiver, e); // really confused what the first parameter here is supposed to be.    });    // set up stage and show it    Stage stage = new Stage();    VBox root = new VBox(btnSender, lblReceiver);    root.setSpacing(10);    root.setPadding(new Insets(10, 10, 10, 10));    Scene scene = new Scene(root);    stage.setScene(scene);    stage.show();    }}
查看完整描述

1 回答

?
翻翻過去那場雪

TA貢獻2065條經驗 獲得超14個贊

回答

除了兩個問題外,您似乎已正確設置所有內容。


你永遠不會添加一個EventHandler監聽你的事件的。


實現任意接口不會使您的對象對您的自定義事件做出反應。事件處理系統不知道你的接口,甚至不知道你已經實現了它。如果您希望onMyEvent()在事件到達標簽時調用您的方法,則需要執行以下操作:


public MyLabel() {

    //...

    addEventHandler(MyEvent.MY_EVENT, event -> onMyEvent());

}

請注意,我使用addEventHandler的是類本身不依賴于該onMyEvent屬性。如果您依賴該屬性,則外部代碼可能會通過替換EventHandler.


這讓我想知道MyEventListener接口是否真的有必要。你不能在里面做你需要的EventHandler嗎?


您實際上從未觸發過您的MyEvent.


您目前擁有:


btnSender.setOnAction(e -> MyEvent.fireEvent(lblReceiver, e));

這只是將e(an ActionEvent) 重新點燃到lblReceiver. 該fireEvent方法是由static聲明的方法javafx.event.Event。為方法調用加上前綴MyEvent不會改變此處實際調用的方法。將其更改為以下內容:


btnSender.setOnAction(e -> Event.fireEvent(lblReceiver, new MyEvent()));

// or...

btnSender.setOnAction(e -> lblReceiver.fireEvent(new MyEvent()));


// The second option is a convenience method and simply forwards to Event.fireEvent

為了在您的標簽上實際觸發您自己的事件類的實例。

事件派發基礎

JavaFX 中的事件處理有兩個階段:

  • 捕獲階段

    • 第一階段。在這里,事件從其路徑的起點向下傳播到目標。在此過程中的每一步,都會調用適當的事件過濾器。過濾器是通過諸如Node.addEventFilter(EventType,EventHandler).

  • 冒泡階段

    • 第二階段。在這里,事件從目標返回到路徑的起點。在此過程中的每一步,都會調用適當的事件處理程序。處理程序是通過諸如 和 之類的方法和Node.addEventHandler(EventType,EventHandler)屬性添加的。Node.onKeyPressedButtonBase.onAction

事件處理由以下組件組成:

  • javafx.event.Event(和子類)

    • 實際對象傳遞過來。攜帶與事件相關的信息(例如MouseEvents 的光標位置)。

      一個Event也攜帶來源。但是,來源是動態的;它始終是EventHandler當前處理事件的對象。因此,EventHandler添加到 a的事件Button將具有Button作為事件源的事件,但同一事件將具有父級作為EventHandler添加到父級的源。即使您EventHandler兩次使用同一個實例,此行為也不會改變。

  • javafx.event.EventType

    • 細化一類的含義Event。例如,MouseEvent帶有MOUSE_PRESSED類型的 a 毫不奇怪地表示鼠標被按下了。一個EventType有一個超類型;這為每種事件形成了所有類型的層次結構。為超類型注冊的處理程序也將收到子類型的通知。

      不能有兩個或多個EventType具有相同超類型和名稱的 s。這就是為什么實例通常public static final是相應事件類的字段。

  • javafx.event.EventHandler

    • 處理其注冊的任何事件。這是一個功能接口(可以是 lambda 表達式或方法引用的目標)。執行應用程序級工作的是此接口的實現(即,在觸發按鈕時執行某些操作)。

  • javafx.event.EventDispatcher

    • 負責將事件分派給適當的處理程序。每個能夠成為事件目標的對象通常都有自己的調度程序。例如,每個Window、SceneNodeinstance 都有自己的EventDispatcher實例(保存在屬性中)。

      注意:在高度專業化的情況之外,您永遠不必直接處理此接口。

  • javafx.event.EventDispatchChain

    • 表示事件在目標處觸發時將采用的路徑。此接口的實例用作EventDispatchers 的堆棧。觸發事件時,將根據事件的目標創建和配置新鏈。在場景圖和目標是 a 的情況下Node,堆棧由EventDispatcher屬于 s的 s 組成Window,Scene然后每個Node向下到(父到子)并包括目標。事件沿這條鏈向下傳播(捕獲階段),然后返回這條鏈(冒泡階段)。

      注意:您可能永遠不需要直接使用此界面。

  • javafx.event.EventTarget

    • 事件的實際目標。該EventTarget接口具有一種用于構建EventDispatchChain. 換句話說,目標決定了事件的路徑。這是中的第一個參數Event.fireEvent(EventTarget,Event)

      注意:如果您正在創建一個可以(顯然)成為事件目標的對象(并且您的對象不是從 的實現擴展的EventTarget),則只需要使用此接口。



查看完整回答
反對 回復 2022-12-15
  • 1 回答
  • 0 關注
  • 108 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號