- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
例如,当我们向 Pane 添加新按钮时,我们需要编写以下代码:
StackPane pane = new StackPane();
pane.getChildren().add(new Button("OK"));
StackPane pane = new StackPane();
pane.add(new Button("OK"));
最佳答案
简短的答案就是“您必须那样做,因为这就是API的编写方式”。当然,您可能真正要问的是为什么要这样编写API。我认为这实际上是两个(相关的)问题。一种与方法名称有关,以及该方法的作用,另一种与实际的API设计有关。
通常,在计算中,重用现有的问题解决方案通常是有益的。 (知道何时进行此操作是一种艺术,但是在这两种情况下显然都是有益的。)通过两种不同的方式,此API设计将现有的解决方案重用到了众所周知的问题上,从而使之成为现实。对于以前遇到过这些解决方案的程序员来说,更容易理解和使用。
场景图
从总体上看,考虑一下通用用户界面的整体结构。有一个大容器(包含JavaFX场景的根源),其中包含各种UI组件。其中一些可能是简单的控件,例如按钮和标签等,其中一些可能是其他容器,这些容器又包含各种UI组件。当然,其中一些也可能是容器,依此类推。如果不强加某种结构,这可能变得复杂且难以使用。
为了理解结构,我们将其抽象化。有一个根节点,它有零个或多个其他节点的集合。每个节点都有零个或多个其他节点的集合,依此类推。这是计算中众所周知的抽象结构,称为“树”,基本上每个计算机程序员(无论使用哪种语言)都熟悉该结构。因此,如果我们将其视为树结构,因为我们已经很熟悉它,那么可以使复杂性更易于使用。为了将其视为树结构,我们对树状方面使用标准名称。每个节点(根节点除外)都只有一个“父”(它所属的容器):因此您会在Node
类中找到一个方法( getParent()
,这是树结构中的另一种术语),可以访问父节点(包含当前节点的容器)。类似地,包含其他节点的UI元素(节点)具有一种称为getChildren()
的方法,该方法返回当前节点中包含的所有节点的集合。 Oracle JavaFX教程在Scene graph上有一节对此进行了描述,其中包含许多漂亮的图表和相关代码。
简而言之,之所以有一种名为getChildren()
的方法,是因为我们将UI中所有事物的集合视为树结构,并且此方法名称准确地描述了该方法在所有集合的上下文中的作用UI元素是一棵树。具有一点经验的程序员可以立即识别术语“节点”,“父”和“子”,并帮助他们理解整体结构并与之合作。他们基本上可以立即推断出getChildren()
返回该容器中立即包含的所有UI元素的列表(该容器在您的示例中为StackPane
)。Pane
的API设计(例如StackPane
)
要考虑API设计,请考虑操作StackPane
中包含的内容,您可能想要做的所有事情。如您所见,您可能想向StackPane
添加一个新的UI元素(“节点”),因此您可能想要一个称为add(...)
的方法来接受Node
。但是,您可能还需要或想要做很多其他事情:
StackPane
删除一个节点StackPane
StackPane
StackPane
StackPane
类的设计人员可能已经编写了所有这些方法,但是有更好的方法。
StackPane
,则需要某种方式来跟踪其包含的节点(UI元素)。这些节点的顺序很重要,因此我们必须对其进行跟踪,并且需要有一种很好的方法来定义上面列出的所有功能。
StackPane
类(或其父类(super class)
Pane
)的作者可能已经构建了一个数据结构来从头开始执行此操作,但是标准库中已经存在一个数据结构。拥有某种特定类型的对象的集合并跟踪其顺序的数据结构称为
List
1,并且
List
接口(interface)是每个Java程序员都熟悉的接口(interface)。
StackPane
的实际实现,则可以在堆栈 Pane 本身中为上面列出的所有功能定义方法。最终看起来像什么(真的会比这更复杂,我只想在这里指出这一点)就像
public class StackPane {
private final List<Node> 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<Node> nodes) {
children.addAll(nodes);
}
// lots more methods like this...
// lots of layout code omitted...
}
StackPane
用户提供完全相同的功能:
public class StackPane {
private final List<Node> children = new ArrayList<>();
public List<Node> getChildren() {
return children ;
}
// layout code omitted...
}
List
,正如前面所指出的,这是一种非常知名的对象类型。假设他们具有一定的Java经验,那么JavaFX的新程序员将已经熟悉
List
的API,并且无需学习太多新知识就可以使用它。这样,程序员现在可以执行操作(使用非常规方式放置代码,并插入程序员的思想):
StackPane pane = new StackPane();
Button button = new Button("OK");
pane.getChildren()
// oooh, a List, I know how those work
.add(button);
List<Label> 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();
List
,API可以公开处理
StackPane
内容所需的所有功能,而无需在
StackPane
类中添加大量方法并以利用每个Java程序员的现有知识。
Pane
所需要的功能比List
中定义的要多:它们需要一种方便的方式来了解列表何时更改(通过添加或删除节点)(因为发生这种情况时 Pane 需要重新计算其布局)。因此,JavaFX团队定义了List
的子接口(interface)ObservableList
,它具有List
的所有功能,并添加了“观察”列表的功能。 List
定义的所有功能是否适合于子节点的集合?如果List
接口(interface)定义了一些在这里实际上没有意义的方法,那么使用此实现可能是一个坏主意,并且在第一个代码块中建议使用的更为膨胀的API实际上可能是一个更好的选择。 关于java - 在javaFx中,为什么在向窗口添加元素时为什么需要调用 “getChildren()”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41991574/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!