如何创建一个动画的JavaFX字段验证警报

339 阅读9分钟

创建一个动画的JavaFX字段验证警报

一个好的界面是很重要的,因为它能增强用户和软件之间的互动。动画可以提高应用程序的质量。这也是一种提供反馈的有趣方式。

现代认证形式已经从古老的静态类型发展到了更多的互动类型。

今天,它们包括验证、造型和动画等方面。这些功能改善了交互过程。

在这篇文章中,我们将讨论基于用户交互的输入验证、效果和动画。

前提条件

要继续学习,你应该具备以下条件

  • 对Java编程语言有一些基本了解
  • 机器上安装了Java SDK
  • 机器上安装了一个Java IDE。

创建一个新项目

打开IDE,然后创建一个新项目。在project type 选项下,选择JavaFX

在右边的窗口中添加以下设置。

  • Name:登录
  • Group: 认证
  • Artifact:登录
  • Project SDK:你可以设置你系统上安装的最新SDK版本。

这些都显示在下面的图片中。

new javafx project

点击Next 按钮,然后在依赖关系窗口中选择BootstrapFX,ControlsFX, 和FormsFX 复选框。BootstrapFX 帮助对表单进行造型。

样式设计类似于CSS。ControlsFX 在项目中启用某些控件。这些控件包括TextFields、PasswordFields、Labels、DatePickers和许多其他控件。最后,FormFX 允许人们轻松设计表单。

上述步骤在下面的图片中得到了强调。

Dependencies

新创建的项目有以下文件夹结构。

文件夹结构

.
├── src
│   ├── main
│       ├── java
│          └── authentication
│             └── login
│                 ├── HelloApplication.java
│                 └── HelloController.java
│       └── resources
│          └── authentication
│             └── login
│                 └── hello-view.fxml
├── login.iml
└── pom.xml

打开hello-view.fxml 文件,该文件包含要显示的页面内容。在状态栏附近,有一个紧邻文本按钮的按钮。

点击它,使用Scene Builder ,查看FXML文件。如果它显示Failed to open the file in Scene Builder 错误,点击Download SceneBuilder

Download the Scene Builder

Project view in scene builder

当你运行该应用程序时,它将打开一个新的应用程序窗口。在这个用户界面中,有一个按钮,点击后会返回一个新的文本。

下面的图片显示了输出的情况。

Running the first project

失去了应用程序的下一个步骤。

创建登录表单

修改场景

HelloApplication.java 文件中,添加以下内容。

  • 将窗口的标题改为 "Login Form"。
  • 确保场景的宽度为400 by 600 pixels
  • 在JavaFX项目的标题标签中添加一个图标。

这些变化如下所示。

package authentication. login;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        
        // Set the scene width and height to 400 and 600 respectively
        Scene scene = new Scene(fxmlLoader.load(), 400, 600);
        
        // Set the name of the window to 'Login Form'
        stage.setTitle("Login Form");
        
        // Add an Icon to the title bar
        stage.getIcons().add(new Image(HelloApplication.class.getResourceAsStream("icon.png")));
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

设计视图

使用场景生成器打开hello-view.fxml 文件。删除VBOX 和其中的元素。

然后,在删除VBox的地方拖放一个AnchorPane。这个新的AnchorPane将容纳其他控件。AnchorPane将有以下功能。

风格

fx-text-fill:#8ecae6Pref Width: 400Pref Height: 600

上述布局使它能完美地融入场景中。从控件标签中拖放一个标签到SceneBuilder中央的AnchorPane中。该标签将有以下内容。

属性

Text:LOGINFont :System 25px Bold

风格

-fx-text-fill:#219ebc

样式

Pref Width:100Pref Height: 20Layout X: 150Layout Y: 40

