Browse Source

Merge pull request #10708 in DESIGN/design from feature/x to release/11.0

* commit '1968b50a166ff5d5204e2984603e9dc9e09fc352':
  REPORT-83391 更新命名细节
  REPORT-83197【设计器】启动页性能优化 遗漏了两部分,代码修复下。
  REPORT-83391 顶部参数面板体验优化 交互更新,自动查找的时候最大值为4,最小值为1
  REPORT-83197【设计器】启动页性能优化 和 vito 讨论,这里的异步可以直接改成 invokeLater 省心省力, get
  REPORT-83197【设计器】启动页性能优化 将异步功能放到 UIUtil 中去执行。避免多线程问题
  REPORT-83391 顶部参数面板体验优化 交互更新,增加联动效果
  REPORT-83197【设计器】启动页性能优化 根据工具提示,修复代码质量
  REPORT-83197【设计器】启动页性能优化 根据工具提示,修复代码质量
  REPORT-83197【设计器】启动页性能优化 1、DesignerEnvManager 异步加载 2、插件更新功能优化, 改成异步 3、启动页启动时样式变化 4、设计器异步面板加载
  REPORT-75091 - 数据脱敏(报表) 【问题原因】处理新增代码行数太多的问题 【改动思路】将新增的UI面板拆出来 【review建议】
  REPORT-83391 顶部参数面板体验优化 修改.*导入
  REPORT-83391 顶部参数面板体验优化 修改下变量命名
  REPORT-83391 顶部参数面板体验优化
  REPORT-83625 适配BaseCriteria在cbb中的包名改动
  REPORT-75091 - 数据脱敏(报表) 【问题原因】上版本因为迭代延期屏蔽了代码功能入口 【改动思路】将屏蔽取消 【review建议】
release/11.0
superman 2 years ago
parent
commit
053318845e
  1. 279
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 30
      designer-base/src/main/java/com/fr/design/actions/core/ActionFactory.java
  3. 353
      designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java
  4. 120
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/PreviewTableDesensitizationPane.java
  5. 7
      designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java
  6. 9
      designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java
  7. 2
      designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java
  8. 46
      designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/topparam/MobileTopParamPane.java
  9. 3
      designer-base/src/main/java/com/fr/start/BaseDesigner.java
  10. 21
      designer-base/src/main/java/com/fr/start/common/DesignerStartupPool.java
  11. 118
      designer-base/src/main/java/com/fr/startup/ui/StartupLoadingPanel.java
  12. 121
      designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java
  13. 30
      designer-realize/src/main/java/com/fr/start/MainDesigner.java
  14. 37
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java
  15. 2
      designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java
  16. 50
      designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java
  17. 36
      designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java

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

