php小編小新為您帶來本期的Java問答:如何正確繼承FXML帶註解的屬性以使其在子類別中可用?在Java開發中,正確繼承FXML帶註解的屬性是常見問題,也是開發過程中需要注意的地方。下面我們將詳細討論如何正確繼承帶註釋的屬性,使其在子類別中可用,以幫助您更好地解決此問題。
問題內容
問題
#我正在嘗試透過控制器區域網路實現訊息傳輸,其中訊息是透過使用 javafx 創建的 gui 根據用戶輸入構建的。
我有一個連結到 main.fxml 的 maincontroller
類別。在 maincontroller
中,我定義了一個帶有 fxml 註解的 textfield 屬性 in_desiredvelocity
,該屬性正確連結到 main.fxml 中的 fx:id
。
然後我定義了一個抽象類別 canmessage
,它定義了必須透過網路傳送的訊息的主幹。
現在類別 pctovcumessage
實作了特定類型的 canmessage。為了能夠存取fxml 屬性(在maincontroller
中定義),我決定抽象類別canmessage
擴充功能maincontroller
,而pctovcumessage
擴充功能 canmessage
。
應用程式編譯正確,但當我在 gui 中輸入時,將啟動 textfield in_desiredvelocity
nullpointerexception
。
問題
儘管上述fxml 屬性是由pctovcumessage
繼承的(它繼承自抽象類別canmessage
並且擴展了maincontroller
),但我如何在此類中使用它來實現我的目標?
主要:
package canbusgui; import javafx.application.application; import javafx.fxml.fxmlloader; import javafx.scene.scene; import javafx.stage.stage; import java.io.ioexception; public class mainapplication extends application { public static stage stage = null; @override public void start(stage stage) throws ioexception { stage.setoncloserequest(event -> { system.exit(0); }); mainapplication.stage = stage; // create a fxmlloader to load the fxml file that defines the user interface fxmlloader fxmlloader = new fxmlloader(mainapplication.class.getresource("mainview.fxml")); scene scene = new scene(fxmlloader.load()); stage.settitle("canbus gui"); stage.setscene(scene); stage.setresizable(false); stage.setminheight(768); stage.setminwidth(1366); stage.show(); } public static void main(string[] args) { launch(); } }
主控制器:
package canbusgui; import javafx.application.platform; import javafx.collections.fxcollections; import javafx.fxml.fxml; import javafx.scene.input.keycode; import javafx.scene.input.keyevent; public class mainviewcontroller { @fxml protected textfield in_desiredvelocity; @fxml public void initialize (){ in_desiredvelocity.addeventfilter(keyevent.key_pressed, event -> { if (event.getcode() == keycode.enter) { try { sendmessage(new pctovcumessage("222")); } catch (exception e) { throw new runtimeexception(e); } } }); } public void sendmessage(canmessage message) throws exception { message.constructdata(); message.validateinputs(); byte[] data = message.getdata(); // send the data array to the can bus canbuscontroller.sendcommand(hexformat.fromhexdigits(message.getid()), data); } }
canmessage.java(它包含一個抽象類別 canmessage
和 pctovcumessage
擴充它):
package canbusgui; import static java.lang.Integer.parseInt; public abstract class canMessage extends MainViewController{ // Declare common attributes protected String id; protected byte[] data; public canMessage(String id) { this.id = id; // Initialize an empty byte array for data this.data = new byte[8]; } // Define an abstract method to construct the data array public abstract void constructData(); // Define an abstract method to validate the inputs public abstract void validateInputs() throws Exception; // Define a getter method for the data array public byte[] getData() { return this.data; } public String getId() { return this.id; } } // Define a subclass for PC_to_VCUMessage message class PcToVcuMessage extends canMessage { public PcToVcuMessage(String id) { // Call the superclass constructor super(id); } // Override the constructData method @Override public void constructData() { data[0] = (byte) 0; data[1] = (byte) 0; data[2] = (byte) 0; data[3] = (byte) parseInt(in_desiredVelocity.getText()); //HERE in_desiredVelocity is null and a NillPointerException is launched data[4] = (byte) 0; data[5] = (byte) 0; data[6] = (byte) 0; data[7] = (byte) 0; } public void validateInputs() throws Exception{} }
編輯
can 封包的格式如下:id(hex), data0, data1, data2, data3, ......, data7。因此,當我在控制器中呼叫 pcutovcumessage
的建構子時,我傳遞訊息 222 的 id(順便說一句,該 id 在裝置的資料表中指定)
在pcutovcumessage
中,我需要存取fxml 屬性in_desiredvelocity
,該屬性已由用戶透過在gui 的textfield 中鍵入值來設定:透過這種方式,可以檢索用戶鍵入的值以建構訊息。
編輯2
由於可以有多個具有不同id的訊息,所以我想到了在控制器中的sendmessage方法中使用多態性。此外,可能存在需要從控制器類別存取多個 fxml 屬性的訊息。
解決方法
這根本不是繼承的作用。繼承是類別之間的關係,而不是物件之間的關係。
當你這樣做時
public class mainviewcontroller { // ... protected textfield indesiredvelocity; // ... }
這意味著 mainviewcontroller
的每個實例都會有一個名為 indesiredvelocity
的字段,其類型為 textfield
。
當你這樣做時
public abstract class canmessage extends mainviewcontroller { // ... }
這表示 canmessage
的每個實例也是 mainviewcontroller
的實例。
載入fxml 時,fxmlloader
會建立mainviewcontroller
的實例(因為fxml 中有fx:controller="canbusgui.mainviewcontroller"
),並在該實例中初始化indesiredvelocity
欄位對fxml 中宣告的文字欄位的參考。
稍後在你的控制器中,你會這樣做
new pctovcumessage("222")
當然,這會創建一個新的 pctovcumessage
實例,其 id 為 "222"
。由於pctovcumessage
繼承自canmessage
,因此該新實例也是canmessage
的實例,並且由於canmessage
繼承自mainviewcontroller
,因此該實例也是mainviewcontrollerzqbendczq 的實例b,由於<code>mainviewcontroller
的每個實例都有一個字段indesiredvelocity
,因此pctovcumessage
的這個新實例有一個名為indesiredvelocity
的字段,類型為textfield
。
但是,您永遠不會初始化該欄位(並且沒有明智的方法可以這樣做),因此 pctovcumessage
中的 indesiredvelocity
欄位為 null。
這樣做沒有任何意義。我真的不明白你的域模型是什麼(我可能不需要回答這個問題),但是對於 textfield
作為類型為某種消息的對象的一部分沒有任何意義.
相反,將此訊息發送的資料作為 pctovcumessage
的一部分可能是有意義的。 ie。你可以做
class pctovcumessage extends canmessage { private int desiredvelocity ; public pctovcumessage(string id, int desiredvelocity) { // call the superclass constructor super(id); this.desiredvelocity = desiredvelocity; } // override the constructdata method @override public void constructdata() { data[0] = (byte) 0; data[1] = (byte) 0; data[2] = (byte) 0; data[3] = (byte) desiredvelocity; data[4] = (byte) 0; data[5] = (byte) 0; data[6] = (byte) 0; data[7] = (byte) 0; } public void validateinputs() throws exception{} }
並在控制器中將 new pctovcumessage("222")
替換為
new PcToVcuMessage("222", Integer.parseInt(inDesiredVelocity.getText()))
然后只需从 canmessage
类中删除 extends mainviewcontroller
即可。这显然完全没有意义(消息不是控制 ui 的东西)。
一些与您的代码无关的问题:
- 不要使用文本字段注册按键处理程序。要处理用户按 enter 的操作,请以通常的方式使用操作处理程序。
- 适当地命名类和变量。类名称应该是名词(它们代表事物)。
canmessage
是一个动词(或动词短语)。可能message
更合适,但我还是不太明白你在这里建模的内容。
以上是如何正確繼承 FXML 帶註解的屬性以使其在子類別中可用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),