package com.persagy.filemove.app; import com.persagy.filemove.dto.SagaFileMoveDTO; import com.persagy.filemove.service.SagaFileMoveService; import com.persagy.filemove.util.StringTools; import javafx.application.Application; import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.Label; import javafx.scene.control.Menu; import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; import javafx.scene.control.TextField; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.stage.Stage; import javax.sound.midi.Soundbank; import java.lang.reflect.Field; import java.util.LinkedHashMap; public class SagaFileMoveApp extends Application { private static int appWidth = 600; private static int appHeight = 500; private SagaFileMoveDTO dto = new SagaFileMoveDTO(); private SagaFileMoveService service = new SagaFileMoveService(dto); /** 文件服务上传下载接口类型 */ private static final String[] apiTypes = {"file", "image"}; /** 对象类型 */ private static String[] objTypes; /** 对象类型对应信息点 */ private static final LinkedHashMap objToInfoCode = new LinkedHashMap<>(); static { objToInfoCode.put("Fl", new String[]{"FloorMap"}); objToInfoCode.put("Eq", new String[]{"EquipQRCode"}); objToInfoCode.put("Sp", new String[]{"RoomQRCode"}); objToInfoCode.put("Sy", new String[]{"EquipQRCode"}); objToInfoCode.put("Ec", new String[]{"EquipQRCode"}); objTypes = objToInfoCode.keySet().stream().toArray(n -> new String[n]); } /** 数据平台地址 */ private TextField tfDPF = new TextField("http://api.sagacloud.cn/data-platform-3"); /** 项目id */ private TextField tfPjId = new TextField("Pj1101010001"); /** 项目密码 */ private TextField tfPjSecret = new TextField(); /** 对象类型 */ private ChoiceBox cbObjType = new ChoiceBox(); /** 对象信息点 */ private ChoiceBox cbObjInfoCodeArray = new ChoiceBox(); /** 文件服务from地址 */ private TextField tfImgFromURL = new TextField("http://127.0.0.1:8080/image-service"); /** 文件服务from的systemId */ private TextField tfImgFromSysId = new TextField("dataPlatform"); /** 文件服务from的secret */ private TextField tfImgFromSecret = new TextField("9e0891a7a8c8e885"); /** 接口类型 */ private ChoiceBox cbImgFromApiType = new ChoiceBox(FXCollections.observableArrayList(apiTypes)); /** 文件服务To地址 */ private TextField tfImgToURL = new TextField("http://127.0.0.1:8080/image-service"); /** 文件服务To的systemId */ private TextField tfImgToSysId = new TextField("dataPlatform"); /** 文件服务To的secret */ private TextField tfImgToSecret = new TextField("9e0891a7a8c8e885"); /** 接口类型 */ private ChoiceBox cbImgToApiType = new ChoiceBox(FXCollections.observableArrayList(apiTypes)); /** 执行校验按钮 */ private Button btnValid = new Button("参数校验"); /** 文件传输执行按钮 */ private Button btnExecute = new Button("开始传输"); /** 执行信息 */ private Label lblExecute = new Label(); public static void main(String[] args) { launch(args); } /** * 初始化基础控件 */ private void initComponents() { bindDTO(); tfDPF.setPrefWidth(appWidth * .7); tfPjId.setPrefWidth(appWidth * .25); tfPjSecret.setPrefWidth(appWidth * .25); cbObjType.setItems(FXCollections.observableArrayList(objTypes)); cbObjType.setPrefWidth(appWidth * .1); // 设置默认选择第一项 cbObjType.getSelectionModel().selectFirst(); cbObjInfoCodeArray.setItems(FXCollections.observableArrayList(objToInfoCode.get(cbObjType.getSelectionModel().getSelectedItem().toString()))); cbObjInfoCodeArray.getSelectionModel().selectFirst(); cbObjInfoCodeArray.setPrefWidth(appWidth * .25); tfImgFromURL.setPrefWidth(appWidth * .5); tfImgFromSysId.setPrefWidth(appWidth * .25); tfImgFromSecret.setPrefWidth(appWidth * .25); cbImgFromApiType.setPrefWidth(appWidth * .15); cbImgFromApiType.getSelectionModel().selectFirst(); tfImgToURL.setPrefWidth(appWidth * .5); tfImgToSysId.setPrefWidth(appWidth * .25); tfImgToSecret.setPrefWidth(appWidth * .25); cbImgToApiType.setPrefWidth(appWidth * .15); cbImgToApiType.getSelectionModel().selectFirst(); btnValid.setOnAction(e -> { validParam(); }); btnExecute.setOnAction(e -> { disableSet(true, this); if(validParam()) { // 操作按钮置为不可操作 } }); cbObjType.getSelectionModel().selectedIndexProperty().addListener((obv, ov, nv)->{ cbObjInfoCodeArray.setItems(FXCollections.observableArrayList(objToInfoCode.get(cbObjType.getItems().get(nv.intValue())))); cbObjInfoCodeArray.getSelectionModel().selectFirst(); }); } private void disableSet(boolean isAble, SagaFileMoveApp father) { Field[] allFields = SagaFileMoveApp.class.getDeclaredFields(); for(Field field : allFields) { if(Node.class.isAssignableFrom(field.getDeclaringClass())) { try { Node node = (Node) field.get(father); node.setDisable(isAble); }catch (Exception e) {} } } } /** * 校验参数 * @return */ private boolean validParam() { // if(StringTools.isBlank(dto.dpf.getValue()) || StringTools.isBlank(dto.pjId.getValue()) || StringTools.isBlank(dto.imgFromUrl.getValue()) || StringTools.isBlank(dto.imgFromSysId.getValue()) || StringTools.isBlank(dto.imgFromSecret.getValue()) || StringTools.isBlank(dto.imgToUrl.getValue()) || StringTools.isBlank(dto.imgToSysId.getValue()) || StringTools.isBlank(dto.imgToSecret.getValue())) { showTipsError("必填参数不能为空!"); return false; } if(!service.validParamDpfAndPj()) { showTipsError("获取不到项目信息!请确保数据平台地址和项目id参数正确。"); return false; } if(!service.validParamImgFromUrl()) { showTipsError("[文件服务-From]访问不通!请确保URL正确。"); return false; } if(!service.validParamImgToUrl()) { showTipsError("[文件服务-To]访问不通!请确保URL正确。"); return false; } if(dto.imgFromUrl.getValue().equals(dto.imgToUrl.getValue())) { showTipsWarn("参数校验通过。警告:两个文件服务的URL相同!"); }else { showTipsSuccess("校验通过"); } return true; } private void showTipsSuccess(String info) { lblExecute.setTextFill(Color.DARKGREEN); lblExecute.setText(info); } private void showTipsInfo(String info) { lblExecute.setTextFill(Color.BLACK); lblExecute.setText(info); } private void showTipsError(String errMsg) { lblExecute.setTextFill(Color.RED); lblExecute.setText(errMsg); } private void showTipsWarn(String warnMsg) { lblExecute.setTextFill(Color.DARKORANGE); lblExecute.setText(warnMsg); } /** * 将控件的值绑定到DTO对象的属性上 */ private void bindDTO() { dto.dpf.bind(tfDPF.textProperty()); dto.imgFromApiType.bind(cbImgFromApiType.valueProperty()); dto.imgFromSecret.bind(tfImgFromSecret.textProperty()); dto.imgFromSysId.bind(tfImgFromSysId.textProperty()); dto.imgFromUrl.bind(tfImgFromURL.textProperty()); dto.imgToApiType.bind(cbImgToApiType.valueProperty()); dto.imgToSecret.bind(tfImgToSecret.textProperty()); dto.imgToSysId.bind(tfImgToSysId.textProperty()); dto.imgToUrl.bind(tfImgToURL.textProperty()); dto.objInfoCode.bind(cbObjInfoCodeArray.valueProperty()); dto.objType.bind(cbObjType.valueProperty()); dto.pjId.bind(tfPjId.textProperty()); dto.pjSecret.bind(tfPjSecret.textProperty()); } @Override public void start(Stage primaryStage) throws Exception { initComponents(); // 底层border布局 BorderPane baseBorderPane = new BorderPane(); // 菜单栏 MenuBar menuBar = new MenuBar(); menuBar.prefWidthProperty().bind(primaryStage.widthProperty()); menuBar.getMenus().addAll(getHelpMenu()); // 主视图内容布局 Pane centerPane = getCenterPane(); baseBorderPane.setTop(menuBar); baseBorderPane.setCenter(centerPane); primaryStage.setResizable(false); Scene scene = new Scene(baseBorderPane, appWidth, appHeight); primaryStage.setScene(scene); primaryStage.show(); } /** * 获取主要内容的布局面板实例 * @return */ private Pane getCenterPane() { Pane centerPane = new VBox(); centerPane.setPadding(new Insets(0, 5, 0, 5)); TitledPane paneObjParam = getObjTitlePane(); TitledPane paneImgFrom = getImgTitlePane(true); TitledPane paneImgTo = getImgTitlePane(false); Pane paneExe = getExePane(); centerPane.getChildren().addAll(paneObjParam, paneImgFrom, paneImgTo, paneExe); Insets nodeInsets = new Insets(0, 0, 15, 0); VBox.setMargin(paneObjParam, nodeInsets); VBox.setMargin(paneImgFrom, nodeInsets); return centerPane; } /** * 获取执行控制面板 * @return */ private Pane getExePane() { HBox contentBox = new HBox(btnValid, btnExecute, lblExecute); HBox.setMargin(btnExecute, new Insets(0, 20, 0, 15)); contentBox.setPadding(new Insets(15, 0, 0, 0)); return contentBox; } /** * 生成包含数据平台、项目、对象配置参数的带标题的布局实例 * @return */ private TitledPane getObjTitlePane() { String title = "物理对象 - 配置传输哪个项目,哪类对象,哪个信息点对应的文件数据"; String titlePaneBack = "-fx-background-color: wheat"; LinkedHashMap projectMap = new LinkedHashMap<>(); projectMap.put("*项目id ", tfPjId); projectMap.put("项目密码 ", tfPjSecret); LinkedHashMap objTypeMap = new LinkedHashMap<>(); objTypeMap.put("*对象类型 ", cbObjType); objTypeMap.put("*对象信息点 ", cbObjInfoCodeArray); VBox contentPane = new VBox(getHBoxPane("*数据平台 ", tfDPF), getHBoxPane(projectMap), getHBoxPane(objTypeMap)); contentPane.setPadding(new Insets(5, 0, 5,10)); contentPane.setStyle("-fx-background-color: antiquewhite"); TitledPane titledPane = new TitledPane(title, contentPane); titledPane.setCollapsible(false); return titledPane; } /** * 生成包含文件服务参数控件的带标题的布局实例 * @param isFrom true-数据来源方的文件服务;false-数据接收方的文件服务 * @return */ private TitledPane getImgTitlePane(boolean isFrom) { String titleFrom = "From:即获取文件资源数据所访问的image-service服务"; String titleTo = "To:即获上传文件资源所访问的image-service服务"; String title = "文件服务 - " + (isFrom ? titleFrom : titleTo); String titlePaneBack = "-fx-background-color: wheat"; Node systemId = null, secret = null, serviceURL = null, apiType; if(isFrom) { systemId = tfImgFromSysId; secret = tfImgFromSecret; serviceURL = tfImgFromURL; apiType = cbImgFromApiType; titlePaneBack = "-fx-background-color: bisque"; }else { systemId = tfImgToSysId; secret = tfImgToSecret; serviceURL = tfImgToURL; apiType = cbImgToApiType; } LinkedHashMap urlAndApiTypeMap = new LinkedHashMap<>(); urlAndApiTypeMap.put("*服务URL ", serviceURL); urlAndApiTypeMap.put("*接口类型 ", apiType); LinkedHashMap paramMap = new LinkedHashMap<>(); paramMap.put("*systemId ", systemId); paramMap.put("*secret ", secret); VBox contentPane = new VBox(getHBoxPane(urlAndApiTypeMap), getHBoxPane(paramMap)); contentPane.setPadding(new Insets(5, 0, 5,10)); contentPane.setStyle(titlePaneBack); TitledPane titledPane = new TitledPane(title, contentPane); titledPane.setCollapsible(false); return titledPane; } /** * 获取水平排布的含有Label和Node节点两个控件面板实例 * @param label 标签内容 * @param node 控件节点 * @return */ private Pane getHBoxPane(String label, Node node) { LinkedHashMap map = new LinkedHashMap<>(); map.put(label, node); return getHBoxPane(map); } /** * 获取水平排布的含多对(Label:Node)节点组的面板实例 * @param label_textField {标签名:控件节点} * @return */ private Pane getHBoxPane(LinkedHashMap label_textField) { HBox pane = new HBox(); Insets nodeInsets = new Insets(0, 15, 0, 0); for(String name : label_textField.keySet()) { Label label = new Label(name); Node node = label_textField.get(name); pane.getChildren().addAll(label, node); HBox.setMargin(node, nodeInsets); } pane.setPadding(new Insets(5, 5, 5, 0)); pane.setAlignment(Pos.CENTER_LEFT); return pane; } /** * 获取帮助菜单按钮 * @return */ private Menu getHelpMenu() { // 菜单项 MenuItem mi_help = new MenuItem("Help"); MenuItem mi_about = new MenuItem("About"); SeparatorMenuItem seline = new SeparatorMenuItem(); Menu helpMenu = new Menu("Help"); helpMenu.getItems().addAll(mi_help, seline, mi_about); return helpMenu; } }