java getchildren用法_在javaFx中,为什么在向窗口添加元素时为什么需要调用“ getChildren()”?...

小编典典

简短的答案就是“您必须那样做,因为这就是API的编写方式”。当然,您可能真正要问的是为什么要这样编写API。我认为这实际上是两个(相关的)问题。一种与方法名称有关,以及该方法的作用,另一种与实际的API设计有关。

通常,在计算中,重用现有的问题解决方案通常是有益的。(知道何时进行此操作是一门艺术,但是在这两种情况下,显然都是有益的。)以两种不同的方式,此API设计重用了现有的解决方案来解决众所周知的问题,因此使之成为现实。对于以前遇到过这些解决方案的程序员来说,更容易理解和使用。

场景图

从总体上看,考虑一下通用用户界面的整体结构。有一个大容器(包含JavaFX场景的根源),其中包含各种UI组件。其中一些可能是简单的控件,例如按钮和标签等,其中一些可能是其他容器,这些容器又包含各种UI组件。当然,其中一些也可能是容器,依此类推。如果不强加某种结构,这可能变得复杂且难以使用。

为了理解结构,我们将其抽象化。有一个根节点,它有零个或多个其他节点的集合。每个节点都有零个或多个其他节点的集合,依此类推。这是计算中非常著名的抽象结构,称为“树”,基本上每个计算机程序员(无论他们使用哪种语言)都熟悉。因此,如果我们将其视为树结构,因为我们已经很熟悉它,那么我们可以使复杂性更易于使用。为了将其视为树结构,我们对树状方面使用标准名称。每个节点(根节点除外)都只有一个“父”(它所属的容器):因此您将在Node该类中找到一个方法(“节点”是树结构中的另一种术语),称为getParent(),它可以访问父节点(包含当前节点的容器)。同样,包含其他节点的UI元素(节点)具有一种称为的方法getChildren(),该方法返回当前节点中包含的所有节点的集合。Oracle

JavaFX教程在“ 场景”图上有一节对此进行了描述,其中包含许多精美的图表和相关代码。

简而言之,之所以有一个方法被称为,getChildren()是因为我们认为UI中所有事物的集合都是树形结构,并且此方法名称准确地描述了该方法在所有对象集合的上下文中的作用。

UI元素是一棵树。具有一点经验的程序员可以立即识别术语“节点”,“父”和“子”,并帮助他们理解整体结构并与之合作。他们基本上可以立即推断出getChildren()返回立即包含在该容器中的所有UI元素的列表(该容器是StackPane您的示例中的)。

的API设计Pane(例如StackPane)

要考虑API设计,请考虑操作中可能包含的所有内容StackPane。如您所见,您可能想向中添加一个新的UI元素(“节点”)StackPane,因此您可能想要一个名为的方法add(...),该方法接受一个Node。但是,您可能还需要或想要做很多其他事情:

从节点中删除一个节点 StackPane

将整个节点集合添加到 StackPane

从中删除整个节点集合 StackPane

从(清除)移除所有节点 StackPane

由于节点在堆栈窗格中的顺序很重要(它定义了z顺序,即,如果节点重叠,它定义了哪些绘制在前面,哪些绘制在后面),因此您可能想在特定位置(前面)插入一个节点的东西,但后面的东西)

删除“后”,前或指定位置的节点

还有很多很多

因此,StackPane该类的设计师可以编写所有这些方法,但是有更好的方法。

如果考虑实现StackPane,则需要某种方式来跟踪其中包含的节点(UI元素)。这些节点的顺序很重要,因此我们必须对其进行跟踪,并且需要有一种很好的方法来定义上面列出的所有功能。StackPane该类(或其父类Pane)的作者本可以构建一个数据结构来从头开始执行此操作,但是标准库中已经存在一个。包含某种特定类型的对象的集合并跟踪其顺序的数据结构称为1,并且该接口是

每个Java程序员都熟悉

的接口。ListList

__

因此,如果考虑到的实际实现,则StackPane可以在堆栈窗格本身中为上面列出的所有功能定义方法。最终看起来有些东西(真的会比这更复杂,我只想在这里指出这一点)就像

public class StackPane {

private final List children = new ArrayList<>(); // or some other list implementation...

public void add(Node node) {

children.add(node);

}

public boolean remove(Node node) {

return children.remove(node);

}

public void add(int index, Node node) {

children.add(index, node);

}

public boolean remove(int index) {

return children.remove(index);

}

public void addAll(Collection nodes) {

children.addAll(nodes);

}

// lots more methods like this...

// lots of layout code omitted...

}

我认为你说对了。所有这些代码实际上并没有做什么。只是调用已定义的行为。因此,可以StackPane通过仅提供对列表本身的访问权限2来向用户提供完全相同的功能,而不用使用这种API肿的API

public class StackPane {

private final List children = new ArrayList<>();

public List getChildren() {

return children ;

}

// layout code omitted...

}

现在,该类不再那么blo肿,API也不再那么blo肿,此外,用户会收到List,如前所述,这是一种非常众所周知的对象类型。假设他们具有一定的Java经验,那么新的JavaFX程序员将已经熟悉该API,List并且无需学习太多新知识就可以使用它。因此,程序员现在可以执行此操作(使用非常规方式放置代码,并插入程序员的思想):

StackPane pane = new StackPane();

Button button = new Button("OK");

pane.getChildren()

// oooh, a List, I know how those work

.add(button);

List lotsOfLabels = Arrays.asList(new Label("One"), new Label("Two"), new Label("Three"));

pane.getChildren()

// still a list, I know more things I can do here:

.addAll(lotsOfLabels);

pane.getChildren().remove(button);

pane.getChildren().clear();

我们有一个高兴的程序员,他立即知道API,并且在第一次接触JavaFX中的场景图时立即产生了成果,因此,一个高兴的老板也看到了编程团队的高生产力。

因此,总而言之,通过简单地公开List子节点,API即可公开处理的内容所需的所有功能StackPane,而无需在StackPane类中添加大量方法

并 以利用现有知识的方式来实现每个Java程序员。

脚注

实际上,Panes需要的功能比以下中定义的要多List:他们需要一种方便的方式来了解列表何时更改(通过添加或删除节点)(因为发生这种情况时窗格需要重新计算其布局)。因此,JavaFX团队定义了一个List名为的子接口,该子接口ObservableList具有的所有功能,List并添加了“观察”列表的功能。

JavaFX团队在这里必须认真考虑一件事: 所有 定义的功能是否 都List适合于子节点的集合?如果该List接口定义了一些在这里实际上没有用的方法,那么使用此实现可能是一个坏主意,并且在第一个代码块中建议使用的更肿的API实际上可能是一个更好的选择。

2020-11-16

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Java的Timer类来实现暂停一秒钟的操作,具体步骤如下: 1. 导入java.util.Timer类。 2. 创建一个Timer对象。 3. 使用Timer对象的schedule方法,将需要暂停的操作封装在一个TimerTask对象,并设置延迟间为1秒。 4. 在TimerTask对象的run方法执行需要暂停的操作。 下面是一个简单的示例代码: ``` import java.util.Timer; import java.util.TimerTask; public class PauseOneSecond { public static void main(String[] args) { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { // 这里是需要暂停1秒钟的操作 System.out.println("暂停1秒钟"); } }, 1000); // 延迟1秒钟执行 } } ``` 在JavaFX,你可以将需要暂停的操作放在一个Platform.runLater方法,在TimerTask的run方法调用这个方法即可实现暂停1秒钟的效果。例如: ``` import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.util.Timer; import java.util.TimerTask; public class PauseOneSecondFX extends Application { @Override public void start(Stage primaryStage) throws Exception { VBox root = new VBox(); Label label = new Label("等待1秒钟"); root.getChildren().add(label); Scene scene = new Scene(root, 200, 100); primaryStage.setScene(scene); primaryStage.show(); Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { Platform.runLater(() -> { // 这里是需要暂停1秒钟的操作 label.setText("暂停1秒钟后,执行这里的操作"); }); } }, 1000); // 延迟1秒钟执行 } public static void main(String[] args) { launch(args); } } ``` 在这个示例,我们在JavaFX的start方法创建了一个Label,并将其添加到了一个VBox。然后,我们使用Timer类来实现暂停1秒钟的效果,在TimerTask的run方法使用Platform.runLater方法来更新Label的文本。最后,我们将这个VBox作为JavaFX窗口的根节点,并将窗口显示出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值