Browse Source

Merge remote-tracking branch 'origin/feature/x' into feature/x

feature/x
Maximus 2 years ago
parent
commit
d189036cd1
  1. 17
      build.gradle
  2. 16
      designer-base/src/main/java/com/fr/design/DesignModelAdapter.java
  3. 327
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  4. 4
      designer-base/src/main/java/com/fr/design/actions/AllowAuthorityEditAction.java
  5. 14
      designer-base/src/main/java/com/fr/design/actions/UpdateAction.java
  6. 32
      designer-base/src/main/java/com/fr/design/actions/core/ActionFactory.java
  7. 8
      designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java
  8. 19
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  9. 5
      designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java
  10. 4
      designer-base/src/main/java/com/fr/design/actions/help/AboutPane.java
  11. 240
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineCloudConstants.java
  12. 11
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java
  13. 47
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/component/CustomSortPane.java
  14. 19
      designer-base/src/main/java/com/fr/design/actions/help/replace/ITReplaceOperator.java
  15. 5
      designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java
  16. 7
      designer-base/src/main/java/com/fr/design/carton/FeedbackToolboxDialog.java
  17. 1
      designer-base/src/main/java/com/fr/design/constants/UIConstants.java
  18. 8
      designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java
  19. 44
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  20. 6
      designer-base/src/main/java/com/fr/design/data/StrategyConfigAttrUtils.java
  21. 108
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java
  22. 1
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionManagerPane.java
  23. 21
      designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTableModel.java
  24. 434
      designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java
  25. 136
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/TableDataPreviewDesensitizeManager.java
  26. 114
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/model/DesensitizedPreviewTableModel.java
  27. 133
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/PreviewTableDesensitizationPane.java
  28. 42
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/common/ChooseMark.java
  29. 94
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/common/DesensitizationOpenPane.java
  30. 364
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleChoosePane.java
  31. 128
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleDebugPane.java
  32. 309
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleEditPane.java
  33. 89
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRulePane.java
  34. 49
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleSourceChoosePane.java
  35. 98
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationSettingPane.java
  36. 619
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTableModel.java
  37. 153
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTablePane.java
  38. 7
      designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java
  39. 11
      designer-base/src/main/java/com/fr/design/extra/PluginUtils.java
  40. 9
      designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java
  41. 21
      designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java
  42. 18
      designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java
  43. 1243
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  44. 1233
      designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java
  45. 3
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  46. 7
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  47. 65
      designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java
  48. 35
      designer-base/src/main/java/com/fr/design/fun/TemplateThemePaneProvider.java
  49. 24
      designer-base/src/main/java/com/fr/design/fun/impl/AbstractDefaultValueAdjustProvider.java
  50. 26
      designer-base/src/main/java/com/fr/design/fun/impl/AbstractTemplateThemePaneProvider.java
  51. 98
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java
  52. 7
      designer-base/src/main/java/com/fr/design/gui/core/WidgetOption.java
  53. 2
      designer-base/src/main/java/com/fr/design/gui/frpane/HyperlinkGroupPaneActionProvider.java
  54. 15
      designer-base/src/main/java/com/fr/design/gui/icheckbox/UICheckBox.java
  55. 20
      designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java
  56. 68
      designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java
  57. 4
      designer-base/src/main/java/com/fr/design/gui/iprogressbar/ProgressDialog.java
  58. 19
      designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java
  59. 54
      designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableEditorPane.java
  60. 96
      designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableModelAdapter.java
  61. 7
      designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java
  62. 41
      designer-base/src/main/java/com/fr/design/gui/style/BorderPane.java
  63. 3
      designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java
  64. 3
      designer-base/src/main/java/com/fr/design/gui/style/FRFontPane.java
  65. 81
      designer-base/src/main/java/com/fr/design/gui/style/TextFormatPaneContainer.java
  66. 2
      designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java
  67. 8
      designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperlinkPane.java
  68. 9
      designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java
  69. 13
      designer-base/src/main/java/com/fr/design/javascript/JavaScriptImplPane.java
  70. 18
      designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java
  71. 46
      designer-base/src/main/java/com/fr/design/layout/VerticalFlowLayout.java
  72. 37
      designer-base/src/main/java/com/fr/design/mainframe/AbsoluteMeasureUIMode.java
  73. 4
      designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java
  74. 54
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  75. 46
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  76. 17
      designer-base/src/main/java/com/fr/design/mainframe/DesignerUIMode.java
  77. 63
      designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java
  78. 7
      designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java
  79. 10
      designer-base/src/main/java/com/fr/design/mainframe/JNullTemplate.java
  80. 10
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  81. 27
      designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java
  82. 38
      designer-base/src/main/java/com/fr/design/mainframe/SimulateWebUIMode.java
  83. 2
      designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java
  84. 6
      designer-base/src/main/java/com/fr/design/mainframe/manager/search/searcher/control/pane/TemplateTreeSearchToolbarPane.java
  85. 5
      designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/SidebarMobileBookMarkStyleCustomDefinePane.java
  86. 46
      designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/topparam/MobileTopParamPane.java
  87. 3
      designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/FontConfigPane.java
  88. 30
      designer-base/src/main/java/com/fr/design/mainframe/platform/ServicePlatformAction.java
  89. 9
      designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java
  90. 10
      designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java
  91. 47
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java
  92. 3
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java
  93. 23
      designer-base/src/main/java/com/fr/design/mainframe/theme/processor/AbstractThemePreviewPaneProcessor.java
  94. 35
      designer-base/src/main/java/com/fr/design/mainframe/theme/processor/ThemePreviewPaneProcessor.java
  95. 6
      designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java
  96. 18
      designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java
  97. 8
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java
  98. 8
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java
  99. 3
      designer-base/src/main/java/com/fr/design/mainframe/widget/MobileTabFontConfPane.java
  100. 36
      designer-base/src/main/java/com/fr/design/module/DesignModuleFactory.java
  101. Some files were not shown because too many files have changed in this diff Show More

17
build.gradle