当使用 "文本 "视图查看时,将自动生成以下代码。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="400.0" style="-fx-background-color: #8ecae6;" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1" fx:controller="authentication.login.HelloController">
  <!-- Contents inside the XML file -->
   <children>
     <!-- Title -->
      <Label layoutX="150.0" layoutY="40.0" prefHeight="20.0" prefWidth="100.0" style="-fx-text-fill: #219ebc;" text="LOGIN">
         <font>
            <Font name="System Bold" size="25.0" />
         </font></Label>
   </children>
</AnchorPane>

下载完成后,将图片复制并粘贴到包含FXML文件的文件夹中。然后,拖放一个ImageView到AnchorPane中。这个控件将保存或加载图片。

接下来,给ImageView添加以下属性。

属性

Image: panda.pngFont: System 25px Bold

布局

Fit Width:300Fit Height: 300Layout X: 90Layout Y: 57

Scene Builder 产生的代码如下所示。

<ImageView fitHeight="300.0" fitWidth="300.0" layoutX="90.0" layoutY="57.0" pickOnBounds="true" preserveRatio="true">
   <image>
      <Image url="@panda.png" />
   </image>
   <viewport>
      <Rectangle2D />
   </viewport>
</ImageView>

现在,从Shapes 类别中添加一个矩形。它应该有以下属性。

属性

Arc Width:5Fill: #b9eaf8Stroke:#a3a3a3Stroke Width: 2Stroke Line Cap: RoundFill: BEVEL

布局

Width:370Height: 320Layout X: 15Layout Y: 260

上述矩形将把输入区域与表单上的其他区域区分开来。生成的矩形代码如下所示。

<Rectangle arcHeight="5.0" arcWidth="5.0" fill="#b9eaf8" height="320.0" layoutX="15.0" layoutY="260.0" stroke="#a3a3a3" strokeLineCap="ROUND" strokeLineJoin="BEVEL" strokeType="INSIDE" strokeWidth="2.0" width="370.0" />

使用以下属性添加一个Label

<!-- A label to show the start of inputs -->
<Label layoutX="120.0" layoutY="290.0" text="Enter your details below" textFill="#023047">
   <font>
      <Font name="System Bold" size="14.0" />
   </font>
</Label>

为用户名和电子邮件添加一个TextField 。它有以下配置。

属性

Prompt Text:用户名 / 电子邮件Font: 系统 15px

版面设计

Pref Width: 245Pref Height 。35Layout X: 80Layout Y: 345fx:id: usernameTextField

表格或场景中的每个元素都应该有一个唯一的ID。

<!-- Inputs and their icons -->
<TextField fx:id="usernameTextField" layoutX="80.0" layoutY="345.0" prefHeight="35.0" prefWidth="245.0" promptText="Username / Email">
   <font>
      <Font size="15.0" />
   </font>
</TextField>

我们需要为用户名TextField添加一个图标。

添加一个ImageView,它将容纳该图像。

属性

Image: users.png

布局

Fit Width:35Fit Height: 35Layout X: 80Layout Y: 345fx:id: usersIcon

<ImageView fx:id="usersIcon" fitHeight="35.0" fitWidth="35.0" layoutX="40.0" layoutY="345.0" pickOnBounds="true" preserveRatio="true">
   <image>
      <Image url="@users.png" />
   </image>
</ImageView>

添加一个PasswordField ,以捕获用户密码。它有以下属性。

属性

Prompt Text:密码Font: 系统 15px

版面设计

Pref Width: 245Pref Height 。35Layout X: 80Layout Y: 400fx:id: userPassword

<PasswordField fx:id="userPassword" layoutX="80.0" layoutY="400.0" prefHeight="35.0" prefWidth="245.0" promptText="Password">
   <font>
      <Font size="15.0" />
   </font>
</PasswordField>

我们需要为上述PasswordField添加一个图标。

下载后,添加一个ImageView来容纳它,如下图所示。

属性

Image: lock.pngFit Width: 35Fit Height: 35Layout X: 40Layout Y:400fx:id: passwordIcon

SceneBuilder生成的代码如下。

