一、准备工作
准备好javaFX开发环境,请详见我上篇文章https://www.sdk.cn/details/wAe9P8mXAq5dbqDl4y
二、项目结构
三、启动类创建Stage
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("/fxml/login/index.fxml")));
primaryStage.setTitle("天桥登录页面");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setMaximized(false);
primaryStage.setMaxHeight(600);
primaryStage.setMaxWidth(1300);
//设置窗口的图标.
primaryStage.getIcons().add(new Image(
getClass().getResourceAsStream("/img/top_left_logo.png")));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
四、创建简单的fxml文件
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<GridPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
</GridPane>
五、使用javaFX SceneBuilder可视化组件
javaFX SceneBuilder是什么?详情请见我上篇文章https://www.sdk.cn/details/wAe9P8mXAq5dbqDl4y
打开是这样
六、布局
这里可能需要一点点前端知识,跟H5的div布局类似,但是javaFX细分了一些组件
原始页面:
分隔页面:
整体页面我使用了BorderPane(上下左右中,比较好布局),上下结构布局使用VBox,左右接口布局使用HBox,反正确定好布局后就是拖组件,然后调试调试
六、调整好后的fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane minHeight="-Infinity" minWidth="-Infinity" stylesheets="@../../css/login.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.LoginController">
<left>
<Pane maxWidth="1.7976931348623157E308" prefHeight="600.0" prefWidth="800.0" styleClass="leftpane" BorderPane.alignment="CENTER">
<children>
<BorderPane prefHeight="600.0" prefWidth="800.0">
<center>
<ImageView fitWidth="500.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER">
<image>
<Image url="@../../img/login_background.png" />
</image>
</ImageView>
</center>
</BorderPane>
</children>
</Pane>
</left>
<right>
<Pane prefHeight="600.0" prefWidth="500.0" styleClass="body" BorderPane.alignment="CENTER">
<children>
<VBox alignment="CENTER" prefHeight="300.0" prefWidth="250.0" translateX="125.0" translateY="130.0">
<opaqueInsets>
<Insets />
</opaqueInsets>
<children>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<ImageView fitHeight="40.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../img/juhe_logo.png" />
</image>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</ImageView>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<Label contentDisplay="BOTTOM" prefHeight="40.0" text="账号登录" textFill="#00bdff">
<font>
<Font size="16.0" />
</font>
</Label>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<BorderPane prefHeight="200.0" prefWidth="100.0">
<left>
<Label prefHeight="24.0" prefWidth="20.0" styleClass="login_username" BorderPane.alignment="CENTER">
<opaqueInsets>
<Insets />
</opaqueInsets>
<BorderPane.margin>
<Insets />
</BorderPane.margin>
</Label>
</left>
<right>
<TextField prefHeight="30.0" prefWidth="250.0" promptText="用户名/手机号/邮箱" styleClass="login_username_input" BorderPane.alignment="CENTER" />
</right>
<bottom>
<Line endX="115.0" startX="-150.0" stroke="#e7e7e7" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets />
</BorderPane.margin>
</Line>
</bottom>
</BorderPane>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<BorderPane prefHeight="200.0" prefWidth="200.0">
<bottom>
<Line endX="115.0" startX="-150.0" stroke="#e7e7e7" BorderPane.alignment="CENTER" />
</bottom>
<left>
<Label prefHeight="24.0" prefWidth="20.0" styleClass="login_password" BorderPane.alignment="CENTER">
<opaqueInsets>
<Insets />
</opaqueInsets>
</Label>
</left>
<right>
<PasswordField prefHeight="37.0" prefWidth="250.0" promptText="密码" styleClass="login_password_input" BorderPane.alignment="CENTER" />
</right>
</BorderPane>
</children>
</VBox>
<VBox prefHeight="0.0" prefWidth="100.0">
<children>
<Hyperlink text="忘记密码?" textFill="#00bdff">
<padding>
<Insets left="200.0" />
</padding>
</Hyperlink>
</children>
<padding>
<Insets bottom="10.0" top="10.0" />
</padding>
</VBox>
<VBox>
<children>
<Button fx:id="loginBtn" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" onAction="#login" prefWidth="300.0" styleClass="login_btn" text="登录" textFill="WHITE">
<padding>
<Insets bottom="15.0" top="15.0" />
</padding>
</Button>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<Text fill="#909090" strokeType="OUTSIDE" strokeWidth="0.0" text="还没有聚合账号," textAlignment="RIGHT">
<HBox.margin>
<Insets left="95.0" top="2.0" />
</HBox.margin>
</Text>
<Hyperlink text="立即注册" textFill="#00bdff" />
<Label prefHeight="20.0" prefWidth="20.0" styleClass="login_jump">
<opaqueInsets>
<Insets />
</opaqueInsets>
<HBox.margin>
<Insets top="1.0" />
</HBox.margin>
</Label>
</children>
</HBox>
</children>
<padding>
<Insets bottom="10.0" top="10.0" />
</padding>
</VBox>
</children>
</VBox>
</children>
<BorderPane.margin>
<Insets />
</BorderPane.margin>
</Pane>
</right>
</BorderPane>
七、css
.body{
-fx-background-color: white;
}
.leftpane{
-fx-background-color: #262626;
-fx-background-repeat: stretch;
-fx-background-size: auto;
-fx-background-position: center center;
}
.login_username_input{
-fx-background-insets: 0;
-fx-background-color: #fff;
}
.login_password_input{
-fx-background-insets: 0;
-fx-background-color: #fff;
}
.login_username{
-fx-background-image: url("../img/loginIcon.png");
-fx-background-repeat: no-repeat;
-fx-background-position: -58px -4px;
}
.login_password{
-fx-background-image: url("../img/loginIcon.png");
-fx-background-repeat: no-repeat;
-fx-background-position: -28px -3px;
}
.login_btn{
-fx-background-insets: 0;
-fx-background-color: rgb(3, 197, 255);
-fx-fill:#fff;
}
.login_jump{
-fx-background-image: url("../img/loginIcon.png");
-fx-background-repeat: no-repeat;
-fx-background-position: -52px -37px;
}