diff --git a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java index 33be0b7fc4..3c219d6f5e 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -240,7 +240,6 @@ public class EnvChangeEntrance { } private static void afterSwitch() { - TemplateTreePane.getInstance().refreshDockingView(); DesignModelAdapter model = DesignModelAdapter.getCurrentModelAdapter(); if (model != null) { model.envChanged(); diff --git a/designer-base/src/main/java/com/fr/design/actions/file/PreferenceAction.java b/designer-base/src/main/java/com/fr/design/actions/file/PreferenceAction.java index d571d60f34..eb83ec7bea 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/PreferenceAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/PreferenceAction.java @@ -31,11 +31,10 @@ public class PreferenceAction extends UpdateAction { */ public void actionPerformed(ActionEvent e) { final DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); - final PreferencePane preferencePane = new PreferencePane(); - preferencePane.populate(DesignerEnvManager.getEnvManager()); - BasicDialog basicDialog = preferencePane.showWindow(designerFrame); + // 将当前环境配置填充到PreferencePane中 + preferencePane.populate(basicDialog, DesignerEnvManager.getEnvManager()); basicDialog.addDialogActionListener(new DialogActionAdapter() { public void doOk() { preferencePane.update(DesignerEnvManager.getEnvManager()); diff --git a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java index b526b6ae2b..032f55a952 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java @@ -8,6 +8,7 @@ import com.fine.theme.utils.FineUIStyle; import com.fine.theme.utils.FineUIUtils; import com.fr.config.Configuration; import com.fr.config.ServerPreferenceConfig; +import com.fr.config.utils.SetupDataHelper; import com.fr.design.DesignerEnvManager; import com.fr.design.RestartHelper; import com.fr.design.dialog.BasicDialog; @@ -42,9 +43,11 @@ import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.design.mainframe.vcs.ui.UIPositiveIntEditor; import com.fr.design.mainframe.vcs.ui.VcsMovePanel; import com.fr.design.os.impl.SupportOSImpl; +import com.fr.design.ui.util.UIUtil; import com.fr.design.unit.UnitConvertUtil; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.widget.FRWidgetFactory; +import com.fr.env.SetupDataDesignerRemoteOperator; import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; import com.fr.general.Inter; @@ -53,8 +56,10 @@ import com.fr.io.attr.ImageExportAttr; import com.fr.locale.InterProviderFactory; import com.fr.log.FineLoggerFactory; import com.fr.report.ReportConfigManager; +import com.fr.report.ReportConfigManagerProvider; import com.fr.stable.Constants; import com.fr.third.apache.logging.log4j.Level; +import com.fr.third.guava.base.Supplier; import com.fr.third.guava.collect.BiMap; import com.fr.third.guava.collect.HashBiMap; import com.fr.transaction.Configurations; @@ -67,6 +72,11 @@ import com.fr.workspace.server.vcs.VcsConfig; import com.fr.workspace.server.vcs.git.config.GcConfig; import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanSchedule; import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanService; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; +import java.util.List; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -254,6 +264,14 @@ public class PreferencePane extends BasicPane { put(THREE_MONTH_INDEX, THREE_MONTH_INT); } }); + + private static final List CONFIG_NAMESPACES = Arrays.asList( + VcsConfig.getInstance().getNameSpace(), + ServerPreferenceConfig.getInstance().getNameSpace(), + GcConfig.getInstance().getNameSpace(), + new ReportConfigManager().getNameSpace() + ); + public PreferencePane() { this.initComponents(); } @@ -473,7 +491,7 @@ public class PreferencePane extends BasicPane { } private VcsMovePanel createMovePane(CardLayout cardLayout, JPanel parentPane) { - return new VcsMovePanel(cardLayout, parentPane, new VcsMovePanel.MoveCallBack(){ + return new VcsMovePanel(cardLayout, parentPane, new VcsMovePanel.MoveCallBack() { @Override public void doCallBack(boolean useV2) { saveIntervalPane.setVisible(useV2); @@ -486,7 +504,7 @@ public class PreferencePane extends BasicPane { useVcsAutoSaveScheduleCheckBox.setEnabled(useV2); } }, basicDialog); - }; + } private JPanel createAutoCleanPane() { Row autoCleanPane = new Row(); @@ -865,27 +883,40 @@ public class PreferencePane extends BasicPane { * * @param designerEnvManager 设计器环境管理器 */ - public void populate(DesignerEnvManager designerEnvManager) { + public void populate(BasicDialog basicDialog, DesignerEnvManager designerEnvManager) { if (designerEnvManager == null) { return; } + // 常用 + loadCommonSettings(designerEnvManager); + // 版本管理 + loadVersionControlSettings(designerEnvManager); + // 高级 + loadAdvanceSettings(designerEnvManager); + // 异步加载配置 + loadConfigsAsync(basicDialog); + } + /** + * 选项-常用 + * + * @param designerEnvManager + */ + private void loadCommonSettings(DesignerEnvManager designerEnvManager) { + // 功能设置 supportUndoCheckBox.setSelected(designerEnvManager.isSupportUndo()); if (designerEnvManager.isSupportUndo()) { maxUndoLimit.setSelectedIndex(chooseCase(designerEnvManager.getUndoLimit())); } else { maxUndoLimit.setEnabled(false); } - supportDefaultParentCalculateCheckBox.setSelected(designerEnvManager.isSupportDefaultParentCalculate()); - showTemplateMissingPlugin.setSelected(designerEnvManager.isShowTemplateMissingPlugin()); - + this.startWithEmptyFile.setSelected(designerEnvManager.isStartWithEmptyFile()); + // 编辑器设置 supportStringToFormulaBox.setSelected(designerEnvManager.isSupportStringToFormula()); - shortCutLabel.setText(getDisplayShortCut(designerEnvManager.getAutoCompleteShortcuts())); shortCutKeyStore = convert2KeyStroke(designerEnvManager.getAutoCompleteShortcuts()); - if (supportStringToFormulaBox.isSelected()) { defaultStringToFormulaBox.setEnabled(true); defaultStringToFormulaBox.setSelected(designerEnvManager.isDefaultStringToFormula()); @@ -893,89 +924,125 @@ public class PreferencePane extends BasicPane { defaultStringToFormulaBox.setEnabled(false); defaultStringToFormulaBox.setSelected(false); } + // 颜色设置 + gridLineColorTBButton.setColor(designerEnvManager.getGridLineColor()); + paginationLineColorTBButton.setColor(designerEnvManager.getPaginationLineColor()); + // 语言选择 + this.languageComboBox.setSelectedItem(designerEnvManager.getLanguage()); + // 启动页配置 + this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled()); + } + + /** + * 高级 + * + * @param designerEnvManager + */ + private void loadAdvanceSettings(DesignerEnvManager designerEnvManager) { + // Log导出配置 + this.logExportDirectoryField.setText(designerEnvManager.getLogLocation()); + this.logLevelComboBox.setSelectedItem(Log4jConfig.getInstance().getRootLevel()); + // 标尺单位配置 + this.pageLengthComboBox.setSelectedIndex(designerEnvManager.getPageLengthUnit()); + this.reportLengthComboBox.setSelectedIndex(designerEnvManager.getReportLengthUnit()); + // 端口设置 + this.portEditor.setValue(new Integer(designerEnvManager.getEmbedServerPort())); + // 插件管理器选项 + if (useOptimizedUPMCheckbox != null) { + useOptimizedUPMCheckbox.setSelected(true); + } + // 显示oracle所有表 + this.oracleSpace.setSelected(designerEnvManager.isOracleSystemSpace()); + // 模板内存优化 + this.cachingTemplateSpinner.setValue(designerEnvManager.getCachingTemplateLimit()); + // 产品改良 + this.joinProductImproveCheckBox.setSelected(designerEnvManager.isJoinProductImprove()); + if (this.autoPushUpdateCheckBox != null) { + this.autoPushUpdateCheckBox.setSelected(designerEnvManager.isAutoPushUpdateEnabled()); + } + // 模板预览性能 + this.imageCompressPanelCheckBox.setSelected(designerEnvManager.isImageCompress()); + boolean enabled = WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot(); + previewRenderSpeed.setEnabled(enabled); + previewRenderQuality.setEnabled(enabled); + previewResolutionBtnS.setEnabled(enabled); + previewResolutionBtnM.setEnabled(enabled); + // 设计器启动选项-延迟启动云端运维模块 + this.cloudAnalyticsDelayCheckBox.setSelected(designerEnvManager.isCloudAnalyticsDelay()); + } + + private void loadConfigsAsync(BasicDialog dialog) { + UIUtil.executeAsyncTaskAndUpdateUI(() -> { + dialog.setButtonEnabled(false); + if (!WorkContext.getCurrent().isLocal()) { + SetupDataDesignerRemoteOperator.getInstance().fetchBatchConfDatas(CONFIG_NAMESPACES); + } + return null; + }, + result -> { + populateConfigs(); + dialog.setButtonEnabled(true); + }); + } + + private void populateConfigs() { + updateGcConfigUI(GcConfig.getInstance().isGcEnable()); + useUniverseDBMCheckbox.setSelected(ServerPreferenceConfig.getInstance().isUseUniverseDBM()); + updateImageExportUI(ReportConfigManager.getProviderInstance().getImageExportAttr()); + useVcsAutoCleanScheduleCheckBox.setSelected(VcsConfig.getInstance().isUseV2AutoClean()); + autoCleanIntervalComboBox.setSelectedIndex(getIndex(VcsConfig.getInstance().getV2CleanInterval())); + autoCleanRetainIntervalComboBox.setSelectedIndex(getIndex(VcsConfig.getInstance().getV2RetainInterval())); + } + + /** + * 选项-版本管理 + * + * @param designerEnvManager + */ + private void loadVersionControlSettings(DesignerEnvManager designerEnvManager) { VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager(); //如果是集群并且是老版本则不可用 if (VcsHelper.getInstance().isLegacyMode() && WorkContext.getCurrent().isCluster()) { + // 保存自动生成版本 vcsEnableCheckBox.setEnabled(false); + // 模板版本控制存储优化 gcEnableCheckBox.setEnabled(false); } - if (VcsHelper.getInstance().needInit()) { vcsEnableCheckBox.setSelected(vcsConfigManager.isVcsEnable()); } else { vcsEnableCheckBox.setEnabled(false); vcsEnableCheckBox.setSelected(false); } + useVcsAutoSaveScheduleCheckBox.setSelected(vcsConfigManager.isUseAutoSave()); + autoSaveIntervalEditor.setValue(vcsConfigManager.getAutoSaveInterval()); + //版本管理-存储与清理机制 if (!vcsEnableCheckBox.isSelected()) { saveCommitCheckBox.setEnabled(false); saveIntervalEditor.setEnabled(false); useIntervalCheckBox.setEnabled(false); } - saveIntervalEditor.setValue(vcsConfigManager.getSaveInterval()); saveCommitCheckBox.setSelected(vcsConfigManager.isSaveCommit()); useIntervalCheckBox.setSelected(vcsConfigManager.isUseInterval()); - gcEnableCheckBox.setSelected(GcConfig.getInstance().isGcEnable()); - gcButton.setEnabled(gcEnableCheckBox.isSelected()); - - useVcsAutoSaveScheduleCheckBox.setSelected(vcsConfigManager.isUseAutoSave()); - useVcsAutoCleanScheduleCheckBox.setSelected(VcsConfig.getInstance().isUseV2AutoClean()); - autoSaveIntervalEditor.setValue(vcsConfigManager.getAutoSaveInterval()); - autoCleanIntervalComboBox.setSelectedIndex(getIndex(VcsConfig.getInstance().getV2CleanInterval())); - autoCleanRetainIntervalComboBox.setSelectedIndex(getIndex(VcsConfig.getInstance().getV2RetainInterval())); - - gridLineColorTBButton.setColor(designerEnvManager.getGridLineColor()); - paginationLineColorTBButton.setColor(designerEnvManager.getPaginationLineColor()); - - this.logExportDirectoryField.setText(designerEnvManager.getLogLocation()); - - this.logLevelComboBox.setSelectedItem(Log4jConfig.getInstance().getRootLevel()); - - this.languageComboBox.setSelectedItem(designerEnvManager.getLanguage()); - - this.pageLengthComboBox.setSelectedIndex(designerEnvManager.getPageLengthUnit()); - this.reportLengthComboBox.setSelectedIndex(designerEnvManager.getReportLengthUnit()); - - this.portEditor.setValue(new Integer(designerEnvManager.getEmbedServerPort())); - - if (useOptimizedUPMCheckbox != null) { - useOptimizedUPMCheckbox.setSelected(true); - } - - useUniverseDBMCheckbox.setSelected(ServerPreferenceConfig.getInstance().isUseUniverseDBM()); - - this.oracleSpace.setSelected(designerEnvManager.isOracleSystemSpace()); - this.cachingTemplateSpinner.setValue(designerEnvManager.getCachingTemplateLimit()); - this.joinProductImproveCheckBox.setSelected(designerEnvManager.isJoinProductImprove()); - - if (this.autoPushUpdateCheckBox != null) { - this.autoPushUpdateCheckBox.setSelected(designerEnvManager.isAutoPushUpdateEnabled()); - } - - this.startWithEmptyFile.setSelected(designerEnvManager.isStartWithEmptyFile()); + } - this.imageCompressPanelCheckBox.setSelected(designerEnvManager.isImageCompress()); + private void updateGcConfigUI(Boolean gcEnable) { + gcEnableCheckBox.setSelected(gcEnable); + gcButton.setEnabled(gcEnable); + } - ImageExportAttr attr = ReportConfigManager.getProviderInstance().getImageExportAttr(); + private void updateImageExportUI(ImageExportAttr attr) { if (attr.getPreviewRenderQuality() == ImageExportAttr.RENDER_SPEED) { previewRenderSpeed.setSelected(true); } else { previewRenderQuality.setSelected(true); } - if (attr.getPreviewResolutionScale() == DPI_SCALE_S) { previewResolutionBtnS.setSelected(true); } else { previewResolutionBtnM.setSelected(true); } - boolean enabled = WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot(); - previewRenderSpeed.setEnabled(enabled); - previewRenderQuality.setEnabled(enabled); - previewResolutionBtnS.setEnabled(enabled); - previewResolutionBtnM.setEnabled(enabled); - - this.cloudAnalyticsDelayCheckBox.setSelected(designerEnvManager.isCloudAnalyticsDelay()); - this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled()); } private int chooseCase(int sign) { diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java index c9514f439d..dce04789ad 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java @@ -45,6 +45,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; import com.fr.design.menu.SeparatorDef; import com.fr.design.menu.ToolBarDef; +import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.ParameterUtils; import com.fr.esd.core.strategy.config.StrategyConfig; import com.fr.esd.core.strategy.config.StrategyConfigHelper; @@ -222,6 +223,7 @@ public class DBTableDataPane extends AbstractTableDataPane implemen addConnectionTableProcedurePaneListener(); } + private void addConnectionTableProcedurePaneListener() { this.connectionTableProcedurePane.addDoubleClickListener(new ConnectionTableProcedurePane.DoubleClickSelectedNodeOnTreeListener() { @Override @@ -507,22 +509,23 @@ public class DBTableDataPane extends AbstractTableDataPane implemen } private void populateESDComponents() { - //查找映射的配置 - this.strategyConfig = configHandler.find(); + UIUtil.executeAsyncTaskAndUpdateUI(configHandler::find, this::updateESDComponents); + } + private void updateESDComponents(StrategyConfig strategyConfig) { + this.strategyConfig = strategyConfig; boolean shouldEnable = false; StrategyConfigFrom from = StrategyConfigFrom.GLOBAL; - if (this.strategyConfig != null) { - if (this.strategyConfig.enabled()) { + if (strategyConfig != null) { + if (strategyConfig.enabled()) { shouldEnable = true; } - if (!this.strategyConfig.isUseGlobal()) { + if (!strategyConfig.isUseGlobal()) { from = StrategyConfigFrom.INDIVIDUAL; } } - - //服务器数据集不允许设置来源,只能单独配置 + // 服务器数据集不允许设置来源,只能单独配置 if (dbTableData.getScope() != StrategicTableData.Scope.TEMPLATE) { from = StrategyConfigFrom.INDIVIDUAL; this.esdConfigOption.setEnabled(false); diff --git a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java index aaf95bd765..44a761f060 100644 --- a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java +++ b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java @@ -48,6 +48,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JTemplate; import com.fr.design.parameter.ParameterInputNoneListenerPane; import com.fr.design.parameter.ParameterInputPane; +import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.ComparatorUtils; import com.fr.general.FArray; @@ -1074,7 +1075,10 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { functionTypeScrollPane.setBorder(FineBorderFactory.createWrappedRoundBorder()); functionTypeList.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE)); initTypeListCellRenderer(); - initGroupTypeModel(); + UIUtil.executeAsyncTaskAndUpdateUI(() -> { + FunctionConstants.PLUGIN.getGroupName(); + return null; + }, result -> initGroupTypeModel()); initTypeListSelectionListener(); return this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Function_Category"), functionTypeScrollPane); } @@ -1126,6 +1130,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { //hugh: 从函数分组插件中添加分组 FunctionConstants.addFunctionGroupFromPlugins(functionTypeListModel); + functionTypeList.setSelectedIndex(0); } private void initFunctionNameListCellRenderer() { @@ -1303,7 +1308,6 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { private JPanel initFunctionPane() { JPanel functionTypePane = initFunctionTypeList(); JPanel functionNamePane = initFunctionNameList(); - functionTypeList.setSelectedIndex(0); return Layouts.row(LayoutConstants.HORIZONTAL_GAP, cell(functionTypePane).weight(1), cell(functionNamePane).weight(1) ).getComponent(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index 1417bd548a..8d71ae353f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java @@ -39,6 +39,7 @@ import com.fr.design.mainframe.vcs.ui.VcsMovingExitOption; import com.fr.design.menu.ShortCut; import com.fr.design.os.impl.MacOsAddListenerAction; import com.fr.design.os.impl.SupportOSImpl; +import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.TemplateUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.event.EventDispatcher; @@ -63,7 +64,6 @@ import com.fr.stable.project.ProjectConstants; import com.fr.start.OemHandler; import com.fr.start.common.DesignerOpenEmptyPanel; import com.fr.workspace.WorkContext; -import com.fr.workspace.Workspace; import com.fr.workspace.connect.WorkspaceConnectionInfo; import javax.swing.Icon; @@ -315,7 +315,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta } public void resizeFrame() { - + JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (currentEditingTemplate != null) { currentEditingTemplate.setComposite(); @@ -686,37 +686,50 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta * 设置标题 */ public void setTitle() { - + StringBuilder defaultTitle = buildDefaultTitle(); JTemplate editingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - StringBuilder defaultTitleSB = new StringBuilder(); - defaultTitleSB.append(ProductConstants.APP_NAME); - defaultTitleSB.append(" "); - defaultTitleSB.append(GeneralUtils.getVersion()); - defaultTitleSB.append(" "); - defaultTitleSB.append(ProductConstants.BRANCH); - defaultTitleSB.append(" "); + // 当前模板是否为有效模板 + if (JTemplate.isValid(editingTemplate)) { + String path = editingTemplate.getPath(); + UIUtil.executeAsyncTaskAndUpdateUI(() -> editingTemplate.getEditingFILE().exists(), exists -> { + String finalPath = buildFinalPath(path, exists, editingTemplate); + defaultTitle.append(" ").append(finalPath); + setTitle(defaultTitle.toString()); + }); + } else { + setTitle(defaultTitle.toString()); + } + } + + private String buildFinalPath(String path, boolean exists, JTemplate editingTemplate) { + String finalPath = path; + if (!exists) { + finalPath = FILEFactory.MEM_PREFIX + path; + } else if (finalPath.startsWith(ProjectConstants.REPORTLETS_NAME)) { + finalPath = WorkContext.getCurrent().getPath() + File.separator + TemplateUtils.createLockeTemplatedName(editingTemplate, path); + } + return finalPath; + } + + private StringBuilder buildDefaultTitle() { + StringBuilder defaultTitle = new StringBuilder(); + defaultTitle.append(ProductConstants.APP_NAME).append(" ").append(GeneralUtils.getVersion()).append(" ").append(ProductConstants.BRANCH).append(" "); // james:标识登录的用户和登录的ENV String envName = DesignerEnvManager.getEnvManager().getCurEnvName(); - Workspace workspace = WorkContext.getCurrent(); - DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(envName); + String username = getCurrentUsername(envName); + // 拼接用户名、环境名以及工作环境描述 + defaultTitle.append(username).append("@").append(envName).append("[").append(WorkContext.getCurrent().getDescription()).append("]"); + return defaultTitle; + } + private String getCurrentUsername(String envName) { String username = null; + DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(envName); if (info != null) { WorkspaceConnectionInfo connection = info.getConnection(); username = connection == null ? StringUtils.EMPTY : connection.getUserName(); } - defaultTitleSB.append(username).append("@").append(envName).append("[").append(workspace.getDescription()).append("]"); - if (JTemplate.isValid(editingTemplate)) { - String path = editingTemplate.getPath(); - if (!editingTemplate.getEditingFILE().exists()) { - path = FILEFactory.MEM_PREFIX + path; - } else if (path.startsWith(ProjectConstants.REPORTLETS_NAME)) { - path = workspace.getPath() + File.separator + TemplateUtils.createLockeTemplatedName(editingTemplate, path); - } - defaultTitleSB.append(" ").append(path); - } - - setTitle(defaultTitleSB.toString()); + return username; } /** @@ -817,22 +830,22 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta } } } - + public void showEmptyJTemplate() { - + DesignerOpenEmptyPanel designerOpenEmptyPanel = new DesignerOpenEmptyPanel(); BorderLayout layout = (BorderLayout) basePane.getLayout(); basePane.remove(layout.getLayoutComponent(BorderLayout.CENTER)); basePane.remove(layout.getLayoutComponent(BorderLayout.EAST)); basePane.add(designerOpenEmptyPanel, BorderLayout.CENTER); - + resetToolkitByPlus(ToolBarMenuDock.NULLAVOID); - + // 这里挺恶心的,是为了保证对插件的兼容性适配 // 不然的话,插件就会 npe // 见 https://work.fineres.com/browse/REPORT-76091 HistoryTemplateListCache.getInstance().setCurrentEditingTemplate(JNullTemplate.NULL); - + layeredPane.repaint(); } @@ -932,6 +945,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta /** * 根据模板路径获取模板名称 + * * @param templatePath 模板路径 template.getPath() * @return 模板名 */ @@ -950,7 +964,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta * * @return 是否停用失败 */ - private boolean currentTemplateDeactivateFail(JTemplate jt) { + private boolean currentTemplateDeactivateFail(JTemplate jt) { JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); return currentEditingTemplate != null && !currentEditingTemplate.deactivateTemplate(jt); } diff --git a/designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java b/designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java index c03550da2a..b7f23374ff 100644 --- a/designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java +++ b/designer-base/src/main/java/com/fr/design/ui/util/UIUtil.java @@ -3,9 +3,14 @@ package com.fr.design.ui.util; import com.fr.log.FineLoggerFactory; import com.fr.third.guava.base.Stopwatch; import com.fr.third.guava.base.Supplier; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; import org.jetbrains.annotations.NotNull; import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; import javax.swing.UIManager; import java.awt.Color; import java.util.concurrent.TimeUnit; @@ -87,4 +92,32 @@ public class UIUtil { public static Color getPanelBackageColor() { return UIManager.getColor("Panel.background"); } + + /** + * 执行异步任务并在任务完成后更新UI。 + *

+ * 该方法将执行一个耗时的后台任务,并在任务完成后将结果传递给一个回调函数来更新UI。 + * 使用 SwingWorker 来处理后台任务,确保在任务完成后回到 EDT(事件分发线程) 更新 UI。 + * + * @param 任务结果的类型 + * @param task 需要在后台执行的任务。该任务的执行过程由 Supplier 提供,返回任务的结果。 + * @param uiUpdater 在任务完成后执行的回调函数,用来处理结果并更新UI。 + */ + public static void executeAsyncTaskAndUpdateUI(Supplier task, Consumer uiUpdater) { + new SwingWorker() { + @Override + protected T doInBackground() throws Exception { + return task.get(); + } + @Override + protected void done() { + try { + T result = get(); + uiUpdater.accept(result); + } catch (InterruptedException | ExecutionException e) { + FineLoggerFactory.getLogger().debug(e.getMessage(), e); + } + } + }.execute(); + } } diff --git a/designer-base/src/main/java/com/fr/env/SetupDataDesignerRemoteOperator.java b/designer-base/src/main/java/com/fr/env/SetupDataDesignerRemoteOperator.java new file mode 100644 index 0000000000..c0b8161fb4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/SetupDataDesignerRemoteOperator.java @@ -0,0 +1,115 @@ +package com.fr.env; + +import com.fanruan.repository.ConfigRepository; +import com.fr.config.dao.DaoContext; +import com.fr.config.dao.impl.remote.RemoteConfigValidator; +import com.fr.config.utils.ConfData; +import com.fr.config.utils.ConfigReadUtils; +import com.fr.config.utils.PrefixHandler; +import com.fr.config.utils.SetupDataOperator; +import com.fr.nx.app.web.out.widget.utils.CollectionUtils; +import com.fr.stable.StringUtils; +import com.fr.tenant.context.TenantContext; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 设计器远程下获取Updata的操作类 + * + * @author Destiny.Lin + * @since 11.0 + * Created on 2024/10/14 + */ +public class SetupDataDesignerRemoteOperator implements SetupDataOperator { + + private static final SetupDataDesignerRemoteOperator INSTANCE = new SetupDataDesignerRemoteOperator(); + + private static final String EMPTY_STRING = ""; + + /** + * 单例 + */ + public static SetupDataDesignerRemoteOperator getInstance() { + return INSTANCE; + } + + /** + * 批量拉取配置 + * @param nameSpaces + */ + public void fetchBatchConfDatas(List nameSpaces) { + if(nameSpaces.isEmpty()){ + return; + } + List namespaceList = nameSpaces.stream() + .filter(namespace -> !checkRemoteConfigCacheExistence(namespace)) + .collect(Collectors.toList()); + if(CollectionUtils.isEmpty(namespaceList)){ + return; + } + ConfigRepository.getInstance().batchGetConfigsByConfigsCache(namespaceList, () -> { + batchSaveConfigs(namespaceList, TenantContext.getCurrentWithException().getId()); + return null; + }); + } + + private void batchSaveConfigs(List nameSpaces, String tenantId) { + nameSpaces.forEach(namespace -> { + String prefix = PrefixHandler.concatPrefix(namespace, EMPTY_STRING); + ConfigReadUtils.getData(prefix, tenantId); + ConfigReadUtils.getClassInfo(prefix, tenantId); + }); + } + + @Override + public ConfData getData(String prefix, String tenantId) { + String configNamespace = getConfigNameSpace(prefix); + if (checkRemoteConfigCacheExistence(configNamespace)) { + return createConfData(prefix, tenantId); + } + return ConfigRepository.getInstance().getConfigByConfigsCache(configNamespace, () -> createConfData(prefix, tenantId)); + } + + private ConfData createConfData(String prefix, String tenantId) { + ConfData data = new ConfData(); + data.setDataMap(ConfigReadUtils.getData(prefix, tenantId)); + data.setMap(ConfigReadUtils.getClassInfo(prefix, tenantId)); + return data; + } + + private String getConfigNameSpace(String id) { + + if (StringUtils.isEmpty(id)) { + throw new IllegalArgumentException("id cannot be null"); + } + int length = id.length(); + for (int i = 0; i < length; i++) { + if (PrefixHandler.SEPERATOR == id.charAt(i)) { + return id.substring(0, i); + } + } + throw new IllegalArgumentException("cannot resolve namespace of " + id); + } + + /** + * 检查远程配置缓存是否存在 + *

+ * 该方法通过判断三个远程配置相关的DAO(EntityDao、XmlEntityDao、ClassHelperDao)是否在缓存中存在指定的命名空间。 + * 如果DAO实现了RemoteConfigOperable接口,则会依次检查缓存。 + * 如果DAO不支持远程缓存检查,返回false。 + * + * @param nameSpace 命名空间 + * @return 如果三个远程DAO的缓存中都存在指定命名空间的数据,返回true;否则返回false + */ + private boolean checkRemoteConfigCacheExistence(String nameSpace) { + // 只判断一次,所有远程的Dao都实现了RemoteConfigValidator接口 + if (DaoContext.getEntityDao() instanceof RemoteConfigValidator) { + return ((RemoteConfigValidator) DaoContext.getEntityDao()).checkCacheValid(nameSpace) && + ((RemoteConfigValidator) DaoContext.getXmlEntityDao()).checkCacheValid(nameSpace) && + ((RemoteConfigValidator) DaoContext.getClassHelperDao()).checkCacheValid(nameSpace); + } + // 非远程配置不支持设计器缓存检查,返回false + return false; + } +} diff --git a/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java b/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java index 2612cdfae9..04612be802 100644 --- a/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java +++ b/designer-realize/src/main/java/com/fanruan/boot/env/DesignEnvComponent.java @@ -12,7 +12,7 @@ import com.fanruan.carina.annotions.Stop; import com.fanruan.carina.annotions.Supplemental; import com.fanruan.config.ConfigProviderFactory; import com.fanruan.config.LocalConfigSource; -import com.fanruan.config.SetupDataDesignerRemoteOperator; +import com.fr.env.SetupDataDesignerRemoteOperator; import com.fanruan.config.realm.ConfigRealm; import com.fanruan.dao.context.DBContextProvider; import com.fanruan.dao.context.DBContextStarter; diff --git a/designer-realize/src/main/java/com/fanruan/config/SetupDataDesignerRemoteOperator.java b/designer-realize/src/main/java/com/fanruan/config/SetupDataDesignerRemoteOperator.java deleted file mode 100644 index bf5193c2ae..0000000000 --- a/designer-realize/src/main/java/com/fanruan/config/SetupDataDesignerRemoteOperator.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.fanruan.config; - -import com.fanruan.repository.ConfigRepository; -import com.fr.config.utils.ConfData; -import com.fr.config.utils.ConfigReadUtils; -import com.fr.config.utils.PrefixHandler; -import com.fr.config.utils.SetupDataOperator; -import com.fr.stable.StringUtils; - -/** - * 设计器远程下获取Updata的操作类 - * - * @author Destiny.Lin - * @since 11.0 - * Created on 2024/10/14 - */ -public class SetupDataDesignerRemoteOperator implements SetupDataOperator { - - private static final SetupDataDesignerRemoteOperator INSTANCE = new SetupDataDesignerRemoteOperator(); - - /** - * 单例 - */ - public static SetupDataDesignerRemoteOperator getInstance() { - return INSTANCE; - } - - @Override - public ConfData getData(String prefix, String tenantId) { - return ConfigRepository.getInstance().getConfigByConfigsCache(getConfigNameSpace(prefix), () -> { - ConfData data = new ConfData(); - data.setDataMap(ConfigReadUtils.getData(prefix, tenantId)); - data.setMap(ConfigReadUtils.getClassInfo(prefix, tenantId)); - return data; - }); - } - - private String getConfigNameSpace(String id) { - - if (StringUtils.isEmpty(id)) { - throw new IllegalArgumentException("id cannot be null"); - } - int length = id.length(); - for (int i = 0; i < length; i++) { - if (PrefixHandler.SEPERATOR == id.charAt(i)) { - return id.substring(0, i); - } - } - throw new IllegalArgumentException("cannot resolve namespace of " + id); - } -} diff --git a/designer-realize/src/main/java/com/fr/design/cell/editor/FormulaCellEditor.java b/designer-realize/src/main/java/com/fr/design/cell/editor/FormulaCellEditor.java index af5a86259e..012dd5d41e 100644 --- a/designer-realize/src/main/java/com/fr/design/cell/editor/FormulaCellEditor.java +++ b/designer-realize/src/main/java/com/fr/design/cell/editor/FormulaCellEditor.java @@ -22,11 +22,11 @@ public class FormulaCellEditor extends com.fr.design.cell.editor.AbstractCellEdi private UIFormula formulaEditorPane = null; - /** + /** * Constructor. */ public FormulaCellEditor(ElementCasePane ePane) { - super(ePane); + super(ePane); } /**