<ImageView fx:id="passwordIcon" fitHeight="35.0" fitWidth="35.0" layoutX="40.0" layoutY="400.0" pickOnBounds="true" preserveRatio="true">
   <image>
      <Image url="@lock.png" />
   </image>
</ImageView>

需要另一个标签来显示错误或成功信息。这个标签上不会有任何内容。

属性

Font:System 12pxText Fill: RED

布局

Pref Width: 245Layout X: 80Layout Y: 445fx:id: invalidDetails

<!-- A label to display error and success messages -->
<Label fx:id="invalidDetails" layoutX="88.0" layoutY="446.0" prefWidth="245.0" textFill="RED" />

我们将需要Buttons ,用于各种操作。我们应该首先创建一个cancel button ,当点击时将关闭场景或窗口。

继续,从controls 部分添加一个按钮。这个按钮将有以下属性。

属性

Text:取消Font: System 14pxText Fill:#a3a3a3

风格

fx-background-color: 透明fx-border-width: 2fx-border-color:#a5a5a5

版面设计

Pref Width: 90Pref Height: 30Layout X: 85Layout Y: 480fx:id: cancelButtonOn Action: onCancelButtonClick

onAction 属性将按钮与一个函数绑定。

接下来,使用以下属性创建一个login button

属性

Text:LoginFont: System 15pxText Fill:#a3a3a3fx-background-color:#0077b6fx-border-radius: 5Pref Width: 90Pref Height: 30Layout X: 225Layout Y: 480fx:id: loginButtonOn Action: onLoginButtonClick

它的代码如下所示。

<Button fx:id="loginButton" layoutX="225.0" layoutY="480.0" mnemonicParsing="false" onAction="#onLoginButtonClick" prefHeight="30.0" prefWidth="90.0" style="-fx-background-color: #0077b6; -fx-border-radius: 5;" text="Login" textFill="WHITE">
   <font>
      <Font size="15.0" />
   </font>
</Button>

添加一个reset password button ,如下图所示。

属性

Text:LoginFont: System 12pxText Fill:#a3a3a3fx-background-color: 透明fx-border-radius: 5Pref Width: 140Pref Height: 25Layout X: 120Layout Y: 530fx:id: forgotButton

<Button fx:id="forgotButton" layoutX="120.0" layoutY="533.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="141.0" style="-fx-background-color: transparent;" text="Forgot Password?" textFill="#a3a3a3" />

当你运行该应用程序时,你应该看到以下输出。

The final design

添加表单验证

HelloController.java 文件走去。这个文件包含表单中需要的函数。删除生成的onHelloButtonClick 函数和welcomeText 。剩下的代码应该如下图所示。

package authentication. login;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class HelloController {
    
}

首先,导入我们在前面步骤中添加到表单中的控件。这是用下面的代码完成的。

@FXML
private TextField usernameTextField;

@FXML
private PasswordField userPassword;

@FXML
private Label invalidDetails;

@FXML
private Button cancelButton, loginButton, forgotButton;

@FXML
private ImageView usersIcon, passwordIcon;

添加一个函数,在点击close button 时退出表单。

// Close form
@FXML
protected void onCancelButtonClick() {
    Stage stage = (Stage) cancelButton.getScene().getWindow();
    stage.close();
}

cancel button 将调用onCancelButtonClick 函数。这个事件会立即关闭窗口。

接下来,在HelloController 方法中添加一些变量。它们将保存将在项目中重复使用的样式。

  // Strings which hold css elements to easily re-use in the application
  protected
  String successMessage = String.format("-fx-text-fill: GREEN;");
  String errorMessage = String.format("-fx-text-fill: RED;");
  String errorStyle = String.format("-fx-border-color: RED; -fx-border-width: 2; -fx-border-radius: 5;");
  String successStyle = String.format("-fx-border-color: #A9A9A9; -fx-border-width: 2; -fx-border-radius: 5;");

现在,添加一个函数,当点击Login 按钮时将被调用,如下图所示。

  // On the login button click
  @FXML
  protected void onLoginButtonClick() throws InterruptedException {
    
  }

