Heim  >  Artikel  >  Wie kann ich FXML-annotierte Eigenschaften ordnungsgemäß erben, um sie in Unterklassen verfügbar zu machen?

Wie kann ich FXML-annotierte Eigenschaften ordnungsgemäß erben, um sie in Unterklassen verfügbar zu machen?

WBOY
WBOYnach vorne
2024-02-22 13:46:14710Durchsuche

PHP-Editor Xiaoxin präsentiert Ihnen diese Ausgabe von Java Q&A: Wie vererbt man FXML-annotierte Eigenschaften korrekt, um sie in Unterklassen verfügbar zu machen? In der Java-Entwicklung ist die korrekte Vererbung von FXML-annotierten Eigenschaften ein häufiges Problem und erfordert während des Entwicklungsprozesses Aufmerksamkeit. Im Folgenden besprechen wir ausführlich, wie Sie annotierte Eigenschaften korrekt erben und in Unterklassen verfügbar machen, um Ihnen bei der besseren Lösung dieses Problems zu helfen.

Frageninhalt

Frage

Ich versuche, die Nachrichtenübertragung über ein Controller Area Network zu implementieren, in dem Nachrichten basierend auf Benutzereingaben über eine mit Javafx erstellte GUI erstellt werden.

Ich habe einen Link zu main.fxml maincontroller 类。在 maincontroller 中,我定义了一个带 fxml 注释的 textfield 属性 in_desiredvelocity,该属性正确链接到 main.fxml 中的 fx:id.

Ich habe dann eine abstrakte Klasse canmessage definiert, die das Rückgrat der Nachrichten definiert, die über das Netzwerk gesendet werden müssen.

Die

Now-Klasse pctovcumessage 实现了特定类型的 canmessage。为了能够访问 fxml 属性(在 maincontroller 中定义),我决定抽象类 canmessage 扩展 maincontroller,而 pctovcumessage 扩展 canmessage implementiert einen bestimmten Typ von Canmessage. Um auf die fxml-Eigenschaften (definiert in maincontroller) zugreifen zu können, habe ich beschlossen, dass die abstrakte Klasse

maincontroller und

in_desiredvelocity nullpointerexception erweitert.

Die App wird korrekt kompiliert, aber wenn ich die GUI eingebe, wird das Textfeld gestartet .

Fragepctovcumessage 继承的(它继承自抽象类 canmessage 并且扩展了 maincontroller

Obwohl die obige fxml-Eigenschaft von geerbt wird (sie erbt von der abstrakten Klasse und erweitert maincontroller), wie kann ich sie in dieser Klasse verwenden, um mein Ziel zu erreichen?

Haupt:

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();
    }
}

Master-Controller:canmessagepctovcumessage

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 (es enthält eine abstrakte Klasse und

erweitert sie):

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{}


}
pcutovcumessage

Bearbeiten

pcutovcumessage 中,我需要访问 fxml 属性 in_desiredvelocity

Das Format der Can-Nachricht ist wie folgt: id(hex), data0, data1, data2, data3, ..., data7. Wenn ich also den Konstruktor von

im Controller aufrufe, übergebe ich die ID der Nachricht 222 (die übrigens im Datenblatt des Geräts angegeben ist) In

muss ich auf die fxml-Eigenschaft in_desiredvelocity zugreifen, die vom Benutzer durch Eingabe eines Werts in das Textfeld der GUI festgelegt wurde: Auf diese Weise kann der vom Benutzer eingegebene Wert zum Erstellen abgerufen werden Nachricht.

Edit 2

Da es mehrere Nachrichten mit unterschiedlichen IDs geben kann, habe ich darüber nachgedacht, Polymorphismus in der sendmessage-Methode im Controller zu verwenden. Darüber hinaus kann es Meldungen geben, die Zugriff auf mehrere FXML-Eigenschaften von der Controller-Klasse erfordern. Lösung

Das ist überhaupt nicht das, was die Vererbung bewirkt. Vererbung ist eine Beziehung zwischen

Klassen

, nicht zwischen

Objektenmainviewcontroller 的每个实例都会有一个名为 indesiredvelocity 的字段,其类型为 textfield.

Wenn du das tust

public class mainviewcontroller {
    // ...
    protected textfield indesiredvelocity;
    // ...
}

Das bedeutet canmessage 的每个实例也是 mainviewcontroller.

Wenn du das tustfxmlloader 会创建 mainviewcontroller 的实例(因为 fxml 中有 fx:controller="canbusgui.mainviewcontroller"),并在该实例中初始化 indesiredvelocity

public abstract class canmessage extends mainviewcontroller {
    // ...
}
Das bedeutet, dass jede Instanz von auch eine Instanz von mainviewcontroller ist.

Beim Laden von fxml,

Feld

pctovcumessage 实例,其 id 为 "222"。由于 pctovcumessage 继承自 canmessage,因此该新实例也是 canmessage 的实例,并且由于 canmessage 继承自 mainviewcontroller,因此该实例也是 mainviewcontrollerzqbendczq 的实例b,由于 <code>mainviewcontroller 的每个实例都有一个字段 indesiredvelocity,因此 pctovcumessage 的这个新实例有一个名为 indesiredvelocity 的字段,类型为 textfieldEin Verweis auf das in fxml deklarierte Textfeld.

Später in Ihrem Controller werden Sie dies tunpctovcumessage 中的 indesiredvelocity

new pctovcumessage(&quot;222&quot;)

Dadurch wird natürlich eine neue

Instanz mit der ID "222" erstellt. Da textfield von

erbt, ist diese neue Instanz auch eine Instanz von

, und da pctovcumessage von mainviewcontroller erbt, ist diese Instanz auch eine Instanz von mainviewcontrollerzqbendczq, da <code>mainviewcontroller Jede Instanz von hat ein Feld indesiredvelocity, daher hat diese neue Instanz von

ein Feld namens indesiredvelocity vom Typ

. new pctovcumessage(&quot;222&quot;)

Allerdings initialisieren Sie das Feld nie (und es gibt keine sinnvolle Möglichkeit, dies zu tun), daher ist das 🎜-Feld null. 🎜 🎜Es hat keinen Sinn, dies zu tun. Ich verstehe nicht wirklich, was Ihr Domänenmodell ist (ich muss die Frage wahrscheinlich nicht beantworten), aber es macht keinen Sinn, wenn 🎜 Teil eines Objekts vom Typ einer Nachricht ist.🎜 🎜Stattdessen kann es sinnvoll sein, die mit dieser Nachricht gesendeten Daten im Rahmen von 🎜 zu versenden. dh. Du kannst es schaffen 🎜
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{}


}
🎜 und ersetzen Sie 🎜 durch 🎜 im Controller
new PcToVcuMessage("222", Integer.parseInt(inDesiredVelocity.getText()))

然后只需从 canmessage 类中删除 extends mainviewcontroller 即可。这显然完全没有意义(消息不是控制 ui 的东西)。

一些与您的代码无关的问题:

  1. 不要使用文本字段注册按键处理程序。要处理用户按 enter 的操作,请以通常的方式使用操作处理程序。
  2. 适当地命名类和变量。类名称应该是名词(它们代表事物)。 canmessage 是一个动词(或动词短语)。可能 message 更合适,但我还是不太明白你在这里建模的内容。

Das obige ist der detaillierte Inhalt vonWie kann ich FXML-annotierte Eigenschaften ordnungsgemäß erben, um sie in Unterklassen verfügbar zu machen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen