Maison >Java >Comment hériter correctement des propriétés annotées FXML pour les rendre disponibles dans les sous-classes ?

Comment hériter correctement des propriétés annotées FXML pour les rendre disponibles dans les sous-classes ?

WBOY
WBOYavant
2024-02-22 13:46:14762parcourir

L'éditeur PHP Xiaoxin vous propose ce numéro de questions-réponses Java : Comment hériter correctement des propriétés annotées FXML pour les rendre disponibles dans les sous-classes ? Dans le développement Java, hériter correctement des propriétés annotées FXML est un problème courant qui nécessite une attention particulière pendant le processus de développement. Ci-dessous, nous verrons en détail comment hériter correctement des propriétés annotées et les rendre disponibles dans les sous-classes pour vous aider à mieux résoudre ce problème.

Contenu de la question

Question

J'essaie d'implémenter le transfert de messages via un réseau de zone de contrôleur, où les messages sont construits en fonction des entrées de l'utilisateur via une interface graphique créée à l'aide de javafx.

J'ai un lien vers main.fxml maincontroller 类。在 maincontroller 中,我定义了一个带 fxml 注释的 textfield 属性 in_desiredvelocity,该属性正确链接到 main.fxml 中的 fx:id.

J'ai ensuite défini une classe abstraite canmessage qui définit l'épine dorsale des messages qui doivent être envoyés sur le réseau.

Maintenant, la classe pctovcumessage 实现了特定类型的 canmessage。为了能够访问 fxml 属性(在 maincontroller 中定义),我决定抽象类 canmessage 扩展 maincontroller,而 pctovcumessage 扩展 canmessage implémente un type spécifique de message can. Pour pouvoir accéder aux propriétés fxml (définies dans maincontroller), j'ai décidé que la classe abstraite

étend maincontroller, et

étend in_desiredvelocity nullpointerexception.

L'application se compile correctement, mais lorsque je tape dans l'interface graphique, le champ de texte est lancé .

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

Bien que la propriété fxml ci-dessus soit héritée par (elle hérite de la classe abstraite et étend maincontroller), comment puis-je l'utiliser dans cette classe pour atteindre mon objectif ?

Principal :

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

Contrôleur principal :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 (il contient une classe abstraite et

l'étend) :

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

Modifier

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

Le format du message can est le suivant : id(hex), data0, data1, data2, data3, ..., data7. Ainsi, lorsque j'appelle le constructeur de

dans le contrôleur, je transmets l'identifiant du message 222 (qui est d'ailleurs spécifié dans la fiche technique de l'appareil) Dans

, j'ai besoin d'accéder à la propriété fxml in_desiredvelocity qui a été définie par l'utilisateur en tapant une valeur dans le champ de texte de l'interface graphique : de cette façon, la valeur saisie par l'utilisateur peut être récupérée pour construire le message.

Edit 2

Comme il peut y avoir plusieurs messages avec des identifiants différents, j'ai pensé à utiliser le polymorphisme dans la méthode sendmessage du contrôleur. De plus, certains messages peuvent nécessiter l'accès à plusieurs propriétés fxml à partir de la classe du contrôleur. Solution

Ce n'est pas du tout ce que fait l'héritage. L'héritage est une relation entre

classes

, et non entre

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

Quand tu fais ça

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

Cela signifie canmessage 的每个实例也是 mainviewcontroller.

Quand tu fais çafxmlloader 会创建 mainviewcontroller 的实例(因为 fxml 中有 fx:controller="canbusgui.mainviewcontroller"),并在该实例中初始化 indesiredvelocity

public abstract class canmessage extends mainviewcontroller {
    // ...
}
Cela signifie que chaque instance de est également une instance de mainviewcontroller.

Lors du chargement de fxml,

champ

pctovcumessage 实例,其 id 为 "222"。由于 pctovcumessage 继承自 canmessage,因此该新实例也是 canmessage 的实例,并且由于 canmessage 继承自 mainviewcontroller,因此该实例也是 mainviewcontrollerzqbendczq 的实例b,由于 <code>mainviewcontroller 的每个实例都有一个字段 indesiredvelocity,因此 pctovcumessage 的这个新实例有一个名为 indesiredvelocity 的字段,类型为 textfieldUne référence au champ de texte déclaré dans fxml.

Plus tard dans votre contrôleur, vous ferez cecipctovcumessage 中的 indesiredvelocity

new pctovcumessage(&quot;222&quot;)

Bien sûr, cela crée une nouvelle

instance avec l'identifiant "222". Puisque textfield hérite de

, cette nouvelle instance est également une instance de

, et puisque pctovcumessage hérite de mainviewcontroller, cette instance est également une instance de mainviewcontrollerzqbendczq, puisque <code>mainviewcontroller Chaque instance de a un champ indesiredvelocity, donc cette nouvelle instance de

a un champ nommé indesiredvelocity de type

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

Cependant, vous n'initialisez jamais le champ (et il n'y a aucun moyen sensé de le faire), donc le champ 🎜 est nul. 🎜 🎜Cela ne sert à rien de faire ça. Je ne comprends pas vraiment quel est votre modèle de domaine (je n'ai probablement pas besoin de répondre à la question), mais cela n'a aucun sens que 🎜 fasse partie d'un objet de type une sorte de message.🎜 🎜Au lieu de cela, il pourrait être judicieux d'envoyer les données envoyées avec ce message dans le cadre de 🎜. c'est à dire. Vous pouvez le faire 🎜
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{}


}
🎜 et remplacez 🎜 par 🎜 dans le contrôleur
new PcToVcuMessage("222", Integer.parseInt(inDesiredVelocity.getText()))

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

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer