實現效果:

實現代碼:
FxmlController:
/** * 添加數據 * @param actionEvent */ @FXML public void addData(ActionEvent actionEvent) { // 打開新的場景需要UI更新線程執行 Platform.runLater(()->{ Stage saveDiary = StageManager.getStage("saveDiary"); // 每次創建場景前,判斷該場景是否被創建過,創建過直接顯示場景即可,無需多次創建,但是需要清除上次輸入的數據 if(Objects.isNull(saveDiary)) { try { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/saveDiary.fxml")); Parent pane = (Parent)fxmlLoader.load(); Scene scene = new Scene(pane); Stage stage = new Stage(); stage.setScene(scene); stage.setTitle("添加數據"); stage.initStyle(StageStyle.TRANSPARENT); stage.show(); // 存放Scene StageManager.put("saveDiary", stage); } catch (IOException e) { e.printStackTrace(); } } else { saveDiary.show(); } }); }
加載resources/fxml路徑下的fxml文件,創建Stage,並且顯示出來,把Stage放入全局Stage管理器方便其他頁面關閉該Stage;
StageManager:
import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; /** * 場景管理器 */ public class StageManager { /** * 場景集合 */ private static Map<String, Stage> stageMap = new ConcurrentHashMap<>(); /** * 根據key存放Scene * @param key * @param stage */ public static void put(String key, Stage stage) { if(StringUtils.isEmpty(key)) { throw new RuntimeException("key不為空!"); } if(Objects.isNull(stage)) { throw new RuntimeException("scene不為空!"); } stageMap.put(key, stage); } /** * 根據key獲取Scene * @param key * @return */ public static Stage getStage(String key) { if(StringUtils.isEmpty(key)) { throw new RuntimeException("key不為空!"); } return stageMap.get(key); } }
管理全局的Stage,擴大Stage作用域,方便Stage在其他頁面關閉;
關閉場景方法:
/** * 關閉當前場景 * @param actionEvent */ @FXML public void cancel(ActionEvent actionEvent) { Stage stage = StageManager.getStage("saveDiary"); logger.info("stage: {}",stage); if(!Objects.isNull(stage)) { stage.close(); logger.info("關閉場景成功!"); } }
根據要關閉界面的key拿到Stage,調用close方法關閉該Stage;
效果圖:

關於多界面參數傳遞問題:
解決思路:可以使用全局變量,根據界面名稱、參數名稱將參數放到公共內存里,需要的時候去獲取即可;
代碼實現:
import java.util.HashMap; import java.util.Map; /** * 參數管理器 */ public class ParamManager { // 頁面參數集合 private static Map<String, Map<String, Object>> paramMap = new HashMap<>(); /** * 根據pageName,key存放value * @param pageName * @param key * @param value */ public static void putParam(String pageName, String key, Object value) { Map<String, Object> pageMap = paramMap.get(pageName); if(null == pageMap) { Map<String, Object> page = new HashMap<>(); page.put(key, value); paramMap.put(pageName, page); } else { pageMap.put(key, value); paramMap.put(pageName, pageMap); } } /** * 根據pageName,key獲取value * @param pageName * @param key * @return */ public static Object getParam(String pageName, String key) { Map<String, Object> pageMap = paramMap.get(pageName); if(null == pageMap) { return null; } Object value = pageMap.get(key); return value; } }
問題補充:
當我打開新的stage后,填上數據,會調用Jpa的save方法去保存數據,會發現Repository注入為空,是因為Spring實例化這個FXML控制器,需要添加黃色標記的代碼;
/** * 添加item */ @FXML public void addItem() { Platform.runLater(()->{ try { Map<String, Object> pageData = new HashMap<>(); pageData.put("isSave", "0"); CacheManager.putPageData("/table/item", pageData); Stage stage = CacheManager.getStage("/table/item"); if (Objects.isNull(stage)) { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/item.fxml")); fxmlLoader.setControllerFactory(springContext::getBean); Parent pane = (Parent) fxmlLoader.load(); Scene scene = new Scene(pane); stage = new Stage(); stage.setScene(scene); stage.setTitle("添加數據"); stage.initStyle(StageStyle.TRANSPARENT); stage.show(); CacheManager.putStage("/table/item", stage); } stage.show(); } catch (IOException e) { e.printStackTrace(); } }); }
setControllerFactory()方法允許Spring實例化FXML控制器,並在應用程序中注入對Spring Bean的引用;
推薦閱讀:http://codingdict.com/questions/130490
