主要分为两种情况
- 从一个界面跳转到另外一个新的界面
- 在原有界面上加载其他页面。类似iframe
先从第一个情况的实现说起。
页面跳转
1. 创建一个登录界面
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="login" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.view.login.LoginController">
<children>
<BorderPane prefHeight="20.0" prefWidth="600.0" />
<Label layoutX="99.0" layoutY="96.0" text="用户名:" />
<Label layoutX="99.0" layoutY="146.0" text="密 码:" />
<TextField fx:id="login_username" layoutX="174.0" layoutY="91.0" promptText="用户名" />
<TextField fx:id="login_password" layoutX="174.0" layoutY="141.0" promptText="8位密码" />
<Button fx:id="login_button" layoutX="140.0" layoutY="206.0" mnemonicParsing="false" onAction="#loginButtonClick" text="登 录" />
</children>
</AnchorPane>
2. 创建登录页面对应的组件实现
package app.view.login;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import app.alterview.ViewAlter;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
public class LoginController extends LoginView implements Initializable {
private static final Logger logger = Logger.getLogger(LoginController.class.getName());
private ViewAlter viewAlter;
@FXML
private Button login_button;
@FXML
private TextField login_username;
@FXML
private TextField login_password;
public void loginButtonClick() {
logger.log(Level.INFO, "输入用户名为:" + login_username.getText());
logger.log(Level.INFO, "输入密 码为:" + login_password.getText());
if("nikolazhang".equalsIgnoreCase(login_username.getText())
&& "123654".equalsIgnoreCase(login_password.getText())) {
logger.log(Level.INFO, "登录成功!");
viewAlter.gotoMain();
} else {
logger.log(Level.WARNING, "用户名或密码错误!");
}
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
public void setApp(ViewAlter viewAlter) {
this.viewAlter = viewAlter;
}
}
3. 创建一个主页面
登录进去之后显示该界面
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.web.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="main" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.view.main.MainController">
<children>
<BorderPane prefHeight="640.0" prefWidth="590.0">
<top>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="欢迎进入系统" BorderPane.alignment="CENTER_LEFT" />
</top>
<left>
<TreeView fx:id="main_treeview" onMouseClicked="#mainTreeViewClick" prefHeight="360.0" prefWidth="126.0" BorderPane.alignment="TOP_LEFT" />
</left>
<center>
<ScrollPane prefHeight="600.0" BorderPane.alignment="CENTER">
<content>
<AnchorPane fx:id="main_pane_under_scroll" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="593.0" prefWidth="480.0" />
</content>
</ScrollPane>
</center>
<bottom>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="this system is created by NikolaZhang!" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
</children>
</AnchorPane>
4. 创建ViewAlter类用于跳转页面
package app.alterview;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import app.resource.StaticResourcesConfig;
import app.view.login.LoginController;
import app.view.main.MainController;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class ViewAlter extends Application {
private static final Logger logger = Logger.getLogger(ViewAlter.class.getName());
private Stage stage;
@Override
public void start(Stage primaryStage) throws Exception {
stage = primaryStage;
stage.setTitle("XXXX系统");
gotoLogin();
stage.show();
}
/**
* 跳转到登录界面
*/
public void gotoLogin() {
try {
LoginController login = (LoginController) replaceSceneContent(StaticResourcesConfig.LOGIN_VIEW_PATH);
login.setApp(this);
} catch (Exception ex) {
logger.log(Level.SEVERE, null, ex);
}
}
/**
* 跳转到主界面
*/
public void gotoMain() {
try {
MainController main = (MainController) replaceSceneContent(StaticResourcesConfig.MAIN_VIEW_PATH);
main.setApp(this);
} catch (Exception ex) {
logger.log(Level.SEVERE, null, ex);
}
}
/**
* 替换场景
* @param fxml
* @return
* @throws Exception
*/
private Initializable replaceSceneContent(String fxml) throws Exception {
FXMLLoader loader = new FXMLLoader();
InputStream in = ViewAlter.class.getResourceAsStream(fxml);
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(ViewAlter.class.getResource(fxml));
try {
AnchorPane page = (AnchorPane) loader.load(in);
Scene scene = new Scene(page, StaticResourcesConfig.STAGE_WIDTH, StaticResourcesConfig.STAGE_HEIGHT);
stage.setScene(scene);
stage.sizeToScene();
} catch (Exception e) {
logger.log(Level.SEVERE, "页面加载异常!");
} finally {
in.close();
}
return (Initializable) loader.getController();
}
public static void main(String[] args) {
launch(args);
}
}
这个类是应用的启动类。页面跳转主要使用了自定义的replaceSceneContent
方法,该方法的输入参数为界面的fxml的路径。
应用启动后,执行start方法初始加载登录界面。点击登录按钮,调用LoginController 的loginButtonClick方法,进行登录验证。验证通过调用gotoMain方法,页面跳转到主界面。
同一个布局中加载不同的界面
这里主要是实现了主界面中的TreeView。主界面的控制组件实现如下:
package app.view.main;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import app.alterview.ViewAlter;
import app.resource.StaticResourcesConfig;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.AnchorPane;
public class MainController implements Initializable {
private static final Logger logger = Logger.getLogger(MainController.class.getName());
private ViewAlter viewAlter;
@FXML
private TreeView<String> main_treeview;
@FXML
private ScrollPane main_scroll_pane;
@FXML
private AnchorPane main_pane_under_scroll;
public void setApp(ViewAlter viewAlter) {
this.viewAlter = viewAlter;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
setTreeView();
}
/**
* 设置TreeView
*/
@SuppressWarnings("unchecked")
public void setTreeView() {
TreeItem<String> root = new TreeItem<String>(StaticResourcesConfig.MAIN_TREE_HEADER);
root.setExpanded(true);
root.getChildren().addAll(new TreeItem<String>(StaticResourcesConfig.MAIN_TREE_HEADER_ITEM1),
new TreeItem<String>(StaticResourcesConfig.MAIN_TREE_HEADER_ITEM2),
new TreeItem<String>(StaticResourcesConfig.MAIN_TREE_HEADER_ITEM3),
new TreeItem<String>(StaticResourcesConfig.MAIN_TREE_HEADER_ITEM4),
new TreeItem<String>(StaticResourcesConfig.MAIN_TREE_HEADER_ITEM5));
main_treeview.setRoot(root);
}
/**
* TreeView 点击事件
* @throws IOException
*/
public void mainTreeViewClick() throws IOException {
logger.log(Level.INFO, "点击TreeView");
// 获取鼠标当前点击的Item
TreeItem<String> selectedItem = main_treeview.getSelectionModel().getSelectedItem();
logger.log(Level.INFO, selectedItem.getValue());
String pagePath = "";
switch (selectedItem.getValue()) {
case StaticResourcesConfig.MAIN_TREE_HEADER:
pagePath = StaticResourcesConfig.DEFAULT_VIEW_PATH;
break;
case StaticResourcesConfig.MAIN_TREE_HEADER_ITEM1:
pagePath = StaticResourcesConfig.NOTE_VIEW_PATH;
break;
case StaticResourcesConfig.MAIN_TREE_HEADER_ITEM2:
pagePath = StaticResourcesConfig.CLIP_VIEW_PATH;
break;
case StaticResourcesConfig.MAIN_TREE_HEADER_ITEM3:
pagePath = StaticResourcesConfig.USER_VIEW_PATH;
break;
case StaticResourcesConfig.MAIN_TREE_HEADER_ITEM4:
pagePath = StaticResourcesConfig.DATA_VIEW_PATH;
break;
case StaticResourcesConfig.MAIN_TREE_HEADER_ITEM5:
pagePath = StaticResourcesConfig.LANGUAGE_VIEW_PATH;
break;
}
skipView(pagePath);
}
/**
* 改变右侧scroll的界面
* @param pagePath
* @throws IOException
*/
private void skipView(String pagePath) throws IOException {
logger.info("显示剪切板界面");
ObservableList<Node> scrolChildren = main_pane_under_scroll.getChildren();
scrolChildren.clear();
scrolChildren.add(FXMLLoader.load(getClass().getResource(pagePath)));
}
}
main_treeview.getSelectionModel().getSelectedItem();
获取鼠标点击的是哪个项目。根据点击加载不同的界面。加载界面时调用的方法为skipView
,该方法首先清空之前布局中存在的元素,并通过FXMLLoader重新加载我们需要的页面。
效果如下:
补充
StaticResourcesConfig
定义如下
package app.resource;
public final class StaticResourcesConfig {
public final static int STAGE_WIDTH = 800;
public final static int STAGE_HEIGHT = 600;
public final static String LOGIN_VIEW_PATH = "/app/view/login/LoginView.fxml";
public final static String MAIN_VIEW_PATH = "/app/view/main/MainView.fxml";
public final static String CLIP_VIEW_PATH = "/app/view/panel/clip/ClipView.fxml";
public final static String NOTE_VIEW_PATH = "/app/view/panel/note/NoteView.fxml";
public static final String DEFAULT_VIEW_PATH = "/app/view/panel/note/NoteView.fxml";
public static final String LANGUAGE_VIEW_PATH = "/app/view/panel/note/NoteView.fxml";
public static final String DATA_VIEW_PATH = "/app/view/panel/datanaly/DataView.fxml";
public static final String USER_VIEW_PATH = "/app/view/panel/usermanage/UserView.fxml";
// WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
// WWW 界面字段显示 WWW
// WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
public final static String MAIN_TREE_HEADER = "首页";
public final static String MAIN_TREE_HEADER_ITEM1 = "记事本";
public final static String MAIN_TREE_HEADER_ITEM2 = "剪贴板";
public final static String MAIN_TREE_HEADER_ITEM3 = "用户管理";
public final static String MAIN_TREE_HEADER_ITEM4 = "数据分析";
public final static String MAIN_TREE_HEADER_ITEM5 = "语言";
}