@ -1,4 +1,5 @@
import org.gradle.plugins.ide.idea.model.IdeaLanguageLevel
import org.gradle.internal.os.OperatingSystem
plugins {
id 'java'
@ -65,11 +66,7 @@ allprojects {
implementation 'com.fr.cbb:fine-universal-skeleton:' + cbbVersion
implementation 'com.install4j:install4j-runtime:8.0.4'
implementation 'com.fr.third:jxbrowser:6.23'
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation 'com.fr.third:jxbrowser-v7:7.22'
implementation 'com.fr.third:jxbrowser-mac-v7:7.22'
implementation 'com.fr.third:jxbrowser-win64-v7:7.22'
implementation 'com.fr.third:jxbrowser-swing-v7:7.22'
implementation 'com.fr.third.server:servlet-api:3.0'
implementation 'org.swingexplorer:swexpl:2.0.1'
@ -94,4 +91,16 @@ allprojects {
testImplementation 'org.powermock:powermock-api-easymock:1.7.1'
testImplementation 'junit:junit:4.12'
}
if (OperatingSystem.current().isMacOsX()) {
dependencies {
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation 'com.fr.third:jxbrowser-mac-v7:7.22'
}
} else if (OperatingSystem.current().isWindows()) {
dependencies {
implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation 'com.fr.third:jxbrowser-win64-v7:7.22'
}
}
}

16
designer-base/src/main/java/com/fr/design/DesignModelAdapter.java

@ -276,22 +276,28 @@ public abstract class DesignModelAdapter<T extends BaseBook, S extends JTemplate
protected void addTableDataParameters(Map<String, ParameterProvider> map, Filter<ParameterProvider> filter) {
Iterator<String> it = this.getBook().getTableDataNameIterator();
List<String> names = new ArrayList<>();
try {
// 清空下缓存
tableDataParametersMap.clear();
List<TableData> tableDatas = new ArrayList<>();
while (it.hasNext()) {
String name = it.next();
TableData tableData = this.getBook().getTableData(name);
ParameterProvider[] parameterProviders = DataOperator.getInstance().getTableDataParameters(tableData);
tableDatas.add(tableData);
names.add(name);
}
ParameterProvider[][] totalParameterProviders = DataOperator.getInstance().getTotalTableDataParameters(tableDatas);
tableDataParametersMap.clear();
for (int i = 0; i < totalParameterProviders.length; i++) {
ParameterProvider[] parameterProviders = totalParameterProviders[i];
if (filter != null) {
ParameterApplyHelper.addPara2Map(map, parameterProviders, filter, null, ParameterSource.DEFAULT_SOURCE);
} else {
ParameterApplyHelper.addPara2Map(map, parameterProviders, null, ParameterSource.TEMPLATE_SOURCE);
}
tableDataParametersMap.put(name, parameterProviders);
tableDataParametersMap.put(names.get(i), parameterProviders);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
}

327
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -4,7 +4,9 @@
package com.fr.design;
import com.fr.base.BaseXMLUtils;
import com.fr.base.OptimizeUtil;
import com.fr.base.Utils;
import com.fr.collections.api.Callback;
import com.fr.design.actions.help.alphafine.AlphaFineConfigManager;
import com.fr.design.carton.SwitchForSwingChecker;
import com.fr.design.constants.UIConstants;
@ -21,8 +23,8 @@ import com.fr.design.locale.impl.ProductImproveMark;
import com.fr.design.login.DesignerLoginType;
import com.fr.design.login.config.DesignerLoginConfigManager;
import com.fr.design.mainframe.ComponentReuseNotifyUtil;
import com.fr.design.mainframe.simple.SimpleDesignerConfig;
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo;
import com.fr.design.mainframe.simple.SimpleDesignerConfig;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.notification.SnapChatConfig;
import com.fr.design.os.impl.SupportOSImpl;
@ -41,6 +43,12 @@ import com.fr.general.SupportLocale;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.general.xml.GeneralXMLTools;
import com.fr.general.xml.async.AsyncXmlElement;
import com.fr.general.xml.async.AsyncXmlReadable;
import com.fr.general.xml.async.SimpleXmlElement;
import com.fr.general.xml.async.XmlElement;
import com.fr.general.xml.async.XmlException;
import com.fr.general.xml.async.XmlInitialFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.log.LogHandler;
import com.fr.stable.CommonUtils;
@ -58,8 +66,10 @@ import com.fr.stable.xml.XMLTools;
import com.fr.stable.xml.XMLWriter;
import com.fr.stable.xml.XMLableReader;
import com.fr.start.common.DesignerStartupConfig;
import com.fr.start.common.DesignerStartupPool;
import com.fr.third.apache.logging.log4j.core.appender.FileAppender;
import com.fr.third.apache.logging.log4j.core.layout.PatternLayout;
import com.fr.third.org.apache.commons.io.FileUtils;
import com.fr.third.org.apache.commons.io.FilenameUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.WorkContextCallback;
@ -86,12 +96,18 @@ import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* The manager of Designer GUI.
* 下面的作者日期都是随手写的具体作者已经无法考究
*
* @author anonymous
* @version 11.0
* created by anonymous on 2002/11/08
*/
public class DesignerEnvManager implements XMLReadable, XMLWriter {
public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReadable {
private static final int MAX_SHOW_NUM = 10;
private static final String VERSION_80 = "80";
private static final String VERSION_90 = "90";
@ -104,21 +120,26 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
* 指定默认工作空间
*/
public static final String DEFAULT_WORKSPACE_PATH = "fr.designer.workspace.default";
public static final String LAST_EAST_REGION_LAYOUT = "LastEastRegionLayout";
public static final String LAST_WEST_REGION_LAYOUT = "LastWestRegionLayout";
private static DesignerEnvManager designerEnvManager; // gui.
private String activationKey = null;
private String logLocation = null;
private Rectangle windowBounds = null; // window bounds.
private String DialogCurrentDirectory = null;
private String CurrentDirectoryPrefix = null;
private Map<String, List<String>> recentOpenedFileListMap = new HashMap<>();
private List<String> tempRecentOpenedFilePathList = new ArrayList<String>();
private XmlElement<Map<String, List<String>>> recentOpenedMapping = SimpleXmlElement.of(recentOpenedFileListMap);
private boolean showPaintToolBar = true;
private int maxNumberOrPreviewRow = 200;
// name和Env的键值对
private Map<String, DesignerWorkspaceInfo> nameEnvMap = new ListMap<>();
// marks: 当前报表服务器名字
private String curEnvName = null;
private XmlElement<EnvConfiguration> envConfig = SimpleXmlElement.of(new EnvConfiguration());
private boolean showProjectPane = true;
private boolean showDataPane = true;
//p:这是当前选择的数据库连接的名字,这个在新建数据源的时候用到.
@ -181,7 +202,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
/**
* alphafine
*/
private AlphaFineConfigManager alphaFineConfigManager = AlphaFineConfigManager.getInstance();
private XmlElement<AlphaFineConfigManager> alphaFineConfigManager = SimpleXmlElement.of(AlphaFineConfigManager.getInstance());
/**
* 阅后即焚的配置项
@ -230,7 +251,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private boolean propertiesUsable;
private SimpleDesignerConfig fvsDesignerConfig = SimpleDesignerConfig.getInstance("FvsDesignerConfig");
private XmlElement<SimpleDesignerConfig> fvsDesignerConfig = SimpleXmlElement.of(SimpleDesignerConfig.getInstance("FvsDesignerConfig"));
/**
* DesignerEnvManager.
@ -244,13 +265,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
designerEnvManager = new DesignerEnvManager();
//REPORT-15332有一个国际化调用比较早,需要在这边就设置好locale,由于后台GeneralContext默认是China
GeneralContext.setLocale(designerEnvManager.getLanguage());
try {
XMLTools.readFileXML(designerEnvManager, designerEnvManager.getDesignerEnvFile());
} catch (FileNotFoundException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
XmlHandler.Self.handle(e);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
if (!asyncInitEnvManager()) {
// 如果异步读取失败, 则恢复原来的逻辑
compatibleInitEnvManager();
}
// james:如果没有env定义,要设置一个默认的
@ -267,13 +285,47 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
return designerEnvManager;
}
private static void compatibleInitEnvManager() {
try {
XMLTools.readFileXML(designerEnvManager, designerEnvManager.getDesignerEnvFile());
} catch (FileNotFoundException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
XmlHandler.Self.handle(e);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 异步初始化环境管理, 提供配置, 帮助处理预期外的问题
* 1-当优化开启时才走异步逻辑
* 2-如果异步执行中出错则返回异常 false, 否则返回 true
*
* @return /
*/
private static boolean asyncInitEnvManager() {
AtomicBoolean noEx = new AtomicBoolean(false);
OptimizeUtil.open(DesignerEnvManager.class.getSimpleName().toLowerCase(), OptimizeUtil.Module.COMMON, () -> {
try {
designerEnvManager.initElements(designerEnvManager.getDesignerEnvFile());
noEx.set(true);
} catch (Throwable retryEx) {
FineLoggerFactory.getLogger().debug("try async init DesignerEnvManager failed", retryEx);
}
});
return noEx.get();
}
public ColorSelectConfigManager getColorConfigManager() {
return this.configManager;
}
public static void checkNameEnvMap() {
if (designerEnvManager == null || designerEnvManager.nameEnvMap.size() > 0) {
if (designerEnvManager == null || designerEnvManager.getNameEnvMap().size() > 0) {
return;
}
String installHome = StableUtils.getInstallHome();
@ -443,8 +495,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
// 清空前一个版本中的工作目录和最近打开
nameEnvMap = new ListMap<String, DesignerWorkspaceInfo>();
curEnvName = null;
getEnvConfig().setNameEnvMap(new ListMap<>());
getEnvConfig().setCurEnvName(null);
designerEnvManager.saveXMLFile();
}
@ -606,7 +658,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
String installHome = StableUtils.getInstallHome();
String defaultenvPath = getDefaultenvPath(installHome);
defaultenvPath = new File(defaultenvPath).getPath();
Iterator<Entry<String, DesignerWorkspaceInfo>> entryIt = nameEnvMap.entrySet().iterator();
Iterator<Entry<String, DesignerWorkspaceInfo>> entryIt = getNameEnvMap().entrySet().iterator();
while (entryIt.hasNext()) {
Entry<String, DesignerWorkspaceInfo> entry = entryIt.next();
DesignerWorkspaceInfo env = entry.getValue();
@ -627,8 +679,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
String installHome = StableUtils.getInstallHome();
String defaultenvPath = getDefaultenvPath(installHome);
defaultenvPath = new File(defaultenvPath).getPath();
if (nameEnvMap.size() >= 0) {
Iterator<Entry<String, DesignerWorkspaceInfo>> entryIt = nameEnvMap.entrySet().iterator();
if (getNameEnvMap().size() >= 0) {
Iterator<Entry<String, DesignerWorkspaceInfo>> entryIt = getNameEnvMap().entrySet().iterator();
while (entryIt.hasNext()) {
Entry<String, DesignerWorkspaceInfo> entry = entryIt.next();
DesignerWorkspaceInfo env = entry.getValue();
@ -1019,21 +1071,21 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
public SimpleDesignerConfig getFvsDesignerConfig() {
return fvsDesignerConfig;
return fvsDesignerConfig.getValue();
}
/**
* 返回环境名称迭代器
*/
public Iterator<String> getEnvNameIterator() {
return this.nameEnvMap.keySet().iterator();
return this.getNameEnvMap().keySet().iterator();
}
/**
* 根据名称返回环境
*/
public DesignerWorkspaceInfo getWorkspaceInfo(String name) {
return this.nameEnvMap.get(name);
return this.getNameEnvMap().get(name);
}
/**
@ -1044,7 +1096,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
*/
public void putEnv(String name, DesignerWorkspaceInfo info) {
this.nameEnvMap.put(name, info);
this.getNameEnvMap().put(name, info);
}
/**
@ -1053,14 +1105,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
* @param name 环境的名字
*/
public void removeEnv(String name) {
this.nameEnvMap.remove(name);
this.getNameEnvMap().remove(name);
}
/**
* 清除全部环境
*/
public void clearAllEnv() {
this.nameEnvMap.clear();
this.getNameEnvMap().clear();
}
/**
@ -1082,14 +1134,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
* 返回当前环境的名称.
*/
public String getCurEnvName() {
return this.curEnvName;
return getEnvConfig().getCurEnvName();
}
/**
* 设置当前环境的名称
*/
public void setCurEnvName(String envName) {
this.curEnvName = envName;
getEnvConfig().setCurEnvName(envName);
}
/**
@ -1146,12 +1198,12 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
if (StringUtils.isEmpty(envName)) {
return tempRecentOpenedFilePathList;
} else {
if (!recentOpenedFileListMap.containsKey(envName)) {
recentOpenedFileListMap.put(envName, tempRecentOpenedFilePathList);
if (!recentOpenedMapping.getValue().containsKey(envName)) {
recentOpenedMapping.getValue().put(envName, tempRecentOpenedFilePathList);
}
}
return recentOpenedFileListMap.get(envName);
return recentOpenedMapping.getValue().get(envName);
}
/**
@ -1755,11 +1807,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
public AlphaFineConfigManager getAlphaFineConfigManager() {
return alphaFineConfigManager;
return alphaFineConfigManager.getValue();
}
public void setAlphaFineConfigManager(AlphaFineConfigManager alphaFineConfigManager) {
this.alphaFineConfigManager = alphaFineConfigManager;
this.alphaFineConfigManager.setValue(alphaFineConfigManager);
}
public boolean isImageCompress() {
@ -1801,7 +1853,101 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
public void setLayoutTemplateStyle(int layoutTemplateStyle) {
this.layoutTemplateStyle = layoutTemplateStyle;
}
@Override
public void initElements(File xmlFile) throws XmlException {
try {
backupOldXmlFile();
XmlInitialFactory xmlInitialFactory = XmlInitialFactory.create(xmlFile);
xmlInitialFactory
.init("XMLVersion", DesignerEnvManager.this::readXMLVersion)
.init("Attributes", DesignerEnvManager.this::readAttributes)
.init("ReportPaneAttributions", DesignerEnvManager.this::readReportPaneAttributions)
.init("RecentOpenedFilePath", (e) -> {
this.recentOpenedMapping = AsyncXmlElement.of(DesignerStartupPool.common(), () -> {
DesignerEnvManager.this.readRecentOpenFileList0(e);
return recentOpenedFileListMap;
}).callback(new Callback<Map<String, List<String>>>() {
@Override
public void exec(Map<String, List<String>> stringListMap) {
checkRecentOpenedFileNum();
}
});
})
.init("EnvConfigMap", (e) -> {
final EnvConfiguration previousConfig = this.envConfig.getValue();
this.envConfig = AsyncXmlElement.of(DesignerStartupPool.common(), () -> {
DesignerEnvManager.this.readEnvConfigMap(e, previousConfig);
return previousConfig;
});
})
.init("LogLocation", DesignerEnvManager.this::readLogLocation)
.init("Language", DesignerEnvManager.this::readLanguage)
.init("JettyServerPort", DesignerEnvManager.this::readJettyPort)
.init("PLengthUnit", DesignerEnvManager.this::readPageLengthUnit)
.init("RLengthUnit", DesignerEnvManager.this::readReportLengthUnit)
.init("LastOpenFilePath", DesignerEnvManager.this::readLastOpenFile)
.init("EncryptionKey", DesignerEnvManager.this::readEncrytionKey)
.init("jdkHome", (e) -> this.jdkHome = e.getElementValue())
.init("lastBBSTime", DesignerEnvManager.this::readLastBBSTime)
.init("lastBBSNewsTime", DesignerEnvManager.this::readLastBBSNewsTime)
.init("ActivationKey", DesignerEnvManager.this::readActiveKey)
.init("status", DesignerEnvManager.this::readActiveStatus)
.init(CAS_PARAS, DesignerEnvManager.this::readHttpsParas)
.init(EnvDetectorConfig.XML_TAG, DesignerEnvManager.this::readEnvDetectorConfig)
.init(DesignerStartupConfig.XML_TAG, DesignerEnvManager.this::readStartupConfig)
.init("AlphaFineConfigManager", (e) -> {
this.alphaFineConfigManager = AsyncXmlElement.of(DesignerStartupPool.common(), () -> {
AlphaFineConfigManager config = AlphaFineConfigManager.getInstance();
e.readXMLObject(config);
return config;
});
})
.init("RecentColors", DesignerEnvManager.this::readRecentColor)
.init("OpenDebug", DesignerEnvManager.this::readOpenDebug)
.init(ComponentReuseNotificationInfo.XML_TAG, DesignerEnvManager.this::readComponentReuseNotificationInfo)
.init(DesignerPushUpdateConfigManager.XML_TAG, DesignerEnvManager.this::readDesignerPushUpdateAttr)
.init(VcsConfigManager.XML_TAG, DesignerEnvManager.this::readVcsAttr)
.init(DesignerPort.XML_TAG, DesignerEnvManager.this::readDesignerPort)
.init(SnapChatConfig.XML_TAG, DesignerEnvManager.this::readSnapChatConfig)
.init(DesignerLoginConfigManager.XML_TAG, DesignerEnvManager.this::readDesignerLoginAttr)
.init(fvsDesignerConfig.getValue().getName(), (e) -> {
SimpleDesignerConfig config = this.fvsDesignerConfig.getValue();
this.fvsDesignerConfig = AsyncXmlElement.of(() -> {
e.readXMLObject(config);
return config;
});
})
.init(SwitchForSwingChecker.XML_TAG, DesignerEnvManager.this::readSwitchForSwingCheckerAttr)
.init(LAST_WEST_REGION_LAYOUT, DesignerEnvManager.this::readLastWestRegionLayout)
.init(LAST_EAST_REGION_LAYOUT, DesignerEnvManager.this::readLastEastRegionLayout);
} catch (Exception e) {
throw new XmlException(e);
}
}
/**
* 备份老的 xml 文件, 防止第一次修改存在问题
* 但是只备份一次其他都走老逻辑
*/
private void backupOldXmlFile() {
try {
File oldFile = getEnvFile();
String newFilePath = ProductConstants.getEnvHome() + File.separator + ProductConstants.APP_NAME + "Env_backup.xml";
File newFile = new File(newFilePath);
if (newFile.exists()) {
return;
}
if (oldFile.exists()) {
FileUtils.copyFile(oldFile, newFile);
}
} catch (Exception ignored) {
}
}
/**
* Read XML.<br>
* The method will be invoked when read data from XML file.<br>
@ -1865,7 +2011,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
readComponentReuseNotificationInfo(reader);
} else if (name.equals(DesignerPushUpdateConfigManager.XML_TAG)) {
readDesignerPushUpdateAttr(reader);
} else if (name.equals(vcsConfigManager.XML_TAG)) {
} else if (name.equals(VcsConfigManager.XML_TAG)) {
readVcsAttr(reader);
} else if (DesignerPort.XML_TAG.equals(name)) {
readDesignerPort(reader);
@ -1873,7 +2019,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
readSnapChatConfig(reader);
} else if (name.equals(DesignerLoginConfigManager.XML_TAG)) {
readDesignerLoginAttr(reader);
} else if (name.equals(fvsDesignerConfig.getName())) {
} else if (name.equals(fvsDesignerConfig.getValue().getName())) {
readFvsDesignerConfig(reader);
} else if (name.equals(SwitchForSwingChecker.XML_TAG)) {
readSwitchForSwingCheckerAttr(reader);
@ -1893,7 +2039,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
private void readAlphaFineAttr(XMLableReader reader) {
reader.readXMLObject(this.alphaFineConfigManager = AlphaFineConfigManager.getInstance());
AlphaFineConfigManager config = AlphaFineConfigManager.getInstance();
reader.readXMLObject(config);
this.alphaFineConfigManager = SimpleXmlElement.of(config);
}
private void readEnvDetectorConfig(XMLableReader reader) {
@ -1918,9 +2067,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private void readLayout(XMLableReader reader, String name) {
if ("LastEastRegionLayout".equals(name)) {
if (LAST_EAST_REGION_LAYOUT.equals(name)) {
this.readLastEastRegionLayout(reader);
} else if ("LastWestRegionLayout".equals(name)) {
} else if (LAST_WEST_REGION_LAYOUT.equals(name)) {
this.readLastWestRegionLayout(reader);
}
}
@ -2015,6 +2164,40 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.setPaginationLineColor(new Color(Integer.parseInt(tmpVal)));
}
}
private void readEnvConfigMap(XMLableReader reader, EnvConfiguration envConfigs) {
String currentEnv = reader.getAttrAsString("currentEnv", StringUtils.EMPTY);
envConfigs.setCurEnvName(currentEnv);
reader.readXMLObject(new XMLReadable() {
@Override
public void readXML(XMLableReader reader) {
if (reader.isAttr()) {
envConfigs.getNameEnvMap().clear();
} else if (reader.isChildNode()) {
String tagName = reader.getTagName();
if ("EnvConfigElement".equals(tagName)) {
final String name = reader.getAttrAsString("name", StringUtils.EMPTY);
reader.readXMLObject(new XMLReadable() {
@Override
public void readXML(XMLableReader reader) {
if (reader.isChildNode()) {
String tagName = reader.getTagName();
if (DesignerWorkspaceType.Local.toString().equals(tagName)) {
LocalDesignerWorkspaceInfo envConfig = (LocalDesignerWorkspaceInfo) GeneralXMLTools.readXMLable(reader);
envConfigs.getNameEnvMap().put(name, envConfig);
} else if (DesignerWorkspaceType.Remote.toString().equals(tagName)) {
RemoteDesignerWorkspaceInfo envConfig = (RemoteDesignerWorkspaceInfo) GeneralXMLTools.readXMLable(reader);
envConfigs.getNameEnvMap().put(name, envConfig);
}
}
}
});
}
}
}
});
}
private void readEnvConfigMap(XMLableReader reader) {
String currentEnv = reader.getAttrAsString("currentEnv", StringUtils.EMPTY);
@ -2048,8 +2231,15 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
});
}
private void readRecentOpenFileList(XMLableReader reader) {
readRecentOpenFileList0(reader);
checkRecentOpenedFileNum();
}
private void readRecentOpenFileList0(XMLableReader reader) {
reader.readXMLObject(new XMLReadable() {
@Override
public void readXML(XMLableReader reader) {
@ -2081,7 +2271,6 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
}
});
checkRecentOpenedFileNum();
}
private void readDesignerPushUpdateAttr(XMLableReader reader) {
@ -2151,7 +2340,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private void writeAlphaFineAttr(XMLPrintWriter writer) {
if (this.alphaFineConfigManager != null) {
this.alphaFineConfigManager.writeXML(writer);
this.alphaFineConfigManager.getValue().writeXML(writer);
}
}
@ -2228,10 +2417,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
writer.end();
writer.startTAG("EnvConfigMap");
if (this.curEnvName != null) {
writer.attr("currentEnv", this.curEnvName);
if (this.getCurEnvName() != null) {
writer.attr("currentEnv", this.getCurEnvName());
}
for (Entry<String, DesignerWorkspaceInfo> entry : nameEnvMap.entrySet()) {
for (Entry<String, DesignerWorkspaceInfo> entry : getNameEnvMap().entrySet()) {
writer.startTAG("EnvConfigElement").attr("name", entry.getKey());
DesignerWorkspaceInfo envConfig = entry.getValue();
GeneralXMLTools.writeXMLable(writer, envConfig, envConfig.getType().toString());
@ -2440,11 +2629,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
private void readFvsDesignerConfig(XMLableReader reader) {
reader.readXMLObject(fvsDesignerConfig);
SimpleDesignerConfig config = fvsDesignerConfig.getValue();
reader.readXMLObject(config);
fvsDesignerConfig = SimpleXmlElement.of(config);
}
private void writeFvsDesignerConfig(XMLPrintWriter writer) {
this.fvsDesignerConfig.writeXML(writer);
this.fvsDesignerConfig.getValue().writeXML(writer);
}
private void writeSwitchForSwingChecker(XMLPrintWriter writer) {
@ -2479,4 +2671,39 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
public SnapChatConfig getSnapChatConfig() {
return snapChatConfig;
}
private EnvConfiguration getEnvConfig() {
return envConfig.getValue();
}
private Map<String, DesignerWorkspaceInfo> getNameEnvMap() {
return getEnvConfig().getNameEnvMap();
}
private static class EnvConfiguration {
// name和Env的键值对
private Map<String, DesignerWorkspaceInfo> nameEnvMap = new ListMap<>();
// marks: 当前报表服务器名字
private String curEnvName = null;
public Map<String, DesignerWorkspaceInfo> getNameEnvMap() {
return nameEnvMap;
}
public void setNameEnvMap(Map<String, DesignerWorkspaceInfo> nameEnvMap) {
this.nameEnvMap = nameEnvMap;
}
public String getCurEnvName() {
return curEnvName;
}
public void setCurEnvName(String curEnvName) {
this.curEnvName = curEnvName;
}
}
}

4
designer-base/src/main/java/com/fr/design/actions/AllowAuthorityEditAction.java

@ -1,9 +1,9 @@
package com.fr.design.actions;
import com.fr.base.svg.IconUtils;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.constants.UIConstants;
import com.fr.design.menu.KeySetUtils;
import com.fr.design.module.DesignModuleFactory;
import com.fr.design.roleAuthority.ReportAndFSManagePane;
import com.fr.design.roleAuthority.RolesAlreadyEditedPane;
import com.fr.design.designer.TargetComponent;
@ -61,6 +61,8 @@ public class AllowAuthorityEditAction extends TemplateComponentAction {
DesignerContext.getDesignerFrame().refreshDottedLine();
EastRegionContainerPane.getInstance().replaceConfiguredRolesPane(RolesAlreadyEditedPane.getInstance());
EastRegionContainerPane.getInstance().removeParameterPane();
//进入时要关闭查找替换面板
DesignModuleFactory.getReplaceOperator().close();
//画虚线
return true;

14
designer-base/src/main/java/com/fr/design/actions/UpdateAction.java

@ -185,12 +185,24 @@ public abstract class UpdateAction extends ShortCut implements Action {
* @param resource 图标资源路径
*/
public void setSmallIcon(String resource) {
setSmallIcon(resource, true);
}
/**
* 使用传入资源url的方式设置Icon会自动设置_normal.svg然后通过needDisable参数判断是否需要自动设置_disable.svg
* 因为有些地方是不需要设置灰化图标的所以不存在灰化图标资源这边如果一并设置就会报错文件找不到
* @param resource
* @param needDisable
*/
public void setSmallIcon(String resource, boolean needDisable) {
if (StringUtils.equals(resource, StringUtils.EMPTY)) {
this.putValue(Action.SMALL_ICON, null);
return;
}
this.putValue(Action.SMALL_ICON, IconUtils.readIcon(resource));
this.putValue(UpdateAction.DISABLED_ICON, IconUtils.readSVGIcon(resource, IconUtils.ICON_TYPE_DISABLED));
if (needDisable) {
this.putValue(UpdateAction.DISABLED_ICON, IconUtils.readSVGIcon(resource, IconUtils.ICON_TYPE_DISABLED));
}
}
public void setSmallIcon(Icon[] smallIcon, boolean white) {

32
designer-base/src/main/java/com/fr/design/actions/core/ActionFactory.java

@ -6,6 +6,7 @@ import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.selection.QuickEditor;
import com.fr.design.ui.util.UIUtil;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
@ -32,6 +33,7 @@ public class ActionFactory {
private static Set<Class<?>> actionClasses = new CopyOnWriteArraySet<>();
private static Set<Class<?>> floatActionClasses = new CopyOnWriteArraySet<>();
private static Class chartCollectionClass = null;
/**
* 无需每次实例化的悬浮元素编辑器
*/
@ -57,7 +59,6 @@ public class ActionFactory {
private ActionFactory() {
}
/**
* 元素编辑器释放模板对象
*/
@ -69,7 +70,34 @@ public class ActionFactory {
entry.getValue().release();
}
}
/**
* 注册异步加载的单元格编辑器
* 首先放到 classMap 当初始化成功后则移除并放到 cellEditor
* 如果已经存在则覆盖
*
* @param keyClazz 作为 key 的类
* @param editorClazz 作为 编辑器 的类
*/
public static void registerAsyncInitCellEditorClass(Class keyClazz, Class<? extends QuickEditor> editorClazz) {
cellEditorClass.put(keyClazz, editorClazz);
// 这里直接用 invokeLater 放到 UI 线程中去调用。
// 不阻塞主逻辑的启动
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
try {
QuickEditor quickEditor = editorClazz.newInstance();
cellEditorClass.remove(keyClazz);
cellEditor.put(keyClazz, quickEditor);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
});
}
/**
* 注册无需每次实例化的单元格元素编辑器

8
designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java

@ -3,7 +3,7 @@ package com.fr.design.actions.file;
import com.fr.design.actions.UpdateAction;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.menu.KeySetUtils;
@ -28,9 +28,9 @@ public class CloseCurrentTemplateAction extends UpdateAction {
* @param e 事件
*/
public void actionPerformed(ActionEvent e) {
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MutilTempalteTabPane.getInstance().closeFormat(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
MultiTemplateTabPane.getInstance().closeFormat(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate());
}
@Override

19
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -119,6 +119,7 @@ public class PreferencePane extends BasicPane {
private static final int CACHING_DEFAULT = 5;
private static final int CACHING_GAP = 5;
private static final int MEMORY_TIP_LABEL_MAX_WIDTH = 230;
private static final int PREFERENCE_LABEL_MAX_WIDTH = 460;
private static final int OFFSET_HEIGHT = 60;
private static final String TYPE = "pressed";
@ -423,22 +424,20 @@ public class PreferencePane extends BasicPane {
private void createFunctionPane(JPanel generalPane) {
JPanel topVerticalTitledBorderPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Function"));
JPanel upper = new JPanel(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
JPanel lower = new JPanel(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
topVerticalTitledBorderPane.add(upper);
topVerticalTitledBorderPane.add(lower);
JPanel supportUndoPanel = new JPanel(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
topVerticalTitledBorderPane.add(supportUndoPanel);
generalPane.add(topVerticalTitledBorderPane);
//添加supportUndo选择项
supportUndoCheckBox = new UICheckBox(i18nText("Fine-Design_Basic_Preference_Support_Undo"));
upper.add(supportUndoCheckBox);
supportUndoPanel.add(supportUndoCheckBox);
//添加maxUndoLimit
//String[] undoTimes = {"最大撤销次数","5次","10次","15次","20次","50次"};
String[] undoTimes = {i18nText("Fine-Design_Basic_Max_Undo_Limit"), MAX_UNDO_LIMIT_5 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_10 + i18nText("Fine-Design_Basic_Time(s)")
, MAX_UNDO_LIMIT_15 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_20 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_50 + i18nText("Fine-Design_Basic_Time(s)")};
maxUndoLimit = new UIComboBox(undoTimes);
upper.add(maxUndoLimit);
supportUndoPanel.add(maxUndoLimit);
//不支持撤销则不能选择撤销可缓存,也不能设置最大撤销次数
supportUndoCheckBox.addActionListener(new ActionListener() {
@ -452,14 +451,14 @@ public class PreferencePane extends BasicPane {
//添加supportDefaultParentCalculate选择项
supportDefaultParentCalculateCheckBox = new UICheckBox(
i18nText("Fine-Design_Basic_Preference_Support_Default_Parent_Calculate"));
upper.add(supportDefaultParentCalculateCheckBox);
topVerticalTitledBorderPane.add(supportDefaultParentCalculateCheckBox);
//添加是否展示打开模板提示缺少插件选择项
showTemplateMissingPlugin = new UICheckBox(
i18nText("Fine-Design_Basic_Preference_Show-Template-Missing-Plugin"));
upper.add(showTemplateMissingPlugin);
topVerticalTitledBorderPane.add(showTemplateMissingPlugin);
startWithEmptyFile = new UICheckBox(i18nText("Fine-Design_Basic_Preference_Start_Empty_File"));
lower.add(startWithEmptyFile);
topVerticalTitledBorderPane.add(startWithEmptyFile);
}
private void createEditPane(JPanel generalPane) {
@ -661,7 +660,7 @@ public class PreferencePane extends BasicPane {
startupPageEnabledCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Startup_Page_Config_Check_Text"));
startupPane.add(startupPageEnabledCheckBox);
UILabel descLabel = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Config_Desc"));
UILabel descLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Startup_Page_Config_Desc"), PREFERENCE_LABEL_MAX_WIDTH);
descLabel.setForeground(new Color(51, 51, 52, (int)Math.round(0.5 * 255)));
startupPane.add(descLabel);
}

5
designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java

@ -7,7 +7,7 @@ import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.FileOperations;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
@ -16,7 +16,6 @@ import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.utils.TemplateUtils;
import com.fr.design.utils.gui.GUICoreUtils;
@ -89,7 +88,7 @@ public class RenameAction extends UpdateAction {
}
new FileRenameDialog(node);
MutilTempalteTabPane.getInstance().repaint();
MultiTemplateTabPane.getInstance().repaint();
DesignerFrameFileDealerPane.getInstance().stateChange();
}

4
designer-base/src/main/java/com/fr/design/actions/help/AboutPane.java

@ -126,8 +126,8 @@ public class AboutPane extends JPanel {
if (GeneralContext.getLocale().equals(Locale.TAIWAN)) {
return;
}
boxCenterAlignmentPane = new BoxCenterAligmentPane("QQ: " + CloudCenter.getInstance().acquireUrlByKind("help.qq"));
contentPane.add(boxCenterAlignmentPane);
JPanel servicePlatformPane = getURLActionPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Service_Platform"), CloudCenter.getInstance().acquireUrlByKind("service.platform"));
contentPane.add(servicePlatformPane);
}
// 是否显示鸣谢面板

240
designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineCloudConstants.java

@ -1,10 +1,14 @@
package com.fr.design.actions.help.alphafine;
import com.fr.design.i18n.Toolkit;
import com.fr.general.CloudCenter;
import com.fr.json.JSONArray;
import java.util.HashMap;
import java.util.Map;
/**
* 需要从云端获取的常量单独放一起
* 以防AlphaFineConstants被加载时CloudCenter还没启动导致常量获取不到
* 云端变量统一管理
*
* @author Link
* @version 11.0
@ -12,55 +16,185 @@ import com.fr.general.CloudCenter;
*/
public class AlphaFineCloudConstants {
public static final String PLUGIN_SEARCH_URL = CloudCenter.getInstance().acquireUrlByKind("plugin.searchAPI");
public static final String SEARCH_ALL_PLUGIN_URL = CloudCenter.getInstance().acquireUrlByKind("plugin.all.searchAPI");
public static final String PLUGIN_URL = CloudCenter.getInstance().acquireUrlByKind("af.pluginInfo");
public static final String REUSE_URL = CloudCenter.getInstance().acquireUrlByKind("af.reuseInfo");
public static final String DOCUMENT_DOC_URL = CloudCenter.getInstance().acquireUrlByKind("af.doc_view");
public static final String DOCUMENT_SEARCH_URL = CloudCenter.getInstance().acquireUrlByKind("af.doc_search");
public static final String DOCUMENT_INFORMATION_URL = CloudCenter.getInstance().acquireUrlByKind("af.doc_info");
public static final String PLUGIN_IMAGE_URL = CloudCenter.getInstance().acquireUrlByKind("af.plugin_image");
public static final String CLOUD_SERVER_URL = CloudCenter.getInstance().acquireUrlByKind("af.record");
public static final String SEARCH_API = CloudCenter.getInstance().acquireUrlByKind("af.cloud_search");
public static final String SIMILAR_SEARCH_URL_PREFIX = CloudCenter.getInstance().acquireUrlByKind("af.similar_search");
public static final String COMPLEMENT_ADVICE_SEARCH_URL_PREFIX = CloudCenter.getInstance().acquireUrlByKind("af.advice_search");
public static final String ALPHA_HOT_SEARCH = CloudCenter.getInstance().acquireUrlByKind("af.hot_search");
public static final String ALPHA_GO_TO_FORUM = CloudCenter.getInstance().acquireUrlByKind("af.go_fourm");
public static final String ALPHA_GO_TO_WEB = CloudCenter.getInstance().acquireUrlByKind("af.go_web");
public static final String ALPHA_PREVIEW = CloudCenter.getInstance().acquireUrlByKind("af.preview");
public static final String ALPHA_CID = CloudCenter.getInstance().acquireUrlByKind("af.cid.new");
public static final String ALPHA_CID_USER_GROUP_INFO = CloudCenter.getInstance().acquireUrlByKind("af.cid.user.group.info");
private static final String QUICK_START_URL = CloudCenter.getInstance().acquireUrlByKind("af.help.quick.start");
private static final String REPORT_LEARNING_PATH = CloudCenter.getInstance().acquireUrlByKind("af.help.report.learning.path");
private static final String PARAMETER_LEARNING_PATH = CloudCenter.getInstance().acquireUrlByKind("af.help.param.learning.path");
private static final String FILL_LEARNING_PATH = CloudCenter.getInstance().acquireUrlByKind("af.help.fill.learning.path");
private static final String API_SUMMARY = CloudCenter.getInstance().acquireUrlByKind("af.help.api.summary");
private static final String MONTHLY_DOCUMENT = CloudCenter.getInstance().acquireUrlByKind("af.help.monthly.document");
private static final String DEFAULT_RECOMMEND = "[ { \"name\":\"快速入门指南\", \"link\":\"" + QUICK_START_URL + "\" }, { \"name\":\"报表应用学习路径\", \"link\":\"" + REPORT_LEARNING_PATH + "\" }, { \"name\":\"参数应用学习路径\", \"link\":\"" + PARAMETER_LEARNING_PATH + "\" }, { \"name\":\"填报学习路径\", \"link\":\"" + FILL_LEARNING_PATH + "\" }, { \"name\":\"API接口汇总\", \"link\":\"" + API_SUMMARY + "\" }, { \"name\":\"文档月刊\", \"link\":\"" + MONTHLY_DOCUMENT + "\" } ]";
public static final String ALPHA_HELP_RECOMMEND = CloudCenter.getInstance().acquireUrlByKind("af.recommend", DEFAULT_RECOMMEND);
private static final String PLUGIN_SEARCH_API = "plugin.searchAPI";
private static final String PLUGIN_ALL_SEARCH_API = "plugin.all.searchAPI";
private static final String AF_PLUGIN_INFO = "af.pluginInfo";
private static final String AF_REUSE_INFO = "af.reuseInfo";
private static final String AF_DOC_VIEW = "af.doc_view";
private static final String AF_DOC_SEARCH = "af.doc_search";
private static final String AF_DOC_INFO = "af.doc_info";
private static final String AF_PLUGIN_IMAGE = "af.plugin_image";
private static final String AF_RECORD = "af.record";
private static final String AF_CLOUD_SEARCH = "af.cloud_search";
private static final String AF_SIMILAR_SEARCH = "af.similar_search";
private static final String AF_ADVICE_SEARCH = "af.advice_search";
private static final String AF_HOT_SEARCH = "af.hot_search";
private static final String AF_GO_FORUM = "af.go_fourm";
private static final String AF_GO_WEB = "af.go_web";
private static final String AF_PREVIEW = "af.preview";
private static final String AF_CID_NEW = "af.cid.new";
private static final String AF_CID_USER_GROUP_INFO = "af.cid.user.group.info";
private static final String AF_HELP_QUICK_START = "af.help.quick.start";
private static final String AF_HELP_REPORT_LEARNING_PATH = "af.help.report.learning.path";
private static final String AF_HELP_PARAM_LEARNING_PATH = "af.help.param.learning.path";
private static final String AF_HELP_FILL_LEARNING_PATH = "af.help.fill.learning.path";
private static final String AF_HELP_API_SUMMARY = "af.help.api.summary";
private static final String AF_HELP_MONTHLY_DOCUMENT = "af.help.monthly.document";
private static final String AF_RECOMMEND = "af.recommend";
private static final String LINK_NAME = "name";
private static final String LINK_URL = "link";
/**
* 获取插件搜索api
*/
public static String getPluginSearchUrl() {
return CloudCenter.getInstance().acquireUrlByKind(PLUGIN_SEARCH_API);
};
/**
* 帆软市场里全部插件api
*/
public static String getSearchAllPluginUrl() {
return CloudCenter.getInstance().acquireUrlByKind(PLUGIN_ALL_SEARCH_API);
}
/**
* 获取插件信息api
*/
public static String getPluginUrl() {
return CloudCenter.getInstance().acquireUrlByKind(AF_PLUGIN_INFO);
}
/**
* 获取组件信息api
*/
public static String getReuseUrl() {
return CloudCenter.getInstance().acquireUrlByKind(AF_REUSE_INFO);
}
/**
* 获取帮助文档url
*/
public static String getDocumentDocUrl() {
return CloudCenter.getInstance().acquireUrlByKind(AF_DOC_VIEW);
}
/**
* 帮助文档搜索api
*/
public static String getDocumentSearchUrl() {
return CloudCenter.getInstance().acquireUrlByKind(AF_DOC_SEARCH);
}
/**
* 帮助文档信息api
*/
public static String getDocumentInformationUrl() {
return CloudCenter.getInstance().acquireUrlByKind(AF_DOC_INFO);
}
/**
* 插件图片api
*/
public static String getPluginImageUrl() {
return CloudCenter.getInstance().acquireUrlByKind(AF_PLUGIN_IMAGE);
}
/**
* 获取云端接口用于上传alphafine搜索记录
*/
public static String getCloudServerUrl() {
return CloudCenter.getInstance().acquireUrlByKind(AF_RECORD);
}
/**
* 获取搜索api输入搜索词返回fr的相关功能
*/
public static String getSearchApi() {
return CloudCenter.getInstance().acquireUrlByKind(AF_CLOUD_SEARCH);
}
/**
* 获取模糊搜索api前缀输入搜索词返回alphaFine相关内容插件文档功能等
*/
public static String getSimilarSearchUrlPrefix() {
return CloudCenter.getInstance().acquireUrlByKind(AF_SIMILAR_SEARCH);
}
/**
* 补全建议搜索结果 api与AF_SIMILAR_SEARCH接口类似但是返回的信息更全
*/
public static String getComplementAdviceSearchUrlPrefix() {
return CloudCenter.getInstance().acquireUrlByKind(AF_ADVICE_SEARCH);
}
/**
* 获取热门问题
*/
public static String getAlphaHotSearch() {
return CloudCenter.getInstance().acquireUrlByKind(AF_HOT_SEARCH);
}
/**
* 跳转论坛url
*/
public static String getAlphaGoToForum() {
return CloudCenter.getInstance().acquireUrlByKind(AF_GO_FORUM);
}
/**
* 推荐搜索api输入搜索词返回猜你想搜的内容html格式
*/
public static String getAlphaGoToWeb() {
return CloudCenter.getInstance().acquireUrlByKind(AF_GO_WEB);
}
/**
* 帆软智能客服页面url
*/
public static String getAlphaPreview() {
return CloudCenter.getInstance().acquireUrlByKind(AF_PREVIEW);
}
/**
* cid系统的产品动态api
*/
public static String getAlphaCid() {
return CloudCenter.getInstance().acquireUrlByKind(AF_CID_NEW);
}
/**
* cid系统的 用户组信息api
*/
public static String getAlphaCidUserGroupInfo() {
return CloudCenter.getInstance().acquireUrlByKind(AF_CID_USER_GROUP_INFO);
}
private static String getDefaultRecommend() {
String[][] links = new String[][]{
{Toolkit.i18nText("Fine-Design_Report_AlphaFine_Doc_Quick_Start"), CloudCenter.getInstance().acquireUrlByKind(AF_HELP_QUICK_START)},
{Toolkit.i18nText("Fine-Design_Report_AlphaFine_Doc_Report_Learning"), CloudCenter.getInstance().acquireUrlByKind(AF_HELP_REPORT_LEARNING_PATH)},
{Toolkit.i18nText("Fine-Design_Report_AlphaFine_Doc_Parameter_Learning"), CloudCenter.getInstance().acquireUrlByKind(AF_HELP_PARAM_LEARNING_PATH)},
{Toolkit.i18nText("Fine-Design_Report_AlphaFine_Doc_Fill_Learning"), CloudCenter.getInstance().acquireUrlByKind(AF_HELP_FILL_LEARNING_PATH)},
{Toolkit.i18nText("Fine-Design_Report_AlphaFine_Doc_Api_Summary"), CloudCenter.getInstance().acquireUrlByKind(AF_HELP_API_SUMMARY)},
{Toolkit.i18nText("Fine-Design_Report_AlphaFine_Doc_Monthly_Document"), CloudCenter.getInstance().acquireUrlByKind(AF_HELP_MONTHLY_DOCUMENT)}
};
JSONArray jsonArray = new JSONArray();
for (String[] link : links) {
Map<String, String> map = new HashMap<>();
map.put(LINK_NAME, link[0]);
map.put(LINK_URL, link[1]);
jsonArray.put(map);
}
return jsonArray.toString();
}
/**
* 获取默认推荐帮助文档url
*/
public static String getAlphaHelpRecommend() {
return CloudCenter.getInstance().acquireUrlByKind(AF_RECOMMEND, getDefaultRecommend());
}
}

11
designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java

@ -108,6 +108,7 @@ public class AlphaFineConfigManager implements XMLable {
private Map<String, String> actionSearchTextCache = new HashMap<>(8);
private String cacheBuildNO;
private static final String CONTAIN_TEMPLATE_SHOP = "isContainTemplateShop";
/**
* key: 登录的bbs用户
@ -151,6 +152,7 @@ public class AlphaFineConfigManager implements XMLable {
this.setContainPlugin(reader.getAttrAsBoolean("isContainDocument", true));
this.setContainDocument(reader.getAttrAsBoolean("isContainDocument", true));
this.setContainRecommend(reader.getAttrAsBoolean("isContainRecommend", true));
this.setShowTemplateShop(reader.getAttrAsBoolean(CONTAIN_TEMPLATE_SHOP, true));
this.setContainAction(reader.getAttrAsBoolean("isContainAction", true));
this.setContainTemplate(reader.getAttrAsBoolean("isContainTemplate", true));
this.setContainFileContent(reader.getAttrAsBoolean("isContainFileContent", false));
@ -258,6 +260,7 @@ public class AlphaFineConfigManager implements XMLable {
.attr("needSegmentationCheckbox", this.isNeedSegmentationCheckbox())
.attr("needIntelligentCustomerService", this.isNeedIntelligentCustomerService())
.attr("productDynamics", this.isProductDynamics())
.attr(CONTAIN_TEMPLATE_SHOP, this.showTemplateShop)
.attr("tabOrder", this.getTabOrderString());
writeActionSearchTextCacheXML(writer);
writeSearchHistory(writer);
@ -484,6 +487,14 @@ public class AlphaFineConfigManager implements XMLable {
this.showTemplateShop = showTemplateShop;
}
/**
* 是否展示alphafine窗口设置-搜索范围 0勾选则不显示
*/
public boolean needShowAlphaFineDialog() {
return hasTemplateShop() || isContainDocument() || isContainPlugin() ||
isContainAction() || isProductDynamics() || isContainMyTemplate();
}
/**
* 返回tab显示顺序
*/

47
designer-base/src/main/java/com/fr/design/actions/help/alphafine/component/CustomSortPane.java

@ -85,6 +85,7 @@ public class CustomSortPane extends JPanel {
top.addActionListener(e -> {
SwingUtilities.invokeLater(() -> {
sortItemPane.setComponentZOrder(selectedLabel, 0);
setToolbarEnable(sortItemPane.getComponentZOrder(selectedLabel), sortItemPane.getComponentCount());
CustomSortPane.this.revalidate();
CustomSortPane.this.repaint();
refreshCurrentOrder();
@ -94,6 +95,7 @@ public class CustomSortPane extends JPanel {
bottom.addActionListener(e -> {
SwingUtilities.invokeLater(() -> {
sortItemPane.setComponentZOrder(selectedLabel, sortItemPane.getComponentCount() - 1);
setToolbarEnable(sortItemPane.getComponentZOrder(selectedLabel), sortItemPane.getComponentCount());
CustomSortPane.this.revalidate();
CustomSortPane.this.repaint();
refreshCurrentOrder();
@ -103,6 +105,7 @@ public class CustomSortPane extends JPanel {
up.addActionListener(e -> {
SwingUtilities.invokeLater(() -> {
sortItemPane.setComponentZOrder(selectedLabel, sortItemPane.getComponentZOrder(selectedLabel) - 1);
setToolbarEnable(sortItemPane.getComponentZOrder(selectedLabel), sortItemPane.getComponentCount());
CustomSortPane.this.revalidate();
CustomSortPane.this.repaint();
refreshCurrentOrder();
@ -112,6 +115,7 @@ public class CustomSortPane extends JPanel {
down.addActionListener(e -> {
SwingUtilities.invokeLater(() -> {
sortItemPane.setComponentZOrder(selectedLabel, sortItemPane.getComponentZOrder(selectedLabel) + 1);
setToolbarEnable(sortItemPane.getComponentZOrder(selectedLabel), sortItemPane.getComponentCount());
CustomSortPane.this.revalidate();
CustomSortPane.this.repaint();
refreshCurrentOrder();
@ -151,16 +155,43 @@ public class CustomSortPane extends JPanel {
private void disableButton() {
int order = sortItemPane.getComponentZOrder(selectedLabel);
if (order == 0) {
top.setEnabled(false);
up.setEnabled(false);
setToolbarEnable(false, false, true, true);
} else if (order == sortItemPane.getComponentCount() - 1) {
down.setEnabled(false);
bottom.setEnabled(false);
setToolbarEnable(true, true, false, false);
} else {
up.setEnabled(true);
top.setEnabled(true);
down.setEnabled(true);
bottom.setEnabled(true);
setToolbarEnable(true, true, true, true);
}
}
/**
* 设置 置顶上移下移置底 按钮的状态
* true启用
* false关闭
*/
private void setToolbarEnable(boolean top, boolean up, boolean down, boolean bottom) {
this.top.setEnabled(top);
this.up.setEnabled(up);
this.down.setEnabled(down);
this.bottom.setEnabled(bottom);
}
/**
* 根据选项当前位置以及菜单大小设置 置顶上移下移置底 按钮的状态
*/
private void setToolbarEnable(int order, int maxOrder) {
this.top.setEnabled(true);
this.up.setEnabled(true);
this.down.setEnabled(true);
this.bottom.setEnabled(true);
// 选项处于顶端,则置灰上移和置顶按钮
if (order == 0) {
this.top.setEnabled(false);
this.up.setEnabled(false);
}
// 选项处于底端,则置灰下移和置底按钮
if (order == maxOrder - 1) {
this.down.setEnabled(false);
this.bottom.setEnabled(false);
}
}

19
designer-base/src/main/java/com/fr/design/actions/help/replace/ITReplaceOperator.java

@ -0,0 +1,19 @@
package com.fr.design.actions.help.replace;
/**
* 定义一些底层操作
*
* @author Destiny.Lin
* @version 11.0
* created by Destiny.Lin on 2022-09-27
*/
public interface ITReplaceOperator {
/**
* 关闭面板
*/
void close();
}

5
designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java

@ -1,13 +1,13 @@
package com.fr.design.carton;
import com.fr.concurrent.FineExecutors;
import com.fr.design.ui.util.UIUtil;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.ProductConstantsBase;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.third.ibm.icu.text.SimpleDateFormat;
import org.jetbrains.annotations.NotNull;
import javax.swing.SwingUtilities;
@ -22,6 +22,7 @@ import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
@ -314,7 +315,7 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
* 将swing中默认的EventQueue换成自己的
*/
public static void initMonitoring() {
Toolkit.getDefaultToolkit().getSystemEventQueue().push(INSTANCE);
UIUtil.invokeLaterIfNeeded(() -> Toolkit.getDefaultToolkit().getSystemEventQueue().push(INSTANCE));
}
/**

7
designer-base/src/main/java/com/fr/design/carton/FeedbackToolboxDialog.java

@ -94,8 +94,7 @@ public class FeedbackToolboxDialog extends JDialog {
private JPanel createInfoPane() {
JPanel northPane = FRGUIPaneFactory.createNColumnGridInnerContainer_Pane(2, 10, 10);
UILabel title = new UILabel();
//空格布局会好看一点
title.setText(" " + Toolkit.i18nText("Fine-Design_Basic_Carton_Record_Lag_Time") + ": ");
title.setText(" " + Toolkit.i18nText("Fine-Design_Basic_Carton_Record_Lag_Time") + ": ");
//判断一下当天是否有卡顿日志记录,如果有将日期设置为当天,如果没有设置为空
boolean cartonExists = SwitchForSwingChecker.isCartonExists();
if (cartonExists) {
@ -344,8 +343,8 @@ public class FeedbackToolboxDialog extends JDialog {
/**
* 导出卡顿日志到本地或远程服务器WEB-INF下
*
* @param sourceFile 导出的卡顿日志所在文件夹
* @param path 文件需要导出到的路径
* @param sourceFile 导出的卡顿日志所在文件夹
* @param path 文件需要导出到的路径
* @param sourceFilePath 导出的卡顿日志所在文件夹的路径
*/
private void exportCartonLog(File sourceFile, String path, String sourceFilePath) {

1
designer-base/src/main/java/com/fr/design/constants/UIConstants.java

@ -150,6 +150,7 @@ public interface UIConstants {
public static final Color LIST_ITEM_SPLIT_LINE = new Color(0xf0f0f3);
public static final Color DESIGNER_LOGIN_BACKGROUND = new Color(0xf1ad14);
public static final Color DESIGNER_LOGIN_BACKGROUND_ONCLICK = new Color(0xd89600);
public static final Color CHECK_BOX_TIP_FONT_COLOR = new Color(51, 51, 52, (int)Math.round(0.5 * 255));
public static final BufferedImage DRAG_BAR = IOUtils.readImage("com/fr/design/images/control/bar.png");
public static final BufferedImage DRAG_BAR_LIGHT = IOUtils.readImage("com/fr/design/images/control/bar-light.png");

8
designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java

@ -378,12 +378,8 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp
protected boolean isDsNameRepeaded(String name) {
allDSNames = DesignTableDataManager.getAllDSNames(tc.getBook());
for (int i = 0; i < allDSNames.length; i++) {
if (ComparatorUtils.equals(name, allDSNames[i])) {
return true;
}
}
return false;
Set<String> allDSNamesWithoutPermissions = DesignTableDataManager.getAllDSNamesWithoutPermissions(tc.getBook());
return allDSNamesWithoutPermissions.contains(name);
}
protected KeyAdapter getTableTreeNodeListener(final UpdateAction editAction, final UpdateAction previewTableDataAction, final UpdateAction removeAction, final TableDataSourceOP op, final TableDataTree dataTree) {

44
designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java

@ -48,6 +48,7 @@ import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -295,6 +296,27 @@ public abstract class DesignTableDataManager {
return list.toArray(new String[0]);
}
/**
* 获取所有的数据集名称,无论模板是不是有数据集的权限
*/
public static Set<String> getAllDSNamesWithoutPermissions(TableDataSource source) {
Set<String> names = new HashSet<>();
Map<String, TableDataWrapper> resMap = new HashMap<>();
// 模板数据集
addTemplateData(resMap, source);
// 存储过程
addStoreProcedureData(resMap);
for (Map.Entry<String, TableDataWrapper> entry : resMap.entrySet()) {
names.add(entry.getKey());
}
//服务器数据集
Map<String, TableData> tableDatas = TableDataConfig.getInstance().getTableDatas();
for (Map.Entry<String, TableData> entry : tableDatas.entrySet()) {
names.add(entry.getKey());
}
return names;
}
/**
* 不根据过滤设置返回当前模板数据集服务器数据集存储过程本身是有顺序的
*/
@ -625,6 +647,8 @@ public abstract class DesignTableDataManager {
// 把storeProcedure写成xml文件到out
DataCoreXmlUtils.writeXMLStoreProcedure(writer, storeProcedure, null);
if (storeProcedure.getDataModelList().size() > 0 && !storeProcedure.isFirstExpand()) {
// 存储过程有些特殊处理
// 这个就简单直接获取暂存列表吧
return storeProcedure.getDataModelList().toArray(new ProcedureDataModel[0]);
}
ParameterProvider[] inParameters = DataOperator.getInstance().getStoreProcedureParameters(storeProcedure);
@ -633,11 +657,13 @@ public abstract class DesignTableDataManager {
showParaWindow(parameterMap, inParameters);
}
storeProcedure.setFirstExpand(false);
} else {
ParameterProvider[] parameters = DataOperator.getInstance().getTableDataParameters(tableData);
if (parameters.length > 0) {
showParaWindow(parameterMap, parameters);
}
}
// 存储过程有些特殊处理
// 这个就简单直接获取暂存列表吧
// TODO 参数处理?
if (needLoadingBar) {
MultiResultTableDataWrapper.loadingBar.start();
}
@ -657,4 +683,14 @@ public abstract class DesignTableDataManager {
public static void setThreadLocal(String value) {
threadLocal.set(value);
}
}
/**
* 根据数据集名称判断是否为服务器数据集或服务器存储过程
*
* @param tableDataName 数据集名称
* @return
*/
public static boolean isGlobalTableData(String tableDataName) {
return globalDsCache.containsKey(tableDataName);
}
}

6
designer-base/src/main/java/com/fr/design/data/StrategyConfigAttrUtils.java

@ -11,11 +11,11 @@ import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.esd.event.xml.XMLSavedHook;
import com.fr.file.FILE;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -46,7 +46,9 @@ public class StrategyConfigAttrUtils {
}
//新建模版此时不存在,不需要注册钩子
if (attr.getXmlSavedHook() == null && WorkContext.getWorkResource().exist(jTemplate.getPath())) {
//不处理外部路径,保存到设计器才处理
String path = jTemplate.getPath();
if (attr.getXmlSavedHook() == null && !Paths.get(path).isAbsolute() && WorkContext.getWorkResource().exist(path)) {
attr.setXmlSavedHook(new StrategyConfigsAttrSavedHook(jTemplate.getPath(), attr));
}
return attr;

108
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java

@ -21,6 +21,9 @@ import com.fr.event.EventDispatcher;
import com.fr.file.ConnectionConfig;
import com.fr.file.ConnectionOperator;
import com.fr.general.NameObject;
import com.fr.license.database.BaseDataBaseTypePoint;
import com.fr.license.database.DBTypes;
import com.fr.license.exception.DataBaseNotSupportedException;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
@ -29,17 +32,22 @@ import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.database.DataBaseTypeOperator;
import org.jetbrains.annotations.NotNull;
import javax.swing.SwingWorker;
import java.awt.Window;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
/**
* Connection List Pane.
@ -49,6 +57,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
private boolean isNamePermitted = true;
private final HashMap<String, String> renameMap = new HashMap<>();
private final Map<String, Connection> populatedConnectionsSnapshot = new LinkedHashMap<>();
private static List<String> supportedDatabaseTypes = new ArrayList<>();
public ConnectionListPane() {
renameMap.clear();
@ -62,6 +71,30 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
rename(selectedName, getEditingName());
}
});
getSupportedTypes();
}
/**
* 获取本地远程环境lic中未受限制的数据库类型信息
*/
private static void getSupportedTypes() {
SwingWorker<List<String>, Void> getSupportedTypesWorker = new SwingWorker<List<String>, Void>() {
@Override
protected List<String> doInBackground() {
return WorkContext.getCurrent().get(DataBaseTypeOperator.class).getSupportedDatabaseTypes();
}
@Override
protected void done() {
try {
supportedDatabaseTypes = get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
};
getSupportedTypesWorker.execute();
}
@Override
@ -114,21 +147,31 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
/**
* 创建菜单项
* <p>
* 方法中获取limitDatabaseType使用了远程rpc调用可能会比较耗时
*
* @return 菜单项
*/
public NameableCreator[] createNameableCreators() {
NameableCreator[] creators = new NameableCreator[]{new NameObjectCreator(
NameObjectCreator jdbc = new NameObjectCreator(
"JDBC",
"/com/fr/design/images/data/source/jdbcTableData.png",
JDBCDatabaseConnection.class,
DatabaseConnectionPane.JDBC.class
), new NameObjectCreator(
);
NameObjectCreator jndi = new NameObjectCreator(
"JNDI",
"/com/fr/design/images/data/source/jdbcTableData.png",
JNDIDatabaseConnection.class,
DatabaseConnectionPane.JNDI.class
)};
);
NameableCreator[] creators;
if (WorkContext.getCurrent().get(DataBaseTypeOperator.class).limitDatabaseType()) {
// 不支持JNDI,屏蔽接口
creators = new NameableCreator[]{jdbc};
} else {
creators = new NameableCreator[]{jdbc, jndi};
}
Set<ConnectionProvider> pluginCreators = ExtraDesignClassManager.getInstance().getArray(ConnectionProvider.XML_TAG);
for (ConnectionProvider provider : pluginCreators) {
NameObjectCreator creator = new NameObjectCreator(
@ -209,7 +252,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
* @return
*/
private boolean needUpdate0(Connection origin, Connection connection) {
return !connection.equals(origin) || !isEmbedConnection(connection);
return !connection.equals(origin) || !isEmbedConnection(connection);
}
/**
@ -221,10 +264,56 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
}
});
this.validateDatabaseType(addedOrUpdatedConnections);
this.validateConnections(addedOrUpdatedConnections);
this.alterConnections(removedConnNames, addedOrUpdatedConnections);
}
/**
* 校验是否支持所有新增和修改数据连接的数据库类型
*/
public void validateDatabaseType(@NotNull List<ConnectionBean> addedOrUpdatedConnections) {
Set<String> notSupportedConnections = new HashSet<>();
if (!addedOrUpdatedConnections.isEmpty()) {
for (ConnectionBean bean : addedOrUpdatedConnections) {
Connection connection = bean.getConnection();
// 仅校验jdbc连接,其他插件数据连接不进行校验
if (connection instanceof JDBCDatabaseConnection) {
BaseDataBaseTypePoint dataBaseTypePoint = BaseDataBaseTypePoint.getDataBaseTypePoint(connection.getDriver(), connection.feature());
if (connectionIsNotSupported(connection, dataBaseTypePoint)) {
notSupportedConnections.addAll(dataBaseTypePoint.getDataBaseType());
}
}
}
}
if (!notSupportedConnections.isEmpty()) {
throw new DataBaseNotSupportedException(notSupportedConnections, supportedDatabaseTypes);
}
}
/**
* 校验当前数据连接是否被限制
*/
private static boolean connectionIsNotSupported(Connection connection, BaseDataBaseTypePoint dataBaseTypePoint) {
return !validateFRDemo(connection.getDriver(), connection.feature()) &&
(dataBaseTypePoint != null && !supportedDatabaseTypes.containsAll(dataBaseTypePoint.getDatabaseType()));
}
/**
* 校验当前是否为FRDemo不对其进行限制
*/
private static boolean validateFRDemo(String driver, String url) {
if (DBTypes.Sqlite.getDriver().equals(driver) && url.contains(DBTypes.Sqlite.getUrlKey())) {
// 产品:对sqlite类型只允许示例连接FRDemo
String databaseName = url.substring(url.lastIndexOf("/") + 1);
return StringUtils.equals("FRDemo.db", databaseName);
}
return false;
}
private void validateConnections(List<ConnectionBean> addedOrUpdatedConnections) throws Exception {
@ -257,12 +346,21 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
}
private boolean saveByOldWay(List<String> removedConnNames, List<ConnectionBean> addedOrUpdatedConnections) {
final int remaining = ConnectionConfig.getInstance().getRemainingCon(removedConnNames.size(), addedOrUpdatedConnections.size());
try {
return Configurations.modify(new WorkerFacade(ConnectionConfig.class) {
@Override
public void run() {
removedConnNames.forEach(n -> ConnectionConfig.getInstance().removeConnection(n));
addedOrUpdatedConnections.forEach(cb -> ConnectionConfig.getInstance().addConnection(cb.getName(), cb.getConnection()));
int innerRemaining = remaining;
for (ConnectionBean cb : addedOrUpdatedConnections) {
if (innerRemaining > 0) {
ConnectionConfig.getInstance().addConnectionWithoutCheck(cb.getName(), cb.getConnection());
innerRemaining--;
} else {
break;
}
}
}
});
} catch (Exception e) {

1
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionManagerPane.java

@ -4,7 +4,6 @@ import com.fr.design.gui.frpane.LoadingBasicPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.file.ConnectionConfig;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.util.HashMap;

21
designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTableModel.java

@ -20,12 +20,20 @@ public class PreviewTableModel extends AbstractTableModel {
private static final int LEN_LIMIT = 1000;
private static final String THREE_DOT = "...";
private static final int DEFAULT_MAX_ROW_COUNT = 10000;
private DataModel dataModel;
private String erroMessage = null;
public IntList dateIndexs = new IntList(4);
/**
* 为了兼容子类的空参构造一般不主动使用
*/
public PreviewTableModel() {
this(new ErrorResultSet(), DEFAULT_MAX_ROW_COUNT);
}
public PreviewTableModel(int maxRowCount) {
// peter:默认必须显示错误的数据源.
this(new ErrorResultSet(), maxRowCount);
@ -108,6 +116,19 @@ public class PreviewTableModel extends AbstractTableModel {
}
}
/**
* 根据列名获取列序号当返回-1时代表异常异常会被忽略不打印日志或给出前台提示
* @param columnName
* @return
*/
public int getColumnIndexWithExceptionIngore(String columnName) {
try {
return dataModel.getColumnIndex(columnName);
} catch (TableDataException ingore) {
return -1;
}
}
public int getRowCount() {
try {
return this.dataModel.getRowCount();

434
designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java

@ -3,17 +3,23 @@
*/
package com.fr.design.data.datapane.preview;
import com.fr.base.BaseUtils;
import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.data.TableDataSource;
import com.fr.data.desensitize.base.DesensitizationTableData;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.EmbeddedTableData;
import com.fr.data.impl.NameDataModel;
import com.fr.data.operator.DataOperator;
import com.fr.design.DesignerEnvManager;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.preview.desensitization.TableDataPreviewDesensitizeManager;
import com.fr.design.data.datapane.preview.desensitization.model.DesensitizedPreviewTableModel;
import com.fr.design.data.datapane.preview.desensitization.view.PreviewTableDesensitizationPane;
import com.fr.design.data.datapane.preview.desensitization.view.setting.TableDataDesensitizationSettingPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.frpane.UITabbedPane;
@ -25,7 +31,9 @@ import com.fr.design.gui.itextfield.UINumberField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.ui.util.UIUtil;
import com.fr.esd.query.StrategicTableData;
import com.fr.function.TIME;
import com.fr.general.FRFont;
import com.fr.general.data.DataModel;
@ -39,6 +47,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
@ -49,20 +58,20 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CancellationException;
/**
* august PreviewTablePane一共提供5个共有的静态方法用来预览
*/
public class PreviewTablePane extends BasicPane {
private TableData tableData;
private DataModel dataModel;
private UINumberField maxPreviewNumberField;
@ -78,6 +87,54 @@ public class PreviewTablePane extends BasicPane {
private static PreviewTablePane THIS;
private EmbeddedTableData previewTableData;
private PreviewTableDesensitizationPane desensitizationPane;
/**
* 用于refreshLabel的鼠标监听
*/
private final MouseAdapter refreshLabelMouseAdapter = new MouseAdapter() {
boolean mouseEntered = false;
boolean buttonPressed = false;
@Override
public void mouseEntered(MouseEvent e) { // 当鼠标进入时候调用.
mouseEntered = true;
if (!buttonPressed) {
refreshLabel.setBackground(java.awt.Color.WHITE);
refreshLabel.setOpaque(true);
refreshLabel.setBorder(BorderFactory.createLineBorder(java.awt.Color.GRAY));
}
}
@Override
public void mouseExited(MouseEvent e) {
mouseEntered = false;
refreshLabel.setOpaque(false);
refreshLabel.setBorder(BorderFactory.createEmptyBorder());
}
@Override
public void mousePressed(MouseEvent e) {
buttonPressed = true;
refreshLabel.setBackground(java.awt.Color.lightGray);
}
@Override
public void mouseReleased(MouseEvent e) {
buttonPressed = false;
if (mouseEntered) {
refreshLabel.setBackground(java.awt.Color.WHITE);
try {
populate(tableData);
if (dataModel != null) {
setRowsLimitTableModel();
}
} catch (Exception ignore) {
}
}
}
};
public static final PreviewTablePane getInstance() {
if (THIS == null) {
THIS = new PreviewTablePane();
@ -87,91 +144,181 @@ public class PreviewTablePane extends BasicPane {
private PreviewTablePane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
// northPane
this.add(initNorthPane(), BorderLayout.NORTH);
// centerPane
this.add(initCenterPane(), BorderLayout.CENTER);
// dialog
initDialog();
// progressBar
initProgressBar();
}
// elalke:预览行数
JPanel previewNumberPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
this.add(previewNumberPanel, BorderLayout.NORTH);
/**
* 初始化northPane
*
* @return
*/
private JComponent initNorthPane() {
JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
// 预览行数面板
northPane.add(initPreviewNumberPane(), BorderLayout.CENTER);
// 脱敏预览设置面板
northPane.add(initDesensitizationPane(), BorderLayout.EAST);
return northPane;
}
/**
* 初始化预览行数面板
*
* @return
*/
private JComponent initPreviewNumberPane() {
JPanel previewNumberPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
// 当前行数
JPanel currentPreviewPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
previewNumberPanel.add(currentPreviewPanel);
currentPreviewPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Current_Preview_Rows") + ":"));
currentRowsField = new UINumberField();
currentPreviewPanel.add(currentRowsField);
currentRowsField.setEditable(false);
currentRowsField.setColumns(4);
currentRowsField.setInteger(true);
// 最大行数
JPanel maxPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
previewNumberPanel.add(maxPanel);
maxPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Datasource_Maximum_Number_of_Preview_Rows") + ":"));
maxPreviewNumberField = new UINumberField();
maxPanel.add(maxPreviewNumberField);
maxPreviewNumberField.setColumns(4);
maxPreviewNumberField.setInteger(true);
DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager();
maxPreviewNumberField.setValue(designerEnvManager.getMaxNumberOrPreviewRow());
maxPreviewNumberField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager();
designerEnvManager.setMaxNumberOrPreviewRow((int) ((UINumberField) evt.getSource()).getValue());
}
maxPreviewNumberField.setValue(DesignerEnvManager.getEnvManager().getMaxNumberOrPreviewRow());
maxPreviewNumberField.addActionListener(event -> {
DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager();
designerEnvManager.setMaxNumberOrPreviewRow((int) ((UINumberField) event.getSource()).getValue());
});
// 刷新按钮
initRefreshLabel();
Icon refreshImage = BaseUtils.readIcon("/com/fr/design/images/control/refresh.png");
refreshLabel = new UILabel(refreshImage);
previewNumberPanel.add(currentPreviewPanel);
previewNumberPanel.add(maxPanel);
previewNumberPanel.add(refreshLabel);
refreshLabel.addMouseListener(new MouseAdapter() {
boolean mouseEntered = false;
boolean buttonPressed = false;
public void mouseEntered(MouseEvent e) { // 当鼠标进入时候调用.
mouseEntered = true;
if (!buttonPressed) {
refreshLabel.setBackground(java.awt.Color.WHITE);
refreshLabel.setOpaque(true);
refreshLabel.setBorder(BorderFactory.createLineBorder(java.awt.Color.GRAY));
return previewNumberPanel;
}
private void initRefreshLabel() {
Icon refreshImage = IconUtils.readIcon("/com/fr/design/images/control/refresh");
refreshLabel = new UILabel(refreshImage);
refreshLabel.addMouseListener(refreshLabelMouseAdapter);
}
/**
* 初始化脱敏设置面板
*
* @return
*/
private JComponent initDesensitizationPane() {
desensitizationPane = new PreviewTableDesensitizationPane(this);
return desensitizationPane;
}
/**
* 点击脱敏配置后的操作
*/
public void clickDesensitizationLabel() {
// 埋点记录
recordDesensitization();
// 判断数据集类型
if (isGlobalTableData()) {
// 服务器数据集不允许在设计器端修改脱敏配置
FineJOptionPane.showMessageDialog(
this,
Toolkit.i18nText("Fine-Design_Report_Cannot_Modify_Desensitization_Config_Of_ServerTableData"),
Toolkit.i18nText("Fine-Design_Basic_Alert"),
FineJOptionPane.WARNING_MESSAGE);
return;
}
TableDataDesensitizationSettingPane settingPane = new TableDataDesensitizationSettingPane((DesensitizationTableData) tableData);
settingPane.populateBean((DesensitizationTableData) tableData);
BasicDialog dialog = settingPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(PreviewTablePane.this), new DialogActionAdapter() {
@Override
public void doOk() {
// 保存脱敏规则配置
settingPane.updateBean();
// 改变模板保存状态
JTemplate<?, ?> editingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (Objects.nonNull(editingTemplate)) {
editingTemplate.fireTargetModified(true);
}
}
public void mouseExited(MouseEvent e) {
mouseEntered = false;
refreshLabel.setOpaque(false);
refreshLabel.setBorder(BorderFactory.createEmptyBorder());
}
@Override
public void doCancel() {
public void mousePressed(MouseEvent e) {
buttonPressed = true;
refreshLabel.setBackground(java.awt.Color.lightGray);
}
}, BasicDialog.DEFAULT);
dialog.setVisible(true);
// 关闭预览页面
PreviewTablePane.this.dialog.setVisible(false);
}
public void mouseReleased(MouseEvent e) {
buttonPressed = false;
if (mouseEntered) {
refreshLabel.setBackground(java.awt.Color.WHITE);
try {
populate(tableData);
if (dataModel != null) {
setRowsLimitTableModel();
}
} catch (Exception e1) {
}
}
}
});
/**
* 触发数据脱敏埋点记录
*
* @return 数据脱敏字段数量
*/
private int recordDesensitization() {
return getCurrentTableDataDesensitizationCount();
}
/**
* 当前tableData是否为服务器数据集或服务器存储过程
*
* @return
*/
public boolean isGlobalTableData() {
return this.tableData instanceof StrategicTableData &&
DesignTableDataManager.isGlobalTableData(((StrategicTableData) this.tableData).getDsName());
}
/**
* 根据TableData设置脱敏设置的个数
*/
private void setDesensitizationCountByTableData() {
desensitizationPane.setDesensitizationCount(isDesensitizeOpened(), getCurrentTableDataDesensitizationCount());
desensitizationPane.dealWithTableDataType(isGlobalTableData());
}
/**
* 获取当前数据集中设置脱敏规则的个数
*
* @return
*/
private int getCurrentTableDataDesensitizationCount() {
return this.tableData instanceof DesensitizationTableData ?
((DesensitizationTableData) this.tableData).getDesensitizationConfig().getDesensitizationItems().size() :
0;
}
/**
* 初始化centerPane
*
* @return
*/
private JComponent initCenterPane() {
preveiwTable = new CopyableJTable(new TableSorter());
preveiwTable.setRowSelectionAllowed(false);
preveiwTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
return new JScrollPane(preveiwTable);
}
this.add(new JScrollPane(preveiwTable), BorderLayout.CENTER);
private void initDialog() {
if (this.dialog == null) {
this.dialog = this.showWindow(new JFrame());
}
}
private void initProgressBar() {
progressBar = new AutoProgressBar(this, Toolkit.i18nText("Fine-Design_Basic_Loading_Data"), "", 0, 100) {
@Override
public void doMonitorCanceled() {
if (getWorker() != null) {
getWorker().cancel(true);
@ -182,7 +329,7 @@ public class PreviewTablePane extends BasicPane {
}
public AutoProgressBar getProgressBar() {
return this.progressBar;
return PreviewTablePane.progressBar;
}
@Override
@ -222,13 +369,19 @@ public class PreviewTablePane extends BasicPane {
return this.worker;
}
// elake:为预览表的columnIndex列着c色.
/**
* 为预览表的columnIndex列着色.
*
* @param columnIndex 列索引值
* @param c 颜色
*/
private void setPreviewTableColumnColor(final int columnIndex, final Color c) {
addLoadedListener(new LoadedEventListener() {
@Override
public void fireLoaded() {
TableColumn column = preveiwTable.getColumnModel().getColumn(columnIndex);
DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
comp.setBackground(c);
@ -249,7 +402,7 @@ public class PreviewTablePane extends BasicPane {
getInstance().preveiwTable = new SortableJTable(new TableSorter());
getInstance().preveiwTable.setRowSelectionAllowed(false);
getInstance().preveiwTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
getInstance().progressBar.close();
PreviewTablePane.progressBar.close();
getInstance().repaint();
}
@ -331,6 +484,7 @@ public class PreviewTablePane extends BasicPane {
private void previewTableDataSQL() throws Exception {
connectionBar = new AutoProgressBar(this, Toolkit.i18nText("Fine-Design_Basic_Utils_Now_Create_Connection"), "", 0, 100) {
@Override
public void doMonitorCanceled() {
getWorker().cancel(true);
getDialog().setVisible(false);
@ -345,42 +499,49 @@ public class PreviewTablePane extends BasicPane {
private void setPreviewTableColumnValue(final Graphics g) {
for (int i = 0; i < preveiwTable.getColumnModel().getColumnCount(); i++) {
TableColumn column = preveiwTable.getColumnModel().getColumn(i);
DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Font f = table.getFont();
//默认在系统不支持 无法显示时 如自造的字 ,字体设置为空.
Font defaultShowFont = FRFont.getInstance("", f.getStyle(), f.getSize());
if (value instanceof String) {
String str = (String) value;
for (int j = 0; j < str.length(); j++) {
char c = str.charAt(j);
if (!f.canDisplay(c)) {
table.setFont(defaultShowFont);
}
DefaultTableCellRenderer cellRenderer = getDefaultTableCellRenderer();
column.setCellRenderer(cellRenderer);
}
}
/**
* 默认表格格子渲染器
*
* @return
*/
private DefaultTableCellRenderer getDefaultTableCellRenderer() {
return new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Font f = table.getFont();
//默认在系统不支持 无法显示时 如自造的字 ,字体设置为空.
Font defaultShowFont = FRFont.getInstance("", f.getStyle(), f.getSize());
if (value instanceof String) {
String str = (String) value;
for (int j = 0; j < str.length(); j++) {
char c = str.charAt(j);
if (!f.canDisplay(c)) {
table.setFont(defaultShowFont);
}
}
return comp;
}
};
column.setCellRenderer(cellRenderer);
}
return comp;
}
};
}
private void setWorker() {
worker = new SwingWorker<PreviewTableModel, Void>() {
protected PreviewTableModel doInBackground() throws Exception {
worker = new SwingWorker<TableModel, Void>() {
@Override
protected TableModel doInBackground() throws Exception {
connectionBar.start();
try {
if (tableData instanceof DBTableData) {
boolean status = DataOperator.getInstance().testConnection(((DBTableData) tableData).getDatabase());
if (!status) {
throw new Exception(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"));
}
}
testDBTableDataConnection(tableData);
} finally {
// 将close操作放到EDT线程中
UIUtil.invokeLaterIfNeeded(() -> connectionBar.close());
@ -390,22 +551,20 @@ public class PreviewTablePane extends BasicPane {
// parameterInputDialog
// update之后的parameters,转成一个parameterMap,用于预览TableData
PreviewTableModel previewModel = new PreviewTableModel(previewTableData.createDataModel(null), (int) maxPreviewNumberField.getValue());
for (int i = 0; i < previewTableData.getColumnCount(); i++) {
Class<?> cls = previewTableData.getColumnClass(i);
if (cls == Date.class || cls == TIME.class || cls == Timestamp.class) {
previewModel.dateIndexs.add(i);
}
if (TableDataPreviewDesensitizeManager.getInstance().needDesensitize(tableData)) {
// 数据集预览脱敏
previewModel = TableDataPreviewDesensitizeManager.getInstance().desensitizeTableModel(tableData, previewModel);
}
dealWithPreviewTableModelColumnClass(previewModel, previewTableData);
return previewModel;
}
@Override
public void done() {
try {
PreviewTableModel model = get();
setModel(model);
setCurrentRows(model.getRowCount());
TableModel model = get();
setPreviewTableModel(model);
setPreviewTableColumnValue(getParent().getGraphics());
fireLoadedListener();
} catch (Exception e) {
if (!(e instanceof CancellationException)) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
@ -420,6 +579,36 @@ public class PreviewTablePane extends BasicPane {
};
}
/**
* 检查DBTableData连接
*
* @param tableData
* @throws Exception
*/
private void testDBTableDataConnection(TableData tableData) throws Exception {
if (tableData instanceof DBTableData) {
boolean status = DataOperator.getInstance().testConnection(((DBTableData) tableData).getDatabase());
if (!status) {
throw new Exception(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"));
}
}
}
/**
* 处理预览Model的列类型
*
* @param previewModel
* @param previewTableData
*/
private void dealWithPreviewTableModelColumnClass(PreviewTableModel previewModel, EmbeddedTableData previewTableData) {
for (int i = 0; i < previewTableData.getColumnCount(); i++) {
Class<?> cls = previewTableData.getColumnClass(i);
if (cls == Date.class || cls == TIME.class || cls == Timestamp.class) {
previewModel.dateIndexs.add(i);
}
}
}
/**
* 直接预览存储过程的一个返回数据集没有实际值和显示值
*
@ -450,7 +639,7 @@ public class PreviewTablePane extends BasicPane {
/**
* 直接预览数据集的结果集
*
* @param dataModel 结果集
* @param dataModel 结果集
* @param keyIndex
* @param valueIndex
*/
@ -528,9 +717,62 @@ public class PreviewTablePane extends BasicPane {
} catch (Exception e) {
previewModel = new PreviewTableModel((int) maxPreviewNumberField.getValue());
}
setModel(previewModel);
setCurrentRows(previewModel.getRowCount());
setPreviewTableModel(previewModel);
}
/**
* 切换TableModel的展示状态
*/
public void togglePreviewTableModelDesensitizeStatus() {
if (!isDesensitizeOpened()) {
// 未启用数据脱敏时,不需要切换
return;
}
TableSorter tableSorter = (TableSorter) preveiwTable.getModel();
TableModel originTableModel = tableSorter.getTableModel();
if (originTableModel instanceof DesensitizedPreviewTableModel) {
((DesensitizedPreviewTableModel) originTableModel).toggleNeedDesensite();
}
}
/**
* 刷新一下预览页面用于切换脱敏和非脱敏时的显示
*/
public void refreshTable() {
TableModel originTableModel = getCurrentTableModel();
setPreviewTableModel(originTableModel);
}
/**
* 获取当前的TableModel已经除掉了TableSorter的包装
*
* @return
*/
private TableModel getCurrentTableModel() {
TableSorter tableSorter = (TableSorter) preveiwTable.getModel();
return tableSorter.getTableModel();
}
/**
* 设置预览TableModel
*
* @param previewTableModel
*/
private void setPreviewTableModel(TableModel previewTableModel) {
setDesensitizationCountByTableData();
setModel(previewTableModel);
setCurrentRows(previewTableModel.getRowCount());
fireLoadedListener();
}
/**
* 数据脱敏是否启用
*
* @return
*/
private boolean isDesensitizeOpened() {
return tableData instanceof DesensitizationTableData &&
((DesensitizationTableData) tableData).getDesensitizationConfig().isDesensitizeOpened();
}
}

136
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/TableDataPreviewDesensitizeManager.java

@ -0,0 +1,136 @@
package com.fr.design.data.datapane.preview.desensitization;
import com.fr.base.TableData;
import com.fr.data.TableDataSource;
import com.fr.data.desensitize.TableDataDesensitizeManager;
import com.fr.data.desensitize.base.DesensitizationTableData;
import com.fr.data.desensitize.base.TableDataDesensitizationItem;
import com.fr.data.desensitize.manage.DesensitizationManager;
import com.fr.data.desensitize.util.DesentizationUtils;
import com.fr.decision.webservice.bean.user.DepartmentPostBean;
import com.fr.decision.webservice.bean.user.RoleBean;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.v10.user.CustomRoleService;
import com.fr.decision.webservice.v10.user.PositionService;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.preview.PreviewTableModel;
import com.fr.design.data.datapane.preview.desensitization.model.DesensitizedPreviewTableModel;
import com.fr.esd.query.StrategicTableData;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 管理所有数据集预览过程中的脱敏计算
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/14
*/
public class TableDataPreviewDesensitizeManager implements DesensitizationManager {
private static final String CONNECTOR = "_";
private TableDataPreviewDesensitizeManager() {
}
private static class Holder {
private static final TableDataPreviewDesensitizeManager INSTANCE = new TableDataPreviewDesensitizeManager();
}
/**
* 获取TableDataPreviewDesensitizeManager单例
*
* @return
*/
public static TableDataPreviewDesensitizeManager getInstance() {
return TableDataPreviewDesensitizeManager.Holder.INSTANCE;
}
/**
* 判断数据集预览时是否需要脱敏这里不需要判断roleIds因为默认有权限编辑的人一定有权限看脱敏前后字段值
* 只需要保证此数据集存在脱敏配置就行
*
* @param tableData
* @return
*/
public boolean needDesensitize(TableData tableData) {
return tableData instanceof DesensitizationTableData &&
DesentizationUtils.isCollectionNotEmpty(((DesensitizationTableData) tableData).getDesensitizationConfig().getDesensitizationItems());
}
/**
* 数据集预览脱敏使用DesensitizedPreviewTableModel对当前的预览TableModel做包装
*
* @param model
* @return
*/
public PreviewTableModel desensitizeTableModel(TableData tableData, PreviewTableModel model) {
Map<Integer, TableDataDesensitizationItem> desensitizationItemMap = new LinkedHashMap<>();
// 获取此数据集的所有脱敏信息
Collection<TableDataDesensitizationItem> desensitizationItems = ((DesensitizationTableData) tableData).getDesensitizationConfig().getDesensitizationItems();
if (DesentizationUtils.isCollectionNotEmpty(desensitizationItems)) {
// 更新规则
desensitizationItems = TableDataDesensitizeManager.getInstance().dealWithlatestRules(desensitizationItems);
// 对脱敏配置项集合做过滤和排序处理
List<TableDataDesensitizationItem> items = desensitizationItems.stream()
.filter(item -> isAvaliableItem4Preview(item, model))
.sorted(Comparator.comparingInt(item -> matchColumnIndex(item, model)))
.collect(Collectors.toList());
// 然后转换成Map
for (int i = 0; i < items.size(); i++) {
desensitizationItemMap.put(i, items.get(i));
}
}
// 包装TableModel
return new DesensitizedPreviewTableModel(model, desensitizationItemMap);
}
/**
* 判断是否为有效的用于预览脱敏效果的DesensitizationItem
*
* @param item 脱敏配置项
* @param model 数据集预览数据
* @return
*/
private boolean isAvaliableItem4Preview(TableDataDesensitizationItem item, PreviewTableModel model) {
return item.getRule().isEnable() &&
matchColumnIndex(item, model) >= 0;
}
/**
* 通过TableData获取其列名,理论上一定存在缓存值
*
* @param tableData
* @return
*/
public List<String> getColumnNamesByTableData(TableData tableData) {
TableDataSource editingTableDataSource = DesignTableDataManager.getEditingTableDataSource();
if (editingTableDataSource != null && tableData instanceof StrategicTableData) {
return Arrays.asList(DesignTableDataManager.getSelectedColumnNames(editingTableDataSource, ((StrategicTableData) tableData).getDsName()));
}
return Collections.EMPTY_LIST;
}
/**
* 根据列名从PreviewTableModel中匹配列序号如果返回-1代表未匹配到
* @param desensitizationItem
* @param previewModel
* @return
*/
public int matchColumnIndex(TableDataDesensitizationItem desensitizationItem, PreviewTableModel previewModel) {
return previewModel.getColumnIndexWithExceptionIngore(desensitizationItem.getColumnName());
}
}

114
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/model/DesensitizedPreviewTableModel.java

@ -0,0 +1,114 @@
package com.fr.design.data.datapane.preview.desensitization.model;
import com.fr.data.desensitize.base.TableDataDesensitizationItem;
import com.fr.data.desensitize.calculate.DesensitizationCalculator;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.design.data.datapane.preview.PreviewTableModel;
import com.fr.design.data.datapane.preview.desensitization.TableDataPreviewDesensitizeManager;
import java.util.Map;
import java.util.Objects;
/**
* 数据集预览TableModel的脱敏实现
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/14
*/
public class DesensitizedPreviewTableModel extends PreviewTableModel {
/**
* 原始数据Model
*/
private PreviewTableModel previewTableModel;
/**
* 脱敏后新组装的TableModel中列序号 - 脱敏信息 对应的Map
*/
private Map<Integer, TableDataDesensitizationItem> desensitizationItemMap;
private boolean needDesensitize = false;
public DesensitizedPreviewTableModel(PreviewTableModel previewTableModel, Map<Integer, TableDataDesensitizationItem> desensitizationItemMap) {
this.previewTableModel = previewTableModel;
this.desensitizationItemMap = desensitizationItemMap;
}
@Override
public String getColumnName(int column) {
return needDesensitize ?
desensitizationItemMap.get(column).getColumnName() :
previewTableModel.getColumnName(column);
}
@Override
public int getRowCount() {
return previewTableModel.getRowCount();
}
@Override
public int getColumnCount() {
return needDesensitize ?
getDesensitizeColumnsCount() :
previewTableModel.getColumnCount();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return needDesensitize && Objects.nonNull(desensitizationItemMap.get(columnIndex)) ?
getDesensitizedValue(rowIndex, columnIndex) :
previewTableModel.getValueAt(rowIndex, columnIndex);
}
/**
* 返回脱敏后的数据值
*
* @param rowIndex
* @param columnIndex
* @return
*/
private Object getDesensitizedValue(int rowIndex, int columnIndex) {
// 先通过columnIndex找到对应原TableModel的列序号
int originColumnIndex = TableDataPreviewDesensitizeManager.getInstance().matchColumnIndex(desensitizationItemMap.get(columnIndex), previewTableModel);
// 获取原值
Object value = previewTableModel.getValueAt(rowIndex, originColumnIndex);
// 判空
if (Objects.isNull(value)) {
return value;
}
// 脱敏
String strValue = String.valueOf(value);
value = desensitizeValue(strValue, columnIndex);
return value;
}
/**
* 计算脱敏后的value,此时columnIndex对应的脱敏信息一定不为空
*
* @param strValue
* @param columnIndex
* @return
*/
private String desensitizeValue(String strValue, int columnIndex) {
DesensitizationRule rule = desensitizationItemMap.get(columnIndex).getRule();
return DesensitizationCalculator.getInstance().desensitize(strValue, rule);
}
/**
* 获取当前有效的脱敏字段个数
*
* @return
*/
public int getDesensitizeColumnsCount() {
return desensitizationItemMap.size();
}
/**
* 切换脱敏状态
*/
public void toggleNeedDesensite() {
this.needDesensitize = !needDesensitize;
}
}

133
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/PreviewTableDesensitizationPane.java

@ -0,0 +1,133 @@
package com.fr.design.data.datapane.preview.desensitization.view;
import com.fr.base.svg.IconUtils;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.gui.ibutton.UIToggleButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.menu.SeparatorDef;
import com.fr.design.menu.ToolBarDef;
import javax.swing.Icon;
import javax.swing.JPanel;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* 数据集预览-脱敏配置面板主要展示当前脱敏开启状态当前脱敏设定数量等
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/11/14
*/
public class PreviewTableDesensitizationPane extends JPanel {
private static final String DATA_DESENSITIZATION_CONFIG = Toolkit.i18nText("Fine-Design_Report_Desensitization_Config");
private static final String LEFT_BRACKET = "(";
private static final String RIGHT_BRACKET = ")";
private static final String COUNT = Toolkit.i18nText("Fine-Design_Report_Desensitization_Count");
/**
* 预览面板
*/
private PreviewTablePane previewTablePane;
/**
* "数据脱敏设置"-标签
*/
private UILabel desensitizationLabel;
/**
* 脱敏效果预览按钮
*/
private UIToggleButton previewToggle;
public PreviewTableDesensitizationPane(PreviewTablePane previewTablePane) {
this.previewTablePane = previewTablePane;
initComponents();
}
/**
* 初始化面板
*/
private void initComponents() {
this.setLayout(new FlowLayout(FlowLayout.LEFT));
this.add(initDesensitizationLabel());
this.add(initToolBar());
this.add(initPreviewButton());
}
/**
* 初始化Label
*
* @return
*/
private Component initDesensitizationLabel() {
// 初始化Label
desensitizationLabel = new UILabel(DATA_DESENSITIZATION_CONFIG);
desensitizationLabel.setForeground(UIConstants.NORMAL_BLUE);
desensitizationLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
previewTablePane.clickDesensitizationLabel();
}
});
return desensitizationLabel;
}
/**
* 初始化分隔符
*
* @return
*/
private UIToolbar initToolBar() {
ToolBarDef toolbarDef = new ToolBarDef();
toolbarDef.addShortCut(SeparatorDef.DEFAULT);
UIToolbar toolBar = ToolBarDef.createJToolBar();
toolBar.setBorderPainted(false);
toolbarDef.updateToolBar(toolBar);
return toolBar;
}
/**
* 初始化脱敏效果预览按钮
*
* @return
*/
private UIToggleButton initPreviewButton() {
previewToggle = new UIToggleButton(new Icon[]{IconUtils.readIcon("/com/fr/design/images/m_file/preview"), IconUtils.readIcon("/com/fr/design/images/m_file/preview")}, true);
previewToggle.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Preview"));
previewToggle.setSelected(false);
previewToggle.addActionListener(e -> {
// 切换TableModel的脱敏状态
previewTablePane.togglePreviewTableModelDesensitizeStatus();
// 刷新预览页面,展示
previewTablePane.refreshTable();
});
return previewToggle;
}
/**
* 设置Label的值主要是需要动态修改配置的脱敏规则的数量
*
* @param desensitizeOpen
* @param count
*/
public void setDesensitizationCount(boolean desensitizeOpen, int count) {
desensitizationLabel.setText(desensitizeOpen ?
DATA_DESENSITIZATION_CONFIG + LEFT_BRACKET + count + RIGHT_BRACKET + COUNT :
DATA_DESENSITIZATION_CONFIG);
}
/**
* 服务器数据集时Label需要置灰
*/
public void dealWithTableDataType(boolean globalTableData) {
desensitizationLabel.setForeground(globalTableData ? UIConstants.DISABLED_ICON_COLOR : UIConstants.NORMAL_BLUE);
}
}

42
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/common/ChooseMark.java

@ -0,0 +1,42 @@
package com.fr.design.data.datapane.preview.desensitization.view.common;
import com.fr.design.gui.ibutton.UIRadioButton;
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.Component;
/**
* 标记选中的CellEditor
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/12/20
*/
public class ChooseMark extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private final UIRadioButton selectedButton;
public ChooseMark() {
this.selectedButton = new UIRadioButton();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
selectedButton.setSelected(isSelected);
return selectedButton;
}
@Override
public Object getCellEditorValue() {
return selectedButton.isSelected();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
selectedButton.setSelected(isSelected);
return selectedButton;
}
}

94
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/common/DesensitizationOpenPane.java

@ -0,0 +1,94 @@
package com.fr.design.data.datapane.preview.desensitization.view.common;
import com.fr.base.svg.IconUtils;
import com.fr.design.border.UITitledBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.log.FineLoggerFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
/**
* 启用数据脱敏的面板
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/10/12
*/
public class DesensitizationOpenPane extends JPanel {
/**
* 数据脱敏启用框
*/
private UICheckBox desensitizeOpenCheckBox;
/**
* 跳转帮助文档Label
*/
private UILabel hyperlinkLabel;
/**
* 启用提示Label
*/
private UILabel tipsLabel;
public DesensitizationOpenPane() {
VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP);
layout.setAlignLeft(true);
this.setLayout(layout);
this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Report_Desensitization_Config")));
JPanel panel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane();
// 启用数据脱敏的勾选框
desensitizeOpenCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Desensitization_Opened"));
// 跳转帮助文档Label
hyperlinkLabel = new UILabel(IconUtils.readIcon("/com/fr/design/standard/tip/tips"));
hyperlinkLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Open_Tips"));
hyperlinkLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event) {
try {
URL url = new URL(Toolkit.i18nText("Fine-Design_Report_Desensitization_Help_Document_Url"));
Desktop.getDesktop().browse(url.toURI());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, "open browse of table data desensitization help document failed for {}", e.getMessage());
}
}
});
panel.add(desensitizeOpenCheckBox);
panel.add(hyperlinkLabel);
// 提示Label
tipsLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Opened_Tooltips"));
tipsLabel.setForeground(UIConstants.CHECK_BOX_TIP_FONT_COLOR);
this.add(panel);
this.add(tipsLabel);
}
/**
* 数据脱敏启用状态
* @return
*/
public boolean isDesensitizationOpened() {
return desensitizeOpenCheckBox.isSelected();
}
/**
* 设置数据脱敏启用状态
* @param opened
*/
public void setDesensitizationOpened(boolean opened) {
desensitizeOpenCheckBox.setSelected(opened);
}
}

364
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleChoosePane.java

@ -0,0 +1,364 @@
package com.fr.design.data.datapane.preview.desensitization.view.rule;
import com.fr.base.svg.IconUtils;
import com.fr.data.desensitize.rule.DesensitizationRuleManager;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource;
import com.fr.data.desensitize.rule.base.DesensitizationRuleStatus;
import com.fr.design.data.datapane.preview.desensitization.view.common.ChooseMark;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itableeditorpane.UITableModelAdapter;
import com.fr.design.i18n.Toolkit;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.CollectionUtils;
import javax.swing.AbstractCellEditor;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 脱敏规则选择页面
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/26
*/
public class DesensitizationRuleChoosePane extends JPanel {
private CardLayout cardLayout;
private UITableEditorPane<DesensitizationRule> serverRuleEditPane;
private UITableEditorPane<DesensitizationRule> customRuleEditPane;
private DesensitizationRuleSource currentRuleSource;
private Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules;
public DesensitizationRuleChoosePane(Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules) {
this.latestRules = latestRules;
this.cardLayout = new CardLayout();
this.setLayout(cardLayout);
serverRuleEditPane = new UITableEditorPane<>(new DesensitizationRuleChooseTableModel(this, true));
customRuleEditPane = new UITableEditorPane<>(new DesensitizationRuleChooseTableModel(this, false));
serverRuleEditPane.setHeaderResizing(false);
customRuleEditPane.setHeaderResizing(false);
populateDesensitizationRules();
this.add(serverRuleEditPane, DesensitizationRuleSource.SERVER.name());
this.add(customRuleEditPane, DesensitizationRuleSource.CUSTOM.name());
// 默认显示平台规则
switchPaneByRuleSource(DesensitizationRuleSource.SERVER);
}
/**
* 通过脱敏规则来源切换显示不同的脱敏规则Table面板
*
* @param ruleSource
*/
public void switchPaneByRuleSource(DesensitizationRuleSource ruleSource) {
this.currentRuleSource = ruleSource;
this.cardLayout.show(this, ruleSource.name());
}
/**
* 展示当前规则
*/
private void populateDesensitizationRules() {
serverRuleEditPane.populate(latestRules.get(DesensitizationRuleSource.SERVER).values().toArray(new DesensitizationRule[0]));
customRuleEditPane.populate(latestRules.get(DesensitizationRuleSource.CUSTOM).values().toArray(new DesensitizationRule[0]));
}
/**
* 获取当前选中的规则
*
* @return
*/
public DesensitizationRule getSelectedDesensitizationRule() {
switch (currentRuleSource) {
case SERVER:
return serverRuleEditPane.getTableModel().getSelectedValue();
case CUSTOM:
return customRuleEditPane.getTableModel().getSelectedValue();
default:
return null;
}
}
/**
* 规则选择Table的TableModel
*/
private class DesensitizationRuleChooseTableModel extends UITableModelAdapter<DesensitizationRule> {
private Component parent;
private boolean debugActionOnly;
protected DesensitizationRuleChooseTableModel(Component parent, boolean debugActionOnly) {
super(new String[]{
StringUtils.EMPTY,
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Name"),
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Description"),
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status"),
});
this.parent = parent;
this.debugActionOnly = debugActionOnly;
this.setColumnClass(new Class[]{
ChooseMark.class,
UILabel.class,
UILabel.class,
DesensitizationRuleStatusPane.class
});
this.setDefaultEditor(ChooseMark.class, new ChooseMark());
this.setDefaultRenderer(ChooseMark.class, new ChooseMark());
this.setDefaultEditor(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane());
this.setDefaultRenderer(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane());
this.createTable().getColumnModel().getColumn(0).setMaxWidth(20);
this.createTable().getColumnModel().getColumn(3).setMaxWidth(60);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
DesensitizationRule rule = getList().get(rowIndex);
switch (columnIndex) {
case 0:
// 选中状态
return rule.equals(getSelectedValue());
case 1:
// 脱敏规则名称
return rule.getRuleName();
case 2:
// 脱敏规则描述
return DesensitizationRule.getDescription(rule);
case 3:
// 脱敏规则状态
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(rule, latestRules);
// 非正常状态需要标记为异常
return ruleStatus == DesensitizationRuleStatus.NORMAL ? StringUtils.EMPTY : Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status_Abnormal");
default:
return StringUtils.EMPTY;
}
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
@Override
public UITableEditAction[] createAction() {
return debugActionOnly ?
new UITableEditAction[]{new DebugRuleAction(parent)} :
new UITableEditAction[]{new AddRuleAction(), new EditRuleAction(), new DeleteRuleAction(parent), new DebugRuleAction(parent)};
}
private Set<String> getCurrentExistRuleNames(String excludeName) {
List<DesensitizationRule> rules = getList();
return CollectionUtils.isEmpty(rules) ?
new LinkedHashSet<>() :
rules.stream()
.map(DesensitizationRule::getRuleName)
.filter(name -> !StringUtils.equals(name, excludeName))
.collect(Collectors.toSet());
}
/**
* 规则状态展示页面
*/
private class DesensitizationRuleStatusPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private UILabel ruleStatusLabel;
DesensitizationRuleStatusPane() {
// 规则状态
this.ruleStatusLabel = new UILabel();
this.ruleStatusLabel.setForeground(Color.RED);
}
/**
* 根据脱敏规则信息刷新规则状态主要用于与规则选择器的联动
*
* @param rule
*/
public void refreshRuleStatus(DesensitizationRule rule) {
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(rule, latestRules);
if (ruleStatus == DesensitizationRuleStatus.NORMAL) {
// 正常规则时,重置提示Label
this.ruleStatusLabel.setText(StringUtils.EMPTY);
this.ruleStatusLabel.setToolTipText(null);
} else {
this.ruleStatusLabel.setText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status_Abnormal"));
this.ruleStatusLabel.setToolTipText(ruleStatus.getDescription());
}
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
refreshRuleStatus(getList().get(row));
return ruleStatusLabel;
}
@Override
public Object getCellEditorValue() {
return ruleStatusLabel;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
refreshRuleStatus(getList().get(row));
return ruleStatusLabel;
}
}
/**
* 添加规则
*/
private class AddRuleAction extends AddTableRowAction {
public AddRuleAction() {
this.setName(Toolkit.i18nText("Fine-Design_Report_Desensitization_Add"));
this.setSmallIcon("/com/fr/design/standard/add/add_black", false);
}
@Override
public void actionPerformed(ActionEvent e) {
// 新增一条规则
DesensitizationRuleEditPane editPane = new DesensitizationRuleEditPane(getCurrentExistRuleNames(StringUtils.EMPTY));
BasicDialog basicDialog = editPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), new DialogActionAdapter() {
@Override
public void doOk() {
DesensitizationRule rule = editPane.updateBean();
// 添加到Rule Manager中
if (DesensitizationRule.valid(rule)) {
DesensitizationRuleManager.getInstance().addRule(rule);
}
// 添加到Table中
addRow(rule);
fireTableDataChanged();
}
@Override
public void doCancel() {
super.doCancel();
}
}, BasicDialog.DEFAULT);
basicDialog.setVisible(true);
}
}
private class EditRuleAction extends UITableEditAction {
public EditRuleAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Edit"));
this.setSmallIcon(IconUtils.readIcon("/com/fr/design/standard/edit/edit"));
}
@Override
public void checkEnabled() {
setEnabled(table.getSelectedRow() != -1);
}
@Override
public void actionPerformed(ActionEvent e) {
// 获取当前选中规则的副本
DesensitizationRule selectedValue = null;
try {
selectedValue = (DesensitizationRule) getSelectedValue().clone();
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
DesensitizationRuleEditPane editPane = new DesensitizationRuleEditPane(getCurrentExistRuleNames(selectedValue.getRuleName()));
editPane.populateBean(selectedValue);
final DesensitizationRule finalRule = selectedValue;
BasicDialog basicDialog = editPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), new DialogActionAdapter() {
@Override
public void doOk() {
DesensitizationRule rule = editPane.updateBean();
// 修改同步到RuleManager中
if (DesensitizationRule.valid(rule)) {
DesensitizationRuleManager.getInstance().updateRule(finalRule, rule);
}
setSelectedValue(rule);
fireTableDataChanged();
}
@Override
public void doCancel() {
super.doCancel();
}
}, BasicDialog.DEFAULT);
basicDialog.setVisible(true);
}
}
private class DeleteRuleAction extends DeleteAction {
public DeleteRuleAction(Component parent) {
super(parent);
this.setName(Toolkit.i18nText("Fine-Design_Basic_Base_Remove"));
this.setSmallIcon("/com/fr/design/images/control/remove");
}
@Override
public void checkEnabled() {
setEnabled(table.getSelectedRow() != -1);
}
@Override
public void actionPerformed(ActionEvent e) {
// 获取当前选中规则
DesensitizationRule selectedRule = getSelectedValue();
// 删除同步到RuleManager中
if (DesensitizationRule.valid(selectedRule)) {
DesensitizationRuleManager.getInstance().removeRule(selectedRule);
}
super.actionPerformed(e);
}
}
private class DebugRuleAction extends UITableEditAction {
private Component parent;
public DebugRuleAction(Component parent) {
this.parent = parent;
this.setName(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Debug"));
this.setSmallIcon("/com/fr/design/standard/debug/debug");
}
@Override
public void checkEnabled() {
setEnabled(table.getSelectedRow() != -1 && getList().get(table.getSelectedRow()).isEnable());
}
@Override
public void actionPerformed(ActionEvent e) {
// 获取当前选中规则
DesensitizationRule selectedRule = getSelectedValue();
if (selectedRule == null) {
return;
}
DesensitizationRuleDebugPane ruleDebugPane = new DesensitizationRuleDebugPane(selectedRule);
BasicDialog ruleDebugDialog = ruleDebugPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), null, BasicDialog.DEFAULT);
ruleDebugDialog.setVisible(true);
}
}
}
}

128
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleDebugPane.java

@ -0,0 +1,128 @@
package com.fr.design.data.datapane.preview.desensitization.view.rule;
import com.fr.data.desensitize.calculate.DesensitizationCalculator;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
/**
* 脱敏规则调试页
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/8
*/
public class DesensitizationRuleDebugPane extends BasicPane {
/**
* 脱敏规则
*/
private DesensitizationRule rule;
public DesensitizationRuleDebugPane(DesensitizationRule rule) {
this.rule = rule;
initComponent();
}
private void initComponent() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(initNorthPane(), BorderLayout.NORTH);
this.add(initCenterPane(), BorderLayout.CENTER);
}
private JPanel initNorthPane() {
JPanel northPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Description"));
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane();
panel.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 0));
UILabel desensitizationRule = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Algorithm"));
UILabel characterReplace = new UILabel(rule.getRuleType().getRuleTypeName());
UILabel description = new UILabel(DesensitizationRule.getDescription(rule));
JComponent[][] components = new JComponent[][]{
{desensitizationRule, characterReplace},
{new UILabel(), description}
};
panel.add(
TableLayoutHelper.createCommonTableLayoutPane(
components,
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED},
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED},
20),
BorderLayout.CENTER);
northPane.add(panel);
return northPane;
}
private JPanel initCenterPane() {
JPanel centerPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Debug"));
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane();
panel.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 0));
UILabel beforeDesensitize = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Before"));
UITextField beforeDesensitizeText = new UITextField(20);
beforeDesensitizeText.setPlaceholder(Toolkit.i18nText("Fine-Design_Report_Desensitization_Enter_Content"));
UILabel afterDesensitize = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_After"));
UITextField afterDesensitizeText = new UITextField(20);
afterDesensitizeText.setEditable(false);
UIButton desensitizeButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_Desensitization_Debug"));
beforeDesensitizeText.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
afterDesensitizeText.setText(StringUtils.EMPTY);
}
@Override
public void focusLost(FocusEvent e) {
}
});
desensitizeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String text = beforeDesensitizeText.getText();
if (StringUtils.isEmpty(text)) {
FineJOptionPane.showMessageDialog(DesensitizationRuleDebugPane.this,
Toolkit.i18nText("Fine-Design_Report_Desensitization_Please_Enter_Valid_Content"));
}
String desensitizedText = DesensitizationCalculator.getInstance().desensitize(text, rule);
afterDesensitizeText.setText(desensitizedText);
}
});
JComponent[][] components = new JComponent[][]{
{beforeDesensitize, beforeDesensitizeText, desensitizeButton},
{afterDesensitize, afterDesensitizeText, new UILabel()}
};
panel.add(
TableLayoutHelper.createCommonTableLayoutPane(
components,
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED},
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED},
20),
BorderLayout.CENTER);
centerPane.add(panel);
return centerPane;
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Debug");
}
}

309
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleEditPane.java

@ -0,0 +1,309 @@
package com.fr.design.data.datapane.preview.desensitization.view.rule;
import com.fr.data.desensitize.rule.base.DesensitizationCondition;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource;
import com.fr.data.desensitize.rule.base.DesensitizationRuleType;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.constants.UIConstants;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UINumberField;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Insets;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.Arrays;
import java.util.Set;
/**
* 脱敏规则编辑页
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/8
*/
public class DesensitizationRuleEditPane extends BasicBeanPane<DesensitizationRule> {
/**
* 已经存在的规则名称用于检测重名
*/
private Set<String> existRuleNames;
private UITextField ruleNameTextField;
private UIComboBox ruleTypeComboBox;
private UINumberField retainFrontTextField;
private UINumberField retainBackTextField;
private UITextField firstSymbolTextField;
private UITextField secondSymbolTextField;
private CardLayout cardLayout;
private JPanel ruleConditionPane;
private DesensitizationRule rule = DesensitizationRule.createDefaultEmptyRule();
private final FocusListener retainFrontListener = new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
rule.getCondition().setRetainFront((int) retainFrontTextField.getValue());
}
};
private final FocusListener retainBackListener = new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
rule.getCondition().setRetainBack((int) retainBackTextField.getValue());
}
};
private final FocusListener firstSymbolListener = new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
rule.getCondition().setSymbol(firstSymbolTextField.getText());
}
};
private final FocusListener secondSymbolListener = new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
}
@Override
public void focusLost(FocusEvent e) {
rule.getCondition().setRetainFront(0);
rule.getCondition().setRetainBack(0);
rule.getCondition().setSymbol(secondSymbolTextField.getText());
}
};
public DesensitizationRuleEditPane(Set<String> existRuleNames) {
this.existRuleNames = existRuleNames;
initComponent();
}
/**
* 初始化面板
*/
private void initComponent() {
this.setLayout(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane();
panel.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 0));
UILabel ruleNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Name"));
// 规则名称输入框
initRuleNameTextField();
UILabel ruleTypeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Algorithm"));
// 脱敏算法Type设置
JPanel ruleTypePane = initRuleTypePane();
// 脱敏算法Condition设置
JPanel ruleConditionPane = initRuleConditionPane();
JComponent[][] components = {
{ruleNameLabel, ruleNameTextField},
{ruleTypeLabel, ruleTypePane},
{new UILabel(), ruleConditionPane}
};
panel.add(
TableLayoutHelper.createGapTableLayoutPane(
components,
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.FILL},
new double[]{TableLayout.FILL, TableLayout.PREFERRED},
20,
20),
BorderLayout.CENTER);
this.add(panel);
}
/**
* 初始化规则类型面板
*
* @return
*/
private JPanel initRuleTypePane() {
JPanel ruleTypePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
// 脱敏算法类型下拉框
initRuleTypeComboBox();
ruleTypePane.add(ruleTypeComboBox, BorderLayout.CENTER);
return ruleTypePane;
}
/**
* 初始化规则条件面板
*
* @return
*/
private JPanel initRuleConditionPane() {
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane();
cardLayout = new CardLayout();
ruleConditionPane = new JPanel(cardLayout);
// 字符替换
JPanel characterReplacePane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane();
UILabel retainFrontLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_One") + StringUtils.BLANK);
retainFrontTextField = new UINumberField(5);
retainFrontTextField.addFocusListener(retainFrontListener);
UILabel retainBackLabel = new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Two") + StringUtils.BLANK);
retainBackTextField = new UINumberField(5);
retainBackTextField.addFocusListener(retainBackListener);
UILabel replaceLabel = new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Three") + StringUtils.BLANK);
firstSymbolTextField = new UITextField(10);
firstSymbolTextField.addFocusListener(firstSymbolListener);
characterReplacePane.add(retainFrontLabel);
characterReplacePane.add(retainFrontTextField);
characterReplacePane.add(retainBackLabel);
characterReplacePane.add(retainBackTextField);
characterReplacePane.add(replaceLabel);
characterReplacePane.add(firstSymbolTextField);
// 整体替换
JPanel characterAllReplacePane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane();
UILabel allReplaceLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_All_Character_Replace_By") + StringUtils.BLANK);
secondSymbolTextField = new UITextField(10);
secondSymbolTextField.addFocusListener(secondSymbolListener);
characterAllReplacePane.add(allReplaceLabel);
characterAllReplacePane.add(secondSymbolTextField);
ruleConditionPane.add(characterReplacePane, DesensitizationRuleType.CHARACTER_REPLACE.getRuleTypeName());
ruleConditionPane.add(characterAllReplacePane, DesensitizationRuleType.ALL_CHARACTERS_REPLACE.getRuleTypeName());
// 初始化状态为字符替换
switchRuleConditionPane(DesensitizationRuleType.CHARACTER_REPLACE);
panel.add(ruleConditionPane, BorderLayout.CENTER);
return panel;
}
/**
* 切换规则类型面板
*
* @param ruleType
*/
private void switchRuleConditionPane(DesensitizationRuleType ruleType) {
this.cardLayout.show(ruleConditionPane, ruleType.getRuleTypeName());
}
/**
* 初始化规则类型下拉框
*/
private void initRuleTypeComboBox() {
ruleTypeComboBox = new UIComboBox(Arrays.stream(DesensitizationRuleType.values()).map(DesensitizationRuleType::getRuleTypeName).toArray());
ruleTypeComboBox.setSelectedIndex(0);
ruleTypeComboBox.registerChangeListener(new UIObserverListener() {
@Override
public void doChange() {
DesensitizationRuleType ruleType = DesensitizationRuleType.matchByTypeName((String) ruleTypeComboBox.getSelectedItem());
rule.setRuleType(ruleType);
// 修改底下的conditionPane
switchRuleConditionPane(ruleType);
}
});
}
/**
* 初始化规则名称输入框
*/
private void initRuleNameTextField() {
ruleNameTextField = new UITextField(20) {
@Override
public Insets getInsets() {
return new Insets(2, 4, 0, 4);
}
};
ruleNameTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Report_Desensitization_Please_Enter_Rule_Name"));
ruleNameTextField.setBorderPainted(true);
ruleNameTextField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
ruleNameTextField.setBorder(BorderFactory.createLineBorder(UIConstants.NORMAL_BLUE));
ruleNameTextField.repaint();
}
@Override
public void focusLost(FocusEvent e) {
ruleNameTextField.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR));
rule.setRuleName(ruleNameTextField.getText());
ruleNameTextField.repaint();
}
});
}
@Override
public void populateBean(DesensitizationRule ob) {
this.rule = ob;
this.ruleNameTextField.setText(rule.getRuleName());
String typeName = rule.getRuleType().getRuleTypeName();
this.ruleTypeComboBox.setSelectedItem(typeName);
switch (DesensitizationRuleType.matchByTypeName(typeName)) {
case CHARACTER_REPLACE:
this.retainFrontTextField.setValue(rule.getCondition().getRetainFront());
this.retainBackTextField.setValue(rule.getCondition().getRetainBack());
this.firstSymbolTextField.setText(rule.getCondition().getSymbol());
break;
case ALL_CHARACTERS_REPLACE:
this.secondSymbolTextField.setText(rule.getCondition().getSymbol());
break;
default:
}
}
@Override
public DesensitizationRule updateBean() {
rule.setRuleName(this.ruleNameTextField.getText());
rule.setRuleSource(DesensitizationRuleSource.CUSTOM);
DesensitizationRuleType ruleType = DesensitizationRuleType.matchByTypeName(String.valueOf(this.ruleTypeComboBox.getSelectedItem()));
rule.setRuleType(ruleType);
rule.getCondition().setRetainFront((int) this.retainFrontTextField.getValue());
rule.getCondition().setRetainBack((int) this.retainBackTextField.getValue());
rule.getCondition().setSymbol(ruleType == DesensitizationRuleType.CHARACTER_REPLACE ?
this.firstSymbolTextField.getText() :
this.secondSymbolTextField.getText());
rule.setEnable(true);
return rule;
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Custom_Config_Rules");
}
@Override
public void checkValid() throws Exception {
// 保存rule前检查下
String checkMessage = StringUtils.EMPTY;
if (StringUtils.isEmpty(rule.getRuleName())) {
checkMessage = Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Name_Cannot_Be_Empty");
} else if (existRuleNames.contains(rule.getRuleName())) {
checkMessage = Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Name_Cannot_Repeat");
} else if (DesensitizationCondition.invalid(rule.getCondition())) {
checkMessage = Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Wrong_Condition");
}
if (StringUtils.isNotEmpty(checkMessage)) {
throw new Exception(checkMessage);
}
}
}

89
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRulePane.java

@ -0,0 +1,89 @@
package com.fr.design.data.datapane.preview.desensitization.view.rule;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.border.UITitledBorder;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.util.Map;
/**
* 脱敏规则展示页
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/8
*/
public class DesensitizationRulePane extends BasicBeanPane<DesensitizationRule> {
/**
* 规则来源选择面板
*/
private DesensitizationRuleSourceChoosePane ruleSourceChoosePane;
/**
* 规则选择面板
*/
private DesensitizationRuleChoosePane ruleChoosePane;
/**
* 最新的所有规则
*/
private Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules;
/**
* 内容面板
*/
private JPanel contentPane;
public DesensitizationRulePane(Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.latestRules = latestRules;
initPane();
}
private void initPane() {
// 内容面板
contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
contentPane.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Choose")));
this.add(contentPane, BorderLayout.CENTER);
// 规则来源选择Pane
ruleSourceChoosePane = new DesensitizationRuleSourceChoosePane(this);
// 规则选择Pane
ruleChoosePane = new DesensitizationRuleChoosePane(latestRules);
contentPane.add(ruleSourceChoosePane, BorderLayout.NORTH);
contentPane.add(ruleChoosePane, BorderLayout.CENTER);
}
/**
* 处理规则来源选择面板中改动来源的事件
*
* @param newRuleSource
*/
public void dealWithRuleSourceChanged(DesensitizationRuleSource newRuleSource) {
ruleChoosePane.switchPaneByRuleSource(newRuleSource);
}
@Override
public void populateBean(DesensitizationRule ob) {
// 这边展示当前所有规则时,不依靠外界传值,初始化的时候,从规则管理中心去获取
}
@Override
public DesensitizationRule updateBean() {
DesensitizationRule desensitizationRule = ruleChoosePane.getSelectedDesensitizationRule();
return DesensitizationRule.valid(desensitizationRule) ?
desensitizationRule :
DesensitizationRule.createDefaultEmptyRule();
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule");
}
}

49
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleSourceChoosePane.java

@ -0,0 +1,49 @@
package com.fr.design.data.datapane.preview.desensitization.view.rule;
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.i18n.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import java.awt.FlowLayout;
/**
* 脱敏规则来源选择页面
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/26
*/
public class DesensitizationRuleSourceChoosePane extends JPanel {
/**
* 来源平台的按钮
*/
private UIRadioButton serverSource;
/**
* 来源本地的按钮
*/
private UIRadioButton customSource;
public DesensitizationRuleSourceChoosePane(DesensitizationRulePane desensitizationRulePane) {
this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
serverSource = new UIRadioButton(Toolkit.i18nText("Fine-Design_Report_Desensitization_Server_Config_Rules"));
customSource = new UIRadioButton(Toolkit.i18nText("Fine-Design_Report_Desensitization_Custom_Config_Rules"));
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(serverSource);
buttonGroup.add(customSource);
serverSource.setSelected(true);
serverSource.registerChangeListener(() -> desensitizationRulePane.dealWithRuleSourceChanged(DesensitizationRuleSource.SERVER));
customSource.registerChangeListener(() -> desensitizationRulePane.dealWithRuleSourceChanged(DesensitizationRuleSource.CUSTOM));
this.add(serverSource);
this.add(customSource);
}
}

98
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationSettingPane.java

@ -0,0 +1,98 @@
package com.fr.design.data.datapane.preview.desensitization.view.setting;
import com.fr.data.desensitize.base.DesensitizationTableData;
import com.fr.data.desensitize.base.TableDataDesensitizationItem;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.data.datapane.preview.desensitization.view.common.DesensitizationOpenPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.JComponent;
import java.awt.BorderLayout;
import java.util.List;
/**
* 数据集脱敏字段设置页面
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/8
*/
public class TableDataDesensitizationSettingPane extends BasicBeanPane<DesensitizationTableData> {
/**
* 设置针对的数据集
*/
private DesensitizationTableData tableData;
private DesensitizationOpenPane desensitizationOpenPane;
private TableDataDesensitizationTablePane tableDataDesensitizationTablePane;
public TableDataDesensitizationSettingPane(DesensitizationTableData tableData) {
this.tableData = tableData;
initComponents();
}
private void initComponents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(initNorthPane(), BorderLayout.NORTH);
this.add(initCenterPane(), BorderLayout.CENTER);
}
/**
* 初始化启用数据脱敏面板
*
* @return
*/
private JComponent initNorthPane() {
this.desensitizationOpenPane = new DesensitizationOpenPane();
return desensitizationOpenPane;
}
/**
* 初始化数据脱敏规则表面板
*
* @return
*/
private JComponent initCenterPane() {
this.tableDataDesensitizationTablePane = new TableDataDesensitizationTablePane(tableData, this);
return tableDataDesensitizationTablePane;
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Config");
}
@Override
public void populateBean(DesensitizationTableData tableData) {
this.tableData = tableData;
this.desensitizationOpenPane.setDesensitizationOpened(tableData.getDesensitizationConfig().isDesensitizeOpened());
tableDataDesensitizationTablePane.populateDesensitizationSetting(tableData);
}
@Override
public DesensitizationTableData updateBean() {
saveDesensitizeOpened();
saveDesensitizationBeans(tableDataDesensitizationTablePane.updateDesensitizationSetting());
return tableData;
}
/**
* 保存脱敏启用状态
*/
public void saveDesensitizeOpened() {
tableData.getDesensitizationConfig().setDesensitizeOpened(this.desensitizationOpenPane.isDesensitizationOpened());
}
/**
* 保存脱敏规则配置信息
*
* @param desensitizationItems
*/
public void saveDesensitizationBeans(List<TableDataDesensitizationItem> desensitizationItems) {
tableData.getDesensitizationConfig().setDesensitizationItems(desensitizationItems);
}
}

619
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTableModel.java

@ -0,0 +1,619 @@
package com.fr.design.data.datapane.preview.desensitization.view.setting;
import com.fr.data.desensitize.base.DesensitizationTableData;
import com.fr.data.desensitize.base.TableDataDesensitizationItem;
import com.fr.data.desensitize.rule.DesensitizationRuleManager;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource;
import com.fr.data.desensitize.rule.base.DesensitizationRuleStatus;
import com.fr.design.data.datapane.preview.desensitization.view.rule.DesensitizationRulePane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombocheckbox.UIComboCheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableModelAdapter;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.stable.StringUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.AbstractCellEditor;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
/**
* 处理TableDataDesensitizationTablePane中TableEditPane的Model
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/23
*/
public class TableDataDesensitizationTableModel extends UITableModelAdapter<TableDataDesensitizationItem> {
private static final String APOSTROPHE = "...";
private static final String COMMA = ",";
/**
* 当前数据集的所有列名
*/
private List<String> columnNames = new ArrayList<>();
/**
* key为用户组唯一标识id拼接value为用户组名称
*/
private Map<String, String> roleMap = new LinkedHashMap<>();
/**
* 当前最新的所有规则
*/
private Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules = new LinkedHashMap<>();
private Component parent;
public TableDataDesensitizationTableModel(DesensitizationTableData tableData, Component parent, List<String> columnNames, Map<String, String> roleMap, Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules) {
// table相关
super(new String[]{
Toolkit.i18nText("Fine-Design_Report_Desensitization_Column"),
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule"),
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Description"),
Toolkit.i18nText("Fine-Design_Report_Desensitization_Effected_Roles"),
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status"),
});
this.parent = parent;
this.columnNames = columnNames;
this.roleMap = roleMap;
this.latestRules = latestRules;
initTable();
}
/**
* 初始化Table
*/
private void initTable() {
this.setColumnClass(new Class[]{
// 列名选择
ColumnNamesComboBox.class,
// 规则选择
DesensitizationRuleChooser.class,
// 规则详情展示
DesensitizationRuleDescriptionPane.class,
// 生效用户组选择
EffectedRolesChooser.class,
// 规则状态
DesensitizationRuleStatusPane.class
});
ColumnNamesComboBox columnNamesComboBox = new ColumnNamesComboBox();
this.setDefaultEditor(ColumnNamesComboBox.class, columnNamesComboBox);
this.setDefaultEditor(DesensitizationRuleChooser.class, new DesensitizationRuleChooser());
this.setDefaultEditor(DesensitizationRuleDescriptionPane.class, new DesensitizationRuleDescriptionPane());
EffectedRolesChooser effectedRolesChooser = new EffectedRolesChooser();
this.setDefaultEditor(EffectedRolesChooser.class, effectedRolesChooser);
this.setDefaultEditor(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane());
this.setDefaultRenderer(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane());
this.createTable().getColumnModel().getColumn(TableSequences.DesensitizationRuleStatus.getNum()).setMaxWidth(60);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
TableDataDesensitizationItem desensitizationItem = this.getList().get(rowIndex);
TableSequences match = TableSequences.match(columnIndex);
switch (match) {
case ColumnName:
// 选中的数据集字段名称
return desensitizationItem.getColumnName();
case DesensitizationRule:
// 脱敏规则名称
return desensitizationItem.getRule().getRuleName();
case DesensitizationRuleDescription:
// 脱敏规则详情
return DesensitizationRule.getDescription(desensitizationItem.getRule());
case EffectedRoles:
// 生效用户组
return matchRoleNamesByIds(desensitizationItem.getRoleIds());
case DesensitizationRuleStatus:
// 规则状态
return needMarkRule(desensitizationItem.getRule()) ? StringUtils.EMPTY : Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status_Abnormal");
default:
return StringUtils.EMPTY;
}
}
/**
* 通过id匹配此用户组对应的部门职位名称或者说自定义角色名称并拼接成字符串返回
*
* @param roleIds
* @return
*/
private String matchRoleNamesByIds(Collection<String> roleIds) {
StringBuilder builder = new StringBuilder();
for (String roleId : roleIds) {
if (roleMap != null && roleMap.containsKey(roleId)) {
builder.append(roleMap.get(roleId));
builder.append(COMMA);
}
}
return builder.length() <= 1 ? StringUtils.EMPTY : builder.substring(0, builder.length() - 1);
}
@Override
public boolean isCellEditable(int row, int col) {
TableSequences match = TableSequences.match(col);
return match != TableSequences.DesensitizationRuleStatus;
}
@Override
public UITableEditAction[] createAction() {
return new UITableEditAction[]{
new AddDesensitizationAction(),
new RemoveDesensitizationAction(parent),
new RefreshTableAction(),
};
}
/**
* 获取当前选中的item可能为null
*
* @return
*/
@Nullable
private TableDataDesensitizationItem getCurrentSelectBean() {
return table.getSelectedRow() == -1 ?
null :
getList().get(table.getSelectedRow());
}
/**
* 列名选择下拉框
*/
private class ColumnNamesComboBox extends AbstractCellEditor implements TableCellEditor {
private UIComboBox columnNameComboBox;
ColumnNamesComboBox() {
columnNameComboBox = new UIComboBox(columnNames.toArray(new String[0]));
this.addCellEditorListener(new CellEditorListener() {
@Override
public void editingStopped(ChangeEvent e) {
TableDataDesensitizationItem desensitizationItem = getCurrentSelectBean();
if (Objects.nonNull(desensitizationItem)) {
desensitizationItem.setColumnName(columnNames.get(columnNameComboBox.getSelectedIndex()));
fireTableDataChanged();
}
}
@Override
public void editingCanceled(ChangeEvent e) {
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
columnNameComboBox.setSelectedItem(getList().get(row).getColumnName());
return columnNameComboBox;
}
@Override
public Object getCellEditorValue() {
Object selectedItem = columnNameComboBox.getSelectedItem();
return Objects.isNull(selectedItem) ? StringUtils.EMPTY : selectedItem.toString();
}
}
private class DesensitizationRuleChooser extends AbstractCellEditor implements TableCellEditor {
/**
* 规则选择页面
*/
private JPanel choosePane;
/**
* 规则名称
*/
private UITextField ruleNameTextField;
/**
* 规则选择按钮
*/
private UIButton chooseButton;
private ActionListener chooseRuleListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 重新获取一下本地规则缓存
refreshCustomRuleCache();
DesensitizationRulePane rulePane = new DesensitizationRulePane(latestRules);
TableDataDesensitizationItem desensitizationItem = getCurrentSelectBean();
int selectedRow = table.getSelectedRow();
BasicDialog ruleDialog = rulePane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), new DialogActionAdapter() {
@Override
public void doOk() {
DesensitizationRule rule = rulePane.updateBean();
if (Objects.nonNull(desensitizationItem) && DesensitizationRule.valid(rule)) {
desensitizationItem.setRule(rule);
desensitizationItem.setRuleName(rule.getRuleName());
// 刷新规则名称、描述、状态
ruleNameTextField.setText(rule.getRuleName());
fireTableDataChanged();
table.getSelectionModel().setSelectionInterval(selectedRow, selectedRow);
}
}
}, BasicDialog.DEFAULT);
ruleDialog.setVisible(true);
}
};
DesensitizationRuleChooser() {
// 规则名称展示
ruleNameTextField = new UITextField();
ruleNameTextField.setEnabled(false);
// 规则选择按钮
chooseButton = new UIButton(APOSTROPHE);
chooseButton.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Click_To_Choose_Rule"));
chooseButton.addActionListener(chooseRuleListener);
// 规则选择页面
Component[][] templateChooserComponent = {{ruleNameTextField, chooseButton}};
double[] rowSize = {TableLayout.PREFERRED};
double[] columnSize = {TableLayout.FILL, 22};
choosePane = TableLayoutHelper.createCommonTableLayoutPane(templateChooserComponent, rowSize, columnSize, 0);
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
ruleNameTextField.setText(getList().get(row).getRule().getRuleName());
return choosePane;
}
@Override
public Object getCellEditorValue() {
return ruleNameTextField.getText();
}
}
private class DesensitizationRuleDescriptionPane extends AbstractCellEditor implements TableCellEditor {
private UILabel descriptionLabel;
DesensitizationRuleDescriptionPane() {
// 规则描述
this.descriptionLabel = new UILabel();
}
/**
* 根据脱敏规则信息刷新下规则描述文字主要用于与规则选择器的联动
*
* @param desensitizationRule
*/
public void refreshDescription(DesensitizationRule desensitizationRule) {
this.descriptionLabel.setText(DesensitizationRule.getDescription(desensitizationRule));
this.descriptionLabel.setToolTipText(this.descriptionLabel.getText());
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
refreshDescription(getList().get(row).getRule());
return descriptionLabel;
}
@Override
public Object getCellEditorValue() {
return this.descriptionLabel.getText();
}
}
/**
* 生效用户组复选框
*/
private class EffectedRolesChooser extends AbstractCellEditor implements TableCellEditor {
private UIComboCheckBox rolesCheckBox;
EffectedRolesChooser() {
this.rolesCheckBox = new UIComboCheckBox(roleMap.values().toArray(), true) {
@Override
protected void setLayoutAndAddComponents() {
// 使用BorderLayout,否则默认使用的FlowLayout会让整个下拉选框使用最小Size,然后TableCell这边会出现空白
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(getEditor(), BorderLayout.CENTER);
this.add(getArrowButton(), BorderLayout.EAST);
}
@Override
protected void setEditorToolTipText(JComponent editor, String text) {
// 选项过多时,已选中的值会做省略显示处理,此处添加一个Tooltips,显示完整值
if (text != null) {
editor.setToolTipText(text);
}
}
};
this.addCellEditorListener(new CellEditorListener() {
@Override
public void editingStopped(ChangeEvent e) {
TableDataDesensitizationItem desensitizationItem = getCurrentSelectBean();
if (Objects.nonNull(desensitizationItem)) {
desensitizationItem.setRoleIds(generateRolesIdsBySelectedValues());
fireTableDataChanged();
}
}
@Override
public void editingCanceled(ChangeEvent e) {
}
});
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
rolesCheckBox.setSelectedValues(generateRolesCheckBoxSelectedValues(getList().get(row)));
return rolesCheckBox;
}
/**
* 根据当前的规则配置信息生成选中的rolesMap用来展示
*
* @param desensitizationItem
* @return
*/
private Map<Object, Boolean> generateRolesCheckBoxSelectedValues(TableDataDesensitizationItem desensitizationItem) {
Map<Object, Boolean> result = new HashMap<>(roleMap.size());
for (Map.Entry<String, String> roleEntry : roleMap.entrySet()) {
String roleId = roleEntry.getKey();
String roleName = roleEntry.getValue();
if (desensitizationItem.getRoleIds().contains(roleId)) {
result.put(roleName, true);
} else {
result.put(roleName, false);
}
}
return result;
}
/**
* 根据当前的RoleName选择项生成其对应的RoleId的set存入规则配置信息
*
* @return
*/
private Set<String> generateRolesIdsBySelectedValues() {
Set<String> result = new LinkedHashSet<>();
Object[] selectedValues = rolesCheckBox.getSelectedValues();
for (Object selectedValue : selectedValues) {
String selectedRoleName = (String) selectedValue;
if (roleMap.containsValue(selectedRoleName)) {
Optional<Map.Entry<String, String>> matchedEntry = roleMap.entrySet().stream().filter(entry -> StringUtils.equals(entry.getValue(), selectedRoleName)).findFirst();
matchedEntry.ifPresent(stringStringEntry -> result.add(stringStringEntry.getKey()));
}
}
return result;
}
@Override
public Object getCellEditorValue() {
return rolesCheckBox.getSelectedValues();
}
}
/**
* 规则状态展示页面
*/
private class DesensitizationRuleStatusPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private UILabel ruleStatusLabel;
DesensitizationRuleStatusPane() {
// 规则状态
this.ruleStatusLabel = new UILabel();
this.ruleStatusLabel.setForeground(Color.RED);
}
/**
* 根据脱敏规则信息刷新规则状态主要用于与规则选择器的联动
*
* @param currentItem
*/
public void refreshRuleStatus(TableDataDesensitizationItem currentItem) {
DesensitizationRule rule = currentItem.getRule();
if (needMarkRule(rule)) {
// 非正常规则,根据规则状态展示不同提示文字
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(rule, latestRules);
this.ruleStatusLabel.setText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status_Abnormal"));
this.ruleStatusLabel.setToolTipText(ruleStatus.getDescription());
} else {
// 正常规则,重置提示Label
this.ruleStatusLabel.setText(StringUtils.EMPTY);
this.ruleStatusLabel.setToolTipText(null);
}
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
refreshRuleStatus(getList().get(row));
return ruleStatusLabel;
}
@Override
public Object getCellEditorValue() {
return ruleStatusLabel;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
refreshRuleStatus(getList().get(row));
return ruleStatusLabel;
}
}
private class AddDesensitizationAction extends AddTableRowAction {
public AddDesensitizationAction() {
this.setName(Toolkit.i18nText("Fine-Design_Report_Desensitization_Add"));
this.setSmallIcon("/com/fr/design/standard/add/add_black", false);
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
// 添加一条空白数据
addRow(TableDataDesensitizationItem.createDefault());
fireTableDataChanged();
table.getSelectionModel().setSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1);
}
}
private class RemoveDesensitizationAction extends DeleteAction {
public RemoveDesensitizationAction(Component component) {
super(component);
this.setName(Toolkit.i18nText("Fine-Design_Basic_Base_Remove"));
this.setSmallIcon("/com/fr/design/standard/remove/remove_red", false);
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
}
}
private class RefreshTableAction extends UITableEditAction {
public RefreshTableAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Refresh"));
this.setSmallIcon("/com/fr/design/standard/refresh/refresh", false);
}
@Override
public void actionPerformed(ActionEvent e) {
// 刷新TableData的规则,主要是为了自动替换掉平台中被修改的规则
List<TableDataDesensitizationItem> items = getList();
Iterator<TableDataDesensitizationItem> iterator = items.iterator();
while (iterator.hasNext()) {
TableDataDesensitizationItem item = iterator.next();
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(item.getRule(), latestRules);
if (ruleStatus == DesensitizationRuleStatus.REMOVED) {
// 规则被移除,则删除整条脱敏Item
iterator.remove();
} else {
// 规则被修改、禁用等,更新一下规则
item.setRule(DesensitizationRuleManager.getInstance().getLastedDesentizationRule(item.getRule(), latestRules));
}
}
fireTableDataChanged();
}
@Override
public void checkEnabled() {}
}
/**
* 规则表-列字段编号
*/
private enum TableSequences {
/**
* 数据集列名选择
*/
ColumnName(0),
/**
* 规则选择
*/
DesensitizationRule(1),
/**
* 规则描述
*/
DesensitizationRuleDescription(2),
/**
* 规则生效用户组
*/
EffectedRoles(3),
/**
* 规则状态
*/
DesensitizationRuleStatus(4),
/**
* 未知用于无法匹配时的返回
*/
Unknown(100);
private int num;
TableSequences(int num) {
this.num = num;
}
public int getNum() {
return num;
}
/**
* 根据列序号匹配列字段
*
* @param num
* @return
*/
public static TableSequences match(int num) {
for (TableSequences value : TableSequences.values()) {
if (value.getNum() == num) {
return value;
}
}
return Unknown;
}
}
/**
* 是否需要对异常规则做标记需要满足
* 1. 规则非默认空规则
* 2. 规则本身异常
*
* @return
*/
private boolean needMarkRule(DesensitizationRule rule) {
return !rule.equals(DesensitizationRule.createDefaultEmptyRule()) &&
DesensitizationRuleManager.getInstance().getRuleStatus(rule, latestRules) != DesensitizationRuleStatus.NORMAL;
}
/**
* 刷新当前页面的本地规则缓存查询最新本地规则的逻辑也是使用了缓存因此无需考虑耗时
*/
private void refreshCustomRuleCache() {
Map<String, DesensitizationRule> customRules = DesensitizationRuleManager.getInstance().getRulesBySource(DesensitizationRuleSource.CUSTOM);
latestRules.put(DesensitizationRuleSource.CUSTOM, customRules);
}
}

153
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTablePane.java

@ -0,0 +1,153 @@
package com.fr.design.data.datapane.preview.desensitization.view.setting;
import com.fr.base.operator.org.OrganizationOperator;
import com.fr.data.desensitize.base.DesensitizationTableData;
import com.fr.data.desensitize.base.TableDataDesensitizationItem;
import com.fr.data.desensitize.rule.DesensitizationRuleManager;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource;
import com.fr.design.data.datapane.preview.desensitization.TableDataPreviewDesensitizeManager;
import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.WorkContext;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 脱敏字段设置页面中的Table
*
* @author Yvan
* @version 11.0
* Created by Yvan on 2022/9/14
*/
public class TableDataDesensitizationTablePane extends JPanel {
/**
* 脱敏数据集
*/
private DesensitizationTableData tableData;
/**
* 父页面
*/
private Component parent;
/**
* 脱敏信息Table
*/
private UITableEditorPane<TableDataDesensitizationItem> editorPane;
private static final String LOADING_PANE = "loading";
private static final String CONTENT_PANE = "content";
private CardLayout card;
private JPanel loadingPane;
private JPanel contentPane;
public TableDataDesensitizationTablePane(DesensitizationTableData tableData, Component parent) {
this.tableData = tableData;
this.parent = parent;
initComponent();
}
private void initComponent() {
card = new CardLayout();
this.setLayout(card);
// 初始化Loading面板
loadingPane = new TipsPane(true);
this.add(LOADING_PANE, loadingPane);
switchTo(LOADING_PANE);
// 在SwingWorker中初始化Content面板并切换
initContent();
}
/**
* 初始化内容面板
* 考虑到远程设计下的性能需要限制查询数据库的次数所以这里查一次之后子面板内复用
*/
private void initContent() {
final List<String> columnNames = new ArrayList<>();
final Map<String, String> roleMap = new LinkedHashMap<>();
final Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules = new LinkedHashMap<>();
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
// 获取当前数据集的所有列名
columnNames.addAll(TableDataPreviewDesensitizeManager.getInstance().getColumnNamesByTableData(tableData));
// 获取当前所有用户组
roleMap.putAll(WorkContext.getCurrent().get(OrganizationOperator.class).getAllRoles4Desensitization());
// 获取当前最新的所有规则
latestRules.putAll(DesensitizationRuleManager.getInstance().getAllRules());
return null;
}
@Override
protected void done() {
contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
editorPane = new UITableEditorPane<>(new TableDataDesensitizationTableModel(tableData, parent, columnNames, roleMap, latestRules));
editorPane.setHeaderResizing(false);
editorPane.populate(tableData.getDesensitizationConfig().getDesensitizationItems().toArray(new TableDataDesensitizationItem[0]));
contentPane.add(editorPane, BorderLayout.CENTER);
add(CONTENT_PANE, contentPane);
switchTo(CONTENT_PANE);
}
}.execute();
}
/**
* 切换面板
*
* @param panelName
*/
public void switchTo(String panelName) {
try {
if (panelName != null) {
card.show(this, panelName);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 展示此TableData中已配置的脱敏规则信息
*
* @param tableData
*/
public void populateDesensitizationSetting(DesensitizationTableData tableData) {
this.tableData = tableData;
if (editorPane != null) {
// editorPane的初始化在SwingWorker中完成,这里做个判空
editorPane.populate(tableData.getDesensitizationConfig().getDesensitizationItems().toArray(new TableDataDesensitizationItem[0]));
}
}
/**
* 获取当前对TableData的配置脱敏规则信息
*/
public List<TableDataDesensitizationItem> updateDesensitizationSetting() {
return editorPane == null ?
new ArrayList<>() :
editorPane.update()
.stream()
.filter(item -> TableDataDesensitizationItem.valid(item))
.collect(Collectors.toList());
}
}

7
designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java vendored

@ -1,6 +1,7 @@
package com.fr.design.env;
import com.fr.general.ComparatorUtils;
import com.fr.stable.CommonUtils;
import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
@ -98,11 +99,17 @@ public class LocalDesignerWorkspaceInfo implements DesignerWorkspaceInfo {
@Override
public boolean checkValid(){
File file = new File(this.path);
//判断不是文件夹/路径不在WEB-INF下/代码启动三种情况
if(!file.isDirectory() || !ComparatorUtils.equals(file.getName(), "WEB-INF") || this.path.startsWith(".")) {
return false;
}
// 如果当前是 debug 模式,就不检测是否 mainVersion 不一致
if (CommonUtils.isDebug()) {
return true;
}
File engineLib = new File(StableUtils.pathJoin(this.path, ProjectConstants.LIB_NAME, REPORT_ENGINE_JAR));
// 非安装版本允许自由切换

11
designer-base/src/main/java/com/fr/design/extra/PluginUtils.java

@ -10,8 +10,8 @@ import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.PluginVerifyException;
import com.fr.plugin.basic.version.Version;
import com.fr.plugin.basic.version.VersionIntervalType;
import com.fr.plugin.basic.version.VersionIntervalFactory;
import com.fr.plugin.basic.version.VersionIntervalType;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.error.PluginBaseErrorCode;
@ -23,7 +23,7 @@ import com.fr.stable.ProductConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import javax.swing.*;
import javax.swing.JOptionPane;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@ -47,9 +47,10 @@ public class PluginUtils {
public static PluginMarker createPluginMarker(String pluginInfo) {
//todo 判空
String[] plugin = pluginInfo.split("_");
return PluginMarker.create(plugin[0], plugin[1]);
int splitIndex = pluginInfo.lastIndexOf("_");
String pluginID = pluginInfo.substring(0, splitIndex);
String version = pluginInfo.substring(splitIndex + 1);
return PluginMarker.create(pluginID, version);
}
public static JSONObject getLatestPluginInfo(String pluginID) throws Exception {

9
designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java

@ -28,6 +28,7 @@ import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.CollectionUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
@ -229,7 +230,13 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi
}
//确定目标目录并检查权限
FileOperations selectedOperation = DesignerFrameFileDealerPane.getInstance().getSelectedOperation();
if (!selectedOperation.access()) {
boolean rootAuthority = true;
if (selectedOperation.getFileNode() == null && selectedOperation instanceof TemplateTreePane) {
//没有选中文件节点时,默认粘贴到根目录下,所以直接检测根目录是否有权限
ExpandMutableTreeNode root = (ExpandMutableTreeNode) ((TemplateTreePane) selectedOperation).getTemplateFileTree().getModel().getRoot();
rootAuthority = root.hasFullAuthority();
}
if (!rootAuthority && !selectedOperation.access()) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied"),
Toolkit.i18nText("Fine-Design_Basic_Alert"),

21
designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java

@ -127,7 +127,7 @@ public class FileOperationHelper {
WARNING_MESSAGE);
return StringUtils.EMPTY;
}
String name = getNoRepeatedName4Paste(targetDir, sourceFile.getName());
String name = getNoRepeatedName4Paste(targetDir, sourceFile);
String targetFile = StableUtils.pathJoin(targetDir, name);
if (sourceFile.isDirectory()) {
copyDir(sourcePath, targetFile, withCopyVcs);
@ -177,19 +177,22 @@ public class FileOperationHelper {
* 重名处理
*
* @param targetDir
* @param oldName
* @param sourceFile
* @return
*/
private String getNoRepeatedName4Paste(String targetDir, String oldName) {
private String getNoRepeatedName4Paste(String targetDir, FileNode sourceFile) {
String oldName = sourceFile.getName();
while (isNameRepeaded(targetDir, oldName)) {
int index = oldName.lastIndexOf(".");
if (index > 0) {
String oName = oldName.substring(0, index);
oName = oName + Toolkit.i18nText("Fine-Design_Table_Data_Copy_Of_Table_Data");
oldName = oName.concat(oldName.substring(index));
} else {
if (sourceFile.isDirectory()) {
//目录重名
oldName = oldName + Toolkit.i18nText("Fine-Design_Table_Data_Copy_Of_Table_Data");
} else {
int index = oldName.lastIndexOf(".");
if (index > 0) {
String oName = oldName.substring(0, index);
oName = oName + Toolkit.i18nText("Fine-Design_Table_Data_Copy_Of_Table_Data");
oldName = oName.concat(oldName.substring(index));
}
}
}
return oldName;

18
designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java

@ -75,7 +75,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
historyList.remove(contains(selected));
selected.getEditingFILE().closeTemplate();
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Closed_Warn_Text", selected.getEditingFILE().getName()));
MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList);
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(historyList);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
@ -134,10 +134,10 @@ public class HistoryTemplateListCache implements CallbackEvent {
if (contains(jt) == -1) {
addHistory();
}
MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList);
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(historyList);
//设置tab栏为当前选中的那一栏
if (editingTemplate != null) {
MutilTempalteTabPane.getInstance().setSelectedIndex(contains(jt));
MultiTemplateTabPane.getInstance().setSelectedIndex(contains(jt));
}
}
@ -274,7 +274,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
historyList.set(i, new JVirtualTemplate(overTemplate.getEditingFILE()));
}
}
MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList);
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(historyList);
}
@ -297,7 +297,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
int index = iterator.nextIndex();
if (size == index + 1 && index > 0) {
//如果删除的是后一个Tab,则定位到前一个
MutilTempalteTabPane.getInstance().setSelectedIndex(index - 1);
MultiTemplateTabPane.getInstance().setSelectedIndex(index - 1);
}
}
}
@ -307,13 +307,13 @@ public class HistoryTemplateListCache implements CallbackEvent {
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
}
JTemplate selectedFile = MutilTempalteTabPane.getInstance().getSelectedFile();
JTemplate selectedFile = MultiTemplateTabPane.getInstance().getSelectedFile();
if (!isCurrentEditingFile(selectedFile.getPath())) {
//如果此时面板上的实时刷新的selectedIndex得到的和历史的不一样
DesignerContext.getDesignerFrame().activateJTemplate(selectedFile);
}
MutilTempalteTabPane.getInstance().repaint();
MultiTemplateTabPane.getInstance().repaint();
}
@ -474,7 +474,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
int index = contains(this.editingTemplate);
this.editingTemplate = jt;
historyList.set(index, jt);
MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList);
MutilTempalteTabPane.getInstance().setSelectedIndex(contains(jt));
MultiTemplateTabPane.getInstance().refreshOpenedTemplate(historyList);
MultiTemplateTabPane.getInstance().setSelectedIndex(contains(jt));
}
}

1243
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java

File diff suppressed because it is too large Load Diff

1233
designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java

File diff suppressed because it is too large Load Diff

3
designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java

@ -307,10 +307,11 @@ public class TemplateTreePane extends JPanel implements FileOperations {
if (reportletsTree.getSelectionCount() == 0) {
//没选中文件刷新根目录
reportletsTree.refresh();
return;
}
reportletsTree.refreshParent(Objects.requireNonNull(reportletsTree.getSelectionPath()));
DesignerFrameFileDealerPane.getInstance().refreshRightToolBarBy(null);
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_File_Tree_Refresh_Successfully") + "!");
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_File_Tree_Refresh_Successfully"));
}

7
designer-base/src/main/java/com/fr/design/formula/FormulaPane.java

@ -58,7 +58,7 @@ import com.fr.stable.EncodeConstants;
import com.fr.stable.EssentialUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.stable.script.CRAddress;
import com.fr.parser.CRAddress;
import com.fr.stable.script.ColumnRowRange;
import com.fr.stable.script.Expression;
import com.fr.stable.script.Node;
@ -156,6 +156,8 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private DefaultCompletionProvider completionProvider;
private static final Map<String, String> PARAM_PREFIX_MAP = new HashMap<>();
public static final int DESCRIPTION_TEXT_AREA_ROW = 16, DESCRIPTION_TEXT_AREA_COLUMN = 27;
public FormulaPane() {
initComponents();
}
@ -1194,8 +1196,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void initDescriptionTextArea() {
// Description
descriptionTextArea = new UITextArea();
descriptionTextArea = new UITextArea(DESCRIPTION_TEXT_AREA_ROW,DESCRIPTION_TEXT_AREA_COLUMN);
descriptionTextArea.setBackground(Color.white);
descriptionTextArea.setLineWrap(true);
descriptionTextArea.setWrapStyleWord(true);

65
designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java

@ -0,0 +1,65 @@
package com.fr.design.fun;
import com.fr.base.Utils;
import com.fr.base.chart.BaseChartCollection;
import com.fr.chartx.attr.ChartProvider;
import com.fr.general.FRFont;
import com.fr.report.cell.CellElement;
import com.fr.stable.fun.mark.Selectable;
import java.awt.Font;
/**
* 主要用于fvs报表块内元素默认值的调整以达到所见所得效果后续fvs内置后删除
*/
public interface DefaultValueAdjustProvider extends Selectable {
String MARK_STRING = "DefaultValueAdjustProvider";
int CURRENT_LEVEL = 1;
/**
* 调整单元格对象默认值
*
* @param cellElement
*/
void adjustCellElement(CellElement cellElement);
/**
* 调整富文本默认值
*
* @param fontSize
* @return
*/
int adjustRichTextTransform(int fontSize, double transformedFontSize);
/**
* 调整ChartCollection
*
* @param chartCollection
*/
void adjustChartCollectionStyle(BaseChartCollection chartCollection);
/**
* 调整图表
*
* @param chartProvider
*/
void adjustChart(ChartProvider chartProvider);
/**
* 转成当前分辨率下显示的font
* @param font
* @param resolution
* @return
*/
Font transformFontByResolution(FRFont font, int resolution);
/**
* 修改设计可用字体默认列表
* @return
*/
default String[] getAvailableFontFamilyNames4Report() {
return Utils.getAvailableFontFamilyNames4Report();
}
}

35
designer-base/src/main/java/com/fr/design/fun/TemplateThemePaneProvider.java

@ -0,0 +1,35 @@
package com.fr.design.fun;
import com.fr.design.beans.BasicBeanPane;
import com.fr.stable.fun.mark.Mutable;
/**
* 设计器模板主题管理-细节定制部分,支持添加tab
*
* @author Bruce.Deng
* @version 11.0
* Created by Bruce.Deng on 2023/2/7
*/
public interface TemplateThemePaneProvider<T> extends Mutable {
String XML_TAG = "TemplateThemePaneProvider";
int CURRENT_LEVEL = 1;
/**
* 插入tab的位置
*
* @param total 已插入的tab数
* @return 插入位置如果想放到最后则返回-1
*/
int getInsertPosition(int total);
/**
* 获取tab对象
*
* @return tab对象
*/
BasicBeanPane<T> getTab();
}

24
designer-base/src/main/java/com/fr/design/fun/impl/AbstractDefaultValueAdjustProvider.java

@ -0,0 +1,24 @@
package com.fr.design.fun.impl;
import com.fr.design.fun.DefaultValueAdjustProvider;
import com.fr.stable.fun.assist.Selector;
import com.fr.stable.fun.impl.AbstractProvider;
import com.fr.stable.fun.mark.API;
@API(level = DefaultValueAdjustProvider.CURRENT_LEVEL)
public abstract class AbstractDefaultValueAdjustProvider extends AbstractProvider implements DefaultValueAdjustProvider {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
public String mark4Provider() {
return this.getClass().getName();
}
public Selector selector() {
return Selector.ALWAYS;
}
}

26
designer-base/src/main/java/com/fr/design/fun/impl/AbstractTemplateThemePaneProvider.java

@ -0,0 +1,26 @@
package com.fr.design.fun.impl;
import com.fr.design.fun.TemplateThemePaneProvider;
import com.fr.stable.fun.impl.AbstractProvider;
import com.fr.stable.fun.mark.API;
/**
* @author Bruce.Deng
* @version 11.0
* @see TemplateThemePaneProvider
* Created by Bruce.Deng on 2023/2/7
*/
@API(level = TemplateThemePaneProvider.CURRENT_LEVEL)
public abstract class AbstractTemplateThemePaneProvider<T> extends AbstractProvider implements TemplateThemePaneProvider<T> {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
@Override
public String mark4Provider() {
return getClass().getName();
}
}

98
designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java

@ -31,7 +31,6 @@ import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
@ -241,51 +240,12 @@ public abstract class UIControlPane extends JControlPane {
}
private void hideDialog() {
// 检查是否有子弹窗,如果有,则不隐藏
for (Window window : getOwnedWindows()) {
if (window.isVisible()) {
return;
}
}
// 如果有可见模态对话框,则不隐藏
for (Window window : DesignerContext.getDesignerFrame().getOwnedWindows()) {
if (window instanceof JDialog && window.isVisible() && ((JDialog) window).isModal()) {
return;
}
}
try {
//没有指定owner的弹出框用的是SwingUtilities.getSharedOwnerFrame()
Frame sharedOwnerFrame = Reflect.on(SwingUtilities.class).call("getSharedOwnerFrame").get();
for (Window window : sharedOwnerFrame.getOwnedWindows()) {
if (window instanceof JDialog && window.isVisible() && ((JDialog) window).isModal()) {
// 如果有可见模态对话框,则不隐藏
return;
}
}
} catch (Exception ignore) {
//do nothing
}
// 要隐藏 先检查有没有非法输入
// 非法输入检查放在最后,因为可能出现面板弹出新弹框而失去焦点的情况,比如 输入公式时,弹出公式编辑对话框
try {
checkValid();
} catch (Exception exp) {
// 存在非法输入 拒绝隐藏
this.setAlwaysOnTop(true);
FineJOptionPane.showMessageDialog(this, exp.getMessage());
this.requestFocus();
return;
}
if (JavaFxNativeFileChooser.isShowDialogState()) {
JavaFxNativeFileChooser.setShowDialogState(false);
return;
if (needToHidePopupEditDialog()) {
saveSettings();
setVisible(false);
PopupDialogSaveAction saveAction = OSSupportCenter.getAction(PopupDialogSaveAction.class);
saveAction.unregister();
}
saveSettings();
setVisible(false);
PopupDialogSaveAction saveAction = OSSupportCenter.getAction(PopupDialogSaveAction.class);
saveAction.unregister();
}
private void initListener() {
@ -302,6 +262,54 @@ public abstract class UIControlPane extends JControlPane {
}
}
/**
* 是否需要隐藏popupEditDialog
*/
protected boolean needToHidePopupEditDialog() {
// 检查是否有子弹窗,如果有,则不隐藏
for (Window window : popupEditDialog.getOwnedWindows()) {
if (window.isVisible()) {
return false;
}
}
// 如果有可见模态对话框,则不隐藏
for (Window window : DesignerContext.getDesignerFrame().getOwnedWindows()) {
if (window instanceof JDialog && window.isVisible() && ((JDialog) window).isModal()) {
return false;
}
}
try {
//没有指定owner的弹出框用的是SwingUtilities.getSharedOwnerFrame()
Frame sharedOwnerFrame = Reflect.on(SwingUtilities.class).call("getSharedOwnerFrame").get();
for (Window window : sharedOwnerFrame.getOwnedWindows()) {
if (window instanceof JDialog && window.isVisible() && ((JDialog) window).isModal()) {
// 如果有可见模态对话框,则不隐藏
return false;
}
}
} catch (Exception ignore) {
//do nothing
}
// 要隐藏 先检查有没有非法输入
// 非法输入检查放在最后,因为可能出现面板弹出新弹框而失去焦点的情况,比如 输入公式时,弹出公式编辑对话框
try {
checkValid();
} catch (Exception exp) {
// 存在非法输入 拒绝隐藏
popupEditDialog.setAlwaysOnTop(true);
FineJOptionPane.showMessageDialog(this, exp.getMessage());
popupEditDialog.requestFocus();
return false;
}
if (JavaFxNativeFileChooser.isShowDialogState()) {
JavaFxNativeFileChooser.setShowDialogState(false);
return false;
}
return true;
}
// 移动弹出编辑面板的工具条
private class PopupToolPane extends JPanel {
private JDialog parentDialog; // 如果不在对话框中,值为null

7
designer-base/src/main/java/com/fr/design/gui/core/WidgetOption.java

@ -1,6 +1,7 @@
package com.fr.design.gui.core;
import com.fr.base.BaseUtils;
import com.fr.base.svg.IconUtils;
import com.fr.form.ui.Button;
import com.fr.form.ui.CheckBox;
import com.fr.form.ui.CheckBoxGroup;
@ -14,6 +15,7 @@ import com.fr.form.ui.ListEditor;
import com.fr.form.ui.MultiFileEditor;
import com.fr.form.ui.NumberEditor;
import com.fr.form.ui.Password;
import com.fr.form.ui.PictureWidget;
import com.fr.form.ui.RadioGroup;
import com.fr.form.ui.TextArea;
import com.fr.form.ui.TextEditor;
@ -142,7 +144,7 @@ public abstract class WidgetOption implements Serializable {
*/
public static WidgetOption[] getFormWidgetIntance() {
return new WidgetOption[]{TEXTEDITOR, LABEL, FREEBUTTON, COMBOBOX, COMBOCHECKBOX, DATEEDITOR,
NUMBEREDITOR, TREECOMBOBOX, RADIOGROUP, CHECKBOXGROUP, TEXTAREA, PASSWORD, CHECKBOX, TREE, MULTI_FILEEDITOR};
NUMBEREDITOR, TREECOMBOBOX, RADIOGROUP, CHECKBOXGROUP, TEXTAREA, PASSWORD, CHECKBOX, TREE, MULTI_FILEEDITOR,PICTURE};
}
public static final WidgetOption DATEEDITOR = WidgetOptionFactory.createByWidgetClass(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Type_Date"),
@ -214,4 +216,7 @@ public abstract class WidgetOption implements Serializable {
public static final WidgetOption IFRAMEDITOR = WidgetOptionFactory.createByWidgetClass(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Form_Iframe"), BaseUtils.readIcon("/com/fr/web/images/form/resources/iframe_16.png"),
IframeEditor.class);
public static final WidgetOption PICTURE = WidgetOptionFactory.createByWidgetClass(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Type_Image"), IconUtils.readIcon("/com/fr/web/images/form/resources/picture_widget_16.png"),
PictureWidget.class);
}

2
designer-base/src/main/java/com/fr/design/gui/frpane/HyperlinkGroupPaneActionProvider.java

@ -8,6 +8,8 @@ import com.fr.design.designer.TargetComponent;
*/
public interface HyperlinkGroupPaneActionProvider {
String XML_TAG = "HyperlinkGroupPane";
/**
* 刷新面板展示
*

15
designer-base/src/main/java/com/fr/design/gui/icheckbox/UICheckBox.java

@ -139,6 +139,15 @@ public class UICheckBox extends JCheckBox implements UIObserver, GlobalNameObser
return true;
}
/**
* 获取UICheckBox的UI层可以用于设置UI
*
* @return UICheckBoxUI
*/
public UICheckBoxUI getUICheckBoxUI(){
return new UICheckBoxUI();
}
private class UICheckBoxUI extends MetalCheckBoxUI {
@Override
public synchronized void paint(Graphics g, JComponent c) {
@ -186,9 +195,9 @@ public class UICheckBox extends JCheckBox implements UIObserver, GlobalNameObser
g2d.drawRoundRect(iconRect.x, iconRect.y, iconRect.width - 1, iconRect.height - 1, UIConstants.ARC, UIConstants.ARC);
}
if (model.isSelected()) {
UIConstants.YES_ICON.paintIcon(c, g, iconRect.x + 2, iconRect.y + 2);
}
if (model.isSelected()) {
UIConstants.YES_ICON.paintIcon(c, g, iconRect.x + 2, iconRect.y + 2);
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
// Draw the Text

20
designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java

@ -37,6 +37,10 @@ public class UICheckListPopup extends UIPopupMenu {
private Color mouseEnteredColor = UIConstants.CHECKBOX_HOVER_SELECTED;
private int maxDisplayNumber = 8;
private boolean supportSelectAll = true;
/**
* 每项数据都有可能因为宽度设置问题而被省略显示这个常量代表是否要给每项数据添加一个值等于其原值的Tooltips
*/
private boolean labelNeedToolTips = false;
public static final String COMMIT_EVENT = "commit";
private static final String SELECT_ALL = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Choose_All");
@ -47,9 +51,14 @@ public class UICheckListPopup extends UIPopupMenu {
}
public UICheckListPopup(Object[] value, boolean supportSelectAll) {
this(value, supportSelectAll, false);
}
public UICheckListPopup(Object[] values, boolean supportSelectAll, boolean labelNeedToolTips) {
super();
values = value;
this.values = values;
this.supportSelectAll = supportSelectAll;
this.labelNeedToolTips = labelNeedToolTips;
initComponent();
}
@ -62,6 +71,11 @@ public class UICheckListPopup extends UIPopupMenu {
addCheckboxValues();
}
public UICheckListPopup setLabelNeedToolTips(boolean labelNeedToolTips) {
this.labelNeedToolTips = labelNeedToolTips;
return this;
}
private void initComponent() {
checkboxPane = new JPanel();
checkboxPane.setLayout(new GridLayout(checkBoxList.size(), 1, 0, 0));
@ -111,6 +125,10 @@ public class UICheckListPopup extends UIPopupMenu {
checkPane.setBackground(Color.WHITE);
checkPane.add(temp);
checkPane.add(label);
if (labelNeedToolTips) {
// 设置每项Label的tooltips为其省略前的内容
label.setToolTipText(checkValue.toString());
}
addMouseListener(temp, label);
checkBoxList.add(temp);

68
designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java

@ -17,9 +17,6 @@ import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@ -32,6 +29,9 @@ import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 设计器下拉复选框组件
@ -52,7 +52,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
//选中的值之间显示的分隔符
private String valueSperator;
private static final String DEFAULT_VALUE_SPERATOR = ",";
private static final String OMIT_TEXT = "...";
protected static final String OMIT_TEXT = "...";
private UIObserverListener uiObserverListener;
private GlobalNameListener globalNameListener = null;
@ -60,6 +60,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
private boolean showOmitText = true;
private boolean supportSelectAll = true;
private String placeHolder = StringUtils.EMPTY;
public UIComboCheckBox(Object[] value) {
this(value, DEFAULT_VALUE_SPERATOR, true);
@ -112,14 +113,42 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
}
private void initComponent() {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
this.popup = new UICheckListPopup(values, supportSelectAll);
this.popup.addActionListener(new PopupAction());
this.editor = createEditor();
this.arrowButton = createArrowButton();
setLayoutAndAddComponents();
setText();
}
/**
* 设置布局管理器并且添加组件
* 默认使用FlowLayout
*/
protected void setLayoutAndAddComponents() {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
this.add(editor);
this.add(arrowButton);
setText();
}
public UICheckListPopup getPopup() {
return popup;
}
public UITextField getEditor() {
return editor;
}
public String getPlaceHolder() {
return placeHolder;
}
public void setPlaceHolder(String placeHolder) {
this.placeHolder = placeHolder;
}
public UIButton getArrowButton() {
return arrowButton;
}
private UIButton createArrowButton() {
@ -171,6 +200,9 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
attributeChange();
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
}
@Override
@ -270,6 +302,28 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
String text = builder.length() > 0 ? builder.substring(0, builder.length() - 1) : StringUtils.EMPTY;
//计算加省略号后的文本
editor.setText(this.showOmitText ? omitEditorText(editor, text) : text);
// 添加placeHolder
setEditorPlaceHolder(editor);
// tooltips显示原值
setEditorToolTipText(editor, text);
}
/**
* 为为添加placeholder
* @param editor
*/
protected void setEditorPlaceHolder(UITextField editor) {
// 默认空实现
}
/**
* 为UITextField设置悬浮提示值
*
* @param editor
* @param text
*/
protected void setEditorToolTipText(JComponent editor, String text) {
// 默认不做设置
}
/**
@ -279,7 +333,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
* @param text
* @return 省略后的文字
*/
private static String omitEditorText(UITextField textEditor, String text) {
protected String omitEditorText(UITextField textEditor, String text) {
char[] omitChars = OMIT_TEXT.toCharArray();
//获取字体的大小
FontMetrics fontMetrics = textEditor.getFontMetrics(textEditor.getFont());

4
designer-base/src/main/java/com/fr/design/gui/iprogressbar/ProgressDialog.java

@ -20,6 +20,10 @@ import java.awt.Frame;
/**
* 加载进度弹窗
* <em>使用注意点:</em>
* 必须到使用时再初始化不要作为属性存在
* 因为涉及到 大小/位置 相对于 parent 的相对判断
* {@link com.fr.design.gui.iprogressbar.ProgressDialogTest}
*/
public class ProgressDialog extends UIDialog {
protected static final FRFont font = DesignUtils

19
designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java

@ -312,6 +312,25 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver
componentInitListeners();
}
/**
* 设置最大值
* @param maxValue 最大值
*/
public void setMaxValue(double maxValue) {
this.maxValue = maxValue;
textField.setMaxValue(maxValue);
}
/**
* 设置最小值
*
* @param minValue 最小值
*/
public void setMinValue(double minValue) {
this.minValue = minValue;
textField.setMinValue(minValue);
}
private void componentInitListeners() {
preButton.addActionListener(new ActionListener() {
@Override

54
designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableEditorPane.java

@ -8,10 +8,12 @@ import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.List;
/**
@ -31,25 +33,25 @@ public class UITableEditorPane<T> extends BasicPane {
private String leftLabelName;
private JPanel buttonPane;
public UITableEditorPane(UITableModelAdapter<T> model) {
this.tableModel = model;
this.initComponent(model.createAction());
}
public UITableEditorPane(UITableModelAdapter<T> model) {
this.tableModel = model;
this.initComponent(model.createAction());
}
public UITableEditorPane(UITableModelAdapter<T> model, String s) {
leftLabelName = s;
this.tableModel = model;
this.initComponent(model.createAction());
}
public UITableEditorPane(UITableModelAdapter<T> model, String s) {
leftLabelName = s;
this.tableModel = model;
this.initComponent(model.createAction());
}
private void initComponent(UITableEditAction[] action) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel pane = new JPanel(new BorderLayout(4, 4));
this.add(pane, BorderLayout.CENTER);
protected void initComponent(UITableEditAction[] action) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel pane = new JPanel(new BorderLayout(4, 4));
this.add(pane, BorderLayout.CENTER);
UILabel l = new UILabel(leftLabelName);
editTable = tableModel.createTable();
editTable.getTableHeader().setBackground(UIConstants.DEFAULT_BG_RULER);
UILabel l = new UILabel(leftLabelName);
editTable = tableModel.createTable();
editTable.getTableHeader().setBackground(UIConstants.DEFAULT_BG_RULER);
UIScrollPane scrollPane = new UIScrollPane(editTable);
scrollPane.setBorder(new UIRoundedBorder(UIConstants.TITLED_BORDER_COLOR, 1, UIConstants.ARC));
@ -62,11 +64,11 @@ public class UITableEditorPane<T> extends BasicPane {
}
public UITableModelAdapter<T> getTableModel(){
public UITableModelAdapter<T> getTableModel() {
return tableModel;
}
private void initbuttonPane(UITableEditAction[] action) {
protected void initbuttonPane(UITableEditAction[] action) {
buttonPane = new JPanel();
if (action != null) {
@ -146,6 +148,14 @@ public class UITableEditorPane<T> extends BasicPane {
return buttonPane;
}
public JTable getEditTable() {
return editTable;
}
public void setEditTable(JTable editTable) {
this.editTable = editTable;
}
/**
* 停止编辑
*/
@ -157,7 +167,7 @@ public class UITableEditorPane<T> extends BasicPane {
/**
* 设置表头是否可以改变大小
*/
public void setHeaderResizing(boolean resizingAllowed){
public void setHeaderResizing(boolean resizingAllowed) {
editTable.getTableHeader().setResizingAllowed(resizingAllowed);
}

96
designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableModelAdapter.java

@ -219,57 +219,69 @@ public abstract class UITableModelAdapter<T> extends AbstractTableModel implemen
protected class DeleteAction extends UITableEditAction {
private Component component = null;
// 删除时界面显示的提示语,可自定义
private String deleteTipText;
public DeleteAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete"));
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
}
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete"));
this.setDeleteTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?");
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
}
public DeleteAction(Component component){
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete"));
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete"));
this.setDeleteTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?");
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
this.component = component;
}
@Override
public void actionPerformed(ActionEvent e) {
int[] selectedRow = table.getSelectedRows();
if (ismultiSelected()) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multiple_Select_Warn_Text"));
return;
}
if (table.getCellEditor() != null) {
try {
table.getCellEditor().stopCellEditing();
} catch (Exception ee) {
int[] selectedRow = table.getSelectedRows();
if (ismultiSelected()) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multiple_Select_Warn_Text"));
return;
}
if (table.getCellEditor() != null) {
try {
table.getCellEditor().stopCellEditing();
} catch (Exception ee) {
FineLoggerFactory.getLogger().error(ee.getMessage(), ee);
}
}
if (getRowCount() < 1) {
return;
}
if(component == null){
component = DesignerContext.getDesignerFrame();
}
int val = FineJOptionPane.showConfirmDialog(component,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"),
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (val != JOptionPane.OK_OPTION) {
return;
}
for (int i = 0; i < selectedRow.length; i++) {
if (selectedRow[i] - i < 0) {
continue;
}
removeRow(selectedRow[i] - i);
}
fireTableDataChanged();
int selection = selectedRow[0] > table.getRowCount() ? table.getRowCount() - 1
: (selectedRow[0] > 1 ? selectedRow[0] - 1 : 0);
table.getSelectionModel().setSelectionInterval(selection, selection);
}
}
}
if (getRowCount() < 1) {
return;
}
if (component == null) {
component = DesignerContext.getDesignerFrame();
}
int val = FineJOptionPane.showConfirmDialog(component, getDeleteTipText()
, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"),
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (val != JOptionPane.OK_OPTION) {
return;
}
for (int i = 0; i < selectedRow.length; i++) {
if (selectedRow[i] - i < 0) {
continue;
}
removeRow(selectedRow[i] - i);
}
fireTableDataChanged();
int selection = selectedRow[0] > table.getRowCount() ? table.getRowCount() - 1
: (selectedRow[0] > 1 ? selectedRow[0] - 1 : 0);
table.getSelectionModel().setSelectionInterval(selection, selection);
}
public String getDeleteTipText() {
return deleteTipText;
}
public void setDeleteTipText(String deleteTipText) {
this.deleteTipText = deleteTipText;
}
private boolean ismultiSelected(){
private boolean ismultiSelected() {
int[] selectedRow = table.getSelectedRows();
return (selectedRow.length == 1 && (selectedRow[0] > table.getRowCount() - 1 || selectedRow[0] < 0)) || selectedRow.length == 0;
}

7
designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java

@ -144,8 +144,8 @@ public class TemplateFileTree extends EnvFileTree {
Set<FileExtension> supportTypes = createFileExtensionFilter();
return FRContext.getFileNodes().list(
path,
supportTypes.toArray(new FileExtension[supportTypes.size()])
);
supportTypes.toArray(new FileExtension[supportTypes.size()]), false, true
);
}
private Set<FileExtension> createFileExtensionFilter() {
@ -306,8 +306,7 @@ public class TemplateFileTree extends EnvFileTree {
if (interceptRefresh(root)) {
return;
}
if (!TemplateTreeSearchManager.getInstance().isRefreshing()) {
if (!TemplateTreeSearchManager.getInstance().isRefreshing() || TemplateTreeSearchManager.getInstance().allFileNodes().size() != allTreeNode.size()) {
currentTreeMode.clear();
calculateNode.clear();
allTreeNode = TemplateTreeSearchManager.getInstance().allFileNodes().entrySet().stream().collect(

41
designer-base/src/main/java/com/fr/design/gui/style/BorderPane.java

@ -265,34 +265,31 @@ public class BorderPane extends AbstractBasicStylePane implements GlobalNameObse
int lineStyle = currentLineCombo.getSelectedLineStyle();
Color lineColor = currentLineColorPane.getSelectObject();
CellBorderStyle cellBorderStyle = new CellBorderStyle();
if (topToggleButton.isSelected()) {
cellBorderStyle.setTopColor(lineColor);
if (lineColor != null) {
if (topToggleButton.isSelected()) {
cellBorderStyle.setTopColor(lineColor);
}
if (bottomToggleButton.isSelected()) {
cellBorderStyle.setBottomColor(lineColor);
}
if (leftToggleButton.isSelected()) {
cellBorderStyle.setLeftColor(lineColor);
}
if (rightToggleButton.isSelected()) {
cellBorderStyle.setRightColor(lineColor);
}
if (verticalToggleButton.isSelected()) {
cellBorderStyle.setVerticalColor(lineColor);
}
if (horizontalToggleButton.isSelected()) {
cellBorderStyle.setHorizontalColor(lineColor);
}
}
cellBorderStyle.setTopStyle(topToggleButton.isSelected() ? lineStyle : Constants.LINE_NONE);
if (bottomToggleButton.isSelected()) {
cellBorderStyle.setBottomColor(lineColor);
}
cellBorderStyle.setBottomStyle(bottomToggleButton.isSelected() ? lineStyle : Constants.LINE_NONE);
if (leftToggleButton.isSelected()) {
cellBorderStyle.setLeftColor(lineColor);
}
cellBorderStyle.setLeftStyle(leftToggleButton.isSelected() ? lineStyle : Constants.LINE_NONE);
if (rightToggleButton.isSelected()) {
cellBorderStyle.setRightColor(lineColor);
}
cellBorderStyle.setRightStyle(rightToggleButton.isSelected() ? lineStyle : Constants.LINE_NONE);
if (verticalToggleButton.isSelected()) {
cellBorderStyle.setVerticalColor(lineColor);
}
cellBorderStyle.setVerticalStyle(verticalToggleButton.isSelected() ? lineStyle : Constants.LINE_NONE);
if (horizontalToggleButton.isSelected()) {
cellBorderStyle.setHorizontalColor(lineColor);
}
cellBorderStyle.setHorizontalStyle(horizontalToggleButton.isSelected() ? lineStyle : Constants.LINE_NONE);
outerToggleButton.setSelected(leftToggleButton.isSelected() && bottomToggleButton.isSelected() && rightToggleButton.isSelected() && topToggleButton.isSelected());

3
designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java

@ -12,6 +12,7 @@ import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.utils.DesignUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.WidgetTitle;
@ -90,7 +91,7 @@ public class ComponentTitleStylePane extends AbstractBorderPackerPane {
textContentPane = new TinyFormulaPane();
fontFamilyComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
fontFamilyComboBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report());
FRFont frFont = DEFAULT_TITLE_PACKER.getFrFont();
if (frFont != null) {
String fontFamily = frFont.getFamily();

3
designer-base/src/main/java/com/fr/design/gui/style/FRFontPane.java

@ -18,6 +18,7 @@ import com.fr.design.gui.icombobox.LineComboBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.DefaultValues;
@ -246,7 +247,7 @@ public class FRFontPane extends AbstractBasicStylePane implements GlobalNameObse
protected void initComponents() {
fontSizeStyleComboBox = new UIComboBox(fontSizeStyles);
fontNameComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
fontNameComboBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report());
fontNameComboBox.setPreferredSize(new Dimension(144, 20));
fontSizeComboBox = new UIComboBox(getFontSizes());
fontSizeComboBox.setEditable(true);

81
designer-base/src/main/java/com/fr/design/gui/style/TextFormatPaneContainer.java

@ -0,0 +1,81 @@
package com.fr.design.gui.style;
import com.fr.base.Style;
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane;
import com.fr.design.gui.frpane.AttributeChangeListener;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
/**
* 封装格式panel管理 AttributeChangeListener
*
* @author Leo.Qin
* @version 11.0
* Created by Leo.Qin on 2022/10/31
*/
public class TextFormatPaneContainer extends AbstractAttrNoScrollPane {
private TextFormatPane formatPane;
private AttributeChangeListener oldListner;
@Override
protected JPanel createContentPane() {
formatPane = new TextFormatPane();
return formatPane;
}
protected void initContentPane() {
leftContentPane = createContentPane();
if (leftContentPane != null) {
leftContentPane.setBorder(BorderFactory.createEmptyBorder());
this.add(leftContentPane, BorderLayout.CENTER);
}
}
@Override
public Dimension getPreferredSize() {
if (formatPane == null) {
return super.getPreferredSize();
}
return formatPane.getPreferredSize();
}
/**
* 根据单元格样式填充面板设置
*
* @param style 单元格样式
*/
public void populateBean(Style style) {
formatPane.populateBean(style);
}
/**
* 根据面板设置获取修改后的单元格样式
*
* @param style 单元格当前样式
* @return 更新后的单元格样式
*/
public Style update(Style style) {
return formatPane.update(style);
}
@Override
public void removeAttributeChangeListener() {
super.removeAttributeChangeListener();
}
@Override
public void addAttributeChangeListener(AttributeChangeListener listener) {
oldListner = listener;
super.addAttributeChangeListener(listener);
}
/**
* 恢复使用AttributeChangeListener
*/
public void restoreAttributeChangeListener() {
super.addAttributeChangeListener(oldListner);
}
}

2
designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java

@ -191,7 +191,7 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple
String lastUsedBorderImageDirPath = history.getLastSelectedBorderImageDir();
File lastUsedBorderImageDir = StringUtils.isNotEmpty(lastUsedBorderImageDirPath) ? new File(lastUsedBorderImageDirPath) : null;
File inbuiltBorderImagesDir = new File(StableUtils.pathJoin(ProjectLibrary.getInstance().getLibHome(), ProjectConstants.ASSETS_NAME, "border_images"));
File inbuiltBorderImagesDir = new File(StableUtils.pathJoin(ProjectLibrary.getInstance().getLibHome(), ProjectConstants.LOCAL, ProjectConstants.BORDER_IMAGES));
if (lastUsedBorderImageDir!= null && lastUsedBorderImageDir.exists()) {
imageFileChooser.setCurrentDirectory(lastUsedBorderImageDir);

8
designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperlinkPane.java

@ -158,6 +158,14 @@ public class ReportletHyperlinkPane extends AbstractHyperLinkPane<ReportletHyper
protected boolean needRenamePane() {
return false;
}
public ChartNoRename(HashMap hyperLinkEditorMap, boolean needRenamePace) {
super(hyperLinkEditorMap, needRenamePace);
}
public ChartNoRename() {
super();
}
}
public ReportletHyperNorthPane getNorthPane() {

9
designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java

@ -24,9 +24,12 @@ import com.fr.design.javascript.jsapi.JSImplUpdateAction;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.IOUtils;
import com.fr.js.JavaScriptImpl;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
@ -36,10 +39,6 @@ import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
public class JSContentPane extends BasicPane {
protected RSyntaxTextArea contentTextArea;

13
designer-base/src/main/java/com/fr/design/javascript/JavaScriptImplPane.java

@ -14,21 +14,18 @@ import com.fr.design.javascript.jsapi.JSImplUpdateAction;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.scrollruler.ModLineBorder;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.js.JavaScriptImpl;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -149,8 +146,6 @@ public class JavaScriptImplPane extends AbstractHyperLinkPane<JavaScriptImpl> {
return importedJsPane;
}
/**
* 参数改变
*

18
designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java

@ -607,6 +607,24 @@ public class FRGUIPaneFactory {
return jp;
}
/**
* 创建垂直流布局水平填充面板
*
* @param isAlignLeft 是否左对齐
* @param align the alignment value
* @param hgap the horizontal gap between components
* @param vgap the vertical gap between components
* @param hfill 水平填充组件
* @return JPanel对象
*/
public static JPanel createVerticalFlowLayout_F_Pane(boolean isAlignLeft, int align, int hgap, int vgap, boolean hfill) {
JPanel jp = new JPanel();
VerticalFlowLayout layout = new VerticalFlowLayout(align, hgap, vgap, hfill);
layout.setAlignLeft(isAlignLeft);
jp.setLayout(layout);
return jp;
}
/**
* 创建边框面板L
*

46
designer-base/src/main/java/com/fr/design/layout/VerticalFlowLayout.java

@ -95,6 +95,15 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
*/
protected int vgap;
/**
* true: 水平填充组件
*
* @see #isHfill()
* @see #setHfill(boolean)
*/
protected boolean hfill;
/**
* Constructs a new <code>FlowLayout</code> with a centered alignment and a
* default 5-unit horizontal and vertical gap.
@ -135,6 +144,14 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
setAlignment(align);
}
public VerticalFlowLayout(int align, int hgap, int vgap, boolean fill) {
this.hgap = hgap;
this.vgap = vgap;
this.hfill = fill;
setAlignment(align);
}
/**
* Gets the alignment for this layout.
* Possible values are <code>FlowLayout.TOP</code>,
@ -219,6 +236,31 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
* @param name the name of the component
* @param comp the component to be added
*/
/**
* Gets the horizontal filling of components in the
* <code>Container</code>.The default is false.
*
* @return the horizontal filling of components in the
* <code>Container</code>
* @see #setHfill(boolean)
*/
public boolean isHfill() {
return hfill;
}
/**
* Sets the horizontal filling of components in the
* <code>Container</code>.The default is false.
*
* @param hfill the horizontal filling of components in the
* <code>Container</code>
* @see #isHfill()
*/
public void setHfill(boolean hfill) {
this.hfill = hfill;
}
@Override
public void addLayoutComponent(String name, Component comp) {
}
@ -379,6 +421,7 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
Insets insets = target.getInsets();
int maxlen = getMaxLen4LayoutContainer(target, insets);
int maxwidth = target.getWidth() - (insets.left + insets.right);
int nmembers = target.getComponentCount();
int x = getX4LayoutContainer(insets), y = getY4LayoutContainer(insets);
int roww = 0, start = 0;
@ -390,6 +433,9 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = getPreferredSize(target, m);
if (hfill) {
d.width = maxwidth;
}
m.setSize(d.width, d.height);
rs = dealWithDim4LayoutContainer(target, insets, d, x, y, roww, start, maxlen, i, ltr);

37
designer-base/src/main/java/com/fr/design/mainframe/AbsoluteMeasureUIMode.java

@ -0,0 +1,37 @@
package com.fr.design.mainframe;
import com.fr.base.AutoChangeLineProvider;
import com.fr.base.DefaultAutoChangeLine;
import com.fr.base.ScreenResolution;
import com.fr.design.fun.ReportLengthUNITProvider;
import com.fr.design.unit.UnitConvertUtil;
public class AbsoluteMeasureUIMode implements DesignerUIMode {
private static class AbsoluteMeasureUIModeHolder {
private static final AbsoluteMeasureUIMode absoluteMeasureUIMode = new AbsoluteMeasureUIMode();
}
private AbsoluteMeasureUIMode() {
}
public static AbsoluteMeasureUIMode getInstance() {
return AbsoluteMeasureUIModeHolder.absoluteMeasureUIMode;
}
@Override
public ReportLengthUNITProvider parseLengthUNIT(int unitType) {
return UnitConvertUtil.parseLengthUNIT(unitType);
}
@Override
public AutoChangeLineProvider getAutoChangeLineStrategy() {
return new DefaultAutoChangeLine();
}
@Override
public int getScreenResolution() {
return ScreenResolution.getScreenResolution();
}
}

4
designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java

@ -4,7 +4,7 @@ import com.fr.design.DesignState;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.constants.UIConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.NewTemplatePane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.imenu.UIMenuHighLight;
@ -87,7 +87,7 @@ public class CenterRegionContainerPane extends JPanel {
eastCenterPane.add(combineUp, BorderLayout.NORTH);
templateTabPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
templateTabPane.add(newWorkBookPane = getToolBarMenuDock().getNewTemplatePane(), BorderLayout.WEST);
templateTabPane.add(MutilTempalteTabPane.getInstance(), BorderLayout.CENTER);
templateTabPane.add(MultiTemplateTabPane.getInstance(), BorderLayout.CENTER);
eastCenterPane.add(templateTabPane, BorderLayout.CENTER);
eastPane.add(eastCenterPane, BorderLayout.CENTER);

54
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java

@ -21,7 +21,7 @@ import com.fr.design.event.TargetModifiedEvent;
import com.fr.design.event.TargetModifiedListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.SaveSomeTemplatePane;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.fun.OemProcessor;
@ -886,6 +886,54 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
layeredPane.repaint();
}
/**
* 激活模板
* <p>
* activateJTemplate需要模板存在openTemplate需要模板保存过该方法模板保存与未保存皆可激活模板如果关闭并且保存过会重新打开
*
* @param templatePath 模板路径 template.getPath()
*/
public void openOrActiveTemplate(String templatePath) {
//没保存过的模板如果要激活就要从当前历史模板列表里面找
String templateName = getTemplateNameFromPath(templatePath);
if (isTemplateNeverSaved(templatePath)) {
int index = HistoryTemplateListCache.getInstance().contains(templateName);
//如果历史模板列表中存在则激活
if (index != -1) {
DesignerContext.getDesignerFrame().activateJTemplate(HistoryTemplateListCache.getInstance().getTemplate(index));
}
} else {
DesignerContext.getDesignerFrame().openTemplate(FILEFactory.createFILE(templatePath));
}
}
/**
* 指定路径的模板是否保存过
*
* @param templatePath 模板路径 template.getPath()
* @return 如果模板没保存过则返回true
*/
private boolean isTemplateNeverSaved(String templatePath) {
FILE tplFile = FILEFactory.createFILE(templatePath);
//没保存过的模板获取到的templatePath所生成的FILE文件会不存在
return tplFile == null || !tplFile.exists() || StringUtils.isEmpty(templatePath);
}
/**
* 根据模板路径获取模板名称
* @param templatePath 模板路径 template.getPath()
* @return 模板名
*/
private String getTemplateNameFromPath(String templatePath) {
FILE tplFile = FILEFactory.createFILE(templatePath);
String templateName = StringUtils.EMPTY;
if (tplFile != null) {
templateName = tplFile.getName();
}
return templateName;
}
/**
* 当前模板 停用失败
*
@ -1062,7 +1110,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
// 新的form不往前兼容
if (inValidDesigner(jt)) {
this.addAndActivateJTemplate();
MutilTempalteTabPane.getInstance().setTemTemplate(
MultiTemplateTabPane.getInstance().setTemTemplate(
HistoryTemplateListCache.getInstance().getCurrentEditingTemplate());
} else {
this.addAndActivateJTemplate(jt);
@ -1231,6 +1279,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
/**
* 判断是否正在进行服务器配置
*
* @return boolean
*/
public boolean isServerConfig() {
@ -1239,6 +1288,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
/**
* 设置是否正在进行服务器配置
*
* @param serverConfig
*/
public void setServerConfig(boolean serverConfig) {

46
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java

@ -21,7 +21,7 @@ import com.fr.design.file.FileOperations;
import com.fr.design.file.FileToolbarStateChangeListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
@ -172,8 +172,8 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
tooBarPane.add(new UIMenuHighLight(), BorderLayout.SOUTH);
searchToolbarPane = new TemplateTreeSearchToolbarPane(toolBar);
searchToolbarPane.add(createUpToolBarPane(), BorderLayout.EAST);
searchToolbarPane.setPreferredSize(new Dimension(this.getWidth(), 23));
add(searchToolbarPane, BorderLayout.NORTH);
CardLayout card;
JPanel cardPane = new JPanel(card = new CardLayout());
@ -183,7 +183,6 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
card.show(cardPane, FILE);
TemplateTreePane.getInstance().setToolbarStateChangeListener(this);
add(cardPane, BorderLayout.CENTER);
stateChange();
}
@ -219,7 +218,6 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private JPanel createUpToolBarPane() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(toolBar, BorderLayout.CENTER);
if (WorkContext.getCurrent().isRoot()) {
rightToolBar = new UIToolbar(FlowLayout.RIGHT);
rightToolBar.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR));
@ -277,7 +275,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter());
HistoryTemplateListPane.getInstance().setCurrentEditingTemplate(jt);
//处理自动新建的模板
MutilTempalteTabPane.getInstance().doWithtemTemplate();
MultiTemplateTabPane.getInstance().doWithtemTemplate();
if (DesignerMode.isAuthorityEditing()) {
RolesAlreadyEditedPane.getInstance().refreshDockingView();
}
@ -461,6 +459,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
public void actionPerformed(ActionEvent e) {
// 交换层级
searchToolbarPane.switchPane(TemplateTreeSearchToolbarPane.SEARCH_PANE);
refreshRightToolBarByContentPaneType();
TemplateTreePane.getInstance().refreshDockingView();
TemplateTreeSearchManager.getInstance().switchToSearch(TemplateTreePane.getInstance().getTemplateFileTree());
}
@ -548,10 +547,10 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
for (JTemplate jTemplate : HistoryTemplateListCache.getInstance().getHistoryList()) {
if (ComparatorUtils.equals(jTemplate.getEditingFILE().getPath(), path)) {
if (isCurrentEditing) {
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
}
MutilTempalteTabPane.getInstance().closeFormat(jTemplate);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jTemplate);
MultiTemplateTabPane.getInstance().closeFormat(jTemplate);
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(jTemplate);
return;
}
}
@ -595,15 +594,36 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
}
}
/**
* 搜索状态下不显示rightToolBar
*/
public void refreshRightToolBarByContentPaneType() {
if (rightToolBar != null) {
if (StringUtils.equals(TemplateTreeSearchToolbarPane.contentPaneType, TemplateTreeSearchToolbarPane.SEARCH_PANE)) {
rightToolBar.setVisible(false);
}
}
}
public void refreshRightToolBarBy(FileNode fileNode) {
refreshRightToolBarByNode(fileNode);
refreshRightToolBarByContentPaneType();
}
/**
* 根据当前选中节点判断是否锁定状态
*
* @param fileNode 选中文件节点
*/
public void refreshRightToolBarByNode(FileNode fileNode) {
if (rightToolBar != null) {
boolean locked = fileNode != null
&& StringUtils.isNotEmpty(fileNode.getLock())
&& !ComparatorUtils.equals(fileNode.getLock(), fileNode.getUserID());
&& StringUtils.isNotEmpty(fileNode.getLock())
&& !ComparatorUtils.equals(fileNode.getLock(), fileNode.getUserID());
boolean visible = locked
&& WorkContext.getCurrent().isRoot()
&& WorkContext.getCurrent().get(LockInfoOperator.class).isUnLockable()
&& !WorkContext.getCurrent().get(LockInfoOperator.class).isTplUnLocked(fileNode.getEnvPath());
&& WorkContext.getCurrent().isRoot()
&& WorkContext.getCurrent().get(LockInfoOperator.class).isUnLockable()
&& !WorkContext.getCurrent().get(LockInfoOperator.class).isTplUnLocked(fileNode.getEnvPath());
rightToolBar.setVisible(visible);
}
}

17
designer-base/src/main/java/com/fr/design/mainframe/DesignerUIMode.java

@ -0,0 +1,17 @@
package com.fr.design.mainframe;
import com.fr.base.AutoChangeLineProvider;;
import com.fr.design.fun.ReportLengthUNITProvider;
/**
* 设计器上和展示相关配置
*/
public interface DesignerUIMode {
ReportLengthUNITProvider parseLengthUNIT(int unitType);
AutoChangeLineProvider getAutoChangeLineStrategy();
int getScreenResolution();
}

63
designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java

@ -1,19 +1,14 @@
package com.fr.design.mainframe;
import com.fr.base.AutoChangeLineProvider;
import com.fr.base.DefaultAutoChangeLine;
import com.fr.base.ScreenResolution;
import com.fr.design.fun.ReportLengthUNITProvider;
import com.fr.design.unit.UnitConvertUtil;
import com.fr.form.fit.NewUIModeAutoChangeLine;
import com.fr.general.ComparatorUtils;
import com.fr.stable.Constants;
/**
* Created by kerry on 2020-06-05
*/
public class DesignerUIModeConfig {
private DesignerUIMode mode = DesignerUIMode.ABSOLUTE_MEASURE_UI_MODE;
private DesignerUIMode mode = AbsoluteMeasureUIMode.getInstance();
private static class DesignerUIModeConfigHolder {
private static final DesignerUIModeConfig designerUIModeConfig = new DesignerUIModeConfig();
@ -34,21 +29,25 @@ public class DesignerUIModeConfig {
* @return boolean
*/
public boolean simulateWebUIMode() {
return ComparatorUtils.equals(DesignerUIMode.SIMULATE_WEB_UI_MODE, mode);
return ComparatorUtils.equals(SimulateWebUIMode.getInstance(), mode);
}
/**
* 设置新ui模式
*/
public void setSimulateWebUIMode() {
this.mode = DesignerUIMode.SIMULATE_WEB_UI_MODE;
this.mode = SimulateWebUIMode.getInstance();
}
public void setDesignerUIMode(DesignerUIMode mode) {
this.mode = mode;
}
/**
* 设置老ui模式
*/
public void setAbsoluteMeasureUIMode() {
this.mode = DesignerUIMode.ABSOLUTE_MEASURE_UI_MODE;
this.mode = AbsoluteMeasureUIMode.getInstance();
}
/**
@ -78,50 +77,4 @@ public class DesignerUIModeConfig {
return mode.getScreenResolution();
}
private enum DesignerUIMode {
ABSOLUTE_MEASURE_UI_MODE {
@Override
protected ReportLengthUNITProvider parseLengthUNIT(int unitType) {
return UnitConvertUtil.parseLengthUNIT(unitType);
}
@Override
public AutoChangeLineProvider getAutoChangeLineStrategy() {
return new DefaultAutoChangeLine();
}
@Override
protected int getScreenResolution() {
return ScreenResolution.getScreenResolution();
}
},
SIMULATE_WEB_UI_MODE {
@Override
protected ReportLengthUNITProvider parseLengthUNIT(int unitType) {
return new PXReportLengthUNIT();
}
@Override
public AutoChangeLineProvider getAutoChangeLineStrategy() {
return new NewUIModeAutoChangeLine();
}
@Override
protected int getScreenResolution() {
return Constants.DEFAULT_WEBWRITE_AND_SCREEN_RESOLUTION;
}
};
protected abstract ReportLengthUNITProvider parseLengthUNIT(int unitType);
public abstract AutoChangeLineProvider getAutoChangeLineStrategy();
protected abstract int getScreenResolution();
}
}

7
designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java

@ -354,12 +354,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
public void updateCellElementState(boolean isSelectedOneCell) {
PropertyItem cellElement = propertyItemMap.get(KEY_CELL_ELEMENT);
if (isSelectedOneCell) {
enableCellElementPane(cellElement);
} else { // 如果选中多个单元格,禁用单元格元素 tab
disableCellElementPane(cellElement);
refreshRightPane();
}
enableCellElementPane(cellElement);
}
// 禁用单元格元素tab

10
designer-base/src/main/java/com/fr/design/mainframe/JNullTemplate.java

@ -204,4 +204,14 @@ public class JNullTemplate extends JTemplate {
public int getToolBarHeight() {
return 0;
}
@Override
public String getPath() {
return null;
}
@Override
public void refreshToolArea() {
DesignerContext.getDesignerFrame().resetToolkitByPlus(this);
}
}

10
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -54,6 +54,7 @@ import com.fr.design.mainframe.toolbar.VcsScene;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.NameSeparator;
import com.fr.design.menu.ShortCut;
import com.fr.design.module.DesignModuleFactory;
import com.fr.design.preview.PagePreview;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.DesignUtils;
@ -110,6 +111,7 @@ import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.io.ByteArrayOutputStream;
import java.nio.file.Paths;
import java.util.Set;
import java.util.concurrent.Callable;
@ -327,7 +329,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
/**
* 为另存的模板创建新的模板id
*/
private void generateNewTemplateIdForSaveAs() {
protected void generateNewTemplateIdForSaveAs() {
generateTemplateId();
}
@ -1109,6 +1111,10 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
tplMenu.addShortCut(shortCuts4Authority());
}
//查找替换
tplMenu.addShortCut(new NameSeparator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Replace_Name_Separate")));
tplMenu.addShortCut((ShortCut) DesignModuleFactory.getITReplaceAction());
return new MenuDef[]{tplMenu};
}
@ -1615,7 +1621,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
return StringUtils.EMPTY;
}
String path = this.getEditingFILE().getPath();
CptxMetadata metadata = CptxFileUtils.getMetadata(path);
CptxMetadata metadata = Paths.get(path).isAbsolute() ? null : CptxFileUtils.getMetadata(path);
//是否是兼容模式,兼容模式下,设置了新引擎的cpt和cptx的后缀不同
if (metadata != null && metadata.isForceCpt()) {
if (path.endsWith(".cptx")) {

27
designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.gui.itree.filetree.TemplateFileTree;
import com.fr.stable.StringUtils;
@ -19,8 +20,6 @@ public class JTemplateNameHelper {
private static final int PREFIX_NUM = 3000;
private static short currentIndex = 0;// 此变量用于多次新建模板时,让名字不重复
public static String newTemplateNameByIndex(String prefix) {
// 用于获取左侧模板的文件名,如左侧已包含"WorkBook1.cpt, WorkBook12.cpt, WorkBook177.cpt"
// 那么新建的文件名将被命名为"WorkBook178.cpt",即取最大数+1
@ -37,13 +36,33 @@ public class JTemplateNameHelper {
reportNum.add(index);
}
}
//把当前编辑面板的模板名也加进来判断
addHistoryTemplateName2List(reportNum, prefix);
Collections.sort(reportNum);
BigInteger idx = reportNum.size() > 0 ? reportNum.get(reportNum.size() - 1).add(BigInteger.valueOf(1)) : BigInteger.valueOf(1);
idx = idx.add(BigInteger.valueOf(currentIndex));
currentIndex++;
return prefix + idx;
}
/**
* 将当前打开的模板列表的模板名处理一下加进来以便于获取左侧模板文件名与当前模板列表的最大值
*
* @param reportNum 存储后缀的列表
* @param prefix 前缀
*/
private static void addHistoryTemplateName2List(List<BigInteger> reportNum, String prefix) {
int len = HistoryTemplateListCache.getInstance().getHistoryCount();
for (int i = 0; i < len; i++) {
JTemplate<?, ?> jTemplate = HistoryTemplateListCache.getInstance().get(i);
if (jTemplate != null) {
String templateName = jTemplate.getTemplateName();
BigInteger index = getFileNameIndex(prefix, templateName);
if (index != null) {
reportNum.add(index);
}
}
}
}
/**
* @return java.lang.Integer WorkBook11.cpt则返回11如果没有找到index返回null
* @Description 返回文件名中的index

38
designer-base/src/main/java/com/fr/design/mainframe/SimulateWebUIMode.java

@ -0,0 +1,38 @@
package com.fr.design.mainframe;
import com.fr.base.AutoChangeLineProvider;
import com.fr.design.fun.ReportLengthUNITProvider;
import com.fr.form.fit.NewUIModeAutoChangeLine;
import com.fr.stable.Constants;
public class SimulateWebUIMode implements DesignerUIMode {
private static class SimulateWebUIModeHolder {
private static final SimulateWebUIMode simulateWebUIMode = new SimulateWebUIMode();
}
private SimulateWebUIMode() {
}
public static SimulateWebUIMode getInstance() {
return SimulateWebUIModeHolder.simulateWebUIMode;
}
@Override
public ReportLengthUNITProvider parseLengthUNIT(int unitType) {
return new PXReportLengthUNIT();
}
@Override
public AutoChangeLineProvider getAutoChangeLineStrategy() {
return new NewUIModeAutoChangeLine();
}
@Override
public int getScreenResolution() {
return Constants.DEFAULT_WEBWRITE_AND_SCREEN_RESOLUTION;
}
}

2
designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java

@ -1,6 +1,6 @@
package com.fr.design.mainframe.loghandler;
import com.finebi.cbb.base.tuple.Pair;
import com.fr.stable.collections.combination.Pair;
import com.fr.base.BaseUtils;
import com.fr.base.TRL;
import com.fr.design.file.HistoryTemplateListCache;

6
designer-base/src/main/java/com/fr/design/mainframe/manager/search/searcher/control/pane/TemplateTreeSearchToolbarPane.java

@ -39,6 +39,11 @@ public class TemplateTreeSearchToolbarPane extends JPanel implements TreeSearchS
public static final String SEARCH_PANE = "searchPane";
/**
* 判断工具栏是处于搜索栏还是非搜索栏
*/
public static String contentPaneType = "toolbarPane";
/**
* 工具栏
*/
@ -187,6 +192,7 @@ public class TemplateTreeSearchToolbarPane extends JPanel implements TreeSearchS
*/
public void switchPane(String name) {
cardLayout.show(contentPane, name);
contentPaneType = name;
}
public void setPlaceHolder(String placeHolder) {

5
designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/SidebarMobileBookMarkStyleCustomDefinePane.java

@ -17,6 +17,7 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.style.color.ColorSelectBox;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.form.ui.mobile.MobileBookMarkStyle;
import com.fr.form.ui.mobile.impl.SidebarMobileBookMarkStyle;
@ -161,7 +162,7 @@ public class SidebarMobileBookMarkStyleCustomDefinePane extends BasicBeanPane<Mo
normalBorderWidthComBox.setSelectedLineStyle(DEFAULT_STYLE.getBorderLineStyle());
normalBorderColorBox = new ColorSelectBox(COLUMN_WIDTH);
normalBorderColorBox.setSelectObject(DEFAULT_STYLE.getBorderColor());
normalFontNameComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
normalFontNameComboBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report());
normalFontNameComboBox.setSelectedItem(DEFAULT_STYLE.getSelectedFontFamily());
normalFontSizeComboBox = new UIComboBox(FRFontPane.FONT_SIZES);
normalFontSizeComboBox.setSelectedItem(DEFAULT_STYLE.getFontSize());
@ -248,7 +249,7 @@ public class SidebarMobileBookMarkStyleCustomDefinePane extends BasicBeanPane<Mo
selectedBorderWidthComBox.setSelectedLineStyle(DEFAULT_STYLE.getSelectedBorderLineStyle());
selectedBorderColorBox = new ColorSelectBox(COLUMN_WIDTH);
selectedBorderColorBox.setSelectObject(DEFAULT_STYLE.getSelectedBorderColor());
selectedFontNameComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
selectedFontNameComboBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report());
selectedFontNameComboBox.setSelectedItem(DEFAULT_STYLE.getSelectedFontFamily());
selectedFontSizeComboBox = new UIComboBox(FRFontPane.FONT_SIZES);
selectedFontSizeComboBox.setSelectedItem(DEFAULT_STYLE.getSelectedFontSize());

46
designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/topparam/MobileTopParamPane.java

@ -2,15 +2,31 @@ package com.fr.design.mainframe.mobile.ui.topparam;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.form.ui.mobile.impl.MobileTopParamStyle;
import javax.swing.*;
import java.awt.*;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MobileTopParamPane extends BasicBeanPane<MobileTopParamStyle> {
private UICheckBox autoCommitCheckBox;
private UISpinner maxDirectShowCountSpinner;
private UILabel showCountTextField;
private static final int MAX_VALUE_AUTO = 4;
private static final int MAX_VALUE = 3;
private static final int MIN_VALUE = 1;
private static final int DEFAULT_DIERTA = 1;
private static final int DEFAULT_VALUE = 4;
private static final int GAP = 2;
public MobileTopParamPane() {
this.init();
@ -21,19 +37,43 @@ public class MobileTopParamPane extends BasicBeanPane<MobileTopParamStyle> {
JPanel panel = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Plugin-TopParam_Setting"));
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
autoCommitCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Plugin-TopParam_AutoCommit"), true);
panel.add(autoCommitCheckBox);
maxDirectShowCountSpinner = new UISpinner(MIN_VALUE, MAX_VALUE_AUTO, DEFAULT_DIERTA, DEFAULT_VALUE);
showCountTextField = new UILabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_Show_Count"));
Component[][] components = {{autoCommitCheckBox},{showCountTextField, maxDirectShowCountSpinner}};
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p, p};
double[] columnSize = {p, f};
JPanel paraPane = TableLayoutHelper.createCommonTableLayoutPane(components, rowSize, columnSize, GAP);
panel.add(paraPane);
this.add(panel, BorderLayout.CENTER);
autoCommitCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!autoCommitCheckBox.isSelected()) {
maxDirectShowCountSpinner.setMaxValue(MAX_VALUE);
if (maxDirectShowCountSpinner.getValue() >= MAX_VALUE_AUTO) {
maxDirectShowCountSpinner.setValue(MAX_VALUE);
}
} else {
maxDirectShowCountSpinner.setMaxValue(MAX_VALUE_AUTO);
}
}
});
}
@Override
public void populateBean(MobileTopParamStyle topParamStyle) {
autoCommitCheckBox.setSelected(topParamStyle.isAutoCommit());
maxDirectShowCountSpinner.setValue(topParamStyle.getMaxDirectShowCount());
}
@Override
public MobileTopParamStyle updateBean() {
MobileTopParamStyle topParamStyle = new MobileTopParamStyle();
topParamStyle.setAutoCommit(autoCommitCheckBox.isSelected());
topParamStyle.setMaxDirectShowCount((int) maxDirectShowCountSpinner.getValue());
return topParamStyle;
}

3
designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/FontConfigPane.java

@ -5,6 +5,7 @@ import com.fr.base.Utils;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UIToggleButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.utils.DesignUtils;
import com.fr.general.FRFont;
import javax.swing.*;
@ -35,7 +36,7 @@ public class FontConfigPane extends JPanel {
private void init() {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));
fontFamily = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
fontFamily = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report());
Vector<Integer> integerList = new Vector<>();
for (int i = 1; i < 100; i++) {
integerList.add(i);

30
designer-base/src/main/java/com/fr/design/mainframe/platform/ServicePlatformAction.java

@ -0,0 +1,30 @@
package com.fr.design.mainframe.platform;
import com.fr.design.actions.UpdateAction;
import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import com.fr.log.FineLoggerFactory;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.net.URI;
/**
* 帮助-服务平台
*
* @author Destiny.Lin
* @version 11.0
* created by Destiny.Lin on 2022-12-14
*/
public class ServicePlatformAction extends UpdateAction {
public ServicePlatformAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Service_Platform_Title"));
this.setSmallIcon("/com/fr/design/images/platform/platform", false);
}
@Override
public void actionPerformed(ActionEvent e) {
BrowseUtils.browser(CloudCenter.getInstance().acquireUrlByKind("service.platform"));
}
}

9
designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java

@ -4,12 +4,14 @@ import com.fr.base.theme.FormTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemedComponentStyle;
import com.fr.base.theme.settings.ThemedFormBodyStyle;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.edit.ChartStyleFormEditPane;
import com.fr.design.mainframe.theme.edit.ComponentStyleEditPane;
import com.fr.design.mainframe.theme.edit.FormBodyStyleEditPane;
import com.fr.design.mainframe.theme.preview.FormThemePreviewPane;
import com.fr.design.mainframe.theme.processor.ThemePreviewPaneProcessor;
import javax.swing.JPanel;
@ -31,7 +33,11 @@ public class FormThemeProfilePane extends TemplateThemeProfilePane<FormTheme> {
}
@Override
public FormThemePreviewPane createThemePreviewPane() {
public TemplateThemePreviewPane<FormTheme> createThemePreviewPane() {
ThemePreviewPaneProcessor processor = ExtraDesignClassManager.getInstance().getSingle(ThemePreviewPaneProcessor.XML_TAG);
if (processor != null) {
return processor.createFormThemePreviewPane();
}
return new FormThemePreviewPane();
}
@ -61,6 +67,7 @@ public class FormThemeProfilePane extends TemplateThemeProfilePane<FormTheme> {
componentStyleSettingPane = new ComponentStyleEditPane();
addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane);
refreshExtraAdvancedPane();
}
@Override

10
designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java

@ -2,10 +2,11 @@ package com.fr.design.mainframe.theme;
import com.fr.base.theme.ReportTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.theme.edit.ReportBodyStyleEditPane;
import com.fr.design.mainframe.theme.preview.ReportThemePreviewPane;
import javax.swing.JPanel;
import com.fr.design.mainframe.theme.processor.ThemePreviewPaneProcessor;
/**
* @author Starryi
@ -20,7 +21,11 @@ public class ReportThemeProfilePane extends TemplateThemeProfilePane<ReportTheme
}
@Override
public ReportThemePreviewPane createThemePreviewPane() {
public TemplateThemePreviewPane<ReportTheme> createThemePreviewPane() {
ThemePreviewPaneProcessor processor = ExtraDesignClassManager.getInstance().getSingle(ThemePreviewPaneProcessor.XML_TAG);
if (processor != null) {
return processor.createReportThemePreviewPane();
}
return new ReportThemePreviewPane();
}
@ -44,6 +49,7 @@ public class ReportThemeProfilePane extends TemplateThemeProfilePane<ReportTheme
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Template_Background"), reportBodyStyleSettingPane);
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane());
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane());
refreshExtraAdvancedPane();
}
@Override

47
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java

@ -1,13 +1,14 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.FineColorFlushUtils;
import com.fr.base.theme.FineColorManager;
import com.fr.base.theme.FineColorSynchronizer;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.base.theme.settings.ThemedColorScheme;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.fun.TemplateThemePaneProvider;
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane;
import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.gui.frpane.UITabbedPane;
@ -23,6 +24,9 @@ import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import com.fr.design.mainframe.theme.ui.AutoCheckTextField;
import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField;
import com.fr.design.mainframe.theme.ui.BorderUtils;
import com.fr.general.GeneralContext;
import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
@ -34,7 +38,9 @@ import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author Starryi
@ -52,6 +58,7 @@ public abstract class TemplateThemeEditorPane<T extends TemplateTheme> extends J
protected ColorListPane colorListPane;
protected CellStyleListEditPane cellStyleSettingPane;
protected ChartStyleEditPane chartStyleSettingPane;
protected final List<BasicBeanPane<T>> extraPaneList = new ArrayList<>();
protected boolean isPopulating = false;
protected UITabbedPane uiTabbedPane;
@ -171,7 +178,7 @@ public abstract class TemplateThemeEditorPane<T extends TemplateTheme> extends J
uiTabbedPane = new UITabbedPane();
uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1));
container.add(uiTabbedPane, BorderLayout.CENTER);
initPluginListener();
return container;
}
@ -192,6 +199,33 @@ public abstract class TemplateThemeEditorPane<T extends TemplateTheme> extends J
});
uiTabbedPane.addTab(title, settingPane);
}
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
Set<TemplateThemePaneProvider<T>> providers = ExtraDesignClassManager.getInstance().getArray(TemplateThemePaneProvider.XML_TAG);
for (TemplateThemePaneProvider<T> provider : providers) {
insertShortCut(provider.getInsertPosition(extraPaneList.size()), provider.getTab());
}
for (BasicBeanPane<T> pane : extraPaneList) {
addCustomEditorPane(pane.getTitle(), pane);
}
}
private void insertShortCut(int index, BasicBeanPane<T> pane) {
int size = extraPaneList.size();
index = Math.min(index, size);
extraPaneList.add(index, pane);
}
private void initPluginListener() {
GeneralContext.listenPluginRunningChanged(new PluginEventListener() {
@Override
public void on(PluginEvent event) {
refreshExtraAdvancedPane();
}
}, pluginContext -> pluginContext.getRuntime().contain(TemplateThemePaneProvider.XML_TAG));
}
protected JPanel createCellStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
cellStyleSettingPane = new CellStyleListEditPane();
@ -223,6 +257,9 @@ public abstract class TemplateThemeEditorPane<T extends TemplateTheme> extends J
colorListPane.populate(theme.getColorScheme().getColors());
populateBean4CustomEditors(theme);
for (BasicBeanPane<T> pane : extraPaneList) {
pane.populateBean(theme);
}
isPopulating = false;
}
@ -243,7 +280,9 @@ public abstract class TemplateThemeEditorPane<T extends TemplateTheme> extends J
theme.setColorScheme(colorScheme);
updateBean4CustomEditors(theme);
for (BasicBeanPane<T> pane : extraPaneList) {
pane.updateBean(theme);
}
return theme;
}

3
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java

@ -13,6 +13,7 @@ import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.FRFont;
import com.fr.general.GeneralUtils;
@ -52,7 +53,7 @@ public class ChartFontPane extends BasicPane {
}
private void initState() {
fontNameComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
fontNameComboBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report());
fontSizeComboBox = new UIComboBox(FONT_SIZES);
bold = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png"));
italic = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png"));

23
designer-base/src/main/java/com/fr/design/mainframe/theme/processor/AbstractThemePreviewPaneProcessor.java

@ -0,0 +1,23 @@
package com.fr.design.mainframe.theme.processor;
import com.fr.stable.fun.mark.API;
/**
* @author Bruce.Deng
* @version 11.0
* Created by Bruce.Deng on 2023/2/14
*/
@API(level = ThemePreviewPaneProcessor.CURRENT_LEVEL)
public abstract class AbstractThemePreviewPaneProcessor implements ThemePreviewPaneProcessor {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
@Override
public int layerIndex() {
return DEFAULT_LAYER_INDEX;
}
}

35
designer-base/src/main/java/com/fr/design/mainframe/theme/processor/ThemePreviewPaneProcessor.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.theme.processor;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.ReportTheme;
import com.fr.design.mainframe.theme.TemplateThemePreviewPane;
import com.fr.stable.fun.mark.Immutable;
/**
* 主题样式预览界面接口
*
* @author Bruce.Deng
* @version 11.0
* Created by Bruce.Deng on 2023/2/14
*/
public interface ThemePreviewPaneProcessor extends Immutable {
String XML_TAG = "ThemePreviewPaneProcessor";
int CURRENT_LEVEL = 1;
/**
* 创建报表主题样式预览界面
*
* @return 报表主题样式预览界面
*/
TemplateThemePreviewPane<ReportTheme> createReportThemePreviewPane();
/**
* 创建决策报表主题样式预览界面
*
* @return 决策报表主题样式预览界面
*/
TemplateThemePreviewPane<FormTheme> createFormThemePreviewPane();
}

6
designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java

@ -5,7 +5,9 @@ import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyle;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.fun.DefaultValueAdjustProvider;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.DesignUtils;
import com.fr.report.cell.DefaultTemplateCellElement;
/**
@ -41,6 +43,10 @@ public class DefaultThemedTemplateCellElementCase {
cellElement.setStyle(DesignModeContext.isDuchampMode() ? nameStyle.getRealStyle() : nameStyle);
}
}
DefaultValueAdjustProvider adjustProvider = DesignUtils.getValueAdjust();
if (adjustProvider != null) {
adjustProvider.adjustCellElement(cellElement);
}
return cellElement;
}
}

18
designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java

@ -56,6 +56,7 @@ import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.locale.impl.SupportLocaleImpl;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.ToolBarNewTemplatePane;
import com.fr.design.mainframe.platform.ServicePlatformAction;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.SeparatorDef;
import com.fr.design.menu.ShortCut;
@ -571,22 +572,21 @@ public abstract class ToolBarMenuDock {
if (AlphaFineConfigManager.isALPHALicAvailable()) {
shortCuts.add(new AlphaFineAction());
}
shortCuts.add(new EnvDetectorAction());
//服务平台(仅针对中国大陆)
if (GeneralContext.getLocale().equals(Locale.CHINA)) {
shortCuts.add(new ServicePlatformAction());
}
shortCuts.add(SeparatorDef.DEFAULT);
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
OSSupportCenter.buildAction(objects -> shortCuts.add(new FineUIAction()), SupportOSImpl.FINEUI);
}
shortCuts.add(new AboutAction());
try {
if (DesignModuleFactory.getITReplaceAction() != null) {
shortCuts.add((ShortCut) DesignModuleFactory.getITReplaceAction().newInstance());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return shortCuts.toArray(new ShortCut[0]);
}

8
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java

@ -1,7 +1,7 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
@ -57,9 +57,9 @@ public class FileVersionCellEditor extends AbstractCellEditor implements TableCe
jt.stopEditing();
//只有模板路径一致时关闭当前模板
if (ComparatorUtils.equals(fileOfVersion, jt.getPath())) {
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MutilTempalteTabPane.getInstance().closeFormat(jt);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt);
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
MultiTemplateTabPane.getInstance().closeFormat(jt);
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(jt);
}
//再打开cache中的模板

8
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java

@ -5,7 +5,7 @@ import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.base.mode.DesignerMode;
import com.fr.design.dialog.BasicPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
@ -115,9 +115,9 @@ public class FileVersionsPanel extends BasicPane {
// 关闭当前打开的版本
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MutilTempalteTabPane.getInstance().closeFormat(jt);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt);
MultiTemplateTabPane.getInstance().setIsCloseCurrent(true);
MultiTemplateTabPane.getInstance().closeFormat(jt);
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(jt);
updateDesignerFrame(true);

3
designer-base/src/main/java/com/fr/design/mainframe/widget/MobileTabFontConfPane.java

@ -5,6 +5,7 @@ import com.fr.base.Utils;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UIToggleButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.utils.DesignUtils;
import com.fr.general.FRFont;
import javax.swing.Icon;
@ -38,7 +39,7 @@ public class MobileTabFontConfPane extends JPanel {
private void init() {
this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));
fontFamily = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
fontFamily = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report());
Vector<Integer> integerList = new Vector<Integer>();
for (int i = 1; i < 100; i++) {
integerList.add(i);

36
designer-base/src/main/java/com/fr/design/module/DesignModuleFactory.java

@ -1,6 +1,7 @@
package com.fr.design.module;
import com.fr.base.chart.BaseChartCollection;
import com.fr.design.actions.help.replace.ITReplaceOperator;
import com.fr.design.gui.chart.BaseChartPropertyPane;
import com.fr.design.gui.chart.MiddleChartComponent;
import com.fr.design.gui.chart.MiddleChartDialog;
@ -18,6 +19,7 @@ import com.fr.log.FineLoggerFactory;
import com.fr.plugin.solution.sandbox.collection.PluginSandboxCollections;
import com.fr.stable.StableUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Constructor;
import java.awt.Dialog;
@ -50,6 +52,7 @@ public class DesignModuleFactory {
private Class ITReplaceAction;
private Class formParaDesigner;
private Class paraPropertyPane;
private static ITReplaceOperator replaceHelper;
private Class<? extends HierarchyTreePane> formHierarchyPaneCls;
private Class<? extends BaseWidgetPropertyPane> widgetPropertyPane;
private Class buttonDetailPaneClass;
@ -127,8 +130,37 @@ public class DesignModuleFactory {
instance.ITReplaceAction = r;
}
public static Class getITReplaceAction() {
return instance.ITReplaceAction;
/**
* 获取查找替换
*
* @return ITReplaceAction
*/
@Nullable
public static Object getITReplaceAction() {
try {
if (instance.ITReplaceAction != null) {
return instance.ITReplaceAction.newInstance();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
/**
* 注册一下查找替换面板
* @param
*/
public static void registerReplace(ITReplaceOperator replace) {
replaceHelper = replace;
}
/**
* 获取查找替换面板的操作类
* @return
*/
public static ITReplaceOperator getReplaceOperator() {
return replaceHelper;
}
public static void registerParaPropertyPaneClass(Class p) {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save