JavaFx之在當前界面打開另一個界面


實現效果:

實現代碼:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM