主要分爲兩種情況
- 從一個界面跳轉到另外一個新的界面
- 在原有界面上加載其他頁面。類似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重新加載我們需要的頁面。
效果如下: