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.
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
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 :canmessage
和 pctovcumessage
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
Modifierpcutovcumessage
中,我需要访问 fxml 属性 in_desiredvelocity
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é fxmlin_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.
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 entreclasses
, et non entreobjetsmainviewcontroller
的每个实例都会有一个名为 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,
champpctovcumessage
实例,其 id 为 "222"
。由于 pctovcumessage
继承自 canmessage
,因此该新实例也是 canmessage
的实例,并且由于 canmessage
继承自 mainviewcontroller
,因此该实例也是 mainviewcontrollerzqbendczq 的实例b,由于 <code>mainviewcontroller
的每个实例都有一个字段 indesiredvelocity
,因此 pctovcumessage
的这个新实例有一个名为 indesiredvelocity
的字段,类型为 textfield
Une référence au champ de texte déclaré dans fxml.
Plus tard dans votre contrôleur, vous ferez cecipctovcumessage
中的 indesiredvelocity
new pctovcumessage("222")Bien sûr, cela crée une nouvelle
instance avec l'identifiant "222"
. Puisque textfield
hérite 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
indesiredvelocity
de type . new pctovcumessage("222")
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 的东西)。
一些与您的代码无关的问题:
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!