在该函数中,做以下工作。

  • 检查是否
    • 用户名和密码为空白
    • 密码少于四个字符

下面是代码。

// In case the Username and Password fields are left blank then display the error message
if (usernameTextField.getText().isBlank() || userPassword.getText().isBlank()) {
  invalidDetails.setStyle(errorMessage);

// When the username and password are blank
if (usernameTextField.getText().isBlank() || userPassword.getText().isBlank()) {
    invalidDetails.setText("The Login fields are required!");
    usernameTextField.setStyle(errorStyle);
    userPassword.setStyle(errorStyle);
    

} else // When only the username is blank
if (usernameTextField.getText().isBlank()) {
    usernameTextField.setStyle(errorStyle);
    invalidDetails.setText("The Username or Email is required!");
    userPassword.setStyle(successStyle);
    
          
} else // When only the password is blank
    if (userPassword.getText().isBlank()) {
        userPassword.setStyle(errorStyle);
        invalidDetails.setText("The Password is required!");
        usernameTextField.setStyle(successStyle);
        
        
    }
} else // Check if password is less than four characters, if so display error message
  if (userPassword.getText().length() < 4) {
      invalidDetails.setText("The Password can't be less than 4 characters!");
      invalidDetails.setStyle(errorMessage);
      userPassword.setStyle(errorStyle);
      
      
  }
// If all login details are entered as required then display success message
else {
    invalidDetails.setText("Login Successful!");
    invalidDetails.setStyle(successMessage);
    usernameTextField.setStyle(successStyle);
    userPassword.setStyle(successStyle);
    
    
}

当你运行应用程序时,如果没有输入,项目看起来如下图所示。

When there is no input

当用户名为空白时,程序将显示以下错误。

When there is no username input

当没有密码时,错误看起来如下图所示。

When there is no password input

当密码少于四个字符时,错误显示如下。

When the password is less than four

当用户名和密码都符合大纲的标准时,会出现如下输出。

When the login is successful

对用户界面进行动画处理

要在JavaFX项目中添加动画,需要AnimateFX 库。

通过点击状态栏附近的Dependencies 按钮检查项目中安装或使用的依赖关系,然后搜索AnimateFX ,并将其添加到项目中。

AnimateFX dependency

等待几分钟完成下载,然后重新加载文件或IDE。要确定它是否被安装,请检查Dependencies 标签。

在这个过程之后,导航到HelloController.java 文件。在onLoginButtonClick() 函数中,添加下面的代码。

new animatefx.animation.Shake(usernameTextField).play();
new animatefx.animation.Wobble(usersIcon).play();
new animatefx.animation.Shake(userPassword).play();
new animatefx.animation.Wobble(passwordIcon).play();

当出现错误时,这段代码将为输入添加一个'摇晃'动画。它还为图像添加了一个'晃动'动画。

在检查用户名是否为空白的过程中,添加以下代码。

new animatefx.animation.Shake(usernameTextField).play();
new animatefx.animation.Pulse(usersIcon).play();

该代码为inputicon ,分别添加了'Pulse'和'Shake'效果。

在检查用户名是否为空白的过程中,添加以下代码。

new animatefx.animation.Shake(userPassword).play();
new animatefx.animation.Wobble(passwordIcon).play();

在检查密码是否少于四个字符的函数中,添加一个稍微温和的效果,如下图所示。

new animatefx.animation.FadeIn(userPassword).play();
new animatefx.animation.Wobble(passwordIcon).play();

它分别给PasswordField添加了 "FadeIn "和 "Wobble "的效果。最后,在最后的'else'语句中为invalidDetails 标签添加一个小的动画Tada 。该动画显示该过程是成功的。

这里是代码。

new animatefx.animation.Tada(invalidDetails).play();

总结

在这篇文章中,我们已经学会了。

  • 如何创建一个JavaFX登录表单。
  • 如何将样式应用到应用程序中。
  • 如何执行输入验证。
  • 如何在控件上添加动画。