Javafx:从组件本身中删除组件
我有一个带有主控制器的简单Javafx应用程序。在此主控制器中,我动态添加了此组件:
添加的组件:
fxml代码(paramvalue.fxml):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.HBox?>
<HBox alignment="CENTER" prefHeight="40.0" prefWidth="833.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demoSpreadsSheet.ParamValueController">
<children>
<Label prefHeight="95.0" prefWidth="83.0" text="Paramètre : " />
<TextField fx:id="paramName" prefHeight="32.0" prefWidth="300.0" />
<Label prefHeight="95.0" prefWidth="83.0" text="Valeur : ">
<HBox.margin>
<Insets left="40.0" />
</HBox.margin>
</Label>
<TextField fx:id="paramValue" prefHeight="32.0" prefWidth="300.0" />
<Button mnemonicParsing="false" prefHeight="25.0" prefWidth="12.0">
<HBox.margin>
<Insets left="20.0" />
</HBox.margin>
<graphic>
<ImageView fitHeight="26.0" fitWidth="21.0" onMouseClicked="#openSpreadSheet" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../Images/spreadsheet.png" />
</image>
</ImageView>
</graphic>
</Button>
<Button mnemonicParsing="false" onAction="#removeParamValue" prefHeight="25.0" prefWidth="12.0">
<graphic>
<ImageView fitHeight="26.0" fitWidth="21.0" onMouseClicked="#openSpreadSheet" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../Images/remove.png" />
</image>
</ImageView>
</graphic>
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</Button>
</children>
</HBox>
组件的控制器:
package com.example.demoSpreadsSheet;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
public class ParamValueController extends HBox {
@FXML TextField paramName, paramValue;
public ParamValueController() {}
@FXML
public void openSpreadSheet(){
}
@FXML
private void removeParamValue(){
//I don't know if it's possible to remove it here
}
}
我添加自定义组件的控制器:
package com.example.demoSpreadsSheet;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import java.io.IOException;
public class DoublonController extends BorderPane {
@FXML VBox paramValueList;
public DoublonController(){}
@FXML
public void initialize() throws IOException {
paramValueList.getChildren().addAll(createParamValueComponent(), createParamValueComponent());
}
private HBox createParamValueComponent() throws IOException {
FXMLLoader paramValueLoader = new FXMLLoader(DoublonController.class.getResource("paramValue.fxml"));
return paramValueLoader.load();
}
@FXML
private void addParamValue() throws IOException {
this.paramValueList.getChildren().add(createParamValueComponent());
}
}
当用户单击红十字时,我想删除此组件。问题在于,Redcross在我想删除的类中称之为“ RemoveParamValue()”函数,我认为这是不可能的。.
您有解决方法吗?
提前致谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您至少可以使用两种方法。
获取
parent
,如@kleopatra in 问题注释,您可以从“儿童”控制器内获取root fxml节点的父母,请检查它是否是
pane pane
的实例,如果是的,则修改父母的子女列表。例如:
这要求您将根FXML元素注入控制器。我将字段的名称
container
,其类型为hbox
,但是您可以将其命名为任何您想要的任何东西(只需确保添加相应的fx :id
属性属于FXML文件)。我还使用实例>实例
的模式匹配,该在Java中最终确定16。如果您至少不使用Java 16,则需要手动施放parent
到pane
。代码
注释的问题您无法使用
this.getParent()
,因为控制器本身从未添加到场景图中。实际上,使用您的代码当前的编写方式,您的控制器类别不应扩展hbox
(我假设您的其他控制器类也存在类似的问题)。也许您打算使用 ,但这涉及更改FXML文件的根元素以及如何加载FXML文件。阅读换句话说,除非您要使用
fx:root
,否则 扩展了Hbox 和从您的控制器类中扩展了BorderPane
。使用“回调”的
另一种方法是使用回调。将方法添加到您的
paramvaluecontroller
接受某些功能接口(例如,运行
):然后您的“删除param值”方法看起来像:
并且您要修改代码这样可以加载“孩子”的FXML:
就个人而言,我更喜欢这种方法更安全,更灵活,并且我认为更清楚。但这也比第一种方法更多。
There are at least two approaches you can use.
Get the
Parent
As mentioned by @kleopatra in a question comment, you can get the parent of the root FXML node from within the "child" controller, check if it is an instance of
Pane
and, if it is, then modify the parent's children list.For example:
This requires you to inject the root FXML element into the controller. I made the name of the field
container
, whose type would beHBox
, but you can name it anything you'd like (just make sure add the correspondingfx:id
attribute to the FXML file). I also made use of pattern matching forinstanceof
, which was finalized in Java 16. If you are not using at least Java 16, then you'll need to manually castparent
to aPane
.Problem With Your Code
Note you can't use
this.getParent()
, because the controller itself has never been added to the scene graph. In fact, with how your code is currently written, your controller class should not be extendingHBox
at all (and I assume a similar problem with your other controller class). Perhaps you meant to usefx:root
, but that would involve changing both the root element of your FXML file and how you load the FXML file. Read the linked documentation for more information.In other words, unless you want to use
fx:root
, remove theextends HBox
andextends BorderPane
from your controller classes.Use a "Callback"
The other approach is to use a callback. Add a method to your
ParamValueController
which accepts some functional interface (e.g.,Runnable
):Then your "remove param value" method would look like:
And you'd modify the code that loads the "child" FXML like so:
Personally, I prefer this approach as it's safer, more flexible, and in my opinion clearer. But it is also more work than the first approach.