diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index f7bff1f5b..199834fb7 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/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> recentOpenedFileListMap = new HashMap<>(); private List tempRecentOpenedFilePathList = new ArrayList(); + private XmlElement>> recentOpenedMapping = SimpleXmlElement.of(recentOpenedFileListMap); + private boolean showPaintToolBar = true; private int maxNumberOrPreviewRow = 200; - // name和Env的键值对 - private Map nameEnvMap = new ListMap<>(); - // marks: 当前报表服务器名字 - private String curEnvName = null; + + private XmlElement 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 = 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 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(); - 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> entryIt = nameEnvMap.entrySet().iterator(); + Iterator> entryIt = getNameEnvMap().entrySet().iterator(); while (entryIt.hasNext()) { Entry 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> entryIt = nameEnvMap.entrySet().iterator(); + if (getNameEnvMap().size() >= 0) { + Iterator> entryIt = getNameEnvMap().entrySet().iterator(); while (entryIt.hasNext()) { Entry 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 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>>() { + @Override + public void exec(Map> 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.
* The method will be invoked when read data from XML file.
@@ -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 entry : nameEnvMap.entrySet()) { + for (Entry 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 getNameEnvMap() { + + return getEnvConfig().getNameEnvMap(); + } + + private static class EnvConfiguration { + + // name和Env的键值对 + private Map nameEnvMap = new ListMap<>(); + // marks: 当前报表服务器名字 + private String curEnvName = null; + + public Map getNameEnvMap() { + return nameEnvMap; + } + + public void setNameEnvMap(Map nameEnvMap) { + this.nameEnvMap = nameEnvMap; + } + + public String getCurEnvName() { + return curEnvName; + } + + public void setCurEnvName(String curEnvName) { + this.curEnvName = curEnvName; + } + } + } diff --git a/designer-base/src/main/java/com/fr/design/actions/core/ActionFactory.java b/designer-base/src/main/java/com/fr/design/actions/core/ActionFactory.java index 2d4554afd..3a8137f9d 100644 --- a/designer-base/src/main/java/com/fr/design/actions/core/ActionFactory.java +++ b/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> actionClasses = new CopyOnWriteArraySet<>(); private static Set> 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 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); + } + } + }); + } /** * 注册无需每次实例化的单元格元素编辑器 diff --git a/designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java b/designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java index 58fe5666a..22263a871 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/CloseCurrentTemplateAction.java +++ b/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 diff --git a/designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java b/designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java index e9adc880a..c1efc4f5e 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java +++ b/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(); } diff --git a/designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java b/designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java index 56ccaa2c4..a7bf03b40 100644 --- a/designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java +++ b/designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java @@ -1,6 +1,7 @@ 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; @@ -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)); } /** diff --git a/designer-base/src/main/java/com/fr/design/data/StrategyConfigAttrUtils.java b/designer-base/src/main/java/com/fr/design/data/StrategyConfigAttrUtils.java index e2a75fc11..a03ccc99d 100644 --- a/designer-base/src/main/java/com/fr/design/data/StrategyConfigAttrUtils.java +++ b/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; diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index c38c27811..23c22144b 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -209,7 +209,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); } /** @@ -257,12 +257,21 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh } private boolean saveByOldWay(List removedConnNames, List 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) { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java index c9708087b..027afdf5b 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java +++ b/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,6 +31,7 @@ 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.function.TIME; import com.fr.general.FRFont; @@ -39,6 +46,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 +57,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 +86,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 +143,145 @@ 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); + initDesensitizationPane(); + 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() { + 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) { - } - } - } - }); + /** + * 设置脱敏设置的个数 + * + * @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.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 +292,7 @@ public class PreviewTablePane extends BasicPane { } public AutoProgressBar getProgressBar() { - return this.progressBar; + return PreviewTablePane.progressBar; } @Override @@ -223,9 +333,10 @@ public class PreviewTablePane extends BasicPane { } /** - * elake:为预览表的columnIndex列着色. - * @param columnIndex - * @param c + * 为预览表的columnIndex列着色. + * + * @param columnIndex 列索引值 + * @param c 颜色 */ private void setPreviewTableColumnColor(final int columnIndex, final Color c) { addLoadedListener(new LoadedEventListener() { @@ -233,6 +344,7 @@ public class PreviewTablePane extends BasicPane { 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); @@ -253,7 +365,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(); } @@ -335,6 +447,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); @@ -349,42 +462,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() { - protected PreviewTableModel doInBackground() throws Exception { + worker = new SwingWorker() { + + @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()); @@ -394,22 +514,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); @@ -424,6 +542,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); + } + } + } + /** * 直接预览存储过程的一个返回数据集,没有实际值和显示值 * @@ -454,7 +602,7 @@ public class PreviewTablePane extends BasicPane { /** * 直接预览数据集的结果集 * - * @param dataModel 结果集 + * @param dataModel 结果集 * @param keyIndex * @param valueIndex */ @@ -532,9 +680,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) { + setDesensitizationCount(previewTableModel); + setModel(previewTableModel); + setCurrentRows(previewTableModel.getRowCount()); fireLoadedListener(); + } + /** + * 数据脱敏是否启用 + * + * @return + */ + private boolean isDesensitizeOpened() { + return tableData instanceof DesensitizationTableData && + ((DesensitizationTableData) tableData).getDesensitizationConfig().isDesensitizeOpened(); } } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/PreviewTableDesensitizationPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/PreviewTableDesensitizationPane.java new file mode 100644 index 000000000..1bf150dd5 --- /dev/null +++ b/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); + } +} diff --git a/designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java b/designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java index ec8d997c3..d3fb4268d 100644 --- a/designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java +++ b/designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java @@ -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)); // 非安装版本允许自由切换 diff --git a/designer-base/src/main/java/com/fr/design/extra/PluginUtils.java b/designer-base/src/main/java/com/fr/design/extra/PluginUtils.java index 521821ead..f12f8f844 100644 --- a/designer-base/src/main/java/com/fr/design/extra/PluginUtils.java +++ b/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 { diff --git a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java index d7f46ea76..86820aa22 100644 --- a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java +++ b/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)); } } diff --git a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java new file mode 100644 index 000000000..646f0e517 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java @@ -0,0 +1,1243 @@ +package com.fr.design.file; + + +import com.fr.base.BaseUtils; +import com.fr.base.GraphHelper; +import com.fr.base.vcs.DesignerMode; +import com.fr.design.actions.UpdateAction; +import com.fr.design.actions.file.LocateAction; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.imenu.UIMenuItem; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.gui.imenu.UIScrollPopUpMenu; +import com.fr.design.i18n.DesignSizeI18nManager; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.TemplateSavingChecker; +import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager; +import com.fr.design.utils.DesignUtils; +import com.fr.design.utils.TemplateUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.design.worker.WorkerManager; +import com.fr.design.worker.save.CallbackSaveWorker; +import com.fr.file.FILE; +import com.fr.general.ComparatorUtils; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.Constants; +import com.fr.third.javax.annotation.Nonnull; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.lock.TplOperator; + +import javax.swing.BorderFactory; +import javax.swing.ButtonModel; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.MenuElement; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicMenuItemUI; +import java.awt.AWTEvent; +import java.awt.AlphaComposite; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.event.AWTEventListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.geom.Arc2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.Path2D; +import java.awt.geom.RoundRectangle2D; +import java.util.List; + +import static com.fr.design.dialog.FineJOptionPane.showConfirmDialog; +import static javax.swing.JOptionPane.OK_CANCEL_OPTION; +import static javax.swing.JOptionPane.OK_OPTION; +import static javax.swing.JOptionPane.WARNING_MESSAGE; + +/** + * 改个名字,一个拼写 n 个错误 + * + * @author daisy + * @version 11.0 + *

+ * created by daisy on 2013/08/05 + **/ +public class MultiTemplateTabPane extends JComponent { + + private static Icon LIST_DOWN = BaseUtils.readIcon("/com/fr/design/images/buttonicon/list_normal.png"); + private static Icon MOUSE_OVER_LIST_DOWN = BaseUtils.readIcon("/com/fr/design/images/buttonicon/list_pressed.png"); + private static Icon MOUSE_PRESS_LIST_DOWN = BaseUtils.readIcon("/com/fr/design/images/buttonicon/list_pressed.png"); + private static Icon CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png"); + private static Icon MOUSE_OVER_CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/mouseoverclose icon.png"); + private static Icon MOUSE_PRESS_CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/pressclose icon.png"); + private static final Icon WHITE_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/white_saving_close.gif")); + private static final Icon GREY_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/grey_saving_close.gif")); + private static final String ELLIPSIS = "..."; + private static final int GAP = 5; + private static final int SMALLGAP = 3; + private static final int LIST_BUTTON_WIDTH = 34; + private static final int HEIGHT = 26; + private static final int LIST_DOWN_HEIGHT = 25; + private static final double CORNOR_RADIUS = 0.0; + //选了30度和60度的特殊角度的x,y作为经过的两个点的坐标 + private static final double SPECIAL_LOCATION_1 = 2.5; + private static final double SPECIAL_LOCATION_2 = 4.330127; + private static final int ICON_WIDTH = 22; + + + //每个标签页的最大的长度和最小长度。这些长度均为均分 + + private static final int MAXWIDTH = 240; + private static final int MINWIDTH = 100; + + + private static MultiTemplateTabPane THIS; + //用于存放工作簿 + private java.util.List> openedTemplate; + //选中的Tab项 + private int selectedIndex = 0; + // + private int mouseOveredIndex = -1; + + //tab栏可以放下的每个tab的实际宽度 + private int realWidth = MAXWIDTH; + + + //当前标签页栏存放的所有标签页的index + private int minPaintIndex = 0; + private int maxPaintIndex = 0; + + //每个关闭图标的起始位置 + private int[] startX; + + private boolean[] isNeedToolTips; + + //记录关闭按钮的状态 + private int closeIconIndex = -1; + private boolean isCloseCurrent = false; + private Icon clodeMode = CLOSE; + private Icon listDownMode = LIST_DOWN; + private boolean isShowList = false; + + //自动新建的模板B若没有进行任何编辑,切换到其他 + // + // 模板时,模板B会自动关闭 + private JTemplate temTemplate = null; + + + public static MultiTemplateTabPane getInstance() { + if (THIS == null) { + THIS = new MultiTemplateTabPane(); + } + return THIS; + } + + + /** + * 多工作簿面板 + */ + public MultiTemplateTabPane() { + this.setLayout(new BorderLayout(0, 0)); + this.addMouseListener(new MultiTemplateTabMouseListener()); + this.addMouseMotionListener(new MultiTemplateTabMouseMotionListener()); + this.setBorder(null); + this.setForeground(new Color(58, 56, 58)); + this.setFont(DesignUtils.getDefaultGUIFont().applySize(12)); + openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList(); + selectedIndex = openedTemplate.size() - 1; + AWTEventListener awt = new AWTEventListener() { + @Override + public void eventDispatched(AWTEvent event) { + if (event instanceof MouseEvent) { + MouseEvent mv = (MouseEvent) event; + if (mv.getClickCount() > 0 && !ComparatorUtils.equals(mv.getSource(), MultiTemplateTabPane.this)) { + isShowList = false; + } + } + } + + }; + java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(awt, AWTEvent.MOUSE_EVENT_MASK); + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + int tplIndex = getTemplateIndex(e.getX()); + if (tplIndex > -1) { + UIPopupMenu menu = new UIPopupMenu(); + menu.setBorder(BorderFactory.createEmptyBorder(-3, 3, 3, 0)); + + for (CloseOption option : CloseOption.values()) { + menu.add(new UIMenuItem(new RightMenuCloseAction(option, tplIndex))); + } + menu.add(new CloseMenuItemJSeparator()); + menu.add(new UIMenuItem(new OpenInTemplateTreeAction(tplIndex))); + + int height = 0; + for (MenuElement subElement : menu.getSubElements()) { + if (subElement instanceof CloseMenuItemJSeparator) { + height += 10; + } else { + height += 25; + } + } + //根据当前i18n语言环境,动态调整popupMenu的宽度 + menu.setPreferredSize(new Dimension((int) DesignSizeI18nManager.getInstance(). + i18nDimension("com.fr.design.file.MultiTemplateTabPane.popUpMenu").getWidth(), height)); + GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.getInstance(), e.getX(), MultiTemplateTabPane.getInstance().getY() - 1 + MultiTemplateTabPane.getInstance().getHeight()); + } + } + } + }); + } + + enum CloseOption { + Left(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Left")) { + @Override + boolean shouldClose(int tplIndex, int i) { + return i < tplIndex; + } + }, + Right(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Right")) { + @Override + boolean shouldClose(int tplIndex, int i) { + return i > tplIndex; + } + }, + All(Toolkit.i18nText("Fine-Design_Close_All_templates")), + Others(Toolkit.i18nText("Fine-Design_Close_Other_templates")) { + @Override + boolean shouldClose(int tplIndex, int i) { + return i != tplIndex; + } + }; + + + String optionName; + + CloseOption(String optionName) { + this.optionName = optionName; + } + + boolean shouldClose(int tplIndex, int i) { + return true; + } + } + + private static class CloseMenuItemJSeparator extends JSeparator { + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.height = 1; + return d; + } + + @Override + public Color getForeground() { + return UIConstants.PRESSED_DARK_GRAY; + } + } + + + private class OpenInTemplateTreeAction extends LocateAction { + + int tplIndex; + + public OpenInTemplateTreeAction(int tplIndex) { + this.tplIndex = tplIndex; + this.setName(Toolkit.i18nText("Fine-Design_Open_In_Template_Tree")); + } + + @Override + public void actionPerformed(ActionEvent e) { + //处于搜索模式时,先退出搜索模式,再定位 + if (TemplateTreeSearchManager.getInstance().isInSearchMode()) { + TemplateTreeSearchManager.getInstance().outOfSearchMode(); + TemplateTreePane.getInstance().refreshDockingView(); + } + JTemplate template = openedTemplate.get(this.tplIndex); + locateTemplate(template); + } + + private void locateTemplate(JTemplate template) { + FILE currentTemplate = template.getEditingFILE(); + //模板不属于当前环境,跟预览一样先提示保存,再定位模板 + if (!currentTemplate.exists()) { + int selVal = showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Message"), + Toolkit.i18nText("Fine-Design_Basic_Preview_Tool_Tips"), + OK_CANCEL_OPTION, + WARNING_MESSAGE + ); + if (OK_OPTION == selVal) { + CallbackSaveWorker worker = template.saveAs(); + worker.start(template.getRuntimeId()); + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + gotoEditingTemplateLeaf(template.getPath()); + } + }); + } + } else { + gotoEditingTemplateLeaf(template.getPath()); + } + } + } + + private class RightMenuCloseAction extends UpdateAction { + + CloseOption option; + int tplIndex = -1; + + public RightMenuCloseAction(CloseOption option, int tplIndex) { + this.option = option; + this.setName(option.optionName); + this.tplIndex = tplIndex; + } + + + @Override + public void actionPerformed(ActionEvent e) { + SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); + if (saveSomeTempaltePane.showSavePane()) { + + JTemplate[] templates = new JTemplate[openedTemplate.size()]; + for (int i = 0; i < openedTemplate.size(); i++) { + templates[i] = openedTemplate.get(i); + } + JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + closeTemplate(templates, currentTemplate); + + if (option == CloseOption.All) { + DesignerContext.getDesignerFrame().addAndActivateJTemplate(); + } else { + DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate); + } + + MultiTemplateTabPane.getInstance().repaint(); + } + } + + private void closeTemplate(JTemplate[] templates, JTemplate currentTemplate) { + for (int i = 0; i < templates.length; i++) { + if (option.shouldClose(tplIndex, i)) { + JTemplate jTemplate = templates[i]; + if (jTemplate == currentTemplate) { + currentTemplate = option == CloseOption.All ? null : templates[tplIndex]; + } + //判断关闭的模板是不是格式刷的被参照的模板 + openedTemplate.remove(jTemplate); + if (jTemplate != currentTemplate) { + MultiTemplateTabPane.getInstance().closeFormat(jTemplate); + HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate); + closeAndFreeLock(jTemplate); + } + } + } + } + + private void closeAndFreeLock(@Nonnull JTemplate template) { + FILE file = template.getEditingFILE(); + // 只有是环境内的文件,才执行释放锁 + if (file != null && file.isEnvFile()) { + // release lock + WorkContext.getCurrent().get(TplOperator.class).closeAndFreeFile(file.getPath()); + } + } + } + + public JTemplate getSelectedFile() { + if (openedTemplate.size() == selectedIndex) { + selectedIndex = Math.max(--selectedIndex, 0); + } + return openedTemplate.get(selectedIndex); + } + + + /** + * 关闭掉当前已打开文件列表中指定的文件 + * + * @param file 指定的文件 + */ + public void closeFileTemplate(FILE file) { + for (JTemplate temp : openedTemplate) { + if (ComparatorUtils.equals(file, temp.getEditingFILE())) { + closeSpecifiedTemplate(temp); + break; + } + } + + } + + @Override + public Dimension getPreferredSize() { + Dimension dimension = super.getPreferredSize(); + dimension.height = HEIGHT; + return dimension; + } + + private UIMenuItem initCloseOther() { + UIMenuItem closeOther = new UIMenuItem(Toolkit.i18nText("Fine-Design_Basic_FS_Close_Other_Templates")); + // Yvan: 英文下文本显示不全,后续发现如果将模板名设置的比较短,其它语言也会出现显示不全的问题,所以设置一下文本水平居中 + closeOther.setHorizontalAlignment(SwingConstants.CENTER); + setListDownItemPreferredSize(closeOther); + closeOther.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (openedTemplate.size() == 1) { + return; + } + if (!TemplateSavingChecker.check()) { + return; + } + SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); + //点击关闭其他模板,并且点击确定保存 + if (saveSomeTempaltePane.showSavePane()) { + JTemplate[] panes = new JTemplate[openedTemplate.size()]; + for (int i = 0; i < openedTemplate.size(); i++) { + panes[i] = openedTemplate.get(i); + } + for (int i = 0; i < panes.length; i++) { + if (i != selectedIndex) { + JTemplate jTemplate = panes[i]; + //判断关闭的模板是不是格式刷的被参照的模板 + openedTemplate.remove(jTemplate); + closeFormat(jTemplate); + HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate); + closeAndFreeLock(jTemplate); + } + } + JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + HistoryTemplateListCache.getInstance().removeAllHistory(); + DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate); + THIS.repaint(); + } + //如果取消保存了,则不关闭其他模板 + } + }); + if (openedTemplate.size() == 1) { + closeOther.setEnabled(false); + } + return closeOther; + } + + + private UIMenuItem[] createListDownTemplate() { + UIMenuItem[] templates = new UIMenuItem[openedTemplate.size()]; + for (int i = 0; i < openedTemplate.size(); i++) { + final int index = i; + final JTemplate tem = openedTemplate.get(i); + templates[i] = new UIMenuItem(tempalteShowName(tem), tem.getIcon()); + templates[i].setUI(new UIListDownItemUI()); + setListDownItemPreferredSize(templates[i]); + if (i == selectedIndex) { + //画选中的高亮 + templates[i].setBackground(UIConstants.SHADOW_CENTER); + } + templates[i].addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectedIndex = index; + tem.activeNewJTemplate(); + } + }); + } + return templates; + } + + private void setListDownItemPreferredSize(UIMenuItem item) { + Dimension dimension = item.getPreferredSize(); + dimension.height = LIST_DOWN_HEIGHT; + item.setPreferredSize(dimension); + } + + + private String tempalteShowName(JTemplate template) { + String name = TemplateUtils.createLockeTemplatedName(template, template.getTemplateName()); + if (!template.isSaved() && !name.endsWith(" *")) { + name += " *"; + } + return name; + } + + /** + * 刷新打开模板 + * + * @param history 模板 + */ + public void refreshOpenedTemplate(List> history) { + openedTemplate = history; + } + + public void setTemTemplate(JTemplate auotCreate) { + temTemplate = auotCreate; + } + + + private void showListDown() { + + UIScrollPopUpMenu menu = new UIScrollPopUpMenu(); + menu.setBorder(BorderFactory.createEmptyBorder(-3, 3, 3, 0)); + menu.add(initCloseOther()); + JSeparator separator = new JSeparator() { + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.height = 1; + return d; + } + }; + menu.add(new JPanel() { + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.height = 1; + return d; + } + }); + separator.setForeground(UIConstants.LINE_COLOR); + menu.add(separator); + menu.add(new JPanel() { + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.height = 1; + return d; + } + }); + UIMenuItem[] items = createListDownTemplate(); + for (int i = 0; i < items.length; i++) { + menu.add(items[i]); + } + GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.getInstance(), MultiTemplateTabPane.getInstance().getWidth() - menu.getPreferredSize().width, getY() - 1 + getHeight()); + } + + + public void setSelectedIndex(int index) { + selectedIndex = index; + } + + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + double maxWidth = getWidth() - LIST_BUTTON_WIDTH * 1.0D; //最大宽度 + Graphics2D g2d = (Graphics2D) g; + paintBackgroundAndLine(g2d, maxWidth); + } + + + @Override + public void paint(Graphics g) { + //不可见时,按钮.4f透明 + AlphaComposite composite = DesignerMode.isVcsMode() + ? AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f) + : (AlphaComposite) ((Graphics2D) g).getComposite(); + ((Graphics2D) g).setComposite(composite); + super.paint(g); + } + + private void paintBackgroundAndLine(Graphics2D g2d, double maxWidth) { + paintDefaultBackground(g2d); + //最多能画的个数 + int maxTemplateNum = (int) (maxWidth) / MINWIDTH; + //计算开始画的最小模板index和最大模板index + calMinAndMaxIndex(maxTemplateNum); + calculateRealAverageWidth(maxWidth, maxTemplateNum); + int maxStringlength = calculateStringMaxLength(); + if (selectedIndex >= openedTemplate.size()) { + selectedIndex = openedTemplate.size() - 1; + } + if (selectedIndex < 0) { + selectedIndex = 0; + } + double templateStartX = 0; + startX = new int[maxPaintIndex - minPaintIndex + 1]; + isNeedToolTips = new boolean[maxPaintIndex - minPaintIndex + 1]; + + //从可以开始展示在tab面板上的tab开始画 + for (int i = minPaintIndex; i <= maxPaintIndex; i++) { + JTemplate template = openedTemplate.get(i); + Icon icon = template.getIcon(); + String name = tempalteShowName(template); + //如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理 + if (getStringWidth(name) > maxStringlength) { + name = getEllipsisName(name, maxStringlength); + isNeedToolTips[i - minPaintIndex] = true; + } else { + isNeedToolTips[i - minPaintIndex] = false; + } + + Icon selectedIcon; + if (i == closeIconIndex) { + selectedIcon = clodeMode; + } else { + selectedIcon = CLOSE; + } + if (i == selectedIndex) { + if (template.isSaving()) { + selectedIcon = WHITE_SAVING_CLOSE_ICON; + } + startX[i - minPaintIndex] = paintSelectedTab(g2d, icon, templateStartX, name, selectedIcon); + } else { + if (template.isSaving()) { + selectedIcon = GREY_SAVING_CLOSE_ICON; + } + boolean isLeft = i < selectedIndex; + startX[i - minPaintIndex] = paintUnSelectedTab(g2d, icon, templateStartX, name, selectedIcon, isLeft, mouseOveredIndex, i); + } + templateStartX += realWidth; + } + + if (!DesignerMode.isVcsMode()) { + paintListDown(g2d, maxWidth); + } + paintUnderLine(templateStartX, maxWidth, g2d); + } + + + private void paintUnderLine(double templateStartX, double maxWidth, Graphics2D g2d) { + //画下面的那条线 + if (templateStartX < maxWidth) { + GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, 2); + generalPath.moveTo((float) templateStartX, (float) (getHeight() - 1.0D)); + generalPath.lineTo((float) maxWidth, (float) (getHeight() - 1.0D)); + g2d.fill(generalPath); + //TODO hzzz delete +// g2d.setPaint(UIConstants.LINE_COLOR); +// g2d.draw(new Line2D.Double((float) templateStartX, getHeight() - 1, (float) maxWidth + LIST_BUTTON_WIDTH, getHeight() - 1)); + } + } + + private void paintDefaultBackground(Graphics2D g2d) { + //画默认背景 + g2d.setPaint(new GradientPaint(1, 1, UIConstants.TEMPLATE_TAB_PANE_BACKGROUND, 1, (float) (getHeight() - 1.0D), UIConstants.TEMPLATE_TAB_PANE_BACKGROUND)); + g2d.fillRect(0, 0, getWidth(), getHeight()); + } + + + private void paintListDown(Graphics2D g2d, double maxWidth) { + int x = (int) maxWidth + (LIST_BUTTON_WIDTH - listDownMode.getIconWidth()) / 2; + int y = (getHeight() - listDownMode.getIconHeight()) / 2; + listDownMode.paintIcon(this, g2d, x, y); + } + + /** + * 判断tab文字的长度大于能装下的最大文字长度,要用省略号 + * + * @param name + * @param maxStringlength + * @return + */ + private String getEllipsisName(String name, int maxStringlength) { + + //若是名字长度大于能显示的长度,那能显示的文字的最大长度还要减去省略号的最大长度 +// int maxellipsislength = maxStringlength - ELLIPSIS.length(); + int ellipsisWidth = getStringWidth(ELLIPSIS); + int leftkeyPoint = 0; + int rightKeyPoint = name.length() - 1; + int leftStrWidth = 0; + int rightStrWidth = 0; + while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) { + if (leftStrWidth <= rightStrWidth) { + leftkeyPoint++; + } else { + rightKeyPoint--; + } + leftStrWidth = getStringWidth(name.substring(0, leftkeyPoint)); + rightStrWidth = getStringWidth(name.substring(rightKeyPoint)); + + if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) { + if (leftStrWidth <= rightStrWidth) { + rightKeyPoint++; + } + break; + } + } + + return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint); + } + + private void calMinAndMaxIndex(int maxTemplateNum) { + //如果个数大于最多能容纳的个数,则多余的进行处理 + if (openedTemplate.size() > maxTemplateNum) { + //所点击列表中的标签页处在标签页栏最后一个标签页之后,则标签页栏左移至所点击标签页出现 + if (selectedIndex >= maxPaintIndex) { + minPaintIndex = selectedIndex - maxTemplateNum + 1; + maxPaintIndex = selectedIndex; + if (minPaintIndex <= 0) { + minPaintIndex = 0; + maxPaintIndex = maxTemplateNum - 1; + } + } else if (selectedIndex <= minPaintIndex) { + //所点击列表中的标签页处在标签页栏第一个标签页之前,则标签页栏右移至所点击标签页出现 + minPaintIndex = selectedIndex; + maxPaintIndex = minPaintIndex + maxTemplateNum - 1; + if (maxPaintIndex > openedTemplate.size() - 1) { + maxPaintIndex = openedTemplate.size() - 1; + } + } else { + if (selectedIndex >= openedTemplate.size() - 1) { + selectedIndex = openedTemplate.size() - 1; + maxPaintIndex = selectedIndex; + minPaintIndex = selectedIndex - maxTemplateNum + 1; + } else { + maxPaintIndex = minPaintIndex + maxTemplateNum - 1; + if (maxPaintIndex > openedTemplate.size() - 1) { + maxPaintIndex = openedTemplate.size() - 1; + } + } + } + } else { + minPaintIndex = 0; + maxPaintIndex = openedTemplate.size() - 1; + } + } + + + //个数小于最多能容纳的个数的情况下,看看宽度每个要画多少 + private void calculateRealAverageWidth(double maxwidth, int templateNum) { + + int num = openedTemplate.size() > templateNum ? templateNum : openedTemplate.size(); + realWidth = (int) (maxwidth / (num)); + if (realWidth > MAXWIDTH) { + realWidth = MAXWIDTH; + } else if (realWidth < MINWIDTH) { + //平均下来每个的宽度小于最小宽度 + realWidth = MINWIDTH; + } + } + + /** + * 计算过长度之后的每个tab的能接受的文字的英文字符数 + * + * @return + */ + private int calculateStringMaxLength() { + return realWidth - 3 * GAP - ICON_WIDTH - SMALLGAP - CLOSE.getIconWidth(); + + } + + private int getStringWidth(String str) { + return GraphHelper.getFontMetrics(this.getFont()).stringWidth(str); + } + + + /** + * 画选中的tab + * + * @param g2d + * @param sheeticon + * @param templateStartX + * @param sheetName + * @param closeIcon + * @return + */ + private int paintSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon) { + double[] x = {templateStartX, templateStartX, templateStartX + realWidth, templateStartX + realWidth, templateStartX}; + double[] y = {1, getHeight() + 1, getHeight() + 1, 1, 1}; + RoundRectangle2D.Double rect1 = new RoundRectangle2D.Double(templateStartX, 1, this.getWidth(), this.getHeight(), 7, 7); + g2d.setPaint(new GradientPaint(1, 1, UIConstants.SELECT_TAB, 1, (float) (getHeight() - 1.0D), UIConstants.SELECT_TAB)); + //选了30度和60度的特殊角度的x,y作为经过的两个点的坐标 + double specialLocation1 = 2.5; + double specialLocation2 = 4.330127; + GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length); + generalPath.moveTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); + generalPath.curveTo(((float) x[0] + CORNOR_RADIUS - specialLocation1), (y[0] + CORNOR_RADIUS - specialLocation2), ((float) x[0] + CORNOR_RADIUS - specialLocation2), (y[0] + CORNOR_RADIUS - specialLocation1), x[0], y[0] + CORNOR_RADIUS); + + for (int index = 1; index <= 2; index++) { + generalPath.lineTo((float) x[index], (float) y[index]); + } + + generalPath.lineTo((float) x[3], (float) y[3] + CORNOR_RADIUS); + generalPath.curveTo(((float) x[3] - CORNOR_RADIUS + specialLocation1), ((float) y[3] + CORNOR_RADIUS - specialLocation2), ((float) x[3] - CORNOR_RADIUS + specialLocation2), ((float) y[3] + CORNOR_RADIUS - specialLocation1), (float) x[3] - CORNOR_RADIUS, (float) y[3]); + generalPath.lineTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); + + generalPath.closePath(); + g2d.fill(generalPath); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setPaint(new Color(200, 201, 205)); + g2d.draw(new Arc2D.Double(x[0], y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0)); + g2d.draw(new Line2D.Double(x[0], y[0] + CORNOR_RADIUS, x[1], y[1])); + g2d.draw(new Line2D.Double(x[1], y[1], x[2], y[2])); + g2d.draw(new Line2D.Double(x[2], y[2], x[3], y[3] + CORNOR_RADIUS)); + g2d.draw(new Arc2D.Double(x[3] - CORNOR_RADIUS * 2, y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0)); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + int sheetIconY = (getHeight() - sheeticon.getIconHeight()) / 2; + sheeticon.paintIcon(this, g2d, (int) templateStartX + GAP, sheetIconY); + // 画字符 + g2d.setPaint(getForeground()); + g2d.drawString(sheetName, (int) templateStartX + sheeticon.getIconWidth() + 2 * GAP, getHeight() - GAP * 2); + int closePosition = (int) templateStartX + realWidth - CLOSE.getIconWidth() - SMALLGAP; + int closeY = (getHeight() - closeIcon.getIconHeight()) / 2; + if (!DesignerMode.isVcsMode()) { + closeIcon.paintIcon(this, g2d, closePosition, closeY); + } + return closePosition; + + } + + /** + * 画没有选中的tab + * + * @param g2d + * @param sheeticon + * @param templateStartX + * @param sheetName + * @param closeIcon + * @param isLeft + * @return + */ + private int paintUnSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon, boolean isLeft, int mouseOveredIndex, int selfIndex) { + double[] x = {templateStartX, templateStartX, templateStartX + realWidth, templateStartX + realWidth, templateStartX}; + double[] y = {-1, getHeight() - 1, getHeight() - 1, -1, -1}; + if (selfIndex == mouseOveredIndex) { + g2d.setPaint(new GradientPaint(1, 1, UIConstants.HOVER_BLUE, 1, (float) (getHeight() - 1.0D), UIConstants.HOVER_BLUE)); + } else { + g2d.setPaint(new GradientPaint(1, 1, UIConstants.SHADOW_GREY, 1, (float) (getHeight() - 1.0D), UIConstants.SHADOW_GREY)); + } + + + GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length); + + unSelectedClosedPath(generalPath, isLeft, x, y); + g2d.fill(generalPath); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setPaint(UIConstants.TEMPLATE_TAB_PANE_BACKGROUND); + //TODO hzzz delete +// if (isLeft) { +// g2d.draw(new Arc2D.Double(x[0], y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0)); +// } else { +// g2d.draw(new Arc2D.Double(x[0] - CORNOR_RADIUS * 2, y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0)); +// } + +// g2d.draw(new Line2D.Double(x[0], y[0] + CORNOR_RADIUS, x[1], y[1] + 1)); +// g2d.draw(new Line2D.Double(x[1], y[1], x[2], y[2])); + g2d.draw(new Line2D.Double(x[2], y[2], x[3], y[3] + CORNOR_RADIUS)); +// if (isLeft) { +// g2d.draw(new Arc2D.Double(x[3], y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0)); +// } else { +// g2d.draw(new Arc2D.Double(x[3] - CORNOR_RADIUS * 2, y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0)); +// } + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + int sheetIconY = (getHeight() - sheeticon.getIconHeight()) / 2; + sheeticon.paintIcon(this, g2d, (int) templateStartX + GAP, sheetIconY); + // 画字符 + g2d.setPaint(getForeground()); + g2d.drawString(sheetName, (int) templateStartX + sheeticon.getIconWidth() + 2 * GAP, getHeight() - GAP * 2); + int closeY = (getHeight() - closeIcon.getIconHeight()) / 2; + int closePosition = (int) templateStartX + realWidth - CLOSE.getIconWidth() - SMALLGAP; + if (!DesignerMode.isVcsMode()) { + closeIcon.paintIcon(this, g2d, closePosition, closeY); + } + return closePosition; + } + + + private void unSelectedClosedPath(GeneralPath generalPath, boolean isLeft, double[] x, double[] y) { + + if (isLeft) { + generalPath.moveTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); + generalPath.curveTo(((float) x[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), x[0], y[0] + CORNOR_RADIUS); + } else { + generalPath.moveTo((float) x[0] - CORNOR_RADIUS, (float) y[0]); + generalPath.curveTo(((float) x[0] - CORNOR_RADIUS + SPECIAL_LOCATION_1), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[0] - CORNOR_RADIUS + SPECIAL_LOCATION_2), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), x[0], y[0] + CORNOR_RADIUS); + } + + for (int index = 1; index <= 2; index++) { + generalPath.lineTo((float) x[index], (float) y[index]); + } + + generalPath.lineTo((float) x[3], (float) y[3] + CORNOR_RADIUS); + + if (isLeft) { + generalPath.curveTo(((float) x[3] + CORNOR_RADIUS - SPECIAL_LOCATION_1), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) y[3] - CORNOR_RADIUS + SPECIAL_LOCATION_1), (float) x[3] + CORNOR_RADIUS, (float) y[3]); + generalPath.lineTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); + } else { + generalPath.curveTo(((float) x[3] - CORNOR_RADIUS + SPECIAL_LOCATION_1), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[3] - CORNOR_RADIUS + SPECIAL_LOCATION_2), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_1), (float) x[3] - CORNOR_RADIUS, (float) y[3]); + generalPath.lineTo((float) x[0] - CORNOR_RADIUS, (float) y[0]); + } + + generalPath.closePath(); + } + + + public void setIsCloseCurrent(boolean isCloseCurrent) { + this.isCloseCurrent = isCloseCurrent; + + } + + /** + * 关闭模板 + * + * @param specifiedTemplate 模板 + */ + public void closeSpecifiedTemplate(JTemplate specifiedTemplate) { + if (specifiedTemplate == null) { + return; + } + + if (!specifiedTemplate.isALLSaved() && !DesignerMode.isVcsMode()) { + specifiedTemplate.stopEditing(); + int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + specifiedTemplate.getEditingFILE() + "\" ?", + Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + if (returnVal == JOptionPane.YES_OPTION) { + CallbackSaveWorker worker = specifiedTemplate.save(); + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName())); + closeTpl(specifiedTemplate); + } + }); + worker.start(specifiedTemplate.getRuntimeId()); + } else if (returnVal == JOptionPane.NO_OPTION) { + closeTpl(specifiedTemplate); + } + } else { + closeTpl(specifiedTemplate); + } + + } + + private void closeTpl(@Nonnull JTemplate specifiedTemplate) { + HistoryTemplateListCache.getInstance().closeSelectedReport(specifiedTemplate); + closeAndFreeLock(specifiedTemplate); + activePrevTemplateAfterClose(); + } + + private void closeAndFreeLock(@Nonnull JTemplate template) { + FILE file = template.getEditingFILE(); + // 只有是环境内的文件,才执行释放锁 + if (file != null && file.isEnvFile()) { + // release lock + TemplateResourceManager.getResource().closeTemplate(file.getPath()); + } + } + + /** + * 后台关闭当前编辑模板 + */ + public void closeCurrentTpl() { + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + this.setIsCloseCurrent(true); + this.closeFormat(jTemplate); + this.closeSpecifiedTemplate(jTemplate); + } + + /** + * 关闭模板 + * + * @param closedTemplate 模板 + */ + public void closeFormat(JTemplate closedTemplate) { + //表单不需要处理 + if (!closedTemplate.isJWorkBook()) { + return; + } + + if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_NULL) { + return; + } + + //是被参照的模板被关闭,则重置格式刷 + closedTemplate.doConditionCancelFormat(); + } + + /** + * 关闭掉一个模板之后激活新的待显示模板 + */ + public void activePrevTemplateAfterClose() { + if (openedTemplate.isEmpty()) { + //新建并激活模板 + DesignerContext.getDesignerFrame().addAndActivateJTemplate(); + selectedIndex = 0; + //此时刚自动新建的模板在HistoryTemplateListCache的editingTemplate + temTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + + } else { + // 如果关闭的模板是当前选中的模板,则重新激活当前 selectIndex 的模板; + // selectIndex 没有变化,但是对应的模板已经变成了前一张模板 + if (closeIconIndex == selectedIndex || isCloseCurrent) { + // 如果当前关闭的模板在最右侧,那么预览上一个,防止数组越界 + if (selectedIndex >= maxPaintIndex) { + // selectIndex 不会 <0 因为如果关闭的是打开的最后一个模板,那么关闭之后 openedTemplate.isEmpty() = true + selectedIndex--; + } + isCloseCurrent = false; + } + // 如果关闭的模板不是当前选中的模板,那么重新获取一下当前模板的 index,激活该 index + else { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + selectedIndex = HistoryTemplateListCache.getInstance().contains(template); + } + if (selectedIndex < openedTemplate.size()) { + //如果是已后台关闭的模板,则重新打开文件 + openedTemplate.get(selectedIndex).activeOldJTemplate(); + } + + } + } + + + private boolean isOverCloseIcon(int evtX) { + boolean isOverCloseIcon = false; + for (int i = 0; i < startX.length; i++) { + if (evtX >= startX[i] && evtX <= startX[i] + CLOSE.getIconWidth()) { + isOverCloseIcon = true; + break; + } + } + return isOverCloseIcon; + } + + + private boolean isOverListDown(int evtX) { + int maxWidth = getWidth() - LIST_BUTTON_WIDTH; + return evtX >= (maxWidth + SMALLGAP) && evtX <= (getWidth() - SMALLGAP); + } + + + private int getTemplateIndex(int evtX) { + int textX = 0; + for (int i = minPaintIndex; i <= maxPaintIndex; i++) { + int textWidth = realWidth; + if (evtX >= textX && evtX < textX + textWidth) { + return i; + } + textX += textWidth; + } + return -1; + } + + + /** + * 处理自动新建的模板 在切换时的处理 + */ + public void doWithtemTemplate() { + //temtemplate保存的一定是手动新建的没有编辑或是编辑了没有保存的模板 + //没有保存,说明有编辑;已经保存在磁盘里的文件,说明有过处理,并且已经保存,此时切换都不将其自动关闭 + if (temTemplate == null || temTemplate == HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()) { + return; + } + + if (!temTemplate.isSaved() || !temTemplate.getEditingFILE().isMemFile()) { + temTemplate = null; + } + + //自动新建的模板B若没有进行任何编辑(新建模板没有进行任何编辑时saved都是true):还没有存盘 + if (temTemplate != null && temTemplate.getEditingFILE().isMemFile() && temTemplate.isSaved()) { + HistoryTemplateListCache.getInstance().closeSelectedReport(temTemplate); + temTemplate = null; + setSelectedIndex(HistoryTemplateListCache.getInstance().contains(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate())); + } + } + + private class UIListDownItemUI extends BasicMenuItemUI { + @Override + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + if (menuItem.getIcon() == null) { + super.paintBackground(g, menuItem, bgColor); + return; + } + ButtonModel model = menuItem.getModel(); + Color oldColor = g.getColor(); + int menuWidth = menuItem.getWidth(); + int menuHeight = menuItem.getHeight(); + g.setColor(UIConstants.NORMAL_BACKGROUND); + g.fillRect(0, 0, menuWidth, menuHeight); + boolean itemIsSelected = menuItem instanceof JMenu && model.isSelected(); + if (menuItem.isOpaque()) { + if (model.isArmed() || itemIsSelected) { + GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, UIConstants.ARC); + } else { + GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, menuItem.getBackground(), UIConstants.ARC); + } + g.setColor(oldColor); + } else if (model.isArmed() || itemIsSelected) { + GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, UIConstants.ARC); + g.setColor(oldColor); + } + } + } + + private class MultiTemplateTabMouseListener implements MouseListener { + + + /** + * 鼠标进入 + * + * @param e 鼠标事件 + */ + @Override + public void mouseEntered(MouseEvent e) { + // do nothing + } + + /** + * 鼠标离开 + * + * @param e 鼠标事件 + */ + @Override + public void mouseExited(MouseEvent e) { + listDownMode = LIST_DOWN; + closeIconIndex = -1; + mouseOveredIndex = -1; + MultiTemplateTabPane.this.repaint(); + } + + /** + * 鼠标释放 + * + * @param e 鼠标事件 + */ + @Override + public void mouseReleased(MouseEvent e) { + // do nothing + } + + /** + * 点击 + * + * @param e 鼠标事件 + */ + @Override + public void mouseClicked(MouseEvent e) { + // do nothing + } + + /** + * 按下 + * + * @param e 鼠标事件 + */ + @Override + public void mousePressed(MouseEvent e) { + //如果在版本管理情况下,不允许切换tab + if (DesignerMode.isVcsMode()) { + return; + } + + int evtX = e.getX(); + + //是否点击关闭按钮 如果点击了关闭按钮,则将点击的模板关闭,不需要切换,如果没有点击关闭按钮,则切换到点击的模板处 + boolean isOverCloseIcon = isOverCloseIcon(evtX); + if (isOverListDown(evtX)) { + listDownMode = isOverListDown(evtX) ? MOUSE_PRESS_LIST_DOWN : LIST_DOWN; + if (!isShowList) { + showListDown(); + } + isShowList = !isShowList; + + } else if (isOverCloseIcon) { + //关闭按钮的图标变化 + closeIconIndex = getTemplateIndex(evtX); + clodeMode = MOUSE_PRESS_CLOSE; + //关闭close图标所在的模板{ + JTemplate template = openedTemplate.get(closeIconIndex); + if (template.isOpening()) { + WorkerManager.getInstance().cancelWorker(template.getPath()); + } else if (template.isSaving()) { + boolean completed = WorkerManager.getInstance().isCompleted(template.getTarget().getTemplateID()); + if (!completed) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Close_Template_Tip", template.getEditingFILE().getName())); + return; + } + } + closeFormat(template); + closeSpecifiedTemplate(template); + DesignerContext.getDesignerFrame().getContentFrame().repaint(); + isShowList = false; + } else { + //没有点击关闭和ListDown按钮,则切换到点击的模板处 + closeIconIndex = -1; + clodeMode = CLOSE; + int tempSelectedIndex = selectedIndex; + if (selectedIndex != getTemplateIndex(evtX) && getTemplateIndex(evtX) != -1) { + openedTemplate.get(selectedIndex).stopEditing(); + selectedIndex = getTemplateIndex(evtX); + //如果在权限编辑情况下,不允许切换到表单类型的工作簿 + if (DesignerMode.isAuthorityEditing() && !openedTemplate.get(selectedIndex).isJWorkBook()) { + DesignerContext.getDesignerFrame().addAndActivateJTemplate(openedTemplate.get(tempSelectedIndex)); + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Form_Authority_Edited_Cannot_Be_Supported") + + "!", Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); + MultiTemplateTabPane.this.repaint(); + return; + } + JTemplate evtXTemplate = openedTemplate.get(getTemplateIndex(evtX)); + evtXTemplate.activeNewJTemplate(); + } + isShowList = false; + } + MultiTemplateTabPane.this.repaint(); + + + } + + + } + + private class MultiTemplateTabMouseMotionListener implements MouseMotionListener { + /** + * 鼠标拖拽 + * + * @param e 鼠标事件 + */ + @Override + public void mouseDragged(MouseEvent e) { + // do nothing + } + + /** + * 鼠标移动 + * + * @param e 鼠标事件 + */ + @Override + public void mouseMoved(MouseEvent e) { + int evtX = e.getX(); + mouseOveredIndex = getTemplateIndex(evtX); + + //看是否需要显示toolTip + if (mouseOveredIndex != -1 && isNeedToolTips[mouseOveredIndex - minPaintIndex]) { + setToolTipText(openedTemplate.get(mouseOveredIndex).getEditingFILE().getName()); + } else { + setToolTipText(null); + } + + listDownMode = isOverListDown(evtX) ? MOUSE_OVER_LIST_DOWN : LIST_DOWN; + + boolean isOverCloseIcon = isOverCloseIcon(evtX); + clodeMode = isOverCloseIcon ? MOUSE_OVER_CLOSE : CLOSE; + closeIconIndex = isOverCloseIcon ? mouseOveredIndex : -1; + MultiTemplateTabPane.this.repaint(); + } + } + + +} diff --git a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java index 3589d9812..36e0b5875 100644 --- a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java +++ b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java @@ -1,1242 +1,24 @@ package com.fr.design.file; - -import com.fr.base.BaseUtils; -import com.fr.base.GraphHelper; -import com.fr.base.vcs.DesignerMode; -import com.fr.design.actions.UpdateAction; -import com.fr.design.actions.file.LocateAction; -import com.fr.design.constants.UIConstants; -import com.fr.design.dialog.FineJOptionPane; -import com.fr.design.gui.imenu.UIMenuItem; -import com.fr.design.gui.imenu.UIPopupMenu; -import com.fr.design.gui.imenu.UIScrollPopUpMenu; -import com.fr.design.i18n.DesignSizeI18nManager; -import com.fr.design.i18n.Toolkit; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.mainframe.TemplateSavingChecker; -import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager; -import com.fr.design.utils.DesignUtils; -import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.design.utils.gui.GUIPaintUtils; -import com.fr.design.worker.WorkerManager; -import com.fr.design.utils.TemplateUtils; -import com.fr.design.worker.save.CallbackSaveWorker; -import com.fr.file.FILE; -import com.fr.general.ComparatorUtils; -import com.fr.general.GeneralContext; -import com.fr.general.IOUtils; -import com.fr.log.FineLoggerFactory; -import com.fr.stable.Constants; -import com.fr.third.javax.annotation.Nonnull; -import com.fr.workspace.WorkContext; -import com.fr.workspace.server.lock.TplOperator; - -import javax.swing.BorderFactory; -import javax.swing.ButtonModel; -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JComponent; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JSeparator; -import javax.swing.MenuElement; -import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; -import javax.swing.plaf.basic.BasicMenuItemUI; -import java.awt.AWTEvent; -import java.awt.AlphaComposite; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.GradientPaint; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.event.AWTEventListener; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.MouseMotionListener; -import java.awt.geom.Arc2D; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.geom.Path2D; -import java.awt.geom.RoundRectangle2D; -import java.util.List; -import java.util.Locale; - -import static com.fr.design.dialog.FineJOptionPane.showConfirmDialog; -import static javax.swing.JOptionPane.OK_CANCEL_OPTION; -import static javax.swing.JOptionPane.OK_OPTION; -import static javax.swing.JOptionPane.WARNING_MESSAGE; - /** - * Author : daisy - * Date: 13-8-5 - * Time: 下午6:12 + * @author shine + * @version 10.0 + * Created by shine on 2022/11/25 + * fvs plugin jartime升级到2022-12-2之后就可以删了 */ -public class MutilTempalteTabPane extends JComponent { - - private static Icon LIST_DOWN = BaseUtils.readIcon("/com/fr/design/images/buttonicon/list_normal.png"); - private static Icon MOUSE_OVER_LIST_DOWN = BaseUtils.readIcon("/com/fr/design/images/buttonicon/list_pressed.png"); - private static Icon MOUSE_PRESS_LIST_DOWN = BaseUtils.readIcon("/com/fr/design/images/buttonicon/list_pressed.png"); - private static Icon CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png"); - private static Icon MOUSE_OVER_CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/mouseoverclose icon.png"); - private static Icon MOUSE_PRESS_CLOSE = BaseUtils.readIcon("/com/fr/design/images/buttonicon/pressclose icon.png"); - private static final Icon WHITE_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/white_saving_close.gif")); - private static final Icon GREY_SAVING_CLOSE_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/file/grey_saving_close.gif")); - private static final String ELLIPSIS = "..."; - private static final int GAP = 5; - private static final int SMALLGAP = 3; - private static final int LIST_BUTTON_WIDTH = 34; - private static final int HEIGHT = 26; - private static final int LIST_DOWN_HEIGHT = 25; - private static final double CORNOR_RADIUS = 0.0; - //选了30度和60度的特殊角度的x,y作为经过的两个点的坐标 - private static final double SPECIAL_LOCATION_1 = 2.5; - private static final double SPECIAL_LOCATION_2 = 4.330127; - private static final int ICON_WIDTH = 22; - - - //每个标签页的最大的长度和最小长度。这些长度均为均分 - - private static final int MAXWIDTH = 240; - private static final int MINWIDTH = 100; - - - private static MutilTempalteTabPane THIS; - //用于存放工作簿 - private java.util.List> openedTemplate; - //选中的Tab项 - private int selectedIndex = 0; - // - private int mouseOveredIndex = -1; - - //tab栏可以放下的每个tab的实际宽度 - private int realWidth = MAXWIDTH; - - - //当前标签页栏存放的所有标签页的index - private int minPaintIndex = 0; - private int maxPaintIndex = 0; - - //每个关闭图标的起始位置 - private int[] startX; - - private boolean[] isNeedToolTips; - - //记录关闭按钮的状态 - private int closeIconIndex = -1; - private boolean isCloseCurrent = false; - private Icon clodeMode = CLOSE; - private Icon listDownMode = LIST_DOWN; - private boolean isShowList = false; - - //自动新建的模板B若没有进行任何编辑,切换到其他 - // - // 模板时,模板B会自动关闭 - private JTemplate temTemplate = null; - +@Deprecated +public class MutilTempalteTabPane { public static MutilTempalteTabPane getInstance() { - if (THIS == null) { - THIS = new MutilTempalteTabPane(); - } - return THIS; + return new MutilTempalteTabPane(); } + public void setIsCloseCurrent(boolean b) { + MultiTemplateTabPane.getInstance().setIsCloseCurrent(b); - /** - * 多工作簿面板 - */ - public MutilTempalteTabPane() { - this.setLayout(new BorderLayout(0, 0)); - this.addMouseListener(new MultiTemplateTabMouseListener()); - this.addMouseMotionListener(new MultiTemplateTabMouseMotionListener()); - this.setBorder(null); - this.setForeground(new Color(58, 56, 58)); - this.setFont(DesignUtils.getDefaultGUIFont().applySize(12)); - openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList(); - selectedIndex = openedTemplate.size() - 1; - AWTEventListener awt = new AWTEventListener() { - @Override - public void eventDispatched(AWTEvent event) { - if (event instanceof MouseEvent) { - MouseEvent mv = (MouseEvent) event; - if (mv.getClickCount() > 0 && !ComparatorUtils.equals(mv.getSource(), MutilTempalteTabPane.this)) { - isShowList = false; - } - } - } - - }; - java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(awt, AWTEvent.MOUSE_EVENT_MASK); - addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - if (SwingUtilities.isRightMouseButton(e)) { - int tplIndex = getTemplateIndex(e.getX()); - if (tplIndex > -1) { - UIPopupMenu menu = new UIPopupMenu(); - menu.setBorder(BorderFactory.createEmptyBorder(-3, 3, 3, 0)); - - for (CloseOption option : CloseOption.values()) { - menu.add(new UIMenuItem(new RightMenuCloseAction(option, tplIndex))); - } - menu.add(new CloseMenuItemJSeparator()); - menu.add(new UIMenuItem(new OpenInTemplateTreeAction(tplIndex))); - - int height = 0; - for (MenuElement subElement : menu.getSubElements()) { - if (subElement instanceof CloseMenuItemJSeparator) { - height += 10; - } else { - height += 25; - } - } - //根据当前i18n语言环境,动态调整popupMenu的宽度 - menu.setPreferredSize(new Dimension((int) DesignSizeI18nManager.getInstance(). - i18nDimension("com.fr.design.file.MultiTemplateTabPane.popUpMenu").getWidth(), height)); - GUICoreUtils.showPopupMenu(menu, MutilTempalteTabPane.getInstance(), e.getX(), MutilTempalteTabPane.getInstance().getY() - 1 + MutilTempalteTabPane.getInstance().getHeight()); - } - } - } - }); } - enum CloseOption { - Left(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Left")) { - @Override - boolean shouldClose(int tplIndex, int i) { - return i < tplIndex; - } - }, - Right(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Right")) { - @Override - boolean shouldClose(int tplIndex, int i) { - return i > tplIndex; - } - }, - All(Toolkit.i18nText("Fine-Design_Close_All_templates")), - Others(Toolkit.i18nText("Fine-Design_Close_Other_templates")) { - @Override - boolean shouldClose(int tplIndex, int i) { - return i != tplIndex; - } - }; - - - String optionName; - - CloseOption(String optionName) { - this.optionName = optionName; - } - - boolean shouldClose(int tplIndex, int i) { - return true; - } - } - - private static class CloseMenuItemJSeparator extends JSeparator { - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - d.height = 1; - return d; - } - - @Override - public Color getForeground() { - return UIConstants.PRESSED_DARK_GRAY; - } - } - - - private class OpenInTemplateTreeAction extends LocateAction { - - int tplIndex; - - public OpenInTemplateTreeAction(int tplIndex) { - this.tplIndex = tplIndex; - this.setName(Toolkit.i18nText("Fine-Design_Open_In_Template_Tree")); - } - - @Override - public void actionPerformed(ActionEvent e) { - //处于搜索模式时,先退出搜索模式,再定位 - if (TemplateTreeSearchManager.getInstance().isInSearchMode()) { - TemplateTreeSearchManager.getInstance().outOfSearchMode(); - TemplateTreePane.getInstance().refreshDockingView(); - } - JTemplate template = openedTemplate.get(this.tplIndex); - locateTemplate(template); - } - - private void locateTemplate(JTemplate template) { - FILE currentTemplate = template.getEditingFILE(); - //模板不属于当前环境,跟预览一样先提示保存,再定位模板 - if (!currentTemplate.exists()) { - int selVal = showConfirmDialog( - DesignerContext.getDesignerFrame(), - Toolkit.i18nText("Fine-Design_Basic_Web_Preview_Message"), - Toolkit.i18nText("Fine-Design_Basic_Preview_Tool_Tips"), - OK_CANCEL_OPTION, - WARNING_MESSAGE - ); - if (OK_OPTION == selVal) { - CallbackSaveWorker worker = template.saveAs(); - worker.start(template.getRuntimeId()); - worker.addSuccessCallback(new Runnable() { - @Override - public void run() { - gotoEditingTemplateLeaf(template.getPath()); - } - }); - } - } else { - gotoEditingTemplateLeaf(template.getPath()); - } - } - } - - private class RightMenuCloseAction extends UpdateAction { - - CloseOption option; - int tplIndex = -1; - - public RightMenuCloseAction(CloseOption option, int tplIndex) { - this.option = option; - this.setName(option.optionName); - this.tplIndex = tplIndex; - } - - - @Override - public void actionPerformed(ActionEvent e) { - SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); - if (saveSomeTempaltePane.showSavePane()) { - - JTemplate[] templates = new JTemplate[openedTemplate.size()]; - for (int i = 0; i < openedTemplate.size(); i++) { - templates[i] = openedTemplate.get(i); - } - JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - closeTemplate(templates, currentTemplate); - - if (option == CloseOption.All) { - DesignerContext.getDesignerFrame().addAndActivateJTemplate(); - } else { - DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate); - } - - MutilTempalteTabPane.getInstance().repaint(); - } - } - - private void closeTemplate(JTemplate[] templates, JTemplate currentTemplate) { - for (int i = 0; i < templates.length; i++) { - if (option.shouldClose(tplIndex, i)) { - JTemplate jTemplate = templates[i]; - if (jTemplate == currentTemplate) { - currentTemplate = option == CloseOption.All ? null : templates[tplIndex]; - } - //判断关闭的模板是不是格式刷的被参照的模板 - openedTemplate.remove(jTemplate); - if (jTemplate != currentTemplate) { - MutilTempalteTabPane.getInstance().closeFormat(jTemplate); - HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate); - closeAndFreeLock(jTemplate); - } - } - } - } - - private void closeAndFreeLock(@Nonnull JTemplate template) { - FILE file = template.getEditingFILE(); - // 只有是环境内的文件,才执行释放锁 - if (file != null && file.isEnvFile()) { - // release lock - WorkContext.getCurrent().get(TplOperator.class).closeAndFreeFile(file.getPath()); - } - } - } - - public JTemplate getSelectedFile() { - if (openedTemplate.size() == selectedIndex) { - selectedIndex = Math.max(--selectedIndex, 0); - } - return openedTemplate.get(selectedIndex); - } - - - /** - * 关闭掉当前已打开文件列表中指定的文件 - * - * @param file 指定的文件 - */ - public void closeFileTemplate(FILE file) { - for (JTemplate temp : openedTemplate) { - if (ComparatorUtils.equals(file, temp.getEditingFILE())) { - closeSpecifiedTemplate(temp); - break; - } - } - - } - - @Override - public Dimension getPreferredSize() { - Dimension dimension = super.getPreferredSize(); - dimension.height = HEIGHT; - return dimension; - } - - private UIMenuItem initCloseOther() { - UIMenuItem closeOther = new UIMenuItem(Toolkit.i18nText("Fine-Design_Basic_FS_Close_Other_Templates")); - // Yvan: 英文下文本显示不全,后续发现如果将模板名设置的比较短,其它语言也会出现显示不全的问题,所以设置一下文本水平居中 - closeOther.setHorizontalAlignment(SwingConstants.CENTER); - setListDownItemPreferredSize(closeOther); - closeOther.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (openedTemplate.size() == 1) { - return; - } - if (!TemplateSavingChecker.check()) { - return; - } - SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); - //点击关闭其他模板,并且点击确定保存 - if (saveSomeTempaltePane.showSavePane()) { - JTemplate[] panes = new JTemplate[openedTemplate.size()]; - for (int i = 0; i < openedTemplate.size(); i++) { - panes[i] = openedTemplate.get(i); - } - for (int i = 0; i < panes.length; i++) { - if (i != selectedIndex) { - JTemplate jTemplate = panes[i]; - //判断关闭的模板是不是格式刷的被参照的模板 - openedTemplate.remove(jTemplate); - closeFormat(jTemplate); - HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate); - closeAndFreeLock(jTemplate); - } - } - JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - HistoryTemplateListCache.getInstance().removeAllHistory(); - DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate); - THIS.repaint(); - } - //如果取消保存了,则不关闭其他模板 - } - }); - if (openedTemplate.size() == 1) { - closeOther.setEnabled(false); - } - return closeOther; - } - - - private UIMenuItem[] createListDownTemplate() { - UIMenuItem[] templates = new UIMenuItem[openedTemplate.size()]; - for (int i = 0; i < openedTemplate.size(); i++) { - final int index = i; - final JTemplate tem = openedTemplate.get(i); - templates[i] = new UIMenuItem(tempalteShowName(tem), tem.getIcon()); - templates[i].setUI(new UIListDownItemUI()); - setListDownItemPreferredSize(templates[i]); - if (i == selectedIndex) { - //画选中的高亮 - templates[i].setBackground(UIConstants.SHADOW_CENTER); - } - templates[i].addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - selectedIndex = index; - tem.activeNewJTemplate(); - } - }); - } - return templates; - } - - private void setListDownItemPreferredSize(UIMenuItem item) { - Dimension dimension = item.getPreferredSize(); - dimension.height = LIST_DOWN_HEIGHT; - item.setPreferredSize(dimension); - } - - - private String tempalteShowName(JTemplate template) { - String name = TemplateUtils.createLockeTemplatedName(template, template.getTemplateName()); - if (!template.isSaved() && !name.endsWith(" *")) { - name += " *"; - } - return name; - } - - /** - * 刷新打开模板 - * - * @param history 模板 - */ - public void refreshOpenedTemplate(List> history) { - openedTemplate = history; - } - - public void setTemTemplate(JTemplate auotCreate) { - temTemplate = auotCreate; - } - - - private void showListDown() { - - UIScrollPopUpMenu menu = new UIScrollPopUpMenu(); - menu.setBorder(BorderFactory.createEmptyBorder(-3, 3, 3, 0)); - menu.add(initCloseOther()); - JSeparator separator = new JSeparator() { - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - d.height = 1; - return d; - } - }; - menu.add(new JPanel() { - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - d.height = 1; - return d; - } - }); - separator.setForeground(UIConstants.LINE_COLOR); - menu.add(separator); - menu.add(new JPanel() { - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - d.height = 1; - return d; - } - }); - UIMenuItem[] items = createListDownTemplate(); - for (int i = 0; i < items.length; i++) { - menu.add(items[i]); - } - GUICoreUtils.showPopupMenu(menu, MutilTempalteTabPane.getInstance(), MutilTempalteTabPane.getInstance().getWidth() - menu.getPreferredSize().width, getY() - 1 + getHeight()); - } - - - public void setSelectedIndex(int index) { - selectedIndex = index; - } - - - @Override - public void paintComponent(Graphics g) { - super.paintComponent(g); - double maxWidth = getWidth() - LIST_BUTTON_WIDTH * 1.0D; //最大宽度 - Graphics2D g2d = (Graphics2D) g; - paintBackgroundAndLine(g2d, maxWidth); - } - - - @Override - public void paint(Graphics g) { - //不可见时,按钮.4f透明 - AlphaComposite composite = DesignerMode.isVcsMode() - ? AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f) - : (AlphaComposite) ((Graphics2D) g).getComposite(); - ((Graphics2D) g).setComposite(composite); - super.paint(g); - } - - private void paintBackgroundAndLine(Graphics2D g2d, double maxWidth) { - paintDefaultBackground(g2d); - //最多能画的个数 - int maxTemplateNum = (int) (maxWidth) / MINWIDTH; - //计算开始画的最小模板index和最大模板index - calMinAndMaxIndex(maxTemplateNum); - calculateRealAverageWidth(maxWidth, maxTemplateNum); - int maxStringlength = calculateStringMaxLength(); - if (selectedIndex >= openedTemplate.size()) { - selectedIndex = openedTemplate.size() - 1; - } - if (selectedIndex < 0) { - selectedIndex = 0; - } - double templateStartX = 0; - startX = new int[maxPaintIndex - minPaintIndex + 1]; - isNeedToolTips = new boolean[maxPaintIndex - minPaintIndex + 1]; - - //从可以开始展示在tab面板上的tab开始画 - for (int i = minPaintIndex; i <= maxPaintIndex; i++) { - JTemplate template = openedTemplate.get(i); - Icon icon = template.getIcon(); - String name = tempalteShowName(template); - //如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理 - if (getStringWidth(name) > maxStringlength) { - name = getEllipsisName(name, maxStringlength); - isNeedToolTips[i - minPaintIndex] = true; - } else { - isNeedToolTips[i - minPaintIndex] = false; - } - - Icon selectedIcon; - if (i == closeIconIndex) { - selectedIcon = clodeMode; - } else { - selectedIcon = CLOSE; - } - if (i == selectedIndex) { - if (template.isSaving()) { - selectedIcon = WHITE_SAVING_CLOSE_ICON; - } - startX[i - minPaintIndex] = paintSelectedTab(g2d, icon, templateStartX, name, selectedIcon); - } else { - if (template.isSaving()) { - selectedIcon = GREY_SAVING_CLOSE_ICON; - } - boolean isLeft = i < selectedIndex; - startX[i - minPaintIndex] = paintUnSelectedTab(g2d, icon, templateStartX, name, selectedIcon, isLeft, mouseOveredIndex, i); - } - templateStartX += realWidth; - } - - if (!DesignerMode.isVcsMode()) { - paintListDown(g2d, maxWidth); - } - paintUnderLine(templateStartX, maxWidth, g2d); - } - - - private void paintUnderLine(double templateStartX, double maxWidth, Graphics2D g2d) { - //画下面的那条线 - if (templateStartX < maxWidth) { - GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, 2); - generalPath.moveTo((float) templateStartX, (float) (getHeight() - 1.0D)); - generalPath.lineTo((float) maxWidth, (float) (getHeight() - 1.0D)); - g2d.fill(generalPath); - //TODO hzzz delete -// g2d.setPaint(UIConstants.LINE_COLOR); -// g2d.draw(new Line2D.Double((float) templateStartX, getHeight() - 1, (float) maxWidth + LIST_BUTTON_WIDTH, getHeight() - 1)); - } - } - - private void paintDefaultBackground(Graphics2D g2d) { - //画默认背景 - g2d.setPaint(new GradientPaint(1, 1, UIConstants.TEMPLATE_TAB_PANE_BACKGROUND, 1, (float) (getHeight() - 1.0D), UIConstants.TEMPLATE_TAB_PANE_BACKGROUND)); - g2d.fillRect(0, 0, getWidth(), getHeight()); - } - - - private void paintListDown(Graphics2D g2d, double maxWidth) { - int x = (int) maxWidth + (LIST_BUTTON_WIDTH - listDownMode.getIconWidth()) / 2; - int y = (getHeight() - listDownMode.getIconHeight()) / 2; - listDownMode.paintIcon(this, g2d, x, y); - } - - /** - * 判断tab文字的长度大于能装下的最大文字长度,要用省略号 - * - * @param name - * @param maxStringlength - * @return - */ - private String getEllipsisName(String name, int maxStringlength) { - - //若是名字长度大于能显示的长度,那能显示的文字的最大长度还要减去省略号的最大长度 -// int maxellipsislength = maxStringlength - ELLIPSIS.length(); - int ellipsisWidth = getStringWidth(ELLIPSIS); - int leftkeyPoint = 0; - int rightKeyPoint = name.length() - 1; - int leftStrWidth = 0; - int rightStrWidth = 0; - while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) { - if (leftStrWidth <= rightStrWidth) { - leftkeyPoint++; - } else { - rightKeyPoint--; - } - leftStrWidth = getStringWidth(name.substring(0, leftkeyPoint)); - rightStrWidth = getStringWidth(name.substring(rightKeyPoint)); - - if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) { - if (leftStrWidth <= rightStrWidth) { - rightKeyPoint++; - } - break; - } - } - - return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint); - } - - private void calMinAndMaxIndex(int maxTemplateNum) { - //如果个数大于最多能容纳的个数,则多余的进行处理 - if (openedTemplate.size() > maxTemplateNum) { - //所点击列表中的标签页处在标签页栏最后一个标签页之后,则标签页栏左移至所点击标签页出现 - if (selectedIndex >= maxPaintIndex) { - minPaintIndex = selectedIndex - maxTemplateNum + 1; - maxPaintIndex = selectedIndex; - if (minPaintIndex <= 0) { - minPaintIndex = 0; - maxPaintIndex = maxTemplateNum - 1; - } - } else if (selectedIndex <= minPaintIndex) { - //所点击列表中的标签页处在标签页栏第一个标签页之前,则标签页栏右移至所点击标签页出现 - minPaintIndex = selectedIndex; - maxPaintIndex = minPaintIndex + maxTemplateNum - 1; - if (maxPaintIndex > openedTemplate.size() - 1) { - maxPaintIndex = openedTemplate.size() - 1; - } - } else { - if (selectedIndex >= openedTemplate.size() - 1) { - selectedIndex = openedTemplate.size() - 1; - maxPaintIndex = selectedIndex; - minPaintIndex = selectedIndex - maxTemplateNum + 1; - } else { - maxPaintIndex = minPaintIndex + maxTemplateNum - 1; - if (maxPaintIndex > openedTemplate.size() - 1) { - maxPaintIndex = openedTemplate.size() - 1; - } - } - } - } else { - minPaintIndex = 0; - maxPaintIndex = openedTemplate.size() - 1; - } - } - - - //个数小于最多能容纳的个数的情况下,看看宽度每个要画多少 - private void calculateRealAverageWidth(double maxwidth, int templateNum) { - - int num = openedTemplate.size() > templateNum ? templateNum : openedTemplate.size(); - realWidth = (int) (maxwidth / (num)); - if (realWidth > MAXWIDTH) { - realWidth = MAXWIDTH; - } else if (realWidth < MINWIDTH) { - //平均下来每个的宽度小于最小宽度 - realWidth = MINWIDTH; - } - } - - /** - * 计算过长度之后的每个tab的能接受的文字的英文字符数 - * - * @return - */ - private int calculateStringMaxLength() { - return realWidth - 3 * GAP - ICON_WIDTH - SMALLGAP - CLOSE.getIconWidth(); - - } - - private int getStringWidth(String str) { - return GraphHelper.getFontMetrics(this.getFont()).stringWidth(str); - } - - - /** - * 画选中的tab - * - * @param g2d - * @param sheeticon - * @param templateStartX - * @param sheetName - * @param closeIcon - * @return - */ - private int paintSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon) { - double[] x = {templateStartX, templateStartX, templateStartX + realWidth, templateStartX + realWidth, templateStartX}; - double[] y = {1, getHeight() + 1, getHeight() + 1, 1, 1}; - RoundRectangle2D.Double rect1 = new RoundRectangle2D.Double(templateStartX, 1, this.getWidth(), this.getHeight(), 7, 7); - g2d.setPaint(new GradientPaint(1, 1, UIConstants.SELECT_TAB, 1, (float) (getHeight() - 1.0D), UIConstants.SELECT_TAB)); - //选了30度和60度的特殊角度的x,y作为经过的两个点的坐标 - double specialLocation1 = 2.5; - double specialLocation2 = 4.330127; - GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length); - generalPath.moveTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); - generalPath.curveTo(((float) x[0] + CORNOR_RADIUS - specialLocation1), (y[0] + CORNOR_RADIUS - specialLocation2), ((float) x[0] + CORNOR_RADIUS - specialLocation2), (y[0] + CORNOR_RADIUS - specialLocation1), x[0], y[0] + CORNOR_RADIUS); - - for (int index = 1; index <= 2; index++) { - generalPath.lineTo((float) x[index], (float) y[index]); - } - - generalPath.lineTo((float) x[3], (float) y[3] + CORNOR_RADIUS); - generalPath.curveTo(((float) x[3] - CORNOR_RADIUS + specialLocation1), ((float) y[3] + CORNOR_RADIUS - specialLocation2), ((float) x[3] - CORNOR_RADIUS + specialLocation2), ((float) y[3] + CORNOR_RADIUS - specialLocation1), (float) x[3] - CORNOR_RADIUS, (float) y[3]); - generalPath.lineTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); - - generalPath.closePath(); - g2d.fill(generalPath); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setPaint(new Color(200, 201, 205)); - g2d.draw(new Arc2D.Double(x[0], y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0)); - g2d.draw(new Line2D.Double(x[0], y[0] + CORNOR_RADIUS, x[1], y[1])); - g2d.draw(new Line2D.Double(x[1], y[1], x[2], y[2])); - g2d.draw(new Line2D.Double(x[2], y[2], x[3], y[3] + CORNOR_RADIUS)); - g2d.draw(new Arc2D.Double(x[3] - CORNOR_RADIUS * 2, y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0)); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - int sheetIconY = (getHeight() - sheeticon.getIconHeight()) / 2; - sheeticon.paintIcon(this, g2d, (int) templateStartX + GAP, sheetIconY); - // 画字符 - g2d.setPaint(getForeground()); - g2d.drawString(sheetName, (int) templateStartX + sheeticon.getIconWidth() + 2 * GAP, getHeight() - GAP * 2); - int closePosition = (int) templateStartX + realWidth - CLOSE.getIconWidth() - SMALLGAP; - int closeY = (getHeight() - closeIcon.getIconHeight()) / 2; - if (!DesignerMode.isVcsMode()) { - closeIcon.paintIcon(this, g2d, closePosition, closeY); - } - return closePosition; - - } - - /** - * 画没有选中的tab - * - * @param g2d - * @param sheeticon - * @param templateStartX - * @param sheetName - * @param closeIcon - * @param isLeft - * @return - */ - private int paintUnSelectedTab(Graphics2D g2d, Icon sheeticon, double templateStartX, String sheetName, Icon closeIcon, boolean isLeft, int mouseOveredIndex, int selfIndex) { - double[] x = {templateStartX, templateStartX, templateStartX + realWidth, templateStartX + realWidth, templateStartX}; - double[] y = {-1, getHeight() - 1, getHeight() - 1, -1, -1}; - if (selfIndex == mouseOveredIndex) { - g2d.setPaint(new GradientPaint(1, 1, UIConstants.HOVER_BLUE, 1, (float) (getHeight() - 1.0D), UIConstants.HOVER_BLUE)); - } else { - g2d.setPaint(new GradientPaint(1, 1, UIConstants.SHADOW_GREY, 1, (float) (getHeight() - 1.0D), UIConstants.SHADOW_GREY)); - } - - - GeneralPath generalPath = new GeneralPath(Path2D.WIND_EVEN_ODD, x.length); - - unSelectedClosedPath(generalPath, isLeft, x, y); - g2d.fill(generalPath); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setPaint(UIConstants.TEMPLATE_TAB_PANE_BACKGROUND); - //TODO hzzz delete -// if (isLeft) { -// g2d.draw(new Arc2D.Double(x[0], y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0)); -// } else { -// g2d.draw(new Arc2D.Double(x[0] - CORNOR_RADIUS * 2, y[0], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0)); -// } - -// g2d.draw(new Line2D.Double(x[0], y[0] + CORNOR_RADIUS, x[1], y[1] + 1)); -// g2d.draw(new Line2D.Double(x[1], y[1], x[2], y[2])); - g2d.draw(new Line2D.Double(x[2], y[2], x[3], y[3] + CORNOR_RADIUS)); -// if (isLeft) { -// g2d.draw(new Arc2D.Double(x[3], y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, 90, 0)); -// } else { -// g2d.draw(new Arc2D.Double(x[3] - CORNOR_RADIUS * 2, y[3], CORNOR_RADIUS * 2, CORNOR_RADIUS * 2, 90, -90, 0)); -// } - - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - int sheetIconY = (getHeight() - sheeticon.getIconHeight()) / 2; - sheeticon.paintIcon(this, g2d, (int) templateStartX + GAP, sheetIconY); - // 画字符 - g2d.setPaint(getForeground()); - g2d.drawString(sheetName, (int) templateStartX + sheeticon.getIconWidth() + 2 * GAP, getHeight() - GAP * 2); - int closeY = (getHeight() - closeIcon.getIconHeight()) / 2; - int closePosition = (int) templateStartX + realWidth - CLOSE.getIconWidth() - SMALLGAP; - if (!DesignerMode.isVcsMode()) { - closeIcon.paintIcon(this, g2d, closePosition, closeY); - } - return closePosition; - } - - - private void unSelectedClosedPath(GeneralPath generalPath, boolean isLeft, double[] x, double[] y) { - - if (isLeft) { - generalPath.moveTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); - generalPath.curveTo(((float) x[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), x[0], y[0] + CORNOR_RADIUS); - } else { - generalPath.moveTo((float) x[0] - CORNOR_RADIUS, (float) y[0]); - generalPath.curveTo(((float) x[0] - CORNOR_RADIUS + SPECIAL_LOCATION_1), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[0] - CORNOR_RADIUS + SPECIAL_LOCATION_2), (y[0] + CORNOR_RADIUS - SPECIAL_LOCATION_1), x[0], y[0] + CORNOR_RADIUS); - } - - for (int index = 1; index <= 2; index++) { - generalPath.lineTo((float) x[index], (float) y[index]); - } - - generalPath.lineTo((float) x[3], (float) y[3] + CORNOR_RADIUS); - - if (isLeft) { - generalPath.curveTo(((float) x[3] + CORNOR_RADIUS - SPECIAL_LOCATION_1), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) y[3] - CORNOR_RADIUS + SPECIAL_LOCATION_1), (float) x[3] + CORNOR_RADIUS, (float) y[3]); - generalPath.lineTo((float) x[0] + CORNOR_RADIUS, (float) y[0]); - } else { - generalPath.curveTo(((float) x[3] - CORNOR_RADIUS + SPECIAL_LOCATION_1), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_2), ((float) x[3] - CORNOR_RADIUS + SPECIAL_LOCATION_2), ((float) y[3] + CORNOR_RADIUS - SPECIAL_LOCATION_1), (float) x[3] - CORNOR_RADIUS, (float) y[3]); - generalPath.lineTo((float) x[0] - CORNOR_RADIUS, (float) y[0]); - } - - generalPath.closePath(); - } - - - public void setIsCloseCurrent(boolean isCloseCurrent) { - this.isCloseCurrent = isCloseCurrent; - - } - - /** - * 关闭模板 - * - * @param specifiedTemplate 模板 - */ - public void closeSpecifiedTemplate(JTemplate specifiedTemplate) { - if (specifiedTemplate == null) { - return; - } - - if (!specifiedTemplate.isALLSaved() && !DesignerMode.isVcsMode()) { - specifiedTemplate.stopEditing(); - int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + specifiedTemplate.getEditingFILE() + "\" ?", - Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); - if (returnVal == JOptionPane.YES_OPTION) { - CallbackSaveWorker worker = specifiedTemplate.save(); - worker.addSuccessCallback(new Runnable() { - @Override - public void run() { - FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName())); - closeTpl(specifiedTemplate); - } - }); - worker.start(specifiedTemplate.getRuntimeId()); - } else if (returnVal == JOptionPane.NO_OPTION) { - closeTpl(specifiedTemplate); - } - } else { - closeTpl(specifiedTemplate); - } - - } - - private void closeTpl(@Nonnull JTemplate specifiedTemplate) { - HistoryTemplateListCache.getInstance().closeSelectedReport(specifiedTemplate); - closeAndFreeLock(specifiedTemplate); - activePrevTemplateAfterClose(); - } - - private void closeAndFreeLock(@Nonnull JTemplate template) { - FILE file = template.getEditingFILE(); - // 只有是环境内的文件,才执行释放锁 - if (file != null && file.isEnvFile()) { - // release lock - TemplateResourceManager.getResource().closeTemplate(file.getPath()); - } - } - - /** - * 后台关闭当前编辑模板 - */ - public void closeCurrentTpl() { - JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - this.setIsCloseCurrent(true); - this.closeFormat(jTemplate); - this.closeSpecifiedTemplate(jTemplate); - } - - /** - * 关闭模板 - * - * @param closedTemplate 模板 - */ - public void closeFormat(JTemplate closedTemplate) { - //表单不需要处理 - if (!closedTemplate.isJWorkBook()) { - return; - } - - if (DesignerContext.getFormatState() == DesignerContext.FORMAT_STATE_NULL) { - return; - } - - //是被参照的模板被关闭,则重置格式刷 - closedTemplate.doConditionCancelFormat(); - } - - /** - * 关闭掉一个模板之后激活新的待显示模板 - */ public void activePrevTemplateAfterClose() { - if (openedTemplate.isEmpty()) { - //新建并激活模板 - DesignerContext.getDesignerFrame().addAndActivateJTemplate(); - selectedIndex = 0; - //此时刚自动新建的模板在HistoryTemplateListCache的editingTemplate - temTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - - } else { - // 如果关闭的模板是当前选中的模板,则重新激活当前 selectIndex 的模板; - // selectIndex 没有变化,但是对应的模板已经变成了前一张模板 - if (closeIconIndex == selectedIndex || isCloseCurrent) { - // 如果当前关闭的模板在最右侧,那么预览上一个,防止数组越界 - if (selectedIndex >= maxPaintIndex) { - // selectIndex 不会 <0 因为如果关闭的是打开的最后一个模板,那么关闭之后 openedTemplate.isEmpty() = true - selectedIndex--; - } - isCloseCurrent = false; - } - // 如果关闭的模板不是当前选中的模板,那么重新获取一下当前模板的 index,激活该 index - else { - JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - selectedIndex = HistoryTemplateListCache.getInstance().contains(template); - } - if (selectedIndex < openedTemplate.size()) { - //如果是已后台关闭的模板,则重新打开文件 - openedTemplate.get(selectedIndex).activeOldJTemplate(); - } - - } - } - - - private boolean isOverCloseIcon(int evtX) { - boolean isOverCloseIcon = false; - for (int i = 0; i < startX.length; i++) { - if (evtX >= startX[i] && evtX <= startX[i] + CLOSE.getIconWidth()) { - isOverCloseIcon = true; - break; - } - } - return isOverCloseIcon; - } - - - private boolean isOverListDown(int evtX) { - int maxWidth = getWidth() - LIST_BUTTON_WIDTH; - return evtX >= (maxWidth + SMALLGAP) && evtX <= (getWidth() - SMALLGAP); - } - - - private int getTemplateIndex(int evtX) { - int textX = 0; - for (int i = minPaintIndex; i <= maxPaintIndex; i++) { - int textWidth = realWidth; - if (evtX >= textX && evtX < textX + textWidth) { - return i; - } - textX += textWidth; - } - return -1; - } - - - /** - * 处理自动新建的模板 在切换时的处理 - */ - public void doWithtemTemplate() { - //temtemplate保存的一定是手动新建的没有编辑或是编辑了没有保存的模板 - //没有保存,说明有编辑;已经保存在磁盘里的文件,说明有过处理,并且已经保存,此时切换都不将其自动关闭 - if (temTemplate == null || temTemplate == HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()) { - return; - } - - if (!temTemplate.isSaved() || !temTemplate.getEditingFILE().isMemFile()) { - temTemplate = null; - } - - //自动新建的模板B若没有进行任何编辑(新建模板没有进行任何编辑时saved都是true):还没有存盘 - if (temTemplate != null && temTemplate.getEditingFILE().isMemFile() && temTemplate.isSaved()) { - HistoryTemplateListCache.getInstance().closeSelectedReport(temTemplate); - temTemplate = null; - setSelectedIndex(HistoryTemplateListCache.getInstance().contains(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate())); - } - } - - private class UIListDownItemUI extends BasicMenuItemUI { - @Override - protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { - if (menuItem.getIcon() == null) { - super.paintBackground(g, menuItem, bgColor); - return; - } - ButtonModel model = menuItem.getModel(); - Color oldColor = g.getColor(); - int menuWidth = menuItem.getWidth(); - int menuHeight = menuItem.getHeight(); - g.setColor(UIConstants.NORMAL_BACKGROUND); - g.fillRect(0, 0, menuWidth, menuHeight); - boolean itemIsSelected = menuItem instanceof JMenu && model.isSelected(); - if (menuItem.isOpaque()) { - if (model.isArmed() || itemIsSelected) { - GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, UIConstants.ARC); - } else { - GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, menuItem.getBackground(), UIConstants.ARC); - } - g.setColor(oldColor); - } else if (model.isArmed() || itemIsSelected) { - GUIPaintUtils.fillPaint((Graphics2D) g, GAP, 0, menuWidth - GAP, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, UIConstants.ARC); - g.setColor(oldColor); - } - } - } - - private class MultiTemplateTabMouseListener implements MouseListener { - - - /** - * 鼠标进入 - * - * @param e 鼠标事件 - */ - @Override - public void mouseEntered(MouseEvent e) { - // do nothing - } - - /** - * 鼠标离开 - * - * @param e 鼠标事件 - */ - @Override - public void mouseExited(MouseEvent e) { - listDownMode = LIST_DOWN; - closeIconIndex = -1; - mouseOveredIndex = -1; - MutilTempalteTabPane.this.repaint(); - } - - /** - * 鼠标释放 - * - * @param e 鼠标事件 - */ - @Override - public void mouseReleased(MouseEvent e) { - // do nothing - } - - /** - * 点击 - * - * @param e 鼠标事件 - */ - @Override - public void mouseClicked(MouseEvent e) { - // do nothing - } - - /** - * 按下 - * - * @param e 鼠标事件 - */ - @Override - public void mousePressed(MouseEvent e) { - //如果在版本管理情况下,不允许切换tab - if (DesignerMode.isVcsMode()) { - return; - } - - int evtX = e.getX(); - - //是否点击关闭按钮 如果点击了关闭按钮,则将点击的模板关闭,不需要切换,如果没有点击关闭按钮,则切换到点击的模板处 - boolean isOverCloseIcon = isOverCloseIcon(evtX); - if (isOverListDown(evtX)) { - listDownMode = isOverListDown(evtX) ? MOUSE_PRESS_LIST_DOWN : LIST_DOWN; - if (!isShowList) { - showListDown(); - } - isShowList = !isShowList; - - } else if (isOverCloseIcon) { - //关闭按钮的图标变化 - closeIconIndex = getTemplateIndex(evtX); - clodeMode = MOUSE_PRESS_CLOSE; - //关闭close图标所在的模板{ - JTemplate template = openedTemplate.get(closeIconIndex); - if (template.isOpening()) { - WorkerManager.getInstance().cancelWorker(template.getPath()); - } else if (template.isSaving()) { - boolean completed = WorkerManager.getInstance().isCompleted(template.getTarget().getTemplateID()); - if (!completed) { - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), - Toolkit.i18nText("Fine-Design_Close_Template_Tip", template.getEditingFILE().getName())); - return; - } - } - closeFormat(template); - closeSpecifiedTemplate(template); - DesignerContext.getDesignerFrame().getContentFrame().repaint(); - isShowList = false; - } else { - //没有点击关闭和ListDown按钮,则切换到点击的模板处 - closeIconIndex = -1; - clodeMode = CLOSE; - int tempSelectedIndex = selectedIndex; - if (selectedIndex != getTemplateIndex(evtX) && getTemplateIndex(evtX) != -1) { - openedTemplate.get(selectedIndex).stopEditing(); - selectedIndex = getTemplateIndex(evtX); - //如果在权限编辑情况下,不允许切换到表单类型的工作簿 - if (DesignerMode.isAuthorityEditing() && !openedTemplate.get(selectedIndex).isJWorkBook()) { - DesignerContext.getDesignerFrame().addAndActivateJTemplate(openedTemplate.get(tempSelectedIndex)); - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Form_Authority_Edited_Cannot_Be_Supported") - + "!", Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); - MutilTempalteTabPane.this.repaint(); - return; - } - JTemplate evtXTemplate = openedTemplate.get(getTemplateIndex(evtX)); - evtXTemplate.activeNewJTemplate(); - } - isShowList = false; - } - MutilTempalteTabPane.this.repaint(); - - - } - - - } - - private class MultiTemplateTabMouseMotionListener implements MouseMotionListener { - /** - * 鼠标拖拽 - * - * @param e 鼠标事件 - */ - @Override - public void mouseDragged(MouseEvent e) { - // do nothing - } - - /** - * 鼠标移动 - * - * @param e 鼠标事件 - */ - @Override - public void mouseMoved(MouseEvent e) { - int evtX = e.getX(); - mouseOveredIndex = getTemplateIndex(evtX); - - //看是否需要显示toolTip - if (mouseOveredIndex != -1 && isNeedToolTips[mouseOveredIndex - minPaintIndex]) { - setToolTipText(openedTemplate.get(mouseOveredIndex).getEditingFILE().getName()); - } else { - setToolTipText(null); - } - - listDownMode = isOverListDown(evtX) ? MOUSE_OVER_LIST_DOWN : LIST_DOWN; - - boolean isOverCloseIcon = isOverCloseIcon(evtX); - clodeMode = isOverCloseIcon ? MOUSE_OVER_CLOSE : CLOSE; - closeIconIndex = isOverCloseIcon ? mouseOveredIndex : -1; - MutilTempalteTabPane.this.repaint(); - } + MultiTemplateTabPane.getInstance().activePrevTemplateAfterClose(); } - - } diff --git a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java index d4737f084..f53930602 100644 --- a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java +++ b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java @@ -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 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); diff --git a/designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java b/designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java index 0a9361629..1e553735d 100644 --- a/designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java +++ b/designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java @@ -1,5 +1,6 @@ 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; @@ -53,4 +54,12 @@ public interface DefaultValueAdjustProvider extends Selectable { */ Font transformFontByResolution(FRFont font, int resolution); + /** + * 修改设计可用字体默认列表 + * @return + */ + default String[] getAvailableFontFamilyNames4Report() { + return Utils.getAvailableFontFamilyNames4Report(); + } + } diff --git a/designer-base/src/main/java/com/fr/design/gui/iprogressbar/ProgressDialog.java b/designer-base/src/main/java/com/fr/design/gui/iprogressbar/ProgressDialog.java index 2c1e6abf5..44e697d04 100644 --- a/designer-base/src/main/java/com/fr/design/gui/iprogressbar/ProgressDialog.java +++ b/designer-base/src/main/java/com/fr/design/gui/iprogressbar/ProgressDialog.java @@ -20,6 +20,10 @@ import java.awt.Frame; /** * 加载进度弹窗 + * 使用注意点: + * 必须到使用时再初始化,不要作为属性存在 + * 因为涉及到 大小/位置 相对于 parent 的相对判断 + * 见 {@link com.fr.design.gui.iprogressbar.ProgressDialogTest} */ public class ProgressDialog extends UIDialog { protected static final FRFont font = DesignUtils diff --git a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java index 4a722fc50..18207011f 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java +++ b/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(); } + /** + * 设置最大值 + * @param maxValue 最大值 + */ + public void setMaxValue(double maxValue) { + this.maxValue = maxValue; + textField.setMaxValue(maxValue); + } + private void componentInitListeners() { preButton.addActionListener(new ActionListener() { @Override diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java index f273fa209..b87a70b5b 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java +++ b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java @@ -144,8 +144,8 @@ public class TemplateFileTree extends EnvFileTree { Set supportTypes = createFileExtensionFilter(); return FRContext.getFileNodes().list( path, - supportTypes.toArray(new FileExtension[supportTypes.size()]) - ); + supportTypes.toArray(new FileExtension[supportTypes.size()]), false, true + ); } private Set createFileExtensionFilter() { diff --git a/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java b/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java index 33af029ad..1f2fb91b8 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java +++ b/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(); diff --git a/designer-base/src/main/java/com/fr/design/gui/style/FRFontPane.java b/designer-base/src/main/java/com/fr/design/gui/style/FRFontPane.java index f806ded06..8af5c08d4 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/FRFontPane.java +++ b/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); diff --git a/designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperlinkPane.java b/designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperlinkPane.java index 7147ef90e..48affb7dc 100644 --- a/designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperlinkPane.java +++ b/designer-base/src/main/java/com/fr/design/hyperlink/ReportletHyperlinkPane.java @@ -158,6 +158,14 @@ public class ReportletHyperlinkPane extends AbstractHyperLinkPane { 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 { 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; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/FontConfigPane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/FontConfigPane.java index 6386e31e0..2b98479be 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/FontConfigPane.java +++ b/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 integerList = new Vector<>(); for (int i = 1; i < 100; i++) { integerList.add(i); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java index 2b19b232e..a70870a61 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java +++ b/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")); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java index bf5b8ba45..8cff3ffbb 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java +++ b/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中的模板 diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java index 4d9b6e35e..4dd14bce6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java +++ b/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); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/widget/MobileTabFontConfPane.java b/designer-base/src/main/java/com/fr/design/mainframe/widget/MobileTabFontConfPane.java index b4d678f98..8f10d2102 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/widget/MobileTabFontConfPane.java +++ b/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 integerList = new Vector(); for (int i = 1; i < 100; i++) { integerList.add(i); diff --git a/designer-base/src/main/java/com/fr/design/style/FontFamilyPane.java b/designer-base/src/main/java/com/fr/design/style/FontFamilyPane.java index 37076c66f..ba496ae13 100644 --- a/designer-base/src/main/java/com/fr/design/style/FontFamilyPane.java +++ b/designer-base/src/main/java/com/fr/design/style/FontFamilyPane.java @@ -3,6 +3,7 @@ package com.fr.design.style; import com.fr.base.Utils; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.DesignUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.FRFont; @@ -26,7 +27,7 @@ public class FontFamilyPane extends JPanel { familyField = new UITextField(); familyField.setEditable(false); - familyList = new JList(Utils.getAvailableFontFamilyNames4Report()); + familyList = new JList(DesignUtils.getAvailableFontFamilyNames4Report()); familyList.setVisibleRowCount(4); familyList.addListSelectionListener(listener); diff --git a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java index dfeeacc60..4779f9191 100644 --- a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java @@ -2,6 +2,7 @@ package com.fr.design.utils; import com.fr.base.FeedBackInfo; import com.fr.base.ServerConfig; +import com.fr.base.Utils; import com.fr.concurrent.NamedThreadFactory; import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; @@ -481,4 +482,16 @@ public class DesignUtils { return null; } + /** + * 获取设计器可用字体 + * @return + */ + public static String[] getAvailableFontFamilyNames4Report() { + DefaultValueAdjustProvider valueAdjust = DesignUtils.getValueAdjust(); + if (valueAdjust != null) { + return valueAdjust.getAvailableFontFamilyNames4Report(); + } + return Utils.getAvailableFontFamilyNames4Report(); + } + } diff --git a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java index b070b7f07..d9c8568bf 100644 --- a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java @@ -3,7 +3,7 @@ package com.fr.design.worker.open; import com.fr.base.chart.exception.ChartNotFoundException; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.file.HistoryTemplateListCache; -import com.fr.design.file.MutilTempalteTabPane; +import com.fr.design.file.MultiTemplateTabPane; import com.fr.design.file.TemplateTreePane; import com.fr.design.i18n.Toolkit; import com.fr.design.lock.LockInfoDialog; @@ -87,7 +87,7 @@ public class OpenWorker extends SwingWorker { UIManager.getIcon("OptionPane.errorIcon")); } if (cause.getCause() instanceof TplLockedException) { - MutilTempalteTabPane.getInstance().closeCurrentTpl(); + MultiTemplateTabPane.getInstance().closeCurrentTpl(); TemplateTreePane.getInstance().getFileNode().setLock(UUID.randomUUID().toString()); LockInfoDialog.show(null); } diff --git a/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java b/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java index 42490fe7d..1a6e2bf1c 100644 --- a/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java +++ b/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TemplateTransformer.java @@ -2,7 +2,7 @@ package com.fr.nx.app.designer.toolbar; import com.fr.base.extension.FileExtension; 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.JTemplate; import com.fr.file.FILE; @@ -103,9 +103,9 @@ public enum TemplateTransformer { DesignerContext.getDesignerFrame().openTemplate(file); return; } - MutilTempalteTabPane.getInstance().setIsCloseCurrent(true); - MutilTempalteTabPane.getInstance().closeFormat(jt); - MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt); + MultiTemplateTabPane.getInstance().setIsCloseCurrent(true); + MultiTemplateTabPane.getInstance().closeFormat(jt); + MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(jt); DesignerContext.getDesignerFrame().openTemplate(file); } diff --git a/designer-base/src/main/java/com/fr/start/BaseDesigner.java b/designer-base/src/main/java/com/fr/start/BaseDesigner.java index 016c6bd6d..44228c2a4 100644 --- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java +++ b/designer-base/src/main/java/com/fr/start/BaseDesigner.java @@ -8,7 +8,7 @@ import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; import com.fr.design.constants.DesignerLaunchStatus; 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.fun.DesignerStartOpenFileProcessor; import com.fr.design.fun.impl.DesignerStartWithEmptyFile; @@ -39,6 +39,7 @@ import org.jetbrains.annotations.Nullable; import java.awt.Window; import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -136,7 +137,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock { DesignerFrame df = DesignerContext.getDesignerFrame(); isException = openFile(df, isException, file); 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) { FineLoggerFactory.getLogger().error(e.getMessage(), e); if (!isException) { @@ -192,7 +193,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock { } else { df.addAndActivateJTemplate(); // 如果没有模板,则需要确认一下 - MutilTempalteTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); + MultiTemplateTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); } } @@ -252,7 +253,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock { private boolean createNewTemplate(DesignerFrame df) { df.addAndActivateJTemplate(); // 如果没有模板,则需要确认一下 - MutilTempalteTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); + MultiTemplateTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); return true; } diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java b/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java index 7f4a0eeb9..b42cc4ed8 100644 --- a/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java +++ b/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java @@ -3,7 +3,7 @@ package com.fr.start.common; import com.fr.base.svg.IconUtils; 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.gui.ilable.UILabel; import com.fr.design.i18n.DesignSizeI18nManager; import com.fr.design.i18n.Toolkit; @@ -59,7 +59,7 @@ public class DesignerOpenEmptyPanel extends JPanel { HistoryTemplateListCache.getInstance().setCurrentEditingTemplate(null); df.addAndActivateJTemplate(); // 如果没有模板,则需要确认一下 - MutilTempalteTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); + MultiTemplateTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); } }); createButton.setBorder(new EmptyBorder(0, 10, 0, 10)); diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerStartupPool.java b/designer-base/src/main/java/com/fr/start/common/DesignerStartupPool.java index 524c474df..6625a5a31 100644 --- a/designer-base/src/main/java/com/fr/start/common/DesignerStartupPool.java +++ b/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 java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; /** * created by Harrison on 2022/07/03 **/ 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() { return COMMON_EXECUTOR; } + + /** + * + * @return 启动设计器线程池 + */ + public static Executor designer() { + + return DESIGNER_EXECUTOR; + } } diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupLoadingPanel.java b/designer-base/src/main/java/com/fr/startup/ui/StartupLoadingPanel.java new file mode 100644 index 000000000..59f86fc46 --- /dev/null +++ b/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 MODULE_LISTENER = new Listener() { + @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; + } + + +} diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java index 0a0cdb4aa..41cd75890 100644 --- a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java +++ b/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.design.DesignerEnvManager; -import com.fr.design.components.loading.LoadingPane; import com.fr.design.dialog.UIExpandDialog; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; @@ -12,12 +11,14 @@ import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.ColorUtils; import com.fr.design.utils.ThemeUtils; +import com.fr.design.utils.gui.GUICoreUtils; import com.fr.exit.DesignerExiter; import com.fr.general.GeneralUtils; import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; import com.fr.stable.ProductConstants; import com.fr.stable.collections.CollectionUtils; +import com.fr.stable.os.OperatingSystem; import com.fr.start.common.DesignerStartupContext; import com.fr.startup.metric.DesignerMetrics; import org.jetbrains.annotations.NotNull; @@ -25,7 +26,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFrame; -import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.ScrollPaneConstants; @@ -34,7 +34,6 @@ import javax.swing.SwingWorker; import javax.swing.border.EmptyBorder; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; @@ -59,9 +58,6 @@ import java.util.Map; **/ public class StartupPageWindow extends JFrame { - private static final int CONTENT_LAYER = 0; - private static final int TRANSPARENT_LAYER = 1; - private static final Color HOVER_COLOR = new Color(65, 155, 249); private static final Color SEP_COLOR = new Color(224, 224, 225); @@ -84,56 +80,51 @@ public class StartupPageWindow extends JFrame { private JPanel body; - private LoadingPane loadingPane = new LoadingPane(); - - private JLayeredPane layeredPane = new JLayeredPane() { - @Override - public void doLayout() { - for (Component comp : getComponents()) { - comp.setBounds(0, 0, getWidth(), getHeight()); - } - } - }; - public StartupPageWindow(StartupPageModel pageModel) { patchUIAction(pageModel); setLayout(new BorderLayout()); + + initCenter(pageModel); + + // Workspace-detail + setSize(SCREEN_SIZE); + setDefaultTitle(); + addDefaultListeners(); + + 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)); - // 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)); + JPanel headerPanel = createHeader(); this.body.add(headerPanel, BorderLayout.NORTH); - - // Workspace-description - this.workspacePanel = generateWorkspacePanel(pageModel); - this.body.add(workspacePanel, BorderLayout.CENTER); + } - workspacePanel.setSelectWorkspaceRunnable(new Runnable() { - @Override - public void run() { - JPanel newPanel = generateRecentOpenPanel(pageModel); - - body.remove(recentOpenPanel); - recentOpenPanel = newPanel; - body.add(recentOpenPanel, BorderLayout.SOUTH); - validate(); - repaint(); - } - }); + private void initRecentOpenPanel(StartupPageModel pageModel) { this.recentOpenPanel = generateRecentOpenPanel(pageModel); this.body.add(recentOpenPanel, BorderLayout.SOUTH); + } + + private void initContentPanel() { this.contentPane = new JPanel() { @Override protected void paintComponent(Graphics g) { @@ -144,32 +135,58 @@ public class StartupPageWindow extends JFrame { this.contentPane.setLayout(getCenterLayout(body)); this.contentPane.add(this.body, BorderLayout.CENTER); this.contentPane.setPreferredSize(this.body.getPreferredSize()); - - this.layeredPane.setName("layered-pane"); - this.layeredPane.add(this.contentPane, CONTENT_LAYER); - this.layeredPane.add(this.loadingPane, TRANSPARENT_LAYER); - this.layeredPane.moveToFront(this.contentPane); - add(this.layeredPane, BorderLayout.CENTER); + add(this.contentPane, BorderLayout.CENTER); + } + + private void initWorkspacePanel(StartupPageModel pageModel) { - // Workspace-detail - setSize(SCREEN_SIZE); - setDefaultTitle(); - addDefaultListeners(); + // Workspace-description + this.workspacePanel = generateWorkspacePanel(pageModel); + this.body.add(workspacePanel, BorderLayout.CENTER); - repaint(); - validate(); - revalidate(); + workspacePanel.setSelectWorkspaceRunnable(new Runnable() { + @Override + public void run() { + JPanel newPanel = generateRecentOpenPanel(pageModel); + + body.remove(recentOpenPanel); + recentOpenPanel = newPanel; + body.add(recentOpenPanel, BorderLayout.SOUTH); + validate(); + repaint(); + } + }); + } + + @NotNull + private static JPanel createHeader() { - setFullScreen(); - + // 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; } + /** + * 1-mac启动时全屏 + * 2-windows 则居中处理 + */ private void setFullScreen() { - - Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); - this.setLocation(0, 0); - this.setSize(screenSize.width, screenSize.height); + + if (OperatingSystem.isMacos()) { + this.setLocation(0, 0); + this.setSize(SCREEN_SIZE.width, SCREEN_SIZE.height); + } else { + GUICoreUtils.setWindowFullScreen(this); + } } private void addDefaultListeners() { @@ -214,44 +231,51 @@ public class StartupPageWindow extends JFrame { } private void enterWorkspace(Runnable action) { - - loadingPane.start(); - layeredPane.moveToFront(loadingPane); - SwingWorker task = new SwingWorker() { - @Override - protected Void doInBackground() throws Exception { - action.run(); - return null; - } - @Override - protected void done() { - - try { - Void result = get(); - setVisible(false); - } catch (Exception e) { - // 处理错误 - UIUtil.invokeLaterIfNeeded(() -> { - UIExpandDialog.Builder() - .owner(StartupPageWindow.this) - .title(Toolkit.i18nText("Fine-Design_Basic_Remote_Env_Try")) - .message(Toolkit.i18nText("Fine-Design_Basic_Connection_Failed")) - .messageType(UIExpandDialog.WARNING_MESSAGE) - .detail(e.getMessage()) - .expand(true) - .modal(false) - .build() - .setVisible(true); - }); - FineLoggerFactory.getLogger().error(e.getMessage(), e); - layeredPane.moveToFront(contentPane); - } finally { - loadingPane.stop(); + UIUtil.invokeAndWaitIfNeeded(() -> { + + // 必须直接初始化 + // 见 https://work.fineres.com/browse/REPORT-85293 + StartupLoadingPanel loadingPanel = new StartupLoadingPanel(this); + loadingPanel.show(); + setEnabled(false); + + SwingWorker task = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + action.run(); + return null; } - } - }; - task.execute(); + + @Override + protected void done() { + + try { + Void result = get(); + setVisible(false); + } catch (Exception e) { + // 处理错误 + UIUtil.invokeLaterIfNeeded(() -> { + UIExpandDialog.Builder() + .owner(StartupPageWindow.this) + .title(Toolkit.i18nText("Fine-Design_Basic_Remote_Env_Try")) + .message(Toolkit.i18nText("Fine-Design_Basic_Connection_Failed")) + .messageType(UIExpandDialog.WARNING_MESSAGE) + .detail(e.getMessage()) + .expand(true) + .modal(false) + .build() + .setVisible(true); + setEnabled(true); + }); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + loadingPanel.hide(); + } + } + }; + task.execute(); + }); } private JPanel generateRecentOpenPanel(StartupPageModel pageModel) { diff --git a/designer-base/src/test/java/com/fr/design/gui/iprogressbar/ProgressDialogTest.java b/designer-base/src/test/java/com/fr/design/gui/iprogressbar/ProgressDialogTest.java new file mode 100644 index 000000000..336850f26 --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/gui/iprogressbar/ProgressDialogTest.java @@ -0,0 +1,55 @@ +package com.fr.design.gui.iprogressbar; + +import com.fr.design.utils.DevUtils; + +import java.awt.Dimension; +import java.awt.Frame; +import java.util.function.Consumer; + +/** + * @author Harrison + * @version 11.0 + * Created by Harrison on 2022/11/23 + */ +public class ProgressDialogTest { + + public static void main(String[] args) { + + mockInitSize(); + } + + /** + * 模拟 frame 的大小未初始化好的情况 + */ + private static void mockNotInitSize() { + + DevUtils.show(new Consumer() { + @Override + public void accept(Frame frame) { + + Dimension origin = frame.getSize(); + frame.setSize(0, 0); + ProgressDialog progressDialog = new ProgressDialog(frame); + progressDialog.setVisible(true); + progressDialog.updateLoadingText("test"); + frame.setSize(origin); + } + }); + } + + /** + * 模拟 frame 的大小初始化好的情况 + */ + private static void mockInitSize() { + + DevUtils.show(new Consumer() { + @Override + public void accept(Frame frame) { + + ProgressDialog progressDialog = new ProgressDialog(frame); + progressDialog.setVisible(true); + progressDialog.updateLoadingText("test"); + } + }); + } +} \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/design/chart/axis/ChartAlertValuePane.java b/designer-chart/src/main/java/com/fr/design/chart/axis/ChartAlertValuePane.java index d0244ceba..59250c972 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/axis/ChartAlertValuePane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/axis/ChartAlertValuePane.java @@ -18,6 +18,7 @@ import com.fr.design.layout.TableLayoutHelper; import com.fr.design.style.AlphaPane; import com.fr.design.style.FRFontPane; import com.fr.design.style.color.ColorSelectBox; +import com.fr.design.utils.DesignUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.FRFont; @@ -114,7 +115,7 @@ public class ChartAlertValuePane extends BasicBeanPane { fontNameBox.setPreferredSize(new Dimension(80,20)); fontNameBox.addItem("SimSun"); // TODO 这边字体中没有在列表内 - String[] names = Utils.getAvailableFontFamilyNames4Report(); + String[] names = DesignUtils.getAvailableFontFamilyNames4Report(); for(int i = 0; i < names.length; i++) { fontNameBox.addItem(names[i]); } diff --git a/designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/DataLabelStylePane.java b/designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/DataLabelStylePane.java index a2047b4e1..c2036b729 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/DataLabelStylePane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/DataLabelStylePane.java @@ -9,6 +9,7 @@ import com.fr.chart.base.TextAttr; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.dialog.BasicPane; +import com.fr.design.utils.DesignUtils; import com.fr.general.FRFont; import com.fr.design.style.FRFontPane; @@ -36,7 +37,7 @@ public class DataLabelStylePane extends BasicPane { private void initPane(boolean isSurpportFontColor) { this.setLayout(FRGUIPaneFactory.createBoxFlowLayout()); - this.add(nameBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report())); + this.add(nameBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report())); nameBox.setPreferredSize(new Dimension(80, 20)); String[] styles = { diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/AbstractCustomFieldComboBoxPane.java b/designer-chart/src/main/java/com/fr/design/chartx/component/AbstractCustomFieldComboBoxPane.java index 562393699..41deba8d5 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/component/AbstractCustomFieldComboBoxPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/AbstractCustomFieldComboBoxPane.java @@ -23,13 +23,13 @@ import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import java.util.ArrayList; -import java.util.List; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Component; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.List; /** * Created by shine on 2018/9/12. @@ -93,12 +93,13 @@ public abstract class AbstractCustomFieldComboBoxPane extends BasicBeanPane(columnNameList); } private void checkCardPane() { diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/correlation/AbstractCorrelationPane.java b/designer-chart/src/main/java/com/fr/design/chartx/component/correlation/AbstractCorrelationPane.java index 5c468c424..2cb52f454 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/component/correlation/AbstractCorrelationPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/correlation/AbstractCorrelationPane.java @@ -127,4 +127,14 @@ public abstract class AbstractCorrelationPane extends BasicBeanPane { return StringUtils.EMPTY; } + /** + * 清空 “系列名使用字段名” 表格 + */ + public void clearAllBoxList() { + this.correlationPane.getTable().clear(); + this.correlationPane.validate(); + this.correlationPane.repaint(); + this.correlationPane.revalidate(); + } + } diff --git a/designer-chart/src/main/java/com/fr/design/chartx/single/DataSetPane.java b/designer-chart/src/main/java/com/fr/design/chartx/single/DataSetPane.java index 3df0d3d6d..dab74e15a 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/single/DataSetPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/single/DataSetPane.java @@ -8,6 +8,7 @@ import com.fr.design.chartx.fields.AbstractDataSetFieldsPane; import com.fr.design.data.tabledata.wrapper.TableDataWrapper; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.chart.gui.data.DatabaseTableDataPane; +import com.fr.stable.StringUtils; import javax.swing.JPanel; import java.awt.BorderLayout; @@ -75,6 +76,10 @@ public class DataSetPane extends FurtherBasicBeanPane { List columnNameList = dataWrap.calculateColumnNameList(); if (dataSetFieldsPane != null) { + // 如果属性编辑画板中选中的数据集发生改变,则清空之前的匹配项 + if (!StringUtils.equals(dataSetFieldsPane.getTableName(), dataWrap.getTableDataName())) { + dataSetFieldsPane.clearAllBoxList(); + } dataSetFieldsPane.refreshBoxListWithSelectTableData(columnNameList); dataSetFieldsPane.setTableName(dataWrap.getTableDataName()); } diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/table/SeriesNameUseFieldNamePane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/table/SeriesNameUseFieldNamePane.java index 9783c0577..ec63cda9b 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/table/SeriesNameUseFieldNamePane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/table/SeriesNameUseFieldNamePane.java @@ -24,8 +24,6 @@ import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.event.ChangeEvent; -import java.util.ArrayList; -import java.util.List; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; @@ -33,6 +31,8 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.List; /** * 属性表 数据集界面: 系列名 使用字段名. @@ -145,7 +145,7 @@ public class SeriesNameUseFieldNamePane extends FurtherBasicBeanPane { + // kuns: 默认修改500, 在地图修改系列颜色text时, 快速响应. + SwingUtilities.invokeLater(this::runChange); }, 500, TimeUnit.MILLISECONDS); } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartAlertValuePane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartAlertValuePane.java index 387d974d2..49e7f3fa9 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartAlertValuePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartAlertValuePane.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.general.FRFont; import com.fr.general.GeneralUtils; @@ -99,7 +100,7 @@ public class VanChartAlertValuePane extends BasicBeanPane { alertText.setPreferredSize(new Dimension(TEXT_WD, HT)); fontSize = new UIComboBox(FRFontPane.FONT_SIZES); - fontName = new UIComboBox(Utils.getAvailableFontFamilyNames4Report()); + fontName = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report()); fontColor = new ColorSelectBox(100); } diff --git a/designer-chart/src/main/java/com/fr/van/chart/multilayer/data/MultiPiePlotTableDataContentPane.java b/designer-chart/src/main/java/com/fr/van/chart/multilayer/data/MultiPiePlotTableDataContentPane.java index bfea7e1dc..b32ea4b67 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/multilayer/data/MultiPiePlotTableDataContentPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/multilayer/data/MultiPiePlotTableDataContentPane.java @@ -10,6 +10,7 @@ import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ispinner.UISpinner; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.mainframe.chart.gui.ChartDataPane; import com.fr.design.mainframe.chart.gui.data.CalculateComboBox; @@ -17,7 +18,6 @@ import com.fr.design.mainframe.chart.gui.data.table.AbstractTableDataContentPane import com.fr.design.mainframe.chart.gui.data.table.DataPaneHelper; import com.fr.general.ComparatorUtils; import com.fr.plugin.chart.multilayer.data.MultiPieValueDefinition; -import com.fr.design.i18n.Toolkit; import com.fr.stable.ArrayUtils; import com.fr.stable.AssistUtils; import com.fr.stable.StringUtils; @@ -235,7 +235,14 @@ public class MultiPiePlotTableDataContentPane extends AbstractTableDataContentPa @Override public void clearAllBoxList() { - + levelNumEdit.setValue(3); + nameField.setText(StringUtils.EMPTY); + clearBoxItems(value); + for (UIComboBox uiComboBox : levelNameList) { + clearBoxItems(uiComboBox); + } + clearBoxItems(calculateCombox); + refreshCenterPane(); } @Override diff --git a/designer-chart/src/main/java/com/fr/van/chart/wordcloud/designer/style/VanChartWordCloudSeriesPane.java b/designer-chart/src/main/java/com/fr/van/chart/wordcloud/designer/style/VanChartWordCloudSeriesPane.java index 543b8139f..29624a586 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/wordcloud/designer/style/VanChartWordCloudSeriesPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/wordcloud/designer/style/VanChartWordCloudSeriesPane.java @@ -14,6 +14,7 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.backgroundpane.ImageBackgroundQuickPane; import com.fr.design.mainframe.chart.gui.ChartStylePane; +import com.fr.design.utils.DesignUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.FRFont; import com.fr.general.IOUtils; @@ -94,7 +95,7 @@ public class VanChartWordCloudSeriesPane extends VanChartColorValueSeriesPane { double[] northC = {f, e}; double[] northR = {p, p}; - fontNameComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report()); + fontNameComboBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report()); defineFontSize = new UIButtonGroup(new String[]{AUTO_FONT_SIZE, CUSTOM_FONT_SIZE}); Component[][] northComps = new Component[][]{ new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Font")), fontNameComboBox}, diff --git a/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java b/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java index 47512348f..04633435b 100644 --- a/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java +++ b/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java @@ -1,7 +1,7 @@ package com.fr.design.fit.common; import com.fr.design.file.HistoryTemplateListCache; -import com.fr.design.file.MutilTempalteTabPane; +import com.fr.design.file.MultiTemplateTabPane; import com.fr.design.fit.NewJForm; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JTemplate; @@ -86,7 +86,7 @@ public class TemplateTool { JTemplate oldJTemplate = jTemplateList.get(i); if (oldJTemplate != null && ComparatorUtils.equals(oldJTemplate.getEditingFILE(), newJTemplate.getEditingFILE())) { jTemplateList.set(i, newJTemplate); - MutilTempalteTabPane.getInstance().refreshOpenedTemplate(jTemplateList); + MultiTemplateTabPane.getInstance().refreshOpenedTemplate(jTemplateList); return; } } diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutBorderPane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutBorderPane.java index fd0507c81..4d9d104ab 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutBorderPane.java +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutBorderPane.java @@ -12,6 +12,7 @@ import com.fr.design.gui.style.FRFontPane; 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.utils.gui.GUICoreUtils; import com.fr.form.ui.LayoutBorderStyle; @@ -32,7 +33,7 @@ public class CardTagLayoutBorderPane extends LayoutBorderPane { protected UIScrollPane initRightBottomPane(){ this.setFontSizeComboBox(new UIComboBox(FRFontPane.FONT_SIZES)); - this.setFontNameComboBox(new UIComboBox(Utils.getAvailableFontFamilyNames4Report())); + this.setFontNameComboBox(new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report())); JPanel fontSizeTypePane = new JPanel(new BorderLayout(10,0)); fontSizeTypePane.add(this.getFontSizeComboBox(), BorderLayout.CENTER); fontSizeTypePane.add(this.getFontNameComboBox(), BorderLayout.EAST); diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutBorderPane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutBorderPane.java index 7a00075d6..5294687e3 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutBorderPane.java +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutBorderPane.java @@ -33,6 +33,7 @@ import com.fr.design.layout.TableLayoutHelper; import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.JTemplate; +import com.fr.design.utils.DesignUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.form.ui.LayoutBorderStyle; import com.fr.form.ui.WidgetTitle; @@ -437,7 +438,7 @@ public class LayoutBorderPane extends BasicPane { protected UIScrollPane initRightBottomPane(){ formulaPane = new TinyFormulaPane(); fontSizeComboBox = new UIComboBox(FRFontPane.FONT_SIZES); - fontNameComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report()); + fontNameComboBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report()); fontNameComboBox.setPreferredSize(new Dimension(160, 30)); JPanel fontSizeTypePane = new JPanel(new BorderLayout(10,0)); fontSizeTypePane.add(fontSizeComboBox, BorderLayout.CENTER); diff --git a/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java b/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java index 176c44fe0..260ba183d 100644 --- a/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java +++ b/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java @@ -1,7 +1,7 @@ package com.fr.design.preview; import com.fr.design.file.HistoryTemplateListCache; -import com.fr.design.file.MutilTempalteTabPane; +import com.fr.design.file.MultiTemplateTabPane; import com.fr.design.fun.impl.AbstractPreviewProvider; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.JForm; @@ -66,7 +66,7 @@ public class DeveloperPreview extends AbstractPreviewProvider { } private void onPreview(JTemplate jt) { - MutilTempalteTabPane.getInstance().closeCurrentTpl(); + MultiTemplateTabPane.getInstance().closeCurrentTpl(); jt.generateForBiddenTemplate(); } diff --git a/designer-realize/src/main/java/com/fr/design/actions/cell/style/ReportFontNameAction.java b/designer-realize/src/main/java/com/fr/design/actions/cell/style/ReportFontNameAction.java index 5023e6f4f..2b423e0ab 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/cell/style/ReportFontNameAction.java +++ b/designer-realize/src/main/java/com/fr/design/actions/cell/style/ReportFontNameAction.java @@ -3,6 +3,7 @@ */ package com.fr.design.actions.cell.style; +import com.fr.design.utils.DesignUtils; import com.fr.stable.os.OperatingSystem; import java.awt.Dimension; @@ -80,7 +81,7 @@ public class ReportFontNameAction extends AbstractStyleAction { public JComponent createToolBarComponent() { Object object = this.getValue(UIComboBox.class.getName()); if (object == null || !(object instanceof UIComboBox)) { - UIComboBox itemComponent = new UIComboBox(Utils.getAvailableFontFamilyNames4Report()); + UIComboBox itemComponent = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report()); this.putValue(UIComboBox.class.getName(), itemComponent); //设置最佳宽度. itemComponent.setPreferredSize(new Dimension( diff --git a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceSouthPanel.java b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceSouthPanel.java index 2a555a438..57b81077d 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceSouthPanel.java +++ b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceSouthPanel.java @@ -29,7 +29,7 @@ public class ITReplaceSouthPanel { RowSorter sorter = new TableRowSorter(itTableEditor) { @Override public boolean isSortable(int column) { - return column != CHECKBOX_INDEX || column != CONTENT_INDEX; + return column != CHECKBOX_INDEX && column != CONTENT_INDEX; } }; tableEditorPane.getEditTable().setRowSorter(sorter); diff --git a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceWestPanel.java b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceWestPanel.java index 1c9ed1652..a01fa3909 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceWestPanel.java +++ b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceWestPanel.java @@ -14,11 +14,11 @@ import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.JPanel; import javax.swing.SwingConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import java.awt.Color; import java.awt.Cursor; import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.util.List; @@ -49,31 +49,28 @@ public class ITReplaceWestPanel { contentButton = new UIToggleButton(Toolkit.i18nText("Fine-Design_Basic_Templates_Content")); settingButton = new UIToggleButton(Toolkit.i18nText("Fine-Design_Replace_Setting")); contentButton.setText(CONTENT_TEXT); - contentButton.addActionListener(new ActionListener() { + contentButton.addChangeListener(new ChangeListener() { @Override - public void actionPerformed(ActionEvent e) { - if (!contentButton.isSelected()) { + public void stateChanged(ChangeEvent e) { + if (contentButton.isSelected()) { showSelectPanel(ITReplaceNorthPanel.CARD_CONTENT, ITReplaceMainDialog.getSearchContentResultList()); + settingButton.setSelected(!contentButton.isSelected()); + changeColor4SelectContent(); } else { - showSelectPanel(ITReplaceNorthPanel.CARD_SETTING, ITReplaceMainDialog.getSearchSettingResultList()); + contentButton.setSelected(true); } - changeColor4SelectContent(); - settingButton.setSelected(contentButton.isSelected()); - } }); - - settingButton.addActionListener(new ActionListener() { + settingButton.addChangeListener(new ChangeListener() { @Override - public void actionPerformed(ActionEvent e) { - if (!settingButton.isSelected()) { + public void stateChanged(ChangeEvent e) { + if (settingButton.isSelected()) { showSelectPanel(ITReplaceNorthPanel.CARD_SETTING, ITReplaceMainDialog.getSearchSettingResultList()); + contentButton.setSelected(!settingButton.isSelected()); + changeColor4SelectContent(); } else { - showSelectPanel(ITReplaceNorthPanel.CARD_CONTENT, ITReplaceMainDialog.getSearchContentResultList()); + settingButton.setSelected(true); } - changeColor4SelectContent(); - contentButton.setSelected(settingButton.isSelected()); - } }); leftPanel.setBackground(Color.WHITE); @@ -118,7 +115,7 @@ public class ITReplaceWestPanel { * 切换面板时改变颜色 */ public void changeColor4SelectContent() { - if (!contentButton.isSelected()) { + if (contentButton.isSelected()) { contentButton.setText(CONTENT_TEXT); settingButton.setText(Toolkit.i18nText("Fine-Design_Replace_Setting")); } else { diff --git a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableButton.java b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableButton.java index ce11d184d..5cee5af04 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableButton.java +++ b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableButton.java @@ -38,19 +38,6 @@ public class ITTableButton extends AbstractCellEditor implements TableCellEditor paraButton = new UIButton("" + Toolkit.i18nText("Fine-Design_Chart_Location") + " "); paraButton.setVisible(true); paraButton.setBorderPainted(false); - paraButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - ITContent content = (ITContent) getEditTable().getValueAt(getEditTable().getEditingRow(), ITReplaceSouthPanel.CONTENT_INDEX); - if (StringUtils.isNotEmpty(GeneralUtils.objectToString(content.getTrlString()))) { - ITReplaceMainDialog.setITReplaceFlag(true); - TRL trl = new TRL(GeneralUtils.objectToString(content.getTrlString())); - DesignerContext.getDesignerFrame().openOrActiveTemplate(content.getTemplatePath()); - HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().navigate(trl); - } - ITReplaceMainDialog.setITReplaceFlag(false); - } - }); } diff --git a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableEditor.java b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableEditor.java index 7f4960d21..d805d430e 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableEditor.java +++ b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableEditor.java @@ -94,7 +94,7 @@ public class ITTableEditor extends UITableModelAdapter { */ @Override public boolean isCellEditable(int row, int col) { - return col == ITReplaceSouthPanel.CONTENT_INDEX || col == ITReplaceSouthPanel.CHECKBOX_INDEX; + return col == ITReplaceSouthPanel.CHECKBOX_INDEX; } /** diff --git a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableEditorPane.java b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableEditorPane.java index f46ea95ac..ef32da98d 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableEditorPane.java +++ b/designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITTableEditorPane.java @@ -1,17 +1,21 @@ package com.fr.design.actions.replace.ui; +import com.fr.base.TRL; import com.fr.design.actions.replace.info.base.ITContent; import com.fr.design.border.UIRoundedBorder; import com.fr.design.constants.UIConstants; import com.fr.design.dialog.BasicPane; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icontainer.UIScrollPane; 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.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.general.GeneralUtils; import com.fr.stable.StringUtils; @@ -75,6 +79,16 @@ public class ITTableEditorPane extends BasicPane { //改变面板的各个状态 changeComponentStatus(content, row, col); } + if (col == ITReplaceSouthPanel.CONTENT_INDEX) { + ITContent content = (ITContent) editTable.getValueAt(row, ITReplaceSouthPanel.CONTENT_INDEX); + if (StringUtils.isNotEmpty(GeneralUtils.objectToString(content.getTrlString()))) { + ITReplaceMainDialog.setITReplaceFlag(true); + TRL trl = new TRL(GeneralUtils.objectToString(content.getTrlString())); + DesignerContext.getDesignerFrame().openOrActiveTemplate(content.getTemplatePath()); + HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().navigate(trl); + } + ITReplaceMainDialog.setITReplaceFlag(false); + } } }); diff --git a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java b/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java index ebaf13b7f..0a5a93602 100644 --- a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java +++ b/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java @@ -21,6 +21,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.report.RichTextEditingPane; import com.fr.design.style.color.UIToolbarColorButton; import com.fr.design.utils.DesignUtils; +import com.fr.design.utils.DesignUtils; import com.fr.general.FRFont; import com.fr.log.FineLoggerFactory; import com.fr.report.cell.cellattr.core.RichTextConverter; @@ -104,7 +105,7 @@ public class RichTextToolBar extends BasicPane { } private void initAllButton() { - fontNameComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report()); + fontNameComboBox = new UIComboBox(DesignUtils.getAvailableFontFamilyNames4Report()); fontNameComboBox.setPreferredSize(new Dimension(144, 20)); fontSizeComboBox = new UIComboBox(FRFontPane.getFontSizes()); colorSelectPane = new UIToolbarColorButton(BaseUtils.readIcon("/com/fr/design/images/gui/color/foreground.png")); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java index 8fb64a3d1..cab4c6a18 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java @@ -6,8 +6,6 @@ import com.fr.base.Parameter; import com.fr.base.ScreenResolution; import com.fr.base.TRL; import com.fr.base.extension.FileExtension; -import com.fr.base.theme.FineColorGather; -import com.fr.base.theme.FineColorManager; import com.fr.base.theme.FineColorSynchronizer; import com.fr.base.theme.ReportTheme; import com.fr.base.theme.TemplateTheme; @@ -41,7 +39,7 @@ import com.fr.design.designer.TargetComponent; import com.fr.design.dialog.DialogActionAdapter; 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.fun.PreviewProvider; import com.fr.design.fun.PropertyItemPaneProvider; import com.fr.design.fun.ReportSupportedFileUIProvider; @@ -80,7 +78,6 @@ import com.fr.file.FILEChooserPane; import com.fr.file.FileNodeFILE; import com.fr.file.filetree.FileNode; import com.fr.file.filter.ChooseFileFilter; -import com.fr.form.main.Form; import com.fr.general.ComparatorUtils; import com.fr.general.ModuleContext; import com.fr.grid.Grid; @@ -1178,7 +1175,7 @@ public class JWorkBook extends JTemplate { public boolean saveShareFile() { FILE newFile = createNewEmptyFile(); //如果文件已经打开, 那么就覆盖关闭掉他 - MutilTempalteTabPane.getInstance().closeFileTemplate(newFile); + MultiTemplateTabPane.getInstance().closeFileTemplate(newFile); final WorkBook tpl = this.getTarget(); // 弹出输入参数 java.util.Map parameterMap = inputParameters(tpl); diff --git a/designer-realize/src/main/java/com/fr/grid/GridUI.java b/designer-realize/src/main/java/com/fr/grid/GridUI.java index 7ae22a51f..60fb2c30a 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridUI.java +++ b/designer-realize/src/main/java/com/fr/grid/GridUI.java @@ -51,7 +51,7 @@ import com.fr.stable.AssistUtils; import com.fr.stable.ColumnRow; import com.fr.stable.Constants; import com.fr.stable.GraphDrawHelper; -import com.fr.stable.script.CalculatorUtils; +import com.fr.script.CalculatorUtils; import com.fr.stable.unit.FU; import com.fr.stable.unit.UNIT; import com.fr.third.antlr.ANTLRException; diff --git a/designer-realize/src/main/java/com/fr/quickeditor/CellQuickEditor.java b/designer-realize/src/main/java/com/fr/quickeditor/CellQuickEditor.java index 67a65672f..0b0650478 100644 --- a/designer-realize/src/main/java/com/fr/quickeditor/CellQuickEditor.java +++ b/designer-realize/src/main/java/com/fr/quickeditor/CellQuickEditor.java @@ -58,6 +58,9 @@ import java.util.Set; public abstract class CellQuickEditor extends QuickEditor { protected static final Dimension LABEL_DIMENSION = new Dimension(GraphHelper.getWidth(Toolkit.i18nText("Fine-Design_Report_Insert_Cell_Element")), 20); + + // 使用UILabel.getPreferredSize时,若文本为html高度被默认增加3 + protected static final Dimension HIDDEN_LABEL_DIMENSION = new Dimension(0, -3); protected static final int VGAP = 10, HGAP = 8, VGAP_INNER = 3; /** @@ -285,10 +288,10 @@ public abstract class CellQuickEditor extends QuickEditor { if (selectedOneCell) { columnRowTextField.setPreferredSize(null); cellLabel.setPreferredSize(null); - multipleLabelTip.setPreferredSize(new Dimension()); + multipleLabelTip.setPreferredSize(HIDDEN_LABEL_DIMENSION); } else { - columnRowTextField.setPreferredSize(new Dimension()); - cellLabel.setPreferredSize(new Dimension()); + columnRowTextField.setPreferredSize(HIDDEN_LABEL_DIMENSION); + cellLabel.setPreferredSize(HIDDEN_LABEL_DIMENSION); multipleLabelTip.setPreferredSize(null); } } diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index 24c02893b..02116dc41 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -16,7 +16,7 @@ import com.fr.design.constants.UIConstants; import com.fr.design.deeplink.DeepLinkManager; 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.fun.MenuHandler; import com.fr.design.fun.OemProcessor; import com.fr.design.gui.ibutton.UIButton; @@ -72,17 +72,15 @@ import com.fr.start.common.SplashCommon; import com.fr.start.module.StartupArgs; import com.fr.start.preload.PreLoadService; 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.workspace.WorkContext; -import javax.swing.JPanel; + import javax.swing.JComponent; +import javax.swing.JPanel; import javax.swing.border.MatteBorder; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; -import java.awt.Font; -import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -119,11 +117,11 @@ public class MainDesigner extends BaseDesigner { * @param args 参数 */ public static void main(String[] args) { - StopWatch watch = new StopWatch(); - watch.start(); DesignerStartupContext.getRecorder().start(); - showSplash(); + + DesignerEnvManager.getEnvManager(); + startPreload0(); DesignerLifecycleMonitorContext.getMonitor().beforeStart(); @@ -143,7 +141,7 @@ public class MainDesigner extends BaseDesigner { }); 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)); try { @@ -156,8 +154,7 @@ public class MainDesigner extends BaseDesigner { //初始化一下serverTray ServerTray.init(); } - FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", watch.getTime()); - watch.stop(); + FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS)); SwitchForSwingChecker.initThreadMonitoring(); } @@ -168,7 +165,9 @@ public class MainDesigner extends BaseDesigner { private static void startPreload1() { CompletableFuture initLookAndFeel = CompletableFuture.runAsync(DesignUtils::initLookAndFeel); - PreLoadService.getInstance().addFuture(initLookAndFeel); + PreLoadService.getInstance().addUIFuture(initLookAndFeel); + + showSplash(); } /** @@ -189,16 +188,12 @@ public class MainDesigner extends BaseDesigner { action.run(); } }); - - Runnable fontLoad = () -> { - Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); - }; - PreLoadService.getInstance().addRunnable(fontLoad); - } private static void showSplash() { + // 快快显示启动画面 + // vito: 这里必须用 wait, 不然会导致莫名其妙的问题 UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { @@ -392,7 +387,7 @@ public class MainDesigner extends BaseDesigner { for (int i = 0; i < items.length; i++) { menu.add(items[i]); } - GUICoreUtils.showPopupMenu(menu, MutilTempalteTabPane.getInstance(), MutilTempalteTabPane.getInstance().getX() - PREVIEW_DOWN_X_GAP, MutilTempalteTabPane.getInstance().getY() - 1 + MutilTempalteTabPane.getInstance().getHeight()); + GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.getInstance(), MultiTemplateTabPane.getInstance().getX() - PREVIEW_DOWN_X_GAP, MultiTemplateTabPane.getInstance().getY() - 1 + MultiTemplateTabPane.getInstance().getHeight()); } @Override @@ -414,8 +409,8 @@ public class MainDesigner extends BaseDesigner { return; } saveButton.setEnabled(!jt.isSaved() && !DesignModeContext.isVcsMode() && jt.checkEnable()); - MutilTempalteTabPane.getInstance().refreshOpenedTemplate(HistoryTemplateListCache.getInstance().getHistoryList()); - MutilTempalteTabPane.getInstance().repaint(); + MultiTemplateTabPane.getInstance().refreshOpenedTemplate(HistoryTemplateListCache.getInstance().getHistoryList()); + MultiTemplateTabPane.getInstance().repaint(); if (DesignerEnvManager.getEnvManager().isSupportUndo()) { undo.setEnabled(jt.canUndo()); redo.setEnabled(jt.canRedo()); diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java index 66fb549e6..16a923df3 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java +++ b/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.workspace.WorkContext; import com.fr.xml.ReportXMLUtils; + +import javax.swing.SwingWorker; import java.awt.Image; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.CompletableFuture; -import javax.swing.SwingWorker; /** * Created by juhaoyu on 2018/1/31. @@ -191,7 +192,9 @@ public class DesignerActivator extends Activator implements Prepare { }, DesignerStartupPool.common()); CompletableFuture mainDesignerPrepare = CompletableFuture.runAsync(this::designerModuleStart, DesignerStartupPool.common()); - + + CompletableFuture extendDesignerPrepare = CompletableFuture.runAsync(this::designerExtendStart, DesignerStartupPool.common()); + CompletableFuture otherFeaturesPrepare = CompletableFuture.runAsync(() -> { startBBSLoginAuthServer(); migrateBBSInfoFromFineDB(); @@ -207,7 +210,7 @@ public class DesignerActivator extends Activator implements Prepare { storePassport(); AlphaFineHelper.switchConfig4Locale(); RecoverManager.register(new RecoverForDesigner()); - }); + }, DesignerStartupPool.common()); CompletableFuture resourcePrepare = CompletableFuture.runAsync(() -> { pushUpdateTask.run(); @@ -218,7 +221,7 @@ public class DesignerActivator extends Activator implements Prepare { }, DesignerStartupPool.common()); CompletableFuture - .allOf(mainDesignerPrepare, themeConfigPrepare, otherFeaturesPrepare, resourcePrepare) + .allOf(mainDesignerPrepare, extendDesignerPrepare, themeConfigPrepare, otherFeaturesPrepare, resourcePrepare) .join(); } @@ -272,8 +275,12 @@ public class DesignerActivator extends Activator implements Prepare { designerRegister(); - InformationCollector.getInstance().collectStartTime(); + } + + private void designerExtendStart() { + SharableManager.start(); + InformationCollector.getInstance().collectStartTime(); GuideRegister.register(); } @@ -413,16 +420,16 @@ public class DesignerActivator extends Activator implements Prepare { */ private static void registerCellEditor() { - ActionFactory.registerCellEditor(String.class, new CellStringQuickEditor()); - ActionFactory.registerCellEditor(Number.class, new CellStringQuickEditor()); - ActionFactory.registerCellEditor(BaseFormula.class, new CellFormulaQuickEditor()); - ActionFactory.registerCellEditor(SubReport.class, new CellSubReportEditor()); - ActionFactory.registerCellEditor(RichText.class, new CellRichTextEditor()); - ActionFactory.registerCellEditor(DSColumn.class, new CellDSColumnEditor()); - ActionFactory.registerCellEditor(Image.class, new CellImageQuickEditor()); - ActionFactory.registerCellEditor(BiasTextPainter.class, new CellBiasTextPainterEditor()); - ActionFactory.registerCellEditor(BufferedImage.class, new CellImageQuickEditor()); - ActionFactory.registerCellEditor(CellImagePainter.class, new CellImageQuickEditor()); + ActionFactory.registerAsyncInitCellEditorClass(String.class, CellStringQuickEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(Number.class, CellStringQuickEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(BaseFormula.class, CellFormulaQuickEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(SubReport.class, CellSubReportEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(RichText.class, CellRichTextEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(DSColumn.class, CellDSColumnEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(Image.class, CellImageQuickEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(BiasTextPainter.class, CellBiasTextPainterEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(BufferedImage.class, CellImageQuickEditor.class); + ActionFactory.registerAsyncInitCellEditorClass(CellImagePainter.class, CellImageQuickEditor.class); Set providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING); for (ElementUIProvider provider : providers) { @@ -430,7 +437,7 @@ public class DesignerActivator extends Activator implements Prepare { if (provider.quickEditor() == null) { continue; } - ActionFactory.registerCellEditor(provider.targetObjectClass(), provider.quickEditor().newInstance()); + ActionFactory.registerAsyncInitCellEditorClass(provider.targetObjectClass(), provider.quickEditor()); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java index 4a4fbac2b..834f1ee30 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java @@ -67,7 +67,7 @@ public class DesignerStartup extends Activator { registerDaoSelector(); Stopwatch beforeWatch = Stopwatch.createStarted(); - PreLoadService.getInstance().waitForAll(); + PreLoadService.getInstance().waitForCommon(); FineLoggerFactory.getLogger().debug( "DesignerStartup cost {} ms to wait load", beforeWatch.elapsed(TimeUnit.MILLISECONDS)); if (DesignUtils.isStarted()) { diff --git a/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java index e41dafcc8..d861fa052 100644 --- a/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java +++ b/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.log.FineLoggerFactory; import com.fr.module.Activator; +import com.fr.module.engine.base.ActivatorContext; import com.fr.start.SplashContext; import com.fr.start.common.DesignerStartupContext; import com.fr.start.module.StartupArgs; +import com.fr.start.preload.PreLoadService; import com.fr.start.util.DesignerStartupPageUtil; import com.fr.startup.metric.DesignerMetrics; 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 org.jetbrains.annotations.NotNull; +import java.util.concurrent.CountDownLatch; 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 public void start() { @@ -64,14 +74,25 @@ public class DesignerStartupPageActivator extends Activator { // 即时暂停 suspendRecorder(context); + + addMutable(ActivatorContext.KEY, activatorContext); + + PreLoadService.getInstance().waitForUI(); UIUtil.invokeLaterIfNeeded(() -> { StartupPageModel model = StartupPageModel.create(); context.setStartupPageModel(model); - + + StopWatch suspendWatch = new StopWatch(); + final Runnable recordSuspend = () -> { + long suspendTime = suspendWatch.getTime(TimeUnit.MILLISECONDS); + activatorContext.setSuspendTime(suspendTime); + }; + // selectAndOpenLast model.setOpenLastTemplateRunnable(() -> { + recordSuspend.run(); context.setOpenLastFile(true); handleModel(model); launchAfterWarmup(); @@ -79,6 +100,7 @@ public class DesignerStartupPageActivator extends Activator { // selectAndOpenEmpty model.setOpenEmptyTemplateRunnable(() -> { + recordSuspend.run(); context.setOpenEmpty(true); handleModel(model); launchAfterWarmup(); @@ -86,6 +108,7 @@ public class DesignerStartupPageActivator extends Activator { // selectAndCreateNew model.setCreateNewTemplateRunnable(() -> { + recordSuspend.run(); context.setCreateNew(true); handleModel(model); launchAfterWarmup(); @@ -94,8 +117,11 @@ public class DesignerStartupPageActivator extends Activator { StartupPageWindow window = new StartupPageWindow(model); window.setVisible(true); context.setOnWaiting(true); - + suspendWatch.start(); + }); + + waitSubTask(); } private void suspendRecorder(DesignerStartupContext context) { @@ -123,7 +149,11 @@ public class DesignerStartupPageActivator extends Activator { StopWatch stopWatch = StopWatch.createStarted(); try { - DesignerStartupContext.getRecorder().resume(); + + StopWatch recorder = DesignerStartupContext.getRecorder(); + if (recorder.isSuspended()) { + recorder.resume(); + } // 等待中切换 DesignerStartupContext.getInstance().setOnWaiting(false); @@ -136,9 +166,9 @@ public class DesignerStartupPageActivator extends Activator { DesignerStartupContext.getInstance().setOnStartup(false); recordStartupEnd(stopWatch); }); + markComplete(); } - FineLoggerFactory.getLogger().debug("designer-startup-page started cost {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS)); } private void recordStartupEnd(StopWatch stopWatch) { @@ -150,6 +180,28 @@ public class DesignerStartupPageActivator extends Activator { 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 public void stop() { diff --git a/designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java b/designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java index b75021074..e2abb816f 100644 --- a/designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java +++ b/designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java @@ -11,7 +11,9 @@ import java.util.concurrent.CompletableFuture; **/ public class PreLoadService { - private List> futures = new ArrayList<>(); + private List> commonFutures = new ArrayList<>(); + + private List> uIFutures = new ArrayList<>(); public static PreLoadService getInstance() { return PreLoadServiceHolder.INSTANCE; @@ -21,16 +23,40 @@ public class PreLoadService { private static final PreLoadService INSTANCE = new PreLoadService(); } + /** + * 添加 UI 的异步任务 + * + * @param future 任务 + */ + public void addUIFuture(CompletableFuture future) { + uIFutures.add(future); + } + public void addFuture(CompletableFuture future) { - futures.add(future); + commonFutures.add(future); } + /** + * 添加通用的异步任务 + * + * @param runnable 任务 + */ public void addRunnable(Runnable runnable) { - futures.add(CompletableFuture.runAsync(runnable, DesignerStartupPool.common())); + commonFutures.add(CompletableFuture.runAsync(runnable, DesignerStartupPool.common())); + } + + /** + * 等待通用的异步任务执行 + */ + public void waitForCommon() { + CompletableFuture.allOf(commonFutures.toArray(new CompletableFuture[0])).join(); } - public void waitForAll() { - CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + /** + * 等待UI异步任务执行 + */ + public void waitForUI() { + CompletableFuture.allOf(uIFutures.toArray(new CompletableFuture[0])).join(); } }