@ -5,6 +5,7 @@ package com.fr.design;
import com.fr.base.BaseXMLUtils; import com.fr.base.BaseXMLUtils;
import com.fr.base.Utils; import com.fr.base.Utils;
import com.fr.collections.api.Callback;
import com.fr.design.actions.help.alphafine.AlphaFineConfigManager; import com.fr.design.actions.help.alphafine.AlphaFineConfigManager;
import com.fr.design.carton.SwitchForSwingChecker; import com.fr.design.carton.SwitchForSwingChecker;
import com.fr.design.constants.UIConstants; import com.fr.design.constants.UIConstants;
@ -21,8 +22,8 @@ import com.fr.design.locale.impl.ProductImproveMark;
import com.fr.design.login.DesignerLoginType; import com.fr.design.login.DesignerLoginType;
import com.fr.design.login.config.DesignerLoginConfigManager; import com.fr.design.login.config.DesignerLoginConfigManager;
import com.fr.design.mainframe.ComponentReuseNotifyUtil; 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.reuse.ComponentReuseNotificationInfo;
import com.fr.design.mainframe.simple.SimpleDesignerConfig;
import com.fr.design.mainframe.vcs.VcsConfigManager; import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.notification.SnapChatConfig; import com.fr.design.notification.SnapChatConfig;
import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.os.impl.SupportOSImpl;
@ -41,6 +42,12 @@ import com.fr.general.SupportLocale;
import com.fr.general.locale.LocaleCenter; import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark; import com.fr.general.locale.LocaleMark;
import com.fr.general.xml.GeneralXMLTools; 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.FineLoggerFactory;
import com.fr.log.LogHandler; import com.fr.log.LogHandler;
import com.fr.stable.CommonUtils; import com.fr.stable.CommonUtils;
@ -58,8 +65,10 @@ import com.fr.stable.xml.XMLTools;
import com.fr.stable.xml.XMLWriter; import com.fr.stable.xml.XMLWriter;
import com.fr.stable.xml.XMLableReader; import com.fr.stable.xml.XMLableReader;
import com.fr.start.common.DesignerStartupConfig; 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.appender.FileAppender;
import com.fr.third.apache.logging.log4j.core.layout.PatternLayout; 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.third.org.apache.commons.io.FilenameUtils;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.workspace.WorkContextCallback; import com.fr.workspace.WorkContextCallback;
@ -89,8 +98,13 @@ import java.util.Map.Entry;
/** /**
* The manager of Designer GUI. * 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 int MAX_SHOW_NUM = 10;
private static final String VERSION_80 = "80"; private static final String VERSION_80 = "80";
@ -105,20 +119,25 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
*/ */
public static final String DEFAULT_WORKSPACE_PATH = "fr.designer.workspace.default"; 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 static DesignerEnvManager designerEnvManager; // gui.
private String activationKey = null; private String activationKey = null;
private String logLocation = null; private String logLocation = null;
private Rectangle windowBounds = null; // window bounds. private Rectangle windowBounds = null; // window bounds.
private String DialogCurrentDirectory = null; private String DialogCurrentDirectory = null;
private String CurrentDirectoryPrefix = null; private String CurrentDirectoryPrefix = null;
private Map<String, List<String>> recentOpenedFileListMap = new HashMap<>(); private Map<String, List<String>> recentOpenedFileListMap = new HashMap<>();
private List<String> tempRecentOpenedFilePathList = new ArrayList<String>(); private List<String> tempRecentOpenedFilePathList = new ArrayList<String>();
private XmlElement<Map<String, List<String>>> recentOpenedMapping = SimpleXmlElement.of(recentOpenedFileListMap);
private boolean showPaintToolBar = true; private boolean showPaintToolBar = true;
private int maxNumberOrPreviewRow = 200; private int maxNumberOrPreviewRow = 200;
// name和Env的键值对
private Map<String, DesignerWorkspaceInfo> nameEnvMap = new ListMap<>(); private XmlElement<EnvConfiguration> envConfig = SimpleXmlElement.of(new EnvConfiguration());
// marks: 当前报表服务器名字
private String curEnvName = null;
private boolean showProjectPane = true; private boolean showProjectPane = true;
private boolean showDataPane = true; private boolean showDataPane = true;
//p:这是当前选择的数据库连接的名字,这个在新建数据源的时候用到. //p:这是当前选择的数据库连接的名字,这个在新建数据源的时候用到.
@ -181,7 +200,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
/** /**
* alphafine * alphafine
*/ */
private AlphaFineConfigManager alphaFineConfigManager = AlphaFineConfigManager.getInstance(); private XmlElement<AlphaFineConfigManager> alphaFineConfigManager;
/** /**
* 阅后即焚的配置项 * 阅后即焚的配置项
@ -230,7 +249,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private boolean propertiesUsable; private boolean propertiesUsable;
private SimpleDesignerConfig fvsDesignerConfig = SimpleDesignerConfig.getInstance("FvsDesignerConfig"); private XmlElement<SimpleDesignerConfig> fvsDesignerConfig = SimpleXmlElement.of(SimpleDesignerConfig.getInstance("FvsDesignerConfig"));
/** /**
* DesignerEnvManager. * DesignerEnvManager.
@ -244,6 +263,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
designerEnvManager = new DesignerEnvManager(); designerEnvManager = new DesignerEnvManager();
//REPORT-15332有一个国际化调用比较早,需要在这边就设置好locale,由于后台GeneralContext默认是China //REPORT-15332有一个国际化调用比较早,需要在这边就设置好locale,由于后台GeneralContext默认是China
GeneralContext.setLocale(designerEnvManager.getLanguage()); GeneralContext.setLocale(designerEnvManager.getLanguage());
try {
designerEnvManager.initElements(designerEnvManager.getDesignerEnvFile());
} catch (Exception retryEx) {
FineLoggerFactory.getLogger().debug("try async init DesignerEnvManager failed", retryEx);
try { try {
XMLTools.readFileXML(designerEnvManager, designerEnvManager.getDesignerEnvFile()); XMLTools.readFileXML(designerEnvManager, designerEnvManager.getDesignerEnvFile());
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
@ -252,6 +276,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
} }
}
// james:如果没有env定义,要设置一个默认的 // james:如果没有env定义,要设置一个默认的
if (needCheckEnv) { if (needCheckEnv) {
@ -273,7 +298,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
public static void checkNameEnvMap() { public static void checkNameEnvMap() {
if (designerEnvManager == null || designerEnvManager.nameEnvMap.size() > 0) {
if (designerEnvManager == null || designerEnvManager.getNameEnvMap().size() > 0) {
return; return;
} }
String installHome = StableUtils.getInstallHome(); String installHome = StableUtils.getInstallHome();
@ -443,8 +469,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
} }
// 清空前一个版本中的工作目录和最近打开 // 清空前一个版本中的工作目录和最近打开
nameEnvMap = new ListMap<String, DesignerWorkspaceInfo>(); getEnvConfig().setNameEnvMap(new ListMap<>());
curEnvName = null; getEnvConfig().setCurEnvName(null);
designerEnvManager.saveXMLFile(); designerEnvManager.saveXMLFile();
} }
@ -606,7 +632,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
String installHome = StableUtils.getInstallHome(); String installHome = StableUtils.getInstallHome();
String defaultenvPath = getDefaultenvPath(installHome); String defaultenvPath = getDefaultenvPath(installHome);
defaultenvPath = new File(defaultenvPath).getPath(); defaultenvPath = new File(defaultenvPath).getPath();
Iterator<Entry<String, DesignerWorkspaceInfo>> entryIt = nameEnvMap.entrySet().iterator(); Iterator<Entry<String, DesignerWorkspaceInfo>> entryIt = getNameEnvMap().entrySet().iterator();
while (entryIt.hasNext()) { while (entryIt.hasNext()) {
Entry<String, DesignerWorkspaceInfo> entry = entryIt.next(); Entry<String, DesignerWorkspaceInfo> entry = entryIt.next();
DesignerWorkspaceInfo env = entry.getValue(); DesignerWorkspaceInfo env = entry.getValue();
@ -627,8 +653,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
String installHome = StableUtils.getInstallHome(); String installHome = StableUtils.getInstallHome();
String defaultenvPath = getDefaultenvPath(installHome); String defaultenvPath = getDefaultenvPath(installHome);
defaultenvPath = new File(defaultenvPath).getPath(); defaultenvPath = new File(defaultenvPath).getPath();
if (nameEnvMap.size() >= 0) { if (getNameEnvMap().size() >= 0) {
Iterator<Entry<String, DesignerWorkspaceInfo>> entryIt = nameEnvMap.entrySet().iterator(); Iterator<Entry<String, DesignerWorkspaceInfo>> entryIt = getNameEnvMap().entrySet().iterator();
while (entryIt.hasNext()) { while (entryIt.hasNext()) {
Entry<String, DesignerWorkspaceInfo> entry = entryIt.next(); Entry<String, DesignerWorkspaceInfo> entry = entryIt.next();
DesignerWorkspaceInfo env = entry.getValue(); DesignerWorkspaceInfo env = entry.getValue();
@ -1019,21 +1045,21 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
public SimpleDesignerConfig getFvsDesignerConfig() { public SimpleDesignerConfig getFvsDesignerConfig() {
return fvsDesignerConfig; return fvsDesignerConfig.getValue();
} }
/** /**
* 返回环境名称迭代器 * 返回环境名称迭代器
*/ */
public Iterator<String> getEnvNameIterator() { public Iterator<String> getEnvNameIterator() {
return this.nameEnvMap.keySet().iterator(); return this.getNameEnvMap().keySet().iterator();
} }
/** /**
* 根据名称返回环境 * 根据名称返回环境
*/ */
public DesignerWorkspaceInfo getWorkspaceInfo(String name) { public DesignerWorkspaceInfo getWorkspaceInfo(String name) {
return this.nameEnvMap.get(name); return this.getNameEnvMap().get(name);
} }
/** /**
@ -1044,7 +1070,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
*/ */
public void putEnv(String name, DesignerWorkspaceInfo info) { public void putEnv(String name, DesignerWorkspaceInfo info) {
this.nameEnvMap.put(name, info); this.getNameEnvMap().put(name, info);
} }
/** /**
@ -1053,14 +1079,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
* @param name 环境的名字 * @param name 环境的名字
*/ */
public void removeEnv(String name) { public void removeEnv(String name) {
this.nameEnvMap.remove(name); this.getNameEnvMap().remove(name);
} }
/** /**
* 清除全部环境 * 清除全部环境
*/ */
public void clearAllEnv() { public void clearAllEnv() {
this.nameEnvMap.clear(); this.getNameEnvMap().clear();
} }
/** /**
@ -1082,14 +1108,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
* 返回当前环境的名称. * 返回当前环境的名称.
*/ */
public String getCurEnvName() { public String getCurEnvName() {
return this.curEnvName; return getEnvConfig().getCurEnvName();
} }
/** /**
* 设置当前环境的名称 * 设置当前环境的名称
*/ */
public void setCurEnvName(String envName) { public void setCurEnvName(String envName) {
this.curEnvName = envName; getEnvConfig().setCurEnvName(envName);
} }
/** /**
@ -1146,12 +1172,12 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
if (StringUtils.isEmpty(envName)) { if (StringUtils.isEmpty(envName)) {
return tempRecentOpenedFilePathList; return tempRecentOpenedFilePathList;
} else { } else {
if (!recentOpenedFileListMap.containsKey(envName)) { if (!recentOpenedMapping.getValue().containsKey(envName)) {
recentOpenedFileListMap.put(envName, tempRecentOpenedFilePathList); recentOpenedMapping.getValue().put(envName, tempRecentOpenedFilePathList);
} }
} }
return recentOpenedFileListMap.get(envName); return recentOpenedMapping.getValue().get(envName);
} }
/** /**
@ -1755,11 +1781,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
public AlphaFineConfigManager getAlphaFineConfigManager() { public AlphaFineConfigManager getAlphaFineConfigManager() {
return alphaFineConfigManager; return alphaFineConfigManager.getValue();
} }
public void setAlphaFineConfigManager(AlphaFineConfigManager alphaFineConfigManager) { public void setAlphaFineConfigManager(AlphaFineConfigManager alphaFineConfigManager) {
this.alphaFineConfigManager = alphaFineConfigManager; this.alphaFineConfigManager.setValue(alphaFineConfigManager);
} }
public boolean isImageCompress() { public boolean isImageCompress() {
@ -1802,6 +1828,100 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.layoutTemplateStyle = 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> * Read XML.<br>
* The method will be invoked when read data from XML file.<br> * The method will be invoked when read data from XML file.<br>
@ -1865,7 +1985,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
readComponentReuseNotificationInfo(reader); readComponentReuseNotificationInfo(reader);
} else if (name.equals(DesignerPushUpdateConfigManager.XML_TAG)) { } else if (name.equals(DesignerPushUpdateConfigManager.XML_TAG)) {
readDesignerPushUpdateAttr(reader); readDesignerPushUpdateAttr(reader);
} else if (name.equals(vcsConfigManager.XML_TAG)) { } else if (name.equals(VcsConfigManager.XML_TAG)) {
readVcsAttr(reader); readVcsAttr(reader);
} else if (DesignerPort.XML_TAG.equals(name)) { } else if (DesignerPort.XML_TAG.equals(name)) {
readDesignerPort(reader); readDesignerPort(reader);
@ -1873,7 +1993,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
readSnapChatConfig(reader); readSnapChatConfig(reader);
} else if (name.equals(DesignerLoginConfigManager.XML_TAG)) { } else if (name.equals(DesignerLoginConfigManager.XML_TAG)) {
readDesignerLoginAttr(reader); readDesignerLoginAttr(reader);
} else if (name.equals(fvsDesignerConfig.getName())) { } else if (name.equals(fvsDesignerConfig.getValue().getName())) {
readFvsDesignerConfig(reader); readFvsDesignerConfig(reader);
} else if (name.equals(SwitchForSwingChecker.XML_TAG)) { } else if (name.equals(SwitchForSwingChecker.XML_TAG)) {
readSwitchForSwingCheckerAttr(reader); readSwitchForSwingCheckerAttr(reader);
@ -1893,7 +2013,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
private void readAlphaFineAttr(XMLableReader reader) { 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) { private void readEnvDetectorConfig(XMLableReader reader) {
@ -1918,9 +2041,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private void readLayout(XMLableReader reader, String name) { private void readLayout(XMLableReader reader, String name) {
if ("LastEastRegionLayout".equals(name)) { if (LAST_EAST_REGION_LAYOUT.equals(name)) {
this.readLastEastRegionLayout(reader); this.readLastEastRegionLayout(reader);
} else if ("LastWestRegionLayout".equals(name)) { } else if (LAST_WEST_REGION_LAYOUT.equals(name)) {
this.readLastWestRegionLayout(reader); this.readLastWestRegionLayout(reader);
} }
} }
@ -2016,6 +2139,40 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
} }
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) { private void readEnvConfigMap(XMLableReader reader) {
String currentEnv = reader.getAttrAsString("currentEnv", StringUtils.EMPTY); String currentEnv = reader.getAttrAsString("currentEnv", StringUtils.EMPTY);
this.setCurEnvName(currentEnv); this.setCurEnvName(currentEnv);
@ -2050,6 +2207,13 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
private void readRecentOpenFileList(XMLableReader reader) { private void readRecentOpenFileList(XMLableReader reader) {
readRecentOpenFileList0(reader);
checkRecentOpenedFileNum();
}
private void readRecentOpenFileList0(XMLableReader reader) {
reader.readXMLObject(new XMLReadable() { reader.readXMLObject(new XMLReadable() {
@Override @Override
public void readXML(XMLableReader reader) { public void readXML(XMLableReader reader) {
@ -2081,7 +2245,6 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
} }
}); });
checkRecentOpenedFileNum();
} }
private void readDesignerPushUpdateAttr(XMLableReader reader) { private void readDesignerPushUpdateAttr(XMLableReader reader) {
@ -2151,7 +2314,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private void writeAlphaFineAttr(XMLPrintWriter writer) { private void writeAlphaFineAttr(XMLPrintWriter writer) {
if (this.alphaFineConfigManager != null) { if (this.alphaFineConfigManager != null) {
this.alphaFineConfigManager.writeXML(writer); this.alphaFineConfigManager.getValue().writeXML(writer);
} }
} }
@ -2228,10 +2391,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
writer.end(); writer.end();
writer.startTAG("EnvConfigMap"); writer.startTAG("EnvConfigMap");
if (this.curEnvName != null) { if (this.getCurEnvName() != null) {
writer.attr("currentEnv", this.curEnvName); 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()); writer.startTAG("EnvConfigElement").attr("name", entry.getKey());
DesignerWorkspaceInfo envConfig = entry.getValue(); DesignerWorkspaceInfo envConfig = entry.getValue();
GeneralXMLTools.writeXMLable(writer, envConfig, envConfig.getType().toString()); GeneralXMLTools.writeXMLable(writer, envConfig, envConfig.getType().toString());
@ -2440,11 +2603,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
private void readFvsDesignerConfig(XMLableReader reader) { private void readFvsDesignerConfig(XMLableReader reader) {
reader.readXMLObject(fvsDesignerConfig);
SimpleDesignerConfig config = fvsDesignerConfig.getValue();
reader.readXMLObject(config);
fvsDesignerConfig = SimpleXmlElement.of(config);
} }
private void writeFvsDesignerConfig(XMLPrintWriter writer) { private void writeFvsDesignerConfig(XMLPrintWriter writer) {
this.fvsDesignerConfig.writeXML(writer); this.fvsDesignerConfig.getValue().writeXML(writer);
} }
private void writeSwitchForSwingChecker(XMLPrintWriter writer) { private void writeSwitchForSwingChecker(XMLPrintWriter writer) {
@ -2479,4 +2645,39 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
public SnapChatConfig getSnapChatConfig() { public SnapChatConfig getSnapChatConfig() {
return snapChatConfig; 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;
}
}
} }

30
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.mainframe.JTemplate;
import com.fr.design.menu.MenuKeySet; import com.fr.design.menu.MenuKeySet;
import com.fr.design.selection.QuickEditor; import com.fr.design.selection.QuickEditor;
import com.fr.design.ui.util.UIUtil;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
@ -32,6 +33,7 @@ public class ActionFactory {
private static Set<Class<?>> actionClasses = new CopyOnWriteArraySet<>(); private static Set<Class<?>> actionClasses = new CopyOnWriteArraySet<>();
private static Set<Class<?>> floatActionClasses = new CopyOnWriteArraySet<>(); private static Set<Class<?>> floatActionClasses = new CopyOnWriteArraySet<>();
private static Class chartCollectionClass = null; private static Class chartCollectionClass = null;
/** /**
* 无需每次实例化的悬浮元素编辑器 * 无需每次实例化的悬浮元素编辑器
*/ */
@ -57,7 +59,6 @@ public class ActionFactory {
private ActionFactory() { private ActionFactory() {
} }
/** /**
* 元素编辑器释放模板对象 * 元素编辑器释放模板对象
*/ */
@ -70,6 +71,33 @@ public class ActionFactory {
} }
} }
/**
* 注册异步加载的单元格编辑器
* 首先放到 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);
}
}
});
}
/** /**
* 注册无需每次实例化的单元格元素编辑器 * 注册无需每次实例化的单元格元素编辑器

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

@ -3,17 +3,23 @@
*/ */
package com.fr.design.data.datapane.preview; package com.fr.design.data.datapane.preview;
import com.fr.base.BaseUtils;
import com.fr.base.TableData; import com.fr.base.TableData;
import com.fr.base.svg.IconUtils;
import com.fr.data.TableDataSource; import com.fr.data.TableDataSource;
import com.fr.data.desensitize.base.DesensitizationTableData;
import com.fr.data.impl.DBTableData; import com.fr.data.impl.DBTableData;
import com.fr.data.impl.EmbeddedTableData; import com.fr.data.impl.EmbeddedTableData;
import com.fr.data.impl.NameDataModel; import com.fr.data.impl.NameDataModel;
import com.fr.data.operator.DataOperator; import com.fr.data.operator.DataOperator;
import com.fr.design.DesignerEnvManager; import com.fr.design.DesignerEnvManager;
import com.fr.design.data.DesignTableDataManager; 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.BasicDialog;
import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.frpane.UITabbedPane;
@ -25,6 +31,7 @@ import com.fr.design.gui.itextfield.UINumberField;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.ui.util.UIUtil; import com.fr.design.ui.util.UIUtil;
import com.fr.function.TIME; import com.fr.function.TIME;
import com.fr.general.FRFont; import com.fr.general.FRFont;
@ -39,6 +46,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
@ -49,20 +57,20 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Font; import java.awt.Font;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
/** /**
* august PreviewTablePane一共提供5个共有的静态方法用来预览 * august PreviewTablePane一共提供5个共有的静态方法用来预览
*/ */
public class PreviewTablePane extends BasicPane { public class PreviewTablePane extends BasicPane {
private TableData tableData; private TableData tableData;
private DataModel dataModel; private DataModel dataModel;
private UINumberField maxPreviewNumberField; private UINumberField maxPreviewNumberField;
@ -78,6 +86,54 @@ public class PreviewTablePane extends BasicPane {
private static PreviewTablePane THIS; private static PreviewTablePane THIS;
private EmbeddedTableData previewTableData; 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() { public static final PreviewTablePane getInstance() {
if (THIS == null) { if (THIS == null) {
THIS = new PreviewTablePane(); THIS = new PreviewTablePane();
@ -87,91 +143,143 @@ public class PreviewTablePane extends BasicPane {
private PreviewTablePane() { private PreviewTablePane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout()); 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(); * 初始化northPane
this.add(previewNumberPanel, BorderLayout.NORTH); *
* @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(); JPanel currentPreviewPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
previewNumberPanel.add(currentPreviewPanel);
currentPreviewPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Current_Preview_Rows") + ":")); currentPreviewPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Current_Preview_Rows") + ":"));
currentRowsField = new UINumberField(); currentRowsField = new UINumberField();
currentPreviewPanel.add(currentRowsField); currentPreviewPanel.add(currentRowsField);
currentRowsField.setEditable(false); currentRowsField.setEditable(false);
currentRowsField.setColumns(4); currentRowsField.setColumns(4);
currentRowsField.setInteger(true); currentRowsField.setInteger(true);
// 最大行数
JPanel maxPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); JPanel maxPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
previewNumberPanel.add(maxPanel);
maxPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Datasource_Maximum_Number_of_Preview_Rows") + ":")); maxPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Datasource_Maximum_Number_of_Preview_Rows") + ":"));
maxPreviewNumberField = new UINumberField(); maxPreviewNumberField = new UINumberField();
maxPanel.add(maxPreviewNumberField); maxPanel.add(maxPreviewNumberField);
maxPreviewNumberField.setColumns(4); maxPreviewNumberField.setColumns(4);
maxPreviewNumberField.setInteger(true); maxPreviewNumberField.setInteger(true);
maxPreviewNumberField.setValue(DesignerEnvManager.getEnvManager().getMaxNumberOrPreviewRow());
maxPreviewNumberField.addActionListener(event -> {
DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager(); DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager();
maxPreviewNumberField.setValue(designerEnvManager.getMaxNumberOrPreviewRow()); designerEnvManager.setMaxNumberOrPreviewRow((int) ((UINumberField) event.getSource()).getValue());
maxPreviewNumberField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager();
designerEnvManager.setMaxNumberOrPreviewRow((int) ((UINumberField) evt.getSource()).getValue());
}
}); });
// 刷新按钮
initRefreshLabel();
Icon refreshImage = BaseUtils.readIcon("/com/fr/design/images/control/refresh.png"); previewNumberPanel.add(currentPreviewPanel);
refreshLabel = new UILabel(refreshImage); previewNumberPanel.add(maxPanel);
previewNumberPanel.add(refreshLabel); previewNumberPanel.add(refreshLabel);
refreshLabel.addMouseListener(new MouseAdapter() { return previewNumberPanel;
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));
}
} }
public void mouseExited(MouseEvent e) { private void initRefreshLabel() {
mouseEntered = false; Icon refreshImage = IconUtils.readIcon("/com/fr/design/images/control/refresh");
refreshLabel.setOpaque(false); refreshLabel = new UILabel(refreshImage);
refreshLabel.setBorder(BorderFactory.createEmptyBorder()); refreshLabel.addMouseListener(refreshLabelMouseAdapter);
} }
public void mousePressed(MouseEvent e) { /**
buttonPressed = true; * 初始化脱敏设置面板
refreshLabel.setBackground(java.awt.Color.lightGray); *
* @return
*/
private JComponent initDesensitizationPane() {
desensitizationPane = new PreviewTableDesensitizationPane(this);
return desensitizationPane;
} }
public void mouseReleased(MouseEvent e) { /**
buttonPressed = false; * 点击脱敏配置后的操作
if (mouseEntered) { */
refreshLabel.setBackground(java.awt.Color.WHITE); public void clickDesensitizationLabel() {
try { TableDataDesensitizationSettingPane settingPane = new TableDataDesensitizationSettingPane((DesensitizationTableData) tableData);
populate(tableData); settingPane.populateBean((DesensitizationTableData) tableData);
if (dataModel != null) { BasicDialog dialog = settingPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(PreviewTablePane.this), new DialogActionAdapter() {
setRowsLimitTableModel(); @Override
public void doOk() {
// 保存脱敏规则配置
settingPane.updateBean();
// 改变模板保存状态
JTemplate<?, ?> editingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (Objects.nonNull(editingTemplate)) {
editingTemplate.fireTargetModified(true);
} }
} catch (Exception e1) {
} }
@Override
public void doCancel() {
} }
}, BasicDialog.DEFAULT);
dialog.setVisible(true);
// 关闭预览页面
PreviewTablePane.this.dialog.setVisible(false);
} }
});
/**
* 设置脱敏设置的个数
*
* @param model
*/
private void setDesensitizationCount(TableModel model) {
desensitizationPane.setDesensitizationCount(isDesensitizeOpened(),
model instanceof DesensitizedPreviewTableModel ?
((DesensitizedPreviewTableModel) model).getDesensitizeColumnsCount() :
0);
}
/**
* 初始化centerPane
*
* @return
*/
private JComponent initCenterPane() {
preveiwTable = new CopyableJTable(new TableSorter()); preveiwTable = new CopyableJTable(new TableSorter());
preveiwTable.setRowSelectionAllowed(false); preveiwTable.setRowSelectionAllowed(false);
preveiwTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); preveiwTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
return new JScrollPane(preveiwTable);
}
this.add(new JScrollPane(preveiwTable), BorderLayout.CENTER); private void initDialog() {
if (this.dialog == null) { if (this.dialog == null) {
this.dialog = this.showWindow(new JFrame()); this.dialog = this.showWindow(new JFrame());
} }
}
private void initProgressBar() {
progressBar = new AutoProgressBar(this, Toolkit.i18nText("Fine-Design_Basic_Loading_Data"), "", 0, 100) { progressBar = new AutoProgressBar(this, Toolkit.i18nText("Fine-Design_Basic_Loading_Data"), "", 0, 100) {
@Override
public void doMonitorCanceled() { public void doMonitorCanceled() {
if (getWorker() != null) { if (getWorker() != null) {
getWorker().cancel(true); getWorker().cancel(true);
@ -182,7 +290,7 @@ public class PreviewTablePane extends BasicPane {
} }
public AutoProgressBar getProgressBar() { public AutoProgressBar getProgressBar() {
return this.progressBar; return PreviewTablePane.progressBar;
} }
@Override @Override
@ -223,9 +331,10 @@ public class PreviewTablePane extends BasicPane {
} }
/** /**
* elake:为预览表的columnIndex列着色. * 为预览表的columnIndex列着色.
* @param columnIndex *
* @param c * @param columnIndex 列索引值
* @param c 颜色
*/ */
private void setPreviewTableColumnColor(final int columnIndex, final Color c) { private void setPreviewTableColumnColor(final int columnIndex, final Color c) {
addLoadedListener(new LoadedEventListener() { addLoadedListener(new LoadedEventListener() {
@ -233,6 +342,7 @@ public class PreviewTablePane extends BasicPane {
public void fireLoaded() { public void fireLoaded() {
TableColumn column = preveiwTable.getColumnModel().getColumn(columnIndex); TableColumn column = preveiwTable.getColumnModel().getColumn(columnIndex);
DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer() { DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 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); JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
comp.setBackground(c); comp.setBackground(c);
@ -253,7 +363,7 @@ public class PreviewTablePane extends BasicPane {
getInstance().preveiwTable = new SortableJTable(new TableSorter()); getInstance().preveiwTable = new SortableJTable(new TableSorter());
getInstance().preveiwTable.setRowSelectionAllowed(false); getInstance().preveiwTable.setRowSelectionAllowed(false);
getInstance().preveiwTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); getInstance().preveiwTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
getInstance().progressBar.close(); PreviewTablePane.progressBar.close();
getInstance().repaint(); getInstance().repaint();
} }
@ -335,6 +445,7 @@ public class PreviewTablePane extends BasicPane {
private void previewTableDataSQL() throws Exception { private void previewTableDataSQL() throws Exception {
connectionBar = new AutoProgressBar(this, Toolkit.i18nText("Fine-Design_Basic_Utils_Now_Create_Connection"), "", 0, 100) { connectionBar = new AutoProgressBar(this, Toolkit.i18nText("Fine-Design_Basic_Utils_Now_Create_Connection"), "", 0, 100) {
@Override
public void doMonitorCanceled() { public void doMonitorCanceled() {
getWorker().cancel(true); getWorker().cancel(true);
getDialog().setVisible(false); getDialog().setVisible(false);
@ -349,7 +460,19 @@ public class PreviewTablePane extends BasicPane {
private void setPreviewTableColumnValue(final Graphics g) { private void setPreviewTableColumnValue(final Graphics g) {
for (int i = 0; i < preveiwTable.getColumnModel().getColumnCount(); i++) { for (int i = 0; i < preveiwTable.getColumnModel().getColumnCount(); i++) {
TableColumn column = preveiwTable.getColumnModel().getColumn(i); TableColumn column = preveiwTable.getColumnModel().getColumn(i);
DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer() { 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) { 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); JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Font f = table.getFont(); Font f = table.getFont();
@ -368,23 +491,18 @@ public class PreviewTablePane extends BasicPane {
return comp; return comp;
} }
}; };
column.setCellRenderer(cellRenderer);
}
} }
private void setWorker() { private void setWorker() {
worker = new SwingWorker<PreviewTableModel, Void>() { worker = new SwingWorker<TableModel, Void>() {
protected PreviewTableModel doInBackground() throws Exception {
@Override
protected TableModel doInBackground() throws Exception {
connectionBar.start(); connectionBar.start();
try { try {
if (tableData instanceof DBTableData) { testDBTableDataConnection(tableData);
boolean status = DataOperator.getInstance().testConnection(((DBTableData) tableData).getDatabase());
if (!status) {
throw new Exception(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"));
}
}
} finally { } finally {
// 将close操作放到EDT线程中 // 将close操作放到EDT线程中
UIUtil.invokeLaterIfNeeded(() -> connectionBar.close()); UIUtil.invokeLaterIfNeeded(() -> connectionBar.close());
@ -394,22 +512,20 @@ public class PreviewTablePane extends BasicPane {
// parameterInputDialog // parameterInputDialog
// update之后的parameters,转成一个parameterMap,用于预览TableData // update之后的parameters,转成一个parameterMap,用于预览TableData
PreviewTableModel previewModel = new PreviewTableModel(previewTableData.createDataModel(null), (int) maxPreviewNumberField.getValue()); PreviewTableModel previewModel = new PreviewTableModel(previewTableData.createDataModel(null), (int) maxPreviewNumberField.getValue());
for (int i = 0; i < previewTableData.getColumnCount(); i++) { if (TableDataPreviewDesensitizeManager.getInstance().needDesensitize(tableData)) {
Class<?> cls = previewTableData.getColumnClass(i); // 数据集预览脱敏
if (cls == Date.class || cls == TIME.class || cls == Timestamp.class) { previewModel = TableDataPreviewDesensitizeManager.getInstance().desensitizeTableModel(tableData, previewModel);
previewModel.dateIndexs.add(i);
}
} }
dealWithPreviewTableModelColumnClass(previewModel, previewTableData);
return previewModel; return previewModel;
} }
@Override
public void done() { public void done() {
try { try {
PreviewTableModel model = get(); TableModel model = get();
setModel(model); setPreviewTableModel(model);
setCurrentRows(model.getRowCount());
setPreviewTableColumnValue(getParent().getGraphics()); setPreviewTableColumnValue(getParent().getGraphics());
fireLoadedListener();
} catch (Exception e) { } catch (Exception e) {
if (!(e instanceof CancellationException)) { if (!(e instanceof CancellationException)) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
@ -424,6 +540,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);
}
}
}
/** /**
* 直接预览存储过程的一个返回数据集没有实际值和显示值 * 直接预览存储过程的一个返回数据集没有实际值和显示值
* *
@ -532,9 +678,62 @@ public class PreviewTablePane extends BasicPane {
} catch (Exception e) { } catch (Exception e) {
previewModel = new PreviewTableModel((int) maxPreviewNumberField.getValue()); previewModel = new PreviewTableModel((int) maxPreviewNumberField.getValue());
} }
setModel(previewModel); setPreviewTableModel(previewModel);
setCurrentRows(previewModel.getRowCount());
}
/**
* 切换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) {
setDesensitizationCount(previewTableModel);
setModel(previewTableModel);
setCurrentRows(previewTableModel.getRowCount());
fireLoadedListener(); fireLoadedListener();
}
/**
* 数据脱敏是否启用
*
* @return
*/
private boolean isDesensitizeOpened() {
return tableData instanceof DesensitizationTableData &&
((DesensitizationTableData) tableData).getDesensitizationConfig().isDesensitizeOpened();
} }
} }

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

@ -0,0 +1,120 @@
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;
}
public void setDesensitizationCount(boolean desensitizeOpen, int count) {
desensitizationLabel.setText(desensitizeOpen ?
DATA_DESENSITIZATION_CONFIG + LEFT_BRACKET + count + RIGHT_BRACKET + COUNT :
DATA_DESENSITIZATION_CONFIG);
}
}

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

@ -1,6 +1,7 @@
package com.fr.design.env; package com.fr.design.env;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
import com.fr.stable.CommonUtils;
import com.fr.stable.CoreConstants; import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils; import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
@ -98,6 +99,12 @@ public class LocalDesignerWorkspaceInfo implements DesignerWorkspaceInfo {
@Override @Override
public boolean checkValid(){ public boolean checkValid(){
// 如果当前是 debug 模式,就不检测这个逻辑
if (CommonUtils.isDebug()) {
return true;
}
File file = new File(this.path); File file = new File(this.path);
//判断不是文件夹/路径不在WEB-INF下/代码启动三种情况 //判断不是文件夹/路径不在WEB-INF下/代码启动三种情况
if(!file.isDirectory() || !ComparatorUtils.equals(file.getName(), "WEB-INF") || this.path.startsWith(".")) { if(!file.isDirectory() || !ComparatorUtils.equals(file.getName(), "WEB-INF") || this.path.startsWith(".")) {

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

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

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

@ -1,6 +1,6 @@
package com.fr.design.mainframe.loghandler; 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.BaseUtils;
import com.fr.base.TRL; import com.fr.base.TRL;
import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListCache;

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.beans.BasicBeanPane;
import com.fr.design.gui.icheckbox.UICheckBox; 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.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory; 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 com.fr.form.ui.mobile.impl.MobileTopParamStyle;
import javax.swing.*; import javax.swing.JPanel;
import java.awt.*; 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> { public class MobileTopParamPane extends BasicBeanPane<MobileTopParamStyle> {
private UICheckBox autoCommitCheckBox; 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() { public MobileTopParamPane() {
this.init(); this.init();
@ -21,19 +37,43 @@ public class MobileTopParamPane extends BasicBeanPane<MobileTopParamStyle> {
JPanel panel = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Plugin-TopParam_Setting")); JPanel panel = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Plugin-TopParam_Setting"));
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
autoCommitCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Plugin-TopParam_AutoCommit"), true); 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); 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 @Override
public void populateBean(MobileTopParamStyle topParamStyle) { public void populateBean(MobileTopParamStyle topParamStyle) {
autoCommitCheckBox.setSelected(topParamStyle.isAutoCommit()); autoCommitCheckBox.setSelected(topParamStyle.isAutoCommit());
maxDirectShowCountSpinner.setValue(topParamStyle.getMaxDirectShowCount());
} }
@Override @Override
public MobileTopParamStyle updateBean() { public MobileTopParamStyle updateBean() {
MobileTopParamStyle topParamStyle = new MobileTopParamStyle(); MobileTopParamStyle topParamStyle = new MobileTopParamStyle();
topParamStyle.setAutoCommit(autoCommitCheckBox.isSelected()); topParamStyle.setAutoCommit(autoCommitCheckBox.isSelected());
topParamStyle.setMaxDirectShowCount((int) maxDirectShowCountSpinner.getValue());
return topParamStyle; return topParamStyle;
} }

3
designer-base/src/main/java/com/fr/start/BaseDesigner.java

@ -39,6 +39,7 @@ import org.jetbrains.annotations.Nullable;
import java.awt.Window; import java.awt.Window;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
/** /**
@ -136,7 +137,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock {
DesignerFrame df = DesignerContext.getDesignerFrame(); DesignerFrame df = DesignerContext.getDesignerFrame();
isException = openFile(df, isException, file); isException = openFile(df, isException, file);
df.fireDesignerOpened(); df.fireDesignerOpened();
FineLoggerFactory.getLogger().debug("show designer cost {} ms", DesignerStartupContext.getRecorder().getTime()); FineLoggerFactory.getLogger().info("Designer showed.Time used {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS));
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
if (!isException) { if (!isException) {

21
designer-base/src/main/java/com/fr/start/common/DesignerStartupPool.java

@ -4,17 +4,36 @@ import com.fr.concurrent.FineExecutors;
import com.fr.concurrent.NamedThreadFactory; import com.fr.concurrent.NamedThreadFactory;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/** /**
* created by Harrison on 2022/07/03 * created by Harrison on 2022/07/03
**/ **/
public class DesignerStartupPool { public class DesignerStartupPool {
private static final Executor COMMON_EXECUTOR = FineExecutors.newCachedThreadPool(new NamedThreadFactory("startup-common")); private static final int MAX_THREAD_COUNT = Runtime.getRuntime().availableProcessors() * 2;
private static final Executor COMMON_EXECUTOR = FineExecutors.newThreadPoolExecutor(MAX_THREAD_COUNT, MAX_THREAD_COUNT, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("startup-common"));
private static final Executor DESIGNER_EXECUTOR = FineExecutors.newThreadPoolExecutor(MAX_THREAD_COUNT, MAX_THREAD_COUNT, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("startup-designer"));
/**
*
* @return 启动通用线程池
*/
public static Executor common() { public static Executor common() {
return COMMON_EXECUTOR; return COMMON_EXECUTOR;
} }
/**
*
* @return 启动设计器线程池
*/
public static Executor designer() {
return DESIGNER_EXECUTOR;
}
} }

118
designer-base/src/main/java/com/fr/startup/ui/StartupLoadingPanel.java

@ -0,0 +1,118 @@
package com.fr.startup.ui;
import com.fr.concurrent.FineExecutors;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.gui.iprogressbar.ProgressDialog;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.util.UIUtil;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.module.ModuleEvent;
import java.awt.Frame;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 启动加载面板
*
* @author Harrison
* @version 11.0
* created by Harrison on 2022/11/08
**/
public class StartupLoadingPanel {
/**
* 每次更新的步伐
*/
private static final int STEP = 1;
/**
* 40ms更新进度
*/
private static final int STEP_HEARTBEAT = 40;
private final Listener<String> MODULE_LISTENER = new Listener<String>() {
@Override
public void on(Event event, String param) {
moduleId = param;
}
};
private ProgressDialog progressDialog;
private String moduleId;
private int progress;
public StartupLoadingPanel(Frame frame) {
this.progressDialog = new ProgressDialog(frame);
this.moduleId = Toolkit.i18nText("Fine-Design_Basic_Initializing");
initListeners();
}
/**
* 隐藏
*/
public void hide() {
this.progress = progressDialog.getProgressMaximum();
}
/**
* 展示
*/
public void show() {
final ScheduledExecutorService scheduler = FineExecutors.newScheduledThreadPool(1,
new NamedThreadFactory("StartupLoadingPanel"));
scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
UIUtil.invokeAndWaitIfNeeded(() -> {
if (isComplete()) {
scheduler.shutdown();
progressDialog.dispose();
resetListeners();
return;
}
if (!progressDialog.isVisible()) {
progressDialog.setVisible(true);
String moduleId = getModuleId();
progressDialog.updateLoadingText(moduleId);
}
progressDialog.setProgressValue(incrementProgress());
});
}
}, 0, STEP_HEARTBEAT, TimeUnit.MILLISECONDS);
}
private void initListeners() {
EventDispatcher.listen(ModuleEvent.MajorModuleStarting, MODULE_LISTENER);
}
private void resetListeners() {
EventDispatcher.stopListen(MODULE_LISTENER);
}
private boolean isComplete() {
return this.progress >= progressDialog.getProgressMaximum();
}
private String getModuleId() {
return this.moduleId;
}
private int incrementProgress() {
if (progress != progressDialog.getProgressMaximum()) {
progress += STEP;
}
return progress;
}
}

121
designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java

@ -2,7 +2,6 @@ package com.fr.startup.ui;
import com.fr.base.svg.IconUtils; import com.fr.base.svg.IconUtils;
import com.fr.design.DesignerEnvManager; import com.fr.design.DesignerEnvManager;
import com.fr.design.components.loading.LoadingPane;
import com.fr.design.dialog.UIExpandDialog; import com.fr.design.dialog.UIExpandDialog;
import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
@ -25,7 +24,6 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneConstants;
@ -34,7 +32,6 @@ import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FlowLayout; import java.awt.FlowLayout;
import java.awt.Font; import java.awt.Font;
@ -84,16 +81,7 @@ public class StartupPageWindow extends JFrame {
private JPanel body; private JPanel body;
private LoadingPane loadingPane = new LoadingPane(); private StartupLoadingPanel loadingPanel;
private JLayeredPane layeredPane = new JLayeredPane() {
@Override
public void doLayout() {
for (Component comp : getComponents()) {
comp.setBounds(0, 0, getWidth(), getHeight());
}
}
};
public StartupPageWindow(StartupPageModel pageModel) { public StartupPageWindow(StartupPageModel pageModel) {
@ -101,39 +89,47 @@ public class StartupPageWindow extends JFrame {
setLayout(new BorderLayout()); setLayout(new BorderLayout());
this.body = FRGUIPaneFactory.createBorderLayout_S_Pane(); initCenter(pageModel);
this.body.setBackground(new Color(0, 0, 0, 0));
// Header
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Select_Workspace"));
Font font = label.getFont();
Font titleFont = font.deriveFont(font.getStyle(), TITLE_FONT_SIZE);
label.setFont(titleFont);
JPanel headerPanel = new JPanel();
LayoutManager centerFlowLayout = FRGUIPaneFactory.createCenterFlowLayout();
headerPanel.setLayout(centerFlowLayout);
headerPanel.add(label);
headerPanel.setBackground(new Color(0, 0, 0, 0));
this.body.add(headerPanel, BorderLayout.NORTH);
// Workspace-description loadingPanel = new StartupLoadingPanel(this);
this.workspacePanel = generateWorkspacePanel(pageModel);
this.body.add(workspacePanel, BorderLayout.CENTER);
workspacePanel.setSelectWorkspaceRunnable(new Runnable() { // Workspace-detail
@Override setSize(SCREEN_SIZE);
public void run() { setDefaultTitle();
JPanel newPanel = generateRecentOpenPanel(pageModel); addDefaultListeners();
body.remove(recentOpenPanel);
recentOpenPanel = newPanel;
body.add(recentOpenPanel, BorderLayout.SOUTH);
validate();
repaint(); repaint();
validate();
revalidate();
setFullScreen();
}
private void initCenter(StartupPageModel pageModel) {
initHeaderPanel();
initWorkspacePanel(pageModel);
initRecentOpenPanel(pageModel);
initContentPanel();
}
private void initHeaderPanel() {
this.body = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.body.setBackground(new Color(0, 0, 0, 0));
JPanel headerPanel = createHeader();
this.body.add(headerPanel, BorderLayout.NORTH);
} }
});
private void initRecentOpenPanel(StartupPageModel pageModel) {
this.recentOpenPanel = generateRecentOpenPanel(pageModel); this.recentOpenPanel = generateRecentOpenPanel(pageModel);
this.body.add(recentOpenPanel, BorderLayout.SOUTH); this.body.add(recentOpenPanel, BorderLayout.SOUTH);
}
private void initContentPanel() {
this.contentPane = new JPanel() { this.contentPane = new JPanel() {
@Override @Override
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
@ -145,24 +141,43 @@ public class StartupPageWindow extends JFrame {
this.contentPane.add(this.body, BorderLayout.CENTER); this.contentPane.add(this.body, BorderLayout.CENTER);
this.contentPane.setPreferredSize(this.body.getPreferredSize()); this.contentPane.setPreferredSize(this.body.getPreferredSize());
this.layeredPane.setName("layered-pane"); add(this.contentPane, BorderLayout.CENTER);
this.layeredPane.add(this.contentPane, CONTENT_LAYER); }
this.layeredPane.add(this.loadingPane, TRANSPARENT_LAYER);
this.layeredPane.moveToFront(this.contentPane);
add(this.layeredPane, BorderLayout.CENTER); private void initWorkspacePanel(StartupPageModel pageModel) {
// Workspace-detail // Workspace-description
setSize(SCREEN_SIZE); this.workspacePanel = generateWorkspacePanel(pageModel);
setDefaultTitle(); this.body.add(workspacePanel, BorderLayout.CENTER);
addDefaultListeners();
repaint(); workspacePanel.setSelectWorkspaceRunnable(new Runnable() {
@Override
public void run() {
JPanel newPanel = generateRecentOpenPanel(pageModel);
body.remove(recentOpenPanel);
recentOpenPanel = newPanel;
body.add(recentOpenPanel, BorderLayout.SOUTH);
validate(); validate();
revalidate(); repaint();
}
});
}
setFullScreen(); @NotNull
private static JPanel createHeader() {
// Header
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Select_Workspace"));
Font font = label.getFont();
Font titleFont = font.deriveFont(font.getStyle(), TITLE_FONT_SIZE);
label.setFont(titleFont);
JPanel headerPanel = new JPanel();
LayoutManager centerFlowLayout = FRGUIPaneFactory.createCenterFlowLayout();
headerPanel.setLayout(centerFlowLayout);
headerPanel.add(label);
headerPanel.setBackground(new Color(0, 0, 0, 0));
return headerPanel;
} }
private void setFullScreen() { private void setFullScreen() {
@ -215,8 +230,7 @@ public class StartupPageWindow extends JFrame {
private void enterWorkspace(Runnable action) { private void enterWorkspace(Runnable action) {
loadingPane.start(); loadingPanel.show();
layeredPane.moveToFront(loadingPane);
SwingWorker<Void, Void> task = new SwingWorker<Void, Void>() { SwingWorker<Void, Void> task = new SwingWorker<Void, Void>() {
@Override @Override
protected Void doInBackground() throws Exception { protected Void doInBackground() throws Exception {
@ -245,9 +259,8 @@ public class StartupPageWindow extends JFrame {
.setVisible(true); .setVisible(true);
}); });
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
layeredPane.moveToFront(contentPane);
} finally { } finally {
loadingPane.stop(); loadingPanel.hide();
} }
} }
}; };

30
designer-realize/src/main/java/com/fr/start/MainDesigner.java

@ -72,17 +72,15 @@ import com.fr.start.common.SplashCommon;
import com.fr.start.module.StartupArgs; import com.fr.start.module.StartupArgs;
import com.fr.start.preload.PreLoadService; import com.fr.start.preload.PreLoadService;
import com.fr.start.server.ServerTray; import com.fr.start.server.ServerTray;
import com.fr.third.org.apache.commons.lang3.time.StopWatch;
import com.fr.van.chart.map.server.ChartMapEditorAction; import com.fr.van.chart.map.server.ChartMapEditorAction;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import javax.swing.JPanel;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.border.MatteBorder; import javax.swing.border.MatteBorder;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FlowLayout; import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Insets; import java.awt.Insets;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@ -119,11 +117,11 @@ public class MainDesigner extends BaseDesigner {
* @param args 参数 * @param args 参数
*/ */
public static void main(String[] args) { public static void main(String[] args) {
StopWatch watch = new StopWatch();
watch.start();
DesignerStartupContext.getRecorder().start(); DesignerStartupContext.getRecorder().start();
showSplash();
DesignerEnvManager.getEnvManager();
startPreload0(); startPreload0();
DesignerLifecycleMonitorContext.getMonitor().beforeStart(); DesignerLifecycleMonitorContext.getMonitor().beforeStart();
@ -143,7 +141,7 @@ public class MainDesigner extends BaseDesigner {
}); });
Module designerRoot = ModuleContext.parseRoot("designer-startup.xml"); Module designerRoot = ModuleContext.parseRoot("designer-startup.xml");
FineLoggerFactory.getLogger().debug("designer-startup prepared cost {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS)); FineLoggerFactory.getLogger().debug("Designer prepared.Time used {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS));
//传递启动参数 //传递启动参数
designerRoot.setSingleton(StartupArgs.class, new StartupArgs(args)); designerRoot.setSingleton(StartupArgs.class, new StartupArgs(args));
try { try {
@ -156,8 +154,7 @@ public class MainDesigner extends BaseDesigner {
//初始化一下serverTray //初始化一下serverTray
ServerTray.init(); ServerTray.init();
} }
FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", watch.getTime()); FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS));
watch.stop();
SwitchForSwingChecker.initThreadMonitoring(); SwitchForSwingChecker.initThreadMonitoring();
} }
@ -168,7 +165,9 @@ public class MainDesigner extends BaseDesigner {
private static void startPreload1() { private static void startPreload1() {
CompletableFuture<Void> initLookAndFeel = CompletableFuture.runAsync(DesignUtils::initLookAndFeel); CompletableFuture<Void> initLookAndFeel = CompletableFuture.runAsync(DesignUtils::initLookAndFeel);
PreLoadService.getInstance().addFuture(initLookAndFeel); PreLoadService.getInstance().addUIFuture(initLookAndFeel);
showSplash();
} }
/** /**
@ -189,17 +188,12 @@ public class MainDesigner extends BaseDesigner {
action.run(); action.run();
} }
}); });
Runnable fontLoad = () -> {
Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
};
PreLoadService.getInstance().addRunnable(fontLoad);
} }
private static void showSplash() { private static void showSplash() {
// 快快显示启动画面 // 快快显示启动画面
UIUtil.invokeAndWaitIfNeeded(new Runnable() { UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override @Override
public void run() { public void run() {
SplashContext.getInstance().registerSplash(createSplash()); SplashContext.getInstance().registerSplash(createSplash());

37
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -146,13 +146,14 @@ import com.fr.start.common.DesignerStartupPool;
import com.fr.task.Once; import com.fr.task.Once;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.xml.ReportXMLUtils; import com.fr.xml.ReportXMLUtils;
import javax.swing.SwingWorker;
import java.awt.Image; import java.awt.Image;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import javax.swing.SwingWorker;
/** /**
* Created by juhaoyu on 2018/1/31. * Created by juhaoyu on 2018/1/31.
@ -192,6 +193,8 @@ public class DesignerActivator extends Activator implements Prepare {
CompletableFuture<Void> mainDesignerPrepare = CompletableFuture.runAsync(this::designerModuleStart, DesignerStartupPool.common()); CompletableFuture<Void> mainDesignerPrepare = CompletableFuture.runAsync(this::designerModuleStart, DesignerStartupPool.common());
CompletableFuture<Void> extendDesignerPrepare = CompletableFuture.runAsync(this::designerExtendStart, DesignerStartupPool.common());
CompletableFuture<Void> otherFeaturesPrepare = CompletableFuture.runAsync(() -> { CompletableFuture<Void> otherFeaturesPrepare = CompletableFuture.runAsync(() -> {
startBBSLoginAuthServer(); startBBSLoginAuthServer();
migrateBBSInfoFromFineDB(); migrateBBSInfoFromFineDB();
@ -207,7 +210,7 @@ public class DesignerActivator extends Activator implements Prepare {
storePassport(); storePassport();
AlphaFineHelper.switchConfig4Locale(); AlphaFineHelper.switchConfig4Locale();
RecoverManager.register(new RecoverForDesigner()); RecoverManager.register(new RecoverForDesigner());
}); }, DesignerStartupPool.common());
CompletableFuture<Void> resourcePrepare = CompletableFuture.runAsync(() -> { CompletableFuture<Void> resourcePrepare = CompletableFuture.runAsync(() -> {
pushUpdateTask.run(); pushUpdateTask.run();
@ -218,7 +221,7 @@ public class DesignerActivator extends Activator implements Prepare {
}, DesignerStartupPool.common()); }, DesignerStartupPool.common());
CompletableFuture CompletableFuture
.allOf(mainDesignerPrepare, themeConfigPrepare, otherFeaturesPrepare, resourcePrepare) .allOf(mainDesignerPrepare, extendDesignerPrepare, themeConfigPrepare, otherFeaturesPrepare, resourcePrepare)
.join(); .join();
} }
@ -272,8 +275,12 @@ public class DesignerActivator extends Activator implements Prepare {
designerRegister(); designerRegister();
InformationCollector.getInstance().collectStartTime(); }
private void designerExtendStart() {
SharableManager.start(); SharableManager.start();
InformationCollector.getInstance().collectStartTime();
GuideRegister.register(); GuideRegister.register();
} }
@ -413,16 +420,16 @@ public class DesignerActivator extends Activator implements Prepare {
*/ */
private static void registerCellEditor() { private static void registerCellEditor() {
ActionFactory.registerCellEditor(String.class, new CellStringQuickEditor()); ActionFactory.registerAsyncInitCellEditorClass(String.class, CellStringQuickEditor.class);
ActionFactory.registerCellEditor(Number.class, new CellStringQuickEditor()); ActionFactory.registerAsyncInitCellEditorClass(Number.class, CellStringQuickEditor.class);
ActionFactory.registerCellEditor(BaseFormula.class, new CellFormulaQuickEditor()); ActionFactory.registerAsyncInitCellEditorClass(BaseFormula.class, CellFormulaQuickEditor.class);
ActionFactory.registerCellEditor(SubReport.class, new CellSubReportEditor()); ActionFactory.registerAsyncInitCellEditorClass(SubReport.class, CellSubReportEditor.class);
ActionFactory.registerCellEditor(RichText.class, new CellRichTextEditor()); ActionFactory.registerAsyncInitCellEditorClass(RichText.class, CellRichTextEditor.class);
ActionFactory.registerCellEditor(DSColumn.class, new CellDSColumnEditor()); ActionFactory.registerAsyncInitCellEditorClass(DSColumn.class, CellDSColumnEditor.class);
ActionFactory.registerCellEditor(Image.class, new CellImageQuickEditor()); ActionFactory.registerAsyncInitCellEditorClass(Image.class, CellImageQuickEditor.class);
ActionFactory.registerCellEditor(BiasTextPainter.class, new CellBiasTextPainterEditor()); ActionFactory.registerAsyncInitCellEditorClass(BiasTextPainter.class, CellBiasTextPainterEditor.class);
ActionFactory.registerCellEditor(BufferedImage.class, new CellImageQuickEditor()); ActionFactory.registerAsyncInitCellEditorClass(BufferedImage.class, CellImageQuickEditor.class);
ActionFactory.registerCellEditor(CellImagePainter.class, new CellImageQuickEditor()); ActionFactory.registerAsyncInitCellEditorClass(CellImagePainter.class, CellImageQuickEditor.class);
Set<ElementUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING); Set<ElementUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING);
for (ElementUIProvider provider : providers) { for (ElementUIProvider provider : providers) {
@ -430,7 +437,7 @@ public class DesignerActivator extends Activator implements Prepare {
if (provider.quickEditor() == null) { if (provider.quickEditor() == null) {
continue; continue;
} }
ActionFactory.registerCellEditor(provider.targetObjectClass(), provider.quickEditor().newInstance()); ActionFactory.registerAsyncInitCellEditorClass(provider.targetObjectClass(), provider.quickEditor());
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
} }

2
designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java

@ -67,7 +67,7 @@ public class DesignerStartup extends Activator {
registerDaoSelector(); registerDaoSelector();
Stopwatch beforeWatch = Stopwatch.createStarted(); Stopwatch beforeWatch = Stopwatch.createStarted();
PreLoadService.getInstance().waitForAll(); PreLoadService.getInstance().waitForCommon();
FineLoggerFactory.getLogger().debug( "DesignerStartup cost {} ms to wait load", beforeWatch.elapsed(TimeUnit.MILLISECONDS)); FineLoggerFactory.getLogger().debug( "DesignerStartup cost {} ms to wait load", beforeWatch.elapsed(TimeUnit.MILLISECONDS));
if (DesignUtils.isStarted()) { if (DesignUtils.isStarted()) {

50
designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java

@ -5,9 +5,11 @@ import com.fr.design.mainframe.DesignerContext;
import com.fr.design.ui.util.UIUtil; import com.fr.design.ui.util.UIUtil;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.module.Activator; import com.fr.module.Activator;
import com.fr.module.engine.base.ActivatorContext;
import com.fr.start.SplashContext; import com.fr.start.SplashContext;
import com.fr.start.common.DesignerStartupContext; import com.fr.start.common.DesignerStartupContext;
import com.fr.start.module.StartupArgs; import com.fr.start.module.StartupArgs;
import com.fr.start.preload.PreLoadService;
import com.fr.start.util.DesignerStartupPageUtil; import com.fr.start.util.DesignerStartupPageUtil;
import com.fr.startup.metric.DesignerMetrics; import com.fr.startup.metric.DesignerMetrics;
import com.fr.startup.metric.DesignerStartupModel; import com.fr.startup.metric.DesignerStartupModel;
@ -18,6 +20,7 @@ import com.fr.third.org.apache.commons.lang3.time.StopWatch;
import com.fr.value.NotNullLazyValue; import com.fr.value.NotNullLazyValue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@ -37,6 +40,13 @@ public class DesignerStartupPageActivator extends Activator {
} }
}; };
/**
* 上下文
*/
private final ActivatorContext activatorContext = new ActivatorContext();
private final CountDownLatch LATCH = new CountDownLatch(1);
@Override @Override
public void start() { public void start() {
@ -65,13 +75,24 @@ public class DesignerStartupPageActivator extends Activator {
// 即时暂停 // 即时暂停
suspendRecorder(context); suspendRecorder(context);
addMutable(ActivatorContext.KEY, activatorContext);
PreLoadService.getInstance().waitForUI();
UIUtil.invokeLaterIfNeeded(() -> { UIUtil.invokeLaterIfNeeded(() -> {
StartupPageModel model = StartupPageModel.create(); StartupPageModel model = StartupPageModel.create();
context.setStartupPageModel(model); context.setStartupPageModel(model);
StopWatch suspendWatch = new StopWatch();
final Runnable recordSuspend = () -> {
long suspendTime = suspendWatch.getTime(TimeUnit.MILLISECONDS);
activatorContext.setSuspendTime(suspendTime);
};
// selectAndOpenLast // selectAndOpenLast
model.setOpenLastTemplateRunnable(() -> { model.setOpenLastTemplateRunnable(() -> {
recordSuspend.run();
context.setOpenLastFile(true); context.setOpenLastFile(true);
handleModel(model); handleModel(model);
launchAfterWarmup(); launchAfterWarmup();
@ -79,6 +100,7 @@ public class DesignerStartupPageActivator extends Activator {
// selectAndOpenEmpty // selectAndOpenEmpty
model.setOpenEmptyTemplateRunnable(() -> { model.setOpenEmptyTemplateRunnable(() -> {
recordSuspend.run();
context.setOpenEmpty(true); context.setOpenEmpty(true);
handleModel(model); handleModel(model);
launchAfterWarmup(); launchAfterWarmup();
@ -86,6 +108,7 @@ public class DesignerStartupPageActivator extends Activator {
// selectAndCreateNew // selectAndCreateNew
model.setCreateNewTemplateRunnable(() -> { model.setCreateNewTemplateRunnable(() -> {
recordSuspend.run();
context.setCreateNew(true); context.setCreateNew(true);
handleModel(model); handleModel(model);
launchAfterWarmup(); launchAfterWarmup();
@ -94,8 +117,11 @@ public class DesignerStartupPageActivator extends Activator {
StartupPageWindow window = new StartupPageWindow(model); StartupPageWindow window = new StartupPageWindow(model);
window.setVisible(true); window.setVisible(true);
context.setOnWaiting(true); context.setOnWaiting(true);
suspendWatch.start();
}); });
waitSubTask();
} }
private void suspendRecorder(DesignerStartupContext context) { private void suspendRecorder(DesignerStartupContext context) {
@ -136,9 +162,9 @@ public class DesignerStartupPageActivator extends Activator {
DesignerStartupContext.getInstance().setOnStartup(false); DesignerStartupContext.getInstance().setOnStartup(false);
recordStartupEnd(stopWatch); recordStartupEnd(stopWatch);
}); });
markComplete();
} }
FineLoggerFactory.getLogger().debug("designer-startup-page started cost {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS));
} }
private void recordStartupEnd(StopWatch stopWatch) { private void recordStartupEnd(StopWatch stopWatch) {
@ -150,6 +176,28 @@ public class DesignerStartupPageActivator extends Activator {
model.fill(); model.fill();
} }
/**
* 阻塞住当前的方法
* 只有 UI 交互开始执行的时候才会停止阻塞
*/
private void waitSubTask() {
try {
LATCH.await();
} catch (InterruptedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private void markComplete() {
try {
LATCH.countDown();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
@Override @Override
public void stop() { public void stop() {

36
designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java

@ -11,7 +11,9 @@ import java.util.concurrent.CompletableFuture;
**/ **/
public class PreLoadService { public class PreLoadService {
private List<CompletableFuture<?>> futures = new ArrayList<>(); private List<CompletableFuture<?>> commonFutures = new ArrayList<>();
private List<CompletableFuture<?>> uIFutures = new ArrayList<>();
public static PreLoadService getInstance() { public static PreLoadService getInstance() {
return PreLoadServiceHolder.INSTANCE; return PreLoadServiceHolder.INSTANCE;
@ -21,16 +23,40 @@ public class PreLoadService {
private static final PreLoadService INSTANCE = new PreLoadService(); private static final PreLoadService INSTANCE = new PreLoadService();
} }
/**
* 添加 UI 的异步任务
*
* @param future 任务
*/
public void addUIFuture(CompletableFuture<?> future) {
uIFutures.add(future);
}
public void addFuture(CompletableFuture<?> future) { public void addFuture(CompletableFuture<?> future) {
futures.add(future); commonFutures.add(future);
} }
/**
* 添加通用的异步任务
*
* @param runnable 任务
*/
public void addRunnable(Runnable runnable) { public void addRunnable(Runnable runnable) {
futures.add(CompletableFuture.runAsync(runnable, DesignerStartupPool.common())); commonFutures.add(CompletableFuture.runAsync(runnable, DesignerStartupPool.common()));
} }
public void waitForAll() { /**
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); * 等待通用的异步任务执行
*/
public void waitForCommon() {
CompletableFuture.allOf(commonFutures.toArray(new CompletableFuture[0])).join();
}
/**
* 等待UI异步任务执行
*/
public void waitForUI() {
CompletableFuture.allOf(uIFutures.toArray(new CompletableFuture[0])).join();
} }
} }

Loading…
Cancel
Save