提交 7f30ea13 编写于 作者: W wizardforcel

2021-10-05 22:40:11

上级 7fd6b488
......@@ -10,7 +10,7 @@
* 在应用程序中嵌入 HTML
* 在应用程序中嵌入媒体
* 向控件添加效果
* 使用 robotapi
* 使用 RobotAPI
# 介绍
......@@ -28,7 +28,7 @@
许多使用 Swing 的桌面应用程序已经构建,其中许多仍在使用中。然而,随着时间的推移,技术必须不断发展;否则,它最终将过时,很少使用。2008 年,Adobe 的**Flex**开始受到关注。它是构建**富互联网应用程序****RIAs**)的框架。桌面应用程序始终是基于丰富组件的 UI,但 Web 应用程序的使用并不令人惊讶。Adobe 引入了一个名为 Flex 的框架,它使 Web 开发人员能够在 Web 上创建丰富的沉浸式 UI。因此,Web 应用程序不再枯燥乏味。
Adobe 还为桌面引入了富 internet 应用程序运行时环境,称为**Adobe AIR**,允许在桌面上运行 Flex 应用程序。这是对由来已久的 Swing API 的重大打击。但让我们回到市场:2009 年,Sun Microsystems 推出了一款名为**JavaFX**的产品。该框架受 Flex(使用 XML 定义 UI)的启发,并引入了自己的脚本语言**JavaFXScript**,这有点接近 JSON 和 JavaScript。您可以从 JavaFX 脚本调用 JavaAPI。引入了一种新的体系结构,它有一个新的窗口工具包和一个新的图形引擎。它是 Swing 更好的替代方案,但它有一个缺点,开发人员必须学习 JavaFX 脚本来开发基于 JavaFX 的应用程序。除了 Sun Microsystems 无法在 JavaFX 和 Java 平台上进行更多投资外,一般来说,JavaFX 从未像预想的那样起飞。
Adobe 还为桌面引入了富互联网 应用程序运行时环境,称为**Adobe AIR**,允许在桌面上运行 Flex 应用程序。这是对由来已久的 Swing API 的重大打击。但让我们回到市场:2009 年,Sun Microsystems 推出了一款名为**JavaFX**的产品。该框架受 Flex(使用 XML 定义 UI)的启发,并引入了自己的脚本语言**JavaFXScript**,这有点接近 JSON 和 JavaScript。您可以从 JavaFX 脚本调用 JavaAPI。引入了一种新的体系结构,它有一个新的窗口工具包和一个新的图形引擎。它是 Swing 更好的替代方案,但它有一个缺点,开发人员必须学习 JavaFX 脚本来开发基于 JavaFX 的应用程序。除了 Sun Microsystems 无法在 JavaFX 和 Java 平台上进行更多投资外,一般来说,JavaFX 从未像预想的那样起飞。
Oracle(在收购 Sun Microsystems 之后)宣布了新的 JavaFX 版本 2.0,这是对 JavaFX 的完全重写,从而消除了脚本语言,使 JavaFX 成为 Java 平台中的 API。这使得使用 JavaFXAPI 与使用 swingAPI 类似。此外,还可以在 Swing 中嵌入 JavaFX 组件,从而使基于 Swing 的应用程序更具功能性。从那时起,JavaFX 就不再回头了。
......@@ -179,7 +179,7 @@ java -p "PATH_TO_JAVAFX_SDK_LIB:COMPILED_CODE" <other parts of the command line>
`Scene`的一个实例包含 UI 组件的图形,称为**场景图**
10. 我们已经看到,`start()`方法为我们提供了对`Stage`对象的引用。`Stage`对象是 JavaFX 中的顶级容器,类似于 JFrame。我们将`Scene`对象设置为`Stage`对象,并使用其`show()`方法呈现 UI:
10. 我们已经看到,`start()`方法为我们提供了对`Stage`对象的引用。`Stage`对象是 JavaFX 中的顶级容器,类似于`JFrame`。我们将`Scene`对象设置为`Stage`对象,并使用其`show()`方法呈现 UI:
```java
stage.setTitle("Age calculator");
......@@ -187,7 +187,7 @@ java -p "PATH_TO_JAVAFX_SDK_LIB:COMPILED_CODE" <other parts of the command line>
stage.show();
```
11. 现在我们需要从 main 方法启动这个 JavaFXui。我们使用`Application`类的`launch(String[] args)`方法来启动 JavaFXUI:
11. 现在我们需要从`main`方法启动这个 JavaFXui。我们使用`Application`类的`launch(String[] args)`方法来启动 JavaFXUI:
```java
public static void main(String[] args) {
......@@ -235,9 +235,9 @@ java -p "PATH_TO_JAVAFX_SDK_LIB:COMPILED_CODE" <other parts of the command line>
* `launch(Class<? extends Application> appClass, String... args)`
* `launch(String... args)`
此方法是从主方法调用的,只应调用一次。第一个变量采用扩展`javafx.application.Application`类的类的名称以及传递给 main 方法的参数,第二个变量不采用类的名称,而是应从扩展`javafx.application.Application`类的类中调用。在我们的食谱中,我们使用了第二种变体。
此方法是从主方法调用的,只应调用一次。第一个变量采用扩展`javafx.application.Application`类的类的名称以及传递给`main`方法的参数,第二个变量不采用类的名称,而是应从扩展`javafx.application.Application`类的类中调用。在我们的食谱中,我们使用了第二种变体。
我们创建了一个类`CreateGuiDemo`,扩展了`javafx.application.Application`。这将是 JavaFXUI 的入口点,我们还向该类添加了一个 main 方法,使其成为应用程序的入口点。
我们创建了一个类`CreateGuiDemo`,扩展了`javafx.application.Application`。这将是 JavaFXUI 的入口点,我们还向该类添加了一个`main`方法,使其成为应用程序的入口点。
布局构造决定了零部件的布局方式。JavaFX 支持多种布局,如下所示:
......@@ -510,7 +510,7 @@ Pane pane = (Pane)loader.load(getClass()
您在网页上看到的元素或组件通常根据网站的主题进行样式设置。通过使用名为**CSS**的语言,可以实现此样式。CSS 由一组由分号分隔的`name:value`对组成。这些`name:value`对,当与 HTML 元素关联时,比如说`<button>`,为它提供了所需的样式。
有多种方法可以将这些`name:value`对与元素关联,最简单的方法是将这个`name:value`对放在 HTML 元素的 style 属性中。例如,要为按钮提供蓝色背景,我们可以执行以下操作:
有多种方法可以将这些`name:value`对与元素关联,最简单的方法是将这个`name:value`对放在 HTML 元素的`style`属性中。例如,要为按钮提供蓝色背景,我们可以执行以下操作:
```java
<button style="background-color: blue;"></button>
......@@ -528,7 +528,7 @@ Pane pane = (Pane)loader.load(getClass()
#btn1 { background-color: blue; }
```
3. 通过使用 HTML 元素的 class 属性。假设我们有一个带有`class="blue-btn"`的按钮,那么我们可以定义一个选择器`.blue-btn`,根据它我们提供 CSS 属性。请查看以下示例:
3. 通过使用 HTML 元素的`class`属性。假设我们有一个带有`class="blue-btn"`的按钮,那么我们可以定义一个选择器`.blue-btn`,根据它我们提供 CSS 属性。请查看以下示例:
```java
.blue-btn { background-color: blue; }
......@@ -749,7 +749,7 @@ java -p "PATH_TO_JAVAFX_SDK_LIB:COMPILED_CODE" <other parts of the command line>
将类分配给组件后,我们需要为给定的类名编写 CSS 属性。然后,这些属性将应用于具有相同类名的所有组件。
让我们从我们的配方中挑选一种成分,看看我们是如何设计它的。考虑以下两个组件,即 Tyt0}和 OutT1
让我们从我们的配方中挑选一种成分,看看我们是如何设计它的。考虑以下两个组件,即`btn``btn-primary`
```java
primaryBtn.getStyleClass().add("btn");
......@@ -784,7 +784,7 @@ primaryBtn.getStyleClass().add("btn-primary");
`getStylesheets()`的文件说明如下:
URL 是[scheme:][//authority][path]形式的分层 URI。如果 URL 没有[scheme:]组件,则 URL 仅被视为[path]组件。忽略[path]的任何前导“/”字符,[path]被视为相对于应用程序类路径根的路径
URL 是`[scheme:][//authority][path]`形式的分层 URI。如果 URL 没有`[scheme:]`组件,则 URL 仅被视为`[path]`组件。忽略`[path]`的任何前导`/`字符,`[path]`被视为相对于应用程序类路径根的路径
在我们的配方中,我们只使用`path`组件,因此它在类路径中查找文件。这就是为什么我们将样式表添加到与场景相同的包中。这是一种在类路径上使其可用的更简单的方法。
......@@ -900,7 +900,7 @@ java -p "PATH_TO_JAVAFX_SDK_LIB:COMPILED_CODE" <other parts of the command line>
前面的方法使用新的基于流的 API。这些 API 非常强大,他们使用`Collectors.groupingBy()`对学生进行分组,然后使用`Collectors.summarizingInt()`计算他们的成绩统计。
4. 条形图的数据作为`XYChart.Series`的实例提供。对于给定的`x`值,每个系列产生一个`y`值,对于给定的`x`值,这是一个 bar。我们将有多个系列,每个学期一个,即第一学期成绩、第二学期成绩和最后一个成绩。让我们创建一个方法,该方法接受每个学期成绩和`seriesName`的统计信息,并返回一个`series`对象:
4. 条形图的数据作为`XYChart.Series`的实例提供。对于给定的`x`值,每个系列产生一个`y`值,对于给定的`x`值,这是一个条形。我们将有多个系列,每个学期一个,即第一学期成绩、第二学期成绩和最后一个成绩。让我们创建一个方法,该方法接受每个学期成绩和`seriesName`的统计信息,并返回一个`series`对象:
```java
private XYChart.Series<String,Number> getSeries(
......@@ -1212,7 +1212,7 @@ java -p "PATH_TO_JAVAFX_SDK_LIB:COMPILED_CODE" <other parts of the command line>
一旦我们得到了`PieChart`实例,我们将它们添加到`GridPane`中,然后使用`GridPane`构建场景图。场景图必须与`Stage`关联,才能在屏幕上渲染。
main 方法通过调用`Application.launch(args);`方法来启动 UI。
`main`方法通过调用`Application.launch(args);`方法来启动 UI。
JavaFX 提供用于创建不同类型图表的 API,如以下图表:
......@@ -1249,7 +1249,7 @@ java -p "PATH_TO_JAVAFX_SDK_LIB;COMPILED_CODE" <other parts of the command line>
java -p "PATH_TO_JAVAFX_SDK_LIB:COMPILED_CODE" <other parts of the command line>
```
我们将需要一个互联网连接来测试网页的加载。因此,请确保您已连接到 internet。除此之外,使用此配方不需要任何具体要求。
我们将需要一个互联网连接来测试网页的加载。因此,请确保您已连接到互联网。除此之外,使用此配方不需要任何具体要求。
# 怎么做。。。
......@@ -1875,7 +1875,7 @@ reflection.setFraction(0.8);
我们建议您以与我们相同的方式尝试这些效果。
# 使用 robotapi
# 使用 Robot API
**Robot API**用于模拟屏幕上的键盘和鼠标动作,这意味着您将指示代码在文本字段中键入一些文本,选择一个选项,然后单击按钮。来自 Web UI 测试背景的人可以将其与 Selenium 测试库联系起来。**抽象窗口工具包****AWT**)是 JDK 中较老的窗口工具包,提供了 Robot API,但在 JavaFX 上使用相同的 API 并不简单,需要一些技巧。名为**Glass**的 JavaFX 窗口工具包有自己的[机器人 API](https://openjfx.io/javadoc/11/javafx.graphics/javafx/scene/robot/Robot.html),但这些不是公开的。因此,作为 OpenJFX11 发行版的一部分,为同一版本引入了新的公共 API。
......@@ -2046,7 +2046,7 @@ public static void captureScreen(){
}
```
6. 我们将在`main()`方法中绑定 UI 的启动和创建的 helper 方法,如下所示:
6. 我们将在`main()`方法中绑定 UI 的启动和创建的助手方法,如下所示:
```java
public static void main(String[] args)
......
......@@ -718,7 +718,7 @@ Spring2.5 引入了基于注释的上下文配置。springioc 容器与配置元
</dependency>
```
然后,我们创建一个可执行的 Java 类(即,使用 main 方法)。注意,在这个类中,类级别有一个注释:`@ComponentScan`。这是 Spring 中非常重要的注释,因为它允许声明 Spring 将在其中以注释的形式查找 Bean 定义的包。如果未定义特定的包(如示例中所示),则将从声明此注释的类的包(在示例中为包`io.github.bonigarcia`)进行扫描。在 main 方法的主体中,我们使用`AnnotationConfigApplicationContext`创建 Spring 应用程序上下文。从该上下文中,我们得到了类为`MessageComponent`的 Spring 组件,并将其`getMessage()`方法的结果写入标准输出:
然后,我们创建一个可执行的 Java 类(即,使用`main`方法)。注意,在这个类中,类级别有一个注释:`@ComponentScan`。这是 Spring 中非常重要的注释,因为它允许声明 Spring 将在其中以注释的形式查找 Bean 定义的包。如果未定义特定的包(如示例中所示),则将从声明此注释的类的包(在示例中为包`io.github.bonigarcia`)进行扫描。在`main`方法的主体中,我们使用`AnnotationConfigApplicationContext`创建 Spring 应用程序上下文。从该上下文中,我们得到了类为`MessageComponent`的 Spring 组件,并将其`getMessage()`方法的结果写入标准输出:
```java
package io.github.bonigarcia;
......@@ -1104,7 +1104,7 @@ dependencies {
}
```
为了将原始 Spring 应用程序转换为 Spring Boot,我们的组件(在示例中称为`MessageComponent``MessageService`)将完全相同,但我们的主类将发生一些变化(参见此处)。请注意,我们在类级别使用注释`@SpringBootApplication`,使用 Spring Boot 的典型引导机制实现 main 方法。出于日志记录的目的,我们正在实现一个用`@PostConstruct`注释的方法。此方法将在应用程序上下文启动之前触发:
为了将原始 Spring 应用程序转换为 Spring Boot,我们的组件(在示例中称为`MessageComponent``MessageService`)将完全相同,但我们的主类将发生一些变化(参见此处)。请注意,我们在类级别使用注释`@SpringBootApplication`,使用 Spring Boot 的典型引导机制实现`main`方法。出于日志记录的目的,我们正在实现一个用`@PostConstruct`注释的方法。此方法将在应用程序上下文启动之前触发:
```java
package io.github.bonigarcia;
......
......@@ -166,7 +166,7 @@ TestNG 提供了更多的特性,并且比 JUnit 更高级。在本章中,我
想象一下,你的一位同事开始从事这个项目。他是一名优秀的程序员和 TDD 实践者,您相信他的能力能够覆盖良好的测试代码。换句话说,你可以信赖他的工作。然而,这位同事在休假前没有完成申请,你可以继续他停下来的地方。他创建了所有助手类:`Direction``Location``Planet``Point`。您会注意到相应的测试类也在那里。它们与正在测试的类同名,后缀为`Spec`(即`DirectionSpec`。使用此后缀的原因是为了明确测试不仅用于验证代码,而且还用作可执行规范。
helper 类之上,您可以找到`Ship`(实现)和`ShipSpec`(规范/测试)类。我们将把大部分时间花在这两门课上。我们将在`ShipSpec`中编写测试,然后在`Ship`类中编写实现代码(就像我们之前所做的那样)。
助手类之上,您可以找到`Ship`(实现)和`ShipSpec`(规范/测试)类。我们将把大部分时间花在这两门课上。我们将在`ShipSpec`中编写测试,然后在`Ship`类中编写实现代码(就像我们之前所做的那样)。
因为我们已经了解到,测试不仅是用来验证代码的一种方式,而且也是可执行文档,从现在起,我们将使用短语 specification 或 spec 来代替 test。
......@@ -288,7 +288,7 @@ public class ShipSpec {
执行使船向前和向后移动的命令(`f``b`)。
`Location`helper 类已经有了实现此功能的`forward``backward`方法:
`Location`助手类已经有了实现此功能的`forward``backward`方法:
```java
public boolean forward() {
......@@ -385,7 +385,7 @@ public boolean moveBackward() {
执行使船左右转动的命令(`l``r`)。
在实现了前面的需求之后,这个需求应该非常容易,因为它可以遵循相同的逻辑。`Location`helper 类已经包含了`turnLeft``turnRight`方法,它们可以精确地执行此需求所要求的内容。我们需要做的就是将它们集成到`Ship`类中。
在实现了前面的需求之后,这个需求应该非常容易,因为它可以遵循相同的逻辑。`Location`助手类已经包含了`turnLeft``turnRight`方法,它们可以精确地执行此需求所要求的内容。我们需要做的就是将它们集成到`Ship`类中。
# 规格-左转
......@@ -437,7 +437,7 @@ public void turnRight() {
# 需求-命令
到目前为止,我们所做的一切都相当简单,因为有助手类提供了所有的功能。本练习旨在学习如何停止尝试测试最终结果,并专注于我们正在处理的单元。我们正在建立信任;我们必须信任其他人(helper 类)完成的代码。
到目前为止,我们所做的一切都相当简单,因为有助手类提供了所有的功能。本练习旨在学习如何停止尝试测试最终结果,并专注于我们正在处理的单元。我们正在建立信任;我们必须信任其他人(助手类)完成的代码。
从这个需求开始,您必须信任自己编写的代码。我们将以同样的方式继续。我们将编写规范,运行测试,并看到它们失败;我们将编写实现,运行测试,并看到它们成功;最后,如果我们认为代码可以改进,我们将进行重构。继续思考如何测试单元(方法),而不深入单元将调用的方法或类。
......@@ -506,7 +506,7 @@ public void whenReceiveCommandsThenAllAreExecuted() {
}
```
这有点长,但仍然不是一个过于复杂的规范。我们正在传递命令`rflb`(右、前、左、后),并期望`Location`相应地改变。与前面一样,我们不验证最终结果(查看 if 坐标是否已更改),而是检查是否调用了对 helper 方法的正确调用。
这有点长,但仍然不是一个过于复杂的规范。我们正在传递命令`rflb`(右、前、左、后),并期望`Location`相应地改变。与前面一样,我们不验证最终结果(查看 if 坐标是否已更改),而是检查是否调用了对助手方法的正确调用。
# 实施
......@@ -642,7 +642,7 @@ public class Ship {
# 规范-处理地图边界
与其他情况一样,helper 类已经提供了我们需要的所有功能。到目前为止,我们使用了没有参数的`location.forward`方法。为了实现包装,有一个重载的`location.forward(Point max)`方法,当我们到达网格末端时,它将包装位置。在前面的规范中,我们确保将`Planet`传递给`Ship`类,并且它包含`Point max`。我们的工作是确保前进时使用`max`。规范可以是以下内容:
与其他情况一样,助手类已经提供了我们需要的所有功能。到目前为止,我们使用了没有参数的`location.forward`方法。为了实现包装,有一个重载的`location.forward(Point max)`方法,当我们到达网格末端时,它将包装位置。在前面的规范中,我们确保将`Planet`传递给`Ship`类,并且它包含`Point max`。我们的工作是确保前进时使用`max`。规范可以是以下内容:
```java
public void whenOverpassingEastBoundaryThenPositionIsReset() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册