Browse Source

Fixed merge conflict

zheng-1641779399395
zheng 3 years ago
parent
commit
88eb9ffd00
  1. 6
      build.gradle
  2. 12
      designer-base/src/main/java/com/fr/common/exception/ThrowableHandler.java
  3. 193
      designer-base/src/main/java/com/fr/design/DesignerCloudURLManager.java
  4. 95
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  5. 8
      designer-base/src/main/java/com/fr/design/ExtraDesignClassManager.java
  6. 11
      designer-base/src/main/java/com/fr/design/actions/UpdateAction.java
  7. 47
      designer-base/src/main/java/com/fr/design/actions/file/BatchCompileAction.java
  8. 47
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  9. 3
      designer-base/src/main/java/com/fr/design/actions/help/AboutPane.java
  10. 12
      designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java
  11. 26
      designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java
  12. 49
      designer-base/src/main/java/com/fr/design/actions/server/LocalAnalyzerAction.java
  13. 19
      designer-base/src/main/java/com/fr/design/border/UITitledBorder.java
  14. 32
      designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java
  15. 180
      designer-base/src/main/java/com/fr/design/cell/CellRectangleStylePreviewPane.java
  16. 220
      designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java
  17. 52
      designer-base/src/main/java/com/fr/design/config/DesignerProperties.java
  18. 16
      designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java
  19. 32
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  20. 27
      designer-base/src/main/java/com/fr/design/data/NameChangeBean.java
  21. 136
      designer-base/src/main/java/com/fr/design/data/StrategyConfigAttrUtils.java
  22. 117
      designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java
  23. 2
      designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java
  24. 226
      designer-base/src/main/java/com/fr/design/data/datapane/ESDStrategyConfigPane.java
  25. 99
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java
  26. 797
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java
  27. 8
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataComboBox.java
  28. 24
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java
  29. 147
      designer-base/src/main/java/com/fr/design/data/datapane/connect/AdvancePane.java
  30. 50
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java
  31. 48
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java
  32. 110
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java
  33. 35
      designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java
  34. 44
      designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java
  35. 259
      designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java
  36. 37
      designer-base/src/main/java/com/fr/design/data/tabledata/strategy/StrategyConfigHandler.java
  37. 551
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  38. 3
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java
  39. 33
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/db/StrategyConfigFrom.java
  40. 5
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java
  41. 17
      designer-base/src/main/java/com/fr/design/dialog/BasicPane.java
  42. 22
      designer-base/src/main/java/com/fr/design/dialog/UIDialog.java
  43. 7
      designer-base/src/main/java/com/fr/design/event/ComponentChangeListener.java
  44. 6
      designer-base/src/main/java/com/fr/design/event/ComponentChangeObserver.java
  45. 29
      designer-base/src/main/java/com/fr/design/extra/PluginInstalledPane.java
  46. 34
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  47. 5
      designer-base/src/main/java/com/fr/design/extra/PluginUtils.java
  48. 6
      designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java
  49. 18
      designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java
  50. 56
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  51. 1689
      designer-base/src/main/java/com/fr/design/formula/FRFormulaLexer.java
  52. 48
      designer-base/src/main/java/com/fr/design/formula/FormulaChecker.java
  53. 11
      designer-base/src/main/java/com/fr/design/formula/FormulaCheckerException.java
  54. 551
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  55. 9
      designer-base/src/main/java/com/fr/design/formula/FormulaPaneWhenReserveFormula.java
  56. 54
      designer-base/src/main/java/com/fr/design/formula/UnsupportedFormulaScanner.java
  57. 48
      designer-base/src/main/java/com/fr/design/formula/exception/FormulaExceptionTipsProcessor.java
  58. 14
      designer-base/src/main/java/com/fr/design/formula/exception/function/FormulaCheckConstants.java
  59. 80
      designer-base/src/main/java/com/fr/design/formula/exception/function/FormulaCheckWrongFunction.java
  60. 95
      designer-base/src/main/java/com/fr/design/formula/exception/function/MismatchedCharFunction.java
  61. 110
      designer-base/src/main/java/com/fr/design/formula/exception/function/MismatchedTokenFunction.java
  62. 44
      designer-base/src/main/java/com/fr/design/formula/exception/function/NoViableAltForCharFunction.java
  63. 41
      designer-base/src/main/java/com/fr/design/formula/exception/function/NoViableAltFunction.java
  64. 96
      designer-base/src/main/java/com/fr/design/formula/exception/function/TranslateTokenUtils.java
  65. 19
      designer-base/src/main/java/com/fr/design/fun/PcFitProvider.java
  66. 9
      designer-base/src/main/java/com/fr/design/fun/PreviewProvider.java
  67. 19
      designer-base/src/main/java/com/fr/design/fun/impl/AbstractPcFitProvider.java
  68. 28
      designer-base/src/main/java/com/fr/design/fun/impl/DesignerStartWithEmptyFile.java
  69. 1003
      designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaAutoCompletePopupWindow.java
  70. 22
      designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaCompletion.java
  71. 1311
      designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaPaneAutoCompletion.java
  72. 28
      designer-base/src/main/java/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java
  73. 52
      designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java
  74. 8
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java
  75. 23
      designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java
  76. 47
      designer-base/src/main/java/com/fr/design/gui/frpane/AttributeChangeUtils.java
  77. 29
      designer-base/src/main/java/com/fr/design/gui/frpane/JTreeAutoBuildPane.java
  78. 14
      designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java
  79. 12
      designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPane.java
  80. 21
      designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPaneUI.java
  81. 11
      designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java
  82. 50
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java
  83. 13
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIColorButton.java
  84. 36
      designer-base/src/main/java/com/fr/design/gui/ibutton/UINoThemeColorButton.java
  85. 9
      designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java
  86. 6
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIToggleButton.java
  87. 6
      designer-base/src/main/java/com/fr/design/gui/icheckbox/UICheckBox.java
  88. 34
      designer-base/src/main/java/com/fr/design/gui/icombobox/ColorSchemeComboBox.java
  89. 4
      designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java
  90. 77
      designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java
  91. 217
      designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java
  92. 14
      designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupMenu.java
  93. 8
      designer-base/src/main/java/com/fr/design/gui/iprogressbar/ProgressDialog.java
  94. 6
      designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java
  95. 8
      designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableEditorPane.java
  96. 5
      designer-base/src/main/java/com/fr/design/gui/itextfield/UIAutoCompletionField.java
  97. 18
      designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java
  98. 2
      designer-base/src/main/java/com/fr/design/gui/itree/filetree/EnvFileTree.java
  99. 23
      designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileTreeIcon.java
  100. 2
      designer-base/src/main/java/com/fr/design/gui/itree/filetree/ReportletPane.java
  101. Some files were not shown because too many files have changed in this diff Show More

6
build.gradle

@ -49,8 +49,8 @@ allprojects {
idea {
module {
inheritOutputDirs = false
outputDir = file(outputPath +"/classes")
testOutputDir = file(outputPath +"/test-classes")
outputDir = file(outputPath + "/classes")
testOutputDir = file(outputPath + "/test-classes")
languageLevel = new IdeaLanguageLevel(sourceCompatibility)
targetBytecodeVersion = targetCompatibility
}
@ -69,6 +69,7 @@ allprojects {
implementation 'org.swingexplorer:swag:1.0'
implementation 'net.java.dev.jna:jna:5.4.0'
implementation 'org.apache.tomcat:tomcat-catalina:8.5.72'
implementation 'org.apache.tomcat:tomcat-websocket:8.5.72'
implementation 'io.socket:socket.io-client:0.7.0'
implementation 'com.fr.third:fine-third:' + frVersion
implementation 'com.fr.core:fine-core:' + frDevVersion
@ -77,6 +78,7 @@ allprojects {
implementation 'com.fr.decision:fine-decision:' + frVersion
implementation 'com.fr.schedule:fine-schedule:' + frVersion
implementation 'com.fr.report:engine-report:' + frDevVersion
implementation 'com.fr.report:engine-x:' + frDevVersion
implementation 'com.fr.report:engine-chart:' + frDevVersion
implementation 'com.fr.report:engine-i18n:' + frDevVersion
implementation 'com.fr.design:design-i18n:' + frDevVersion

12
designer-base/src/main/java/com/fr/common/exception/ThrowableHandler.java

@ -0,0 +1,12 @@
package com.fr.common.exception;
/**
* @author hades
* @version 11.0
* Created by hades on 2021/12/7
*/
public interface ThrowableHandler {
boolean process(Throwable e);
}

193
designer-base/src/main/java/com/fr/design/DesignerCloudURLManager.java

@ -0,0 +1,193 @@
package com.fr.design;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.general.CloudCenter;
import com.fr.general.CloudCenterConfig;
import com.fr.general.http.HttpToolbox;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ProductConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLReaderHelper;
import com.fr.stable.xml.XMLTools;
import com.fr.stable.xml.XMLable;
import com.fr.stable.xml.XMLableReader;
import com.fr.third.javax.xml.stream.XMLStreamException;
import com.fr.third.org.apache.commons.io.FileUtils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by kerry on 2021/10/22
*/
public class DesignerCloudURLManager implements XMLable {
private static final String CLOUD_URL_INFO = "cloudUrl.info";
private static final String ROOT_XML_TAG = "CloudUrlInfoList";
private static final String CHILD_XML_TAG = "CloudUrlInfo";
private final Map<String, String> urlMap = new HashMap<>();
public static DesignerCloudURLManager getInstance() {
return DesignerCloudURLManager.HOLDER.singleton;
}
private final ExecutorService executorService = Executors.newSingleThreadExecutor(new NamedThreadFactory("TestCloudConnectThread"));
private volatile boolean testResult;
private static class HOLDER {
private static final DesignerCloudURLManager singleton = new DesignerCloudURLManager();
}
private DesignerCloudURLManager() {
loadURLXMLFile();
}
public String acquireUrlByKind(String key) {
String url = urlMap.getOrDefault(key, StringUtils.EMPTY);
if (StringUtils.isEmpty(url)) {
//本地缓存中为空时,直接从云中心获取,获取完成后异步更新本地缓存文件
String latestUrl = CloudCenter.getInstance().acquireConf(key, StringUtils.EMPTY);
executorService.submit(() -> {
updateURLXMLFile(key, latestUrl);
});
return latestUrl;
}
//本地缓存不为空时,直接返回对应 url,同时异步更新
executorService.submit(() -> {
String latestUrl = CloudCenter.getInstance().acquireConf(key, StringUtils.EMPTY);
updateURLXMLFile(key, latestUrl);
});
return url;
}
private synchronized void updateURLXMLFile(String key, String url) {
if (StringUtils.isNotEmpty(url) && (!urlMap.containsKey(key) || !url.equals(urlMap.get(key)))) {
urlMap.put(key, url);
saveURLXMLFile();
}
}
public void testConnect() {
executorService.submit(() -> {
testResult = isOnline();
});
}
public boolean isConnected() {
return testResult;
}
public boolean isOnline() {
if (CloudCenterConfig.getInstance().isOnline()) {
String ping = acquireUrlByKind("ping");
if (StringUtils.isNotEmpty(ping)) {
try {
return StringUtils.isEmpty(HttpToolbox.get(ping));
} catch (Exception ignore) {
}
}
}
return false;
}
/**
* 加载本地 url 管理文件
*/
private void loadURLXMLFile() {
if (!getInfoFile().exists()) {
return;
}
XMLableReader reader = null;
try (InputStream in = new FileInputStream(getInfoFile())) {
// XMLableReader 还是应该考虑实现 Closable 接口的,这样就能使用 try-with 语句了
reader = XMLReaderHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER);
if (reader == null) {
return;
}
reader.readXMLObject(this);
} catch (FileNotFoundException e) {
// do nothing
} catch (XMLStreamException | IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (XMLStreamException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
private File getInfoFile() {
File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), CLOUD_URL_INFO));
try {
if (!file.exists()) {
file.createNewFile();
}
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
return file;
}
/**
* 保存到本地 URL 管理文件中存放在 .Finereport110
*/
void saveURLXMLFile() {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLTools.writeOutputStreamXML(this, out);
out.flush();
out.close();
String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8);
FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8);
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(ex.getMessage());
}
}
@Override
public void readXML(XMLableReader reader) {
String tagName = reader.getTagName();
if (tagName.equals(CHILD_XML_TAG)) {
String key = reader.getAttrAsString("key", StringUtils.EMPTY);
String value = reader.getAttrAsString("url", StringUtils.EMPTY);
this.urlMap.put(key, value);
}
}
@Override
public void writeXML(XMLPrintWriter xmlPrintWriter) {
xmlPrintWriter.startTAG(ROOT_XML_TAG);
Iterator<Map.Entry<String, String>> iterable = urlMap.entrySet().iterator();
while (iterable.hasNext()) {
Map.Entry<String, String> entry = iterable.next();
xmlPrintWriter.startTAG(CHILD_XML_TAG).attr("key", entry.getKey()).attr("url", entry.getValue()).end();
}
xmlPrintWriter.end();
}
@Override
public Object clone() throws CloneNotSupportedException {
return null;
}
}

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

@ -17,9 +17,10 @@ import com.fr.design.env.RemoteDesignerWorkspaceInfo;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.locale.impl.ProductImproveMark;
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo;
import com.fr.design.login.DesignerLoginType;
import com.fr.design.login.config.DesignerLoginConfigManager;
import com.fr.design.mainframe.ComponentReuseNotifyUtil;
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.notification.SnapChatConfig;
import com.fr.design.os.impl.SupportOSImpl;
@ -53,7 +54,8 @@ import com.fr.stable.xml.XMLReadable;
import com.fr.stable.xml.XMLTools;
import com.fr.stable.xml.XMLWriter;
import com.fr.stable.xml.XMLableReader;
import com.fr.third.apache.log4j.FileAppender;
import com.fr.third.apache.logging.log4j.core.appender.FileAppender;
import com.fr.third.apache.logging.log4j.core.layout.PatternLayout;
import com.fr.third.org.apache.commons.io.FilenameUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.WorkContextCallback;
@ -88,8 +90,12 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private static final int MAX_SHOW_NUM = 10;
private static final String VERSION_80 = "80";
private static final String VERSION_90 = "90";
private static final String VERSION100 = "100";
private static final int CACHINGTEMPLATE_LIMIT = 5;
private static final String WEB_NAME = "webapps";
public static final int LAYOUT_TEMPLATE_SIMPLE_STYLE = 0;
public static final int LAYOUT_TEMPLATE_REAL_STYLE = 1;
/**
* 指定默认工作空间
*/
@ -158,7 +164,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
//记录当前激活码的在线激活状态.
private int activeKeyStatus = -1;
private boolean joinProductImprove = true;
private boolean startWithEmptyFile = false;
private boolean embedServerLazyStartup = false;
//最近使用的颜色
private ColorSelectConfigManager configManager = new ColorSelectConfigManager();
@ -194,6 +200,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private static List<SwingWorker> mapWorkerList = new ArrayList<SwingWorker>();
private boolean imageCompress = false;//图片压缩
private boolean showImageCompressMoveTip = true;
private boolean showServerDatasetAuthTip = true;
// 开启内嵌web页面的调试窗口
private boolean openDebug = false;
@ -203,6 +210,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private boolean showTemplateMissingPlugin = true;
private int layoutTemplateStyle = LAYOUT_TEMPLATE_SIMPLE_STYLE;
private boolean useOptimizedUPM4Adapter;
/**
@ -319,18 +328,18 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
if (!new File(fileName).exists()) {
StableUtils.makesureFileExist(new File(fileName));
}
LogHandler handler = new LogHandler<FileAppender>() {
final FileAppender appender = new FileAppender(
new com.fr.third.apache.log4j.PatternLayout("%d{HH:mm:ss} %t %p [%c] %m%n"),
fileName
);
LogHandler<FileAppender> handler = new LogHandler<FileAppender>() {
final FileAppender appender = FileAppender.newBuilder().
setName(FileAppender.class.getSimpleName()).
setLayout(PatternLayout.newBuilder().withPattern("%d{HH:mm:ss} %t %p [%c] %m%n").build()).
withFileName(fileName).build();
@Override
public FileAppender getHandler() {
return appender;
}
};
handler.getHandler().start();
FineLoggerFactory.getLogger().addLogAppender(handler);
} catch (SecurityException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
@ -357,14 +366,21 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
try {
fileWriter = new FileWriter(envFile);
File oldEnvFile = new File(ProductConstants.getEnvHome() + File.separator + ProductConstants.APP_NAME + "6-1" + "Env.xml");
File envFile80 = new File(getEnvHome(VERSION_80) + File.separator + getEnvFile().getName());
if (oldEnvFile.exists()) {
File envFile80 = getOldEnvFile(VERSION_80);
File envFile90 = getOldEnvFile(VERSION_90);
File envFile100 = getOldEnvFile(VERSION100);
// 从10.0往前递进是否存在更老版本的配置文件
if (envFile100.exists()) {
compatibilityPrevVersion(envFile100);
} else if (envFile90.exists()) {
compatibilityPrevVersion(envFile90);
} else if (envFile80.exists()) {
compatibilityPrevVersion(envFile80);
} else if (oldEnvFile.exists()) {
// marks:兼容DesignerEnv6-1.xml
FileReader fileReader = new FileReader(oldEnvFile);
Utils.copyCharTo(fileReader, fileWriter);
fileReader.close();
} else if (envFile80.exists()) {
compatibilityPrevVersion(envFile80);
} else {
// marks:生成一个新的xml文件
StringReader stringReader = new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Env></Env>");
@ -386,6 +402,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
}
private File getOldEnvFile(String version) {
return new File(getEnvHome(version) + File.separator + getEnvFile().getName());
}
private static String getEnvHome(String version) {
String userHome = System.getProperty("user.home");
if (userHome == null) {
@ -400,6 +420,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private void compatibilityPrevVersion(File prevEnvFile) {
try {
XMLTools.readFileXML(designerEnvManager, prevEnvFile);
clearOldVersionDesignerEnvProperties();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
@ -409,6 +430,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
designerEnvManager.saveXMLFile();
}
private void clearOldVersionDesignerEnvProperties() {
SnapChatConfig snapChatConfig = designerEnvManager.getSnapChatConfig();
snapChatConfig.resetRead(ComponentReuseNotifyUtil.COMPONENT_SNAP_CHAT_KEY);
}
public static void setEnvFile(File envFile) {
DesignerEnvManager.envFile = envFile;
}
@ -1368,6 +1394,24 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.maxNumberOrPreviewRow = maxNumberOrPreviewRow;
}
/**
* 启动时是否打开空报表
*
* @return 是否打开空报表
*/
public boolean isStartWithEmptyFile() {
return startWithEmptyFile;
}
/**
* 设置启动时是否打开空报表
*
* @param startWithEmptyFile 是否打开空报表
*/
public void setStartWithEmptyFile(boolean startWithEmptyFile) {
this.startWithEmptyFile = startWithEmptyFile;
}
/**
* 是否展示工程界面
*
@ -1662,6 +1706,13 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.showImageCompressMoveTip = showImageCompressMoveTip;
}
public boolean isShowServerDatasetAuthTip() {
return showServerDatasetAuthTip;
}
public void setShowServerDatasetAuthTip(boolean showServerDatasetAuthTip) {
this.showServerDatasetAuthTip = showServerDatasetAuthTip;
}
public boolean isOpenDebug() {
return openDebug;
@ -1671,6 +1722,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.openDebug = openDebug;
}
public int getLayoutTemplateStyle() {
return layoutTemplateStyle;
}
public void setLayoutTemplateStyle(int layoutTemplateStyle) {
this.layoutTemplateStyle = layoutTemplateStyle;
}
/**
* Read XML.<br>
* The method will be invoked when read data from XML file.<br>
@ -1841,6 +1900,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.setEmbedServerLazyStartup(reader.getAttrAsBoolean("embedServerLazyStartup", false));
this.setShowTemplateMissingPlugin(reader.getAttrAsBoolean("showTemplateMissingPlugin", true));
this.setUseOptimizedUPM4Adapter(reader.getAttrAsBoolean("useOptimizedUPM4Adapter", SupportOSImpl.MACOS_12_VERSION_ADAPTER.support()));
this.setShowServerDatasetAuthTip(reader.getAttrAsBoolean("showServerDatasetAuthTip", true));
this.setLayoutTemplateStyle(reader.getAttrAsInt("layoutTemplateStyle", LAYOUT_TEMPLATE_SIMPLE_STYLE));
}
private void readReportPaneAttributions(XMLableReader reader) {
@ -1856,6 +1917,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.setSupportCellEditorDef(reader.getAttrAsBoolean("supportCellEditorDef", false));
this.setDragPermited(reader.getAttrAsBoolean("isDragPermited", false));
this.setUndoLimit(reader.getAttrAsInt("undoLimit", 5));
this.setStartWithEmptyFile(reader.getAttrAsBoolean("startWithEmptyFile", false));
this.setDefaultStringToFormula(reader.getAttrAsBoolean("defaultStringToFormula", false));
if ((tmpVal = reader.getAttrAsString("gridLineColor", null)) != null) {
this.setGridLineColor(new Color(Integer.parseInt(tmpVal)));
@ -2113,6 +2175,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
if (!this.isShowTemplateMissingPlugin()) {
writer.attr("showTemplateMissingPlugin", this.isShowTemplateMissingPlugin());
}
writer.attr("layoutTemplateStyle", this.getLayoutTemplateStyle());
writer.attr("showServerDatasetAuthTip", this.isShowServerDatasetAuthTip());
writer.attr("useOptimizedUPM4Adapter", this.isUseOptimizedUPM4Adapter());
writer.end();
}
@ -2232,6 +2296,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
.attr("gridLineColor", this.getGridLineColor().getRGB())
.attr("paginationLineColor", this.getPaginationLineColor().getRGB())
.attr("undoLimit", this.getUndoLimit())
.attr("startWithEmptyFile", this.isStartWithEmptyFile())
.end();
}
@ -2288,4 +2353,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
DesignerExiter.getInstance().execute();
}
}
public SnapChatConfig getSnapChatConfig() {
return snapChatConfig;
}
}

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

@ -18,6 +18,7 @@ import com.fr.design.fun.TableDataDefineProvider;
import com.fr.design.fun.ToolbarItemProvider;
import com.fr.design.gui.core.WidgetOption;
import com.fr.design.gui.core.WidgetOptionFactory;
import com.fr.design.mainframe.mobile.utils.MobileStyleProviderManager;
import com.fr.design.menu.ShortCut;
import com.fr.design.widget.Appearance;
import com.fr.design.widget.mobile.WidgetMobilePane;
@ -269,11 +270,10 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement
public MobileWidgetStyleProvider[] getMobileStyleOfWidget(String xType) {
Set<MobileWidgetStyleProvider> set = getArray(MobileWidgetStyleProvider.XML_TAG);
if (set.isEmpty()) {
return new MobileWidgetStyleProvider[0];
}
Set<MobileWidgetStyleProvider> allSet = MobileStyleProviderManager.getArray(MobileWidgetStyleProvider.XML_TAG);
allSet.addAll(set);
List<MobileWidgetStyleProvider> providers = new ArrayList<>();
for (MobileWidgetStyleProvider provider : set) {
for (MobileWidgetStyleProvider provider : allSet) {
if (ComparatorUtils.equalsIgnoreCase(provider.xTypeForWidget(), xType)) {
providers.add(provider);
}

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

@ -345,6 +345,17 @@ public abstract class UpdateAction extends ShortCut implements Action {
return (JComponent) object;
}
public JComponent createToolBarComponentByName(String componentName) {
Object object = this.getValue(componentName);
if (!(object instanceof AbstractButton)) {
UIButton button = null;
button = new UIButton();
object = initButton(button, componentName);
}
return (JComponent) object;
}
protected JComponent initButton(UIButton button, String name) {
// 添加一个名字作为自动化测试用
button.setName(getName());

47
designer-base/src/main/java/com/fr/design/actions/file/BatchCompileAction.java

@ -0,0 +1,47 @@
package com.fr.design.actions.file;
import com.fr.base.BaseUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.menu.MenuKeySet;
import com.fr.locale.InterProviderFactory;
import com.fr.nx.app.designer.transform.ui.BatchTransformPane;
import javax.swing.KeyStroke;
import java.awt.Dialog;
import java.awt.event.ActionEvent;
/**
* Created by kerry on 2019-12-10
*/
public class BatchCompileAction extends UpdateAction {
public BatchCompileAction() {
this.setMenuKeySet(COMPILE);
this.setName(getMenuKeySet().getMenuKeySetName() + "...");
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon(BaseUtils.readIcon("/com/fr/nx/app/designer/transform/batch_transform.png"));
}
@Override
public void actionPerformed(ActionEvent e) {
BatchTransformPane batchTransformPane = new BatchTransformPane();
Dialog dialog = batchTransformPane.showDialog();
dialog.setVisible(true);
}
private static final MenuKeySet COMPILE = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'C';
}
@Override
public String getMenuName() {
return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Batch_Transform");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
}

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

@ -12,6 +12,7 @@ import com.fr.design.editor.editor.IntegerEditor;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UINoThemeColorButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIDictionaryComboBox;
@ -44,7 +45,7 @@ import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.Constants;
import com.fr.stable.os.OperatingSystem;
import com.fr.third.apache.log4j.Level;
import com.fr.third.apache.logging.log4j.Level;
import com.fr.transaction.Configurations;
import com.fr.transaction.Worker;
import com.fr.workspace.WorkContext;
@ -164,6 +165,7 @@ public class PreferencePane extends BasicPane {
private UICheckBox oracleSpace;
private UISpinner cachingTemplateSpinner;
private UICheckBox useOptimizedUPMCheckbox;
private UICheckBox useNewVersionLoginCheckbox;
private UICheckBox useUniverseDBMCheckbox;
private UICheckBox joinProductImproveCheckBox;
private UICheckBox autoPushUpdateCheckBox;
@ -177,7 +179,7 @@ public class PreferencePane extends BasicPane {
private UICheckBox gcEnableCheckBox;
private UIButton gcButton;
private UILabel remindVcsLabel;
private UICheckBox startWithEmptyFile;
private JDialog gcDialog;
private UILabel gcMessage = new UILabel();
private JPanel gcDialogDownPane = new JPanel();
@ -230,6 +232,13 @@ public class PreferencePane extends BasicPane {
advancePane.add(upmSelectorPane);
}
if (SupportOSImpl.DESIGNER_LOGIN.support()) {
JPanel loginSelectorPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Login_Manager"));
useNewVersionLoginCheckbox = new UICheckBox(i18nText("Fine-Design_Basic_Use_New_Login_Manager"));
loginSelectorPane.add(useNewVersionLoginCheckbox);
advancePane.add(loginSelectorPane);
}
JPanel dbmSelectorPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Database_Manager"));
useUniverseDBMCheckbox = new UICheckBox(i18nText("Fine-Design_Basic_Use_Universe_Database_Manager"));
//dbmSelectorPane.add(useUniverseDBMCheckbox);
@ -344,18 +353,23 @@ public class PreferencePane extends BasicPane {
}
private void createFunctionPane(JPanel generalPane) {
JPanel functionPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Function"));
generalPane.add(functionPane);
JPanel topVerticalTitledBorderPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Function"));
JPanel upper = new JPanel(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
JPanel lower = new JPanel(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
topVerticalTitledBorderPane.add(upper);
topVerticalTitledBorderPane.add(lower);
generalPane.add(topVerticalTitledBorderPane);
//添加supportUndo选择项
supportUndoCheckBox = new UICheckBox(i18nText("Fine-Design_Basic_Preference_Support_Undo"));
functionPane.add(supportUndoCheckBox);
upper.add(supportUndoCheckBox);
//添加maxUndoLimit
//String[] undoTimes = {"最大撤销次数","5次","10次","15次","20次","50次"};
String[] undoTimes = {i18nText("Fine-Design_Basic_Max_Undo_Limit"), MAX_UNDO_LIMIT_5 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_10 + i18nText("Fine-Design_Basic_Time(s)")
, MAX_UNDO_LIMIT_15 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_20 + i18nText("Fine-Design_Basic_Time(s)"), MAX_UNDO_LIMIT_50 + i18nText("Fine-Design_Basic_Time(s)")};
maxUndoLimit = new UIComboBox(undoTimes);
functionPane.add(maxUndoLimit);
upper.add(maxUndoLimit);
//不支持撤销则不能选择撤销可缓存,也不能设置最大撤销次数
supportUndoCheckBox.addActionListener(new ActionListener() {
@ -369,12 +383,14 @@ public class PreferencePane extends BasicPane {
//添加supportDefaultParentCalculate选择项
supportDefaultParentCalculateCheckBox = new UICheckBox(
i18nText("Fine-Design_Basic_Preference_Support_Default_Parent_Calculate"));
functionPane.add(supportDefaultParentCalculateCheckBox);
upper.add(supportDefaultParentCalculateCheckBox);
//添加是否展示打开模板提示缺少插件选择项
showTemplateMissingPlugin = new UICheckBox(
i18nText("Fine-Design_Basic_Preference_Show-Template-Missing-Plugin"));
functionPane.add(showTemplateMissingPlugin);
upper.add(showTemplateMissingPlugin);
startWithEmptyFile = new UICheckBox(i18nText("Fine-Design_Basic_Preference_Start_Empty_File"));
lower.add(startWithEmptyFile);
}
private void createEditPane(JPanel generalPane) {
@ -465,10 +481,10 @@ public class PreferencePane extends BasicPane {
JPanel colorSettingPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Setting_Colors"));
generalPane.add(colorSettingPane);
gridLineColorTBButton = new UIColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
gridLineColorTBButton = new UINoThemeColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
gridLineColorTBButton.setEnabled(this.isEnabled());
paginationLineColorTBButton = new UIColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
paginationLineColorTBButton = new UINoThemeColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
paginationLineColorTBButton.setEnabled(this.isEnabled());
JPanel leftPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
@ -716,6 +732,10 @@ public class PreferencePane extends BasicPane {
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter());
}
if (useNewVersionLoginCheckbox != null) {
useNewVersionLoginCheckbox.setSelected(!DesignerEnvManager.getEnvManager().isUseOldVersionLogin());
}
useUniverseDBMCheckbox.setSelected(ServerPreferenceConfig.getInstance().isUseUniverseDBM());
this.oracleSpace.setSelected(designerEnvManager.isOracleSystemSpace());
@ -727,6 +747,7 @@ public class PreferencePane extends BasicPane {
}
this.embedServerLazyStartupCheckBox.setSelected(designerEnvManager.isEmbedServerLazyStartup());
this.startWithEmptyFile.setSelected(designerEnvManager.isStartWithEmptyFile());
this.imageCompressPanelCheckBox.setSelected(designerEnvManager.isImageCompress());
}
@ -810,11 +831,15 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setAutoPushUpdateEnabled(this.autoPushUpdateCheckBox.isSelected());
}
if (useNewVersionLoginCheckbox != null) {
designerEnvManager.setUseOldVersionLogin(!this.useNewVersionLoginCheckbox.isSelected());
}
designerEnvManager.setUndoLimit(maxUndoLimit.getSelectedIndex() * SELECTED_INDEX_5);
if (maxUndoLimit.getSelectedIndex() == SELECTED_INDEX_5) {
designerEnvManager.setUndoLimit(MAX_UNDO_LIMIT_50);
}
designerEnvManager.setStartWithEmptyFile(startWithEmptyFile.isSelected());
if (WorkContext.getCurrent().isLocal()) {
Configurations.update(new Worker() {
@Override

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

@ -14,7 +14,6 @@ import com.fr.general.CloudCenter;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralContext;
import com.fr.general.GeneralUtils;
import com.fr.i18n.UrlI18nManager;
import com.fr.locale.InterProviderFactory;
import com.fr.stable.ProductConstants;
import com.fr.stable.StringUtils;
@ -83,7 +82,7 @@ public class AboutPane extends JPanel {
addPhoneAndQQPane(contentPane);
// 官网
JPanel urlActionPane = getURLActionPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Official_Website"), UrlI18nManager.getInstance().getI18nUrl("website"));
JPanel urlActionPane = getURLActionPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Official_Website"), CloudCenter.getInstance().acquireConf("website." + GeneralContext.getLocale(), ProductConstants.WEBSITE_URL));
// 支持邮箱
String defaultEmail = CloudCenter.getInstance().acquireConf("support.email", ProductConstants.SUPPORT_EMAIL);

12
designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java

@ -3,9 +3,9 @@ package com.fr.design.actions.help;
import com.fr.design.i18n.Toolkit;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.general.http.HttpToolbox;
import com.fr.i18n.UrlI18nManager;
import com.fr.stable.CommonUtils;
import com.fr.stable.ProductConstants;
import com.fr.stable.StringUtils;
@ -28,11 +28,7 @@ public class TutorialAction extends AbstractDesignerSSO {
@Override
public String getJumpUrl() {
return UrlI18nManager.getInstance().getI18nUrl("help");
}
public String getOffLineWarnMessage() {
return Toolkit.i18nText("Fine-Design_Offline_Helptutorial_Msg");
return CloudCenter.getInstance().acquireUrlByKind(createDocKey(), "http://help.finereport.com");
}
// 生成帮助文档 sitecenter key, help.zh_CN.10
@ -57,6 +53,10 @@ public class TutorialAction extends AbstractDesignerSSO {
}
}
public String getOffLineWarnMessage() {
return Toolkit.i18nText("Fine-Design_Offline_Helptutorial_Msg");
}
public static final MenuKeySet HELP_TUTORIAL = new MenuKeySet() {
@Override
public char getMnemonic() {

26
designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java

@ -20,11 +20,11 @@ import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.menu.MenuKeySet;
import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.file.TableDataConfig;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import com.fr.report.LockItem;
import javax.swing.KeyStroke;
@ -88,7 +88,7 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS
}
protected void renameConnection(final String oldName, final String newName) {
tableDataConfig.renameTableData(oldName, newName);
StrategyEventsNotifier.modifyDataSet(DSMapping.ofServerDS(new DsNameTarget(oldName)));
}
};
final BasicDialog globalTableDataDialog = globalTableDataPane.showWindowWithCustomSize(designerFrame, null, DEFAULT_DIMENSION);
@ -102,34 +102,18 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS
globalTableDataDialog.setDoOKSucceed(false);
return;
}
globalTableDataPane.update(tableDataConfig);
DesignTableDataManager.clearGlobalDs();
// 保存时 移除服务器数据集列名缓存
for (String name : tableDataConfig.getTableDatas().keySet()) {
DesignTableDataManager.removeSelectedColumnNames(name);
}
Configurations.modify(new WorkerFacade(TableDataConfig.class) {
@Override
public void run() {
globalTableDataPane.update(tableDataConfig);
}
}.addCallBack(new CallBackAdaptor() {
@Override
public boolean beforeCommit() {
//如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面
return doWithDatasourceManager(tableDataConfig, globalTableDataPane, globalTableDataDialog);
}
@Override
public void afterCommit() {
// 刷新共有数据集
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter());
fireDSChanged(globalTableDataPane.getDsChangedNameMap());
// 关闭服务器数据集页面,为其解锁
EditLockUtils.unlock(LockItem.SERVER_TABLE_DATA);
}
}));
}
@Override
public void doCancel() {

49
designer-base/src/main/java/com/fr/design/actions/server/LocalAnalyzerAction.java

@ -0,0 +1,49 @@
package com.fr.design.actions.server;
import com.fr.base.BaseUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.DesignUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.nx.app.web.URLConstants;
import com.fr.stable.StableUtils;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
/**
* @author Maksim
* Created in 2020/11/5 11:44 上午
*/
public class LocalAnalyzerAction extends UpdateAction {
public LocalAnalyzerAction() {
this.setMenuKeySet(ANALYZER);
this.setName(getMenuKeySet().getMenuKeySetName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon(BaseUtils.readIcon("/com/fr/nx/app/designer/transform/analyzer.png"));
}
@Override
public void actionPerformed(ActionEvent e) {
String path = StableUtils.pathJoin("/nx", URLConstants.ANALYZE_VIEW);
DesignUtils.visitEnvServerByParameters(path, new String[]{}, new String[]{});
}
private static final MenuKeySet ANALYZER = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'R';
}
@Override
public String getMenuName() {
return InterProviderFactory.getProvider().getLocText("Fine-Plugin-Engine_Analyzer_Menu_Name");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
}

19
designer-base/src/main/java/com/fr/design/border/UITitledBorder.java

@ -22,24 +22,7 @@ public class UITitledBorder extends TitledBorder {
}
private UITitledBorder(String title) {
super(
BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(
0,
0,
5,
0),
new UIRoundedBorder(
UIConstants.TITLED_BORDER_COLOR,
1,
10)
),
title,
TitledBorder.LEADING,
TitledBorder.TOP,
null,
new Color(1, 159, 222)
);
this(title, 10);
}
/**

32
designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java

@ -0,0 +1,32 @@
package com.fr.design.border;
import com.fr.design.constants.UIConstants;
import javax.swing.BorderFactory;
import javax.swing.border.TitledBorder;
import java.awt.Color;
public class UITitledMatteBorder extends TitledBorder {
public static UITitledMatteBorder createTitledTopBorder(String title, Color color) {
return new UITitledMatteBorder(title, 1, 0, 0, 0, color);
}
public static UITitledMatteBorder createTitledBorder(String title, Color color) {
return new UITitledMatteBorder(title, 1, 1, 1, 1, color);
}
public static UITitledMatteBorder createTitledBorder(String title, int top, int left, int bottom, int right, Color color) {
return new UITitledMatteBorder(title, top, left, bottom, right, color);
}
private UITitledMatteBorder(String title, int top, int left, int bottom, int right, Color color) {
super(
BorderFactory.createMatteBorder(top, left, bottom, right, UIConstants.TITLED_BORDER_COLOR),
title,
TitledBorder.LEADING,
TitledBorder.TOP,
null,
color
);
}
}

180
designer-base/src/main/java/com/fr/design/cell/CellRectangleStylePreviewPane.java

@ -0,0 +1,180 @@
package com.fr.design.cell;
import com.fr.base.CellBorderSourceFlag;
import com.fr.base.CellBorderStyle;
import com.fr.base.Style;
import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase;
import com.fr.general.IOUtils;
import com.fr.report.cell.TemplateCellElement;
import javax.swing.JPanel;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/9/3
*/
public class CellRectangleStylePreviewPane extends JPanel {
private static final BufferedImage transparentBackgroundImage = IOUtils.readImage("/com/fr/design/images/transparent_background.png");
private final float transparentBackgroundWidth;
private final float transparentBackgroundHeight;
private static final int ROW_COUNT = 2;
private static final int COLUMN_COUNT = 2;
private final TemplateCellElement[][] cellElementGrid = new TemplateCellElement[ROW_COUNT][COLUMN_COUNT];
private final int[][] borderSourceFlags = new int[ROW_COUNT][COLUMN_COUNT];
private final CellStylePreviewPane[][] cellStylePreviewPaneGrid = new CellStylePreviewPane[ROW_COUNT][COLUMN_COUNT];
public CellRectangleStylePreviewPane(boolean supportInnerBorder) {
transparentBackgroundWidth = transparentBackgroundImage.getWidth(null);
transparentBackgroundHeight = transparentBackgroundImage.getHeight(null);
setLayout(new GridLayout(2, 2));
setOpaque(false);
setBackground(null);
for (int r = 0; r < ROW_COUNT; r++) {
for (int c = 0; c < COLUMN_COUNT; c++) {
CellStylePreviewPane pane = new CellStylePreviewPane(c, r, COLUMN_COUNT, ROW_COUNT, false, false);
TemplateCellElement cellElement = DefaultThemedTemplateCellElementCase.createInstance(c, r);
int flags = CellBorderSourceFlag.INVALID_BORDER_SOURCE;
if (supportInnerBorder) {
flags = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER;
if (r != 0) {
flags |= CellBorderSourceFlag.TOP_BORDER_SOURCE_INNER;
}
if (r != ROW_COUNT - 1) {
flags |= CellBorderSourceFlag.BOTTOM_BORDER_SOURCE_INNER;
}
if (c != 0) {
flags |= CellBorderSourceFlag.LEFT_BORDER_SOURCE_INNER;
}
if (c != COLUMN_COUNT - 1) {
flags |= CellBorderSourceFlag.RIGHT_BORDER_SOURCE_INNER;
}
}
pane.setStyle(cellElement.getStyle());
add(pane);
cellElementGrid[r][c] = cellElement;
borderSourceFlags[r][c] = flags;
cellStylePreviewPaneGrid[r][c] = pane;
}
}
}
public void setPlainText(String text) {
cellStylePreviewPaneGrid[0][1].setPaintText(text);
cellStylePreviewPaneGrid[1][1].setPaintText(text);
repaint();
}
public void setStyle(Style style, CellBorderStyle borderStyle) {
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < COLUMN_COUNT; j++) {
CellStylePreviewPane pane = cellStylePreviewPaneGrid[i][j];
TemplateCellElement cellElement = cellElementGrid[i][j];
int flag = borderSourceFlags[i][j];
cellElement.setStyle(CellBorderSourceFlag.deriveBorderedStyle(style, borderStyle, flag));
pane.setStyle(cellElement.getStyle());
}
}
repaint();
}
@Override
public void setPreferredSize(Dimension preferredSize) {
super.setPreferredSize(preferredSize);
int hw = preferredSize.width / 2;
int hh = preferredSize.height / 2;
cellStylePreviewPaneGrid[0][0].setPreferredSize(new Dimension(hw, hh));
cellStylePreviewPaneGrid[0][1].setPreferredSize(new Dimension(hw, hh));
cellStylePreviewPaneGrid[1][0].setPreferredSize(new Dimension(hw, hh));
cellStylePreviewPaneGrid[1][1].setPreferredSize(new Dimension(hw, hh));
}
@Override
public Dimension getPreferredSize() {
Dimension d00 = cellStylePreviewPaneGrid[0][0].getPreferredSize();
Dimension d01 = cellStylePreviewPaneGrid[0][1].getPreferredSize();
Dimension d10 = cellStylePreviewPaneGrid[1][0].getPreferredSize();
Dimension d11 = cellStylePreviewPaneGrid[1][1].getPreferredSize();
int width = Math.max(d00.width + d01.width, d10.width + d11.width);
int height = Math.max(d00.height + d10.height, d01.height + d11.height);
return new Dimension(width, height);
}
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.clearRect(0, 0, getWidth(), getHeight());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
paintTransparentBackground((Graphics2D) g, cellElementGrid[0][0].getStyle());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
super.paint(g);
}
@Override
public Rectangle getBounds() {
return super.getBounds();
}
private void paintTransparentBackground(Graphics2D g2d, Style style) {
float alpha = computeTransparentBackgroundAlpha(style);
float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth;
float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight;
float maxScale = Math.max(scaleWidth, scaleHeight);
if (maxScale <= 1) {
scaleWidth = scaleHeight = 1;
} else {
scaleHeight = scaleWidth = maxScale;
}
Composite oldComposite = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null);
g2d.setComposite(oldComposite);
}
private float computeTextColorBrightness(Style style) {
Color fontColor = style.getFRFont().getForeground();
return fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F + fontColor.getBlue() * 0.114F;
}
private float computeTransparentBackgroundAlpha(Style style) {
float textBrightness = computeTextColorBrightness(style);
float alpha = 1.0F;
if (textBrightness < 50) {
alpha = 0.2F;
} else if (textBrightness < 160){
alpha = 0.5F;
}
return alpha;
}
}

220
designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java

@ -0,0 +1,220 @@
package com.fr.design.cell;
import com.fr.base.BaseUtils;
import com.fr.base.GraphHelper;
import com.fr.base.NameStyle;
import com.fr.base.ScreenResolution;
import com.fr.base.Style;
import com.fr.general.FRFont;
import com.fr.general.IOUtils;
import com.fr.stable.Constants;
import com.fr.stable.unit.PT;
import javax.swing.JPanel;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.List;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/9/3
*/
public class CellStylePreviewPane extends JPanel {
public static final int MINIMUM_HEIGHT = 40;
private static final BufferedImage transparentBackgroundImage = IOUtils.readImage("/com/fr/design/images/transparent_background.png");
private final float transparentBackgroundWidth;
private final float transparentBackgroundHeight;
private String paintText = "Report";
private Style style = Style.DEFAULT_STYLE;
private final int column;
private final int row;
private final int columnSpan;
private final int rowSpan;
private final boolean autoClearCanvas;
private final boolean paintingMosaic;
public CellStylePreviewPane(int column, int row, int columnSpan, int rowSpan, boolean autoClearCanvas, boolean paintingMosaic) {
this.column = column;
this.row = row;
this.columnSpan = columnSpan;
this.rowSpan = rowSpan;
this.autoClearCanvas = autoClearCanvas;
this.paintingMosaic = paintingMosaic;
transparentBackgroundWidth = transparentBackgroundImage.getWidth(null);
transparentBackgroundHeight = transparentBackgroundImage.getHeight(null);
setPreferredSize(new Dimension(0, 0));
}
public void setPaintText(String paintText) {
this.paintText = paintText;
repaint();
}
public void setStyle(Style style) {
this.style = style;
repaint();
}
public void setStyle(NameStyle style) {
paintText = style.getName();
setStyle(style.getRealStyle());
}
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
if (autoClearCanvas) {
g2d.clearRect(0, 0, getWidth(), getHeight());
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
if (paintingMosaic) {
paintTransparentBackground(g2d, style);
}
paintCellStyle(g2d, style);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
private void paintTransparentBackground(Graphics2D g2d, Style style) {
float alpha = computeTransparentBackgroundAlpha(style);
float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth;
float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight;
float maxScale = Math.max(scaleWidth, scaleHeight);
if (maxScale <= 1) {
scaleWidth = scaleHeight = 1;
} else {
scaleHeight = scaleWidth = maxScale;
}
Composite oldComposite = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null);
g2d.setComposite(oldComposite);
}
private float computeTextColorBrightness(Style style) {
Color fontColor = style.getFRFont().getForeground();
return fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F + fontColor.getBlue() * 0.114F;
}
private float computeTransparentBackgroundAlpha(Style style) {
float textBrightness = computeTextColorBrightness(style);
float alpha = 1.0F;
if (textBrightness < 50) {
alpha = 0.2F;
} else if (textBrightness < 160){
alpha = 0.5F;
}
return alpha;
}
private void paintCellStyle(Graphics2D g2d, Style style) {
int resolution = ScreenResolution.getScreenResolution();
int width = getWidth();
int height = getHeight();
if (style == Style.DEFAULT_STYLE) {
// 如果是默认的style,就只写"Report"上去
Style.paintContent(g2d, paintText, style, width, height, resolution);
return;
}
Style.paintBackground(g2d, style, width, height);
Style.paintContent(g2d, paintText, style, width, height, resolution);
paintCellBorder(g2d, style);
}
protected void paintCellBorder(Graphics2D g2d, Style style) {
float adjustLeft = 0;
float adjustTop = 0;
float adjustRight = 0;
float adjustBottom = 0;
if (column == 0) {
adjustLeft = computeHalfSize4StyledBorder(style.getBorderLeft());
}
if (row == 0) {
adjustTop = computeHalfSize4StyledBorder(style.getBorderTop());
}
if (column == columnSpan - 1) {
adjustRight = -computeHalfSize4StyledBorder(style.getBorderRight());
}
if (row == rowSpan - 1) {
adjustBottom = -computeHalfSize4StyledBorder(style.getBorderBottom());
}
g2d.translate(adjustLeft, adjustTop);
Style.paintBorder(g2d, style, getWidth() - adjustLeft + adjustRight, getHeight() - adjustTop + adjustBottom);
g2d.translate(-adjustLeft, -adjustTop);
}
private float computeHalfSize4StyledBorder(int border) {
float size = GraphHelper.getLineStyleSize(border) / 2.0F;
if (border == Constants.LINE_DOUBLE) {
size += GraphHelper.getLineStyleSize(Constants.LINE_THIN) / 2.0F;
} else if (border == Constants.LINE_DOUBLE_DOT) {
size += GraphHelper.getLineStyleSize(Constants.LINE_DOT) / 2.0F;
}
return size;
}
@Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
int width = size.width;
int height = size.height;
if (height != 0) {
// 使用者设置了一个高度
return size;
} else if (width == 0) {
// 使用者未设置任何尺寸
return new Dimension(width, MINIMUM_HEIGHT);
} else {
// 使用者设置了宽度,但未设置高度
return getAutoWrapContentPreferredSize(width, height);
}
}
private Dimension getAutoWrapContentPreferredSize(int width, int height) {
int resolution = ScreenResolution.getScreenResolution();
// 计算文本区域高度
final FRFont frFont = style.getFRFont();
final Font rfont = frFont.applyResolutionNP(resolution);
final FontMetrics metrics = GraphHelper.getFontMetrics(rfont);
final int textLineHeight = metrics.getHeight();
final double textLineSpacing = PT.pt2pix(style.getLineSpacing(), resolution);
List<?> textLineList = BaseUtils.getLineTextList(paintText, style, rfont, height, width, resolution);
double textLinesHeight = textLineList.size() * textLineHeight + Math.max(0, textLineList.size() - 1) * textLineSpacing;
height = (int) Math.max(MINIMUM_HEIGHT, textLinesHeight);
return new Dimension(width, height);
}
}

52
designer-base/src/main/java/com/fr/design/config/DesignerProperties.java

@ -0,0 +1,52 @@
package com.fr.design.config;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Properties;
public class DesignerProperties {
private static DesignerProperties holder = null;
private boolean supportLoginEntry = true;
public DesignerProperties() {
String filePath = StableUtils.pathJoin(StableUtils.getInstallHome(), "/config/config.properties");
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(filePath));
Properties ps = new Properties();
ps.load(is);
this.initProperties(ps);
} catch (FileNotFoundException e) {
// ignore
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
} finally {
IOUtils.close(is);
}
}
public static DesignerProperties getInstance() {
if (holder == null) {
holder = new DesignerProperties();
}
return holder;
}
private void initProperties(Properties ps) {
String supportLoginEntry = ps.getProperty("supportLoginEntry");
if (StringUtils.isNotEmpty(supportLoginEntry)) {
this.supportLoginEntry = Boolean.valueOf(supportLoginEntry);
}
}
public boolean isSupportLoginEntry() {
return supportLoginEntry;
}
}

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

@ -36,8 +36,6 @@ import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.DefaultCellEditor;
@ -55,8 +53,10 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* Coder: zack
@ -83,6 +83,7 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp
protected String[] allDSNames;
protected ConnectionTableAction connectionTableAction;
protected ToolBarDef toolbarDef;
protected TableDataTreePaneListener listener = null;
private String type = "";
@ -142,6 +143,17 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp
public abstract void dgEdit(final AbstractTableDataPane<?> uPanel, String originalName, boolean isUpdate);
public void showEditPane(final AbstractTableDataPane<?> tableDataPane, String originalName, TableDataTreePaneListener listener) {
this.listener = listener;
dgEdit(tableDataPane, originalName);
}
public interface TableDataTreePaneListener {
void doOk();
void doCancel();
}
protected void doPropertyChange(BasicDialog dg, BasicPane.NamePane nPanel, final String oldName) {
type = dg.getTitle();
nPanel.setShowText(StringUtils.BLANK);

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

@ -47,9 +47,11 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -71,8 +73,8 @@ public abstract class DesignTableDataManager {
* 其实globalDsCache没有绝对的必要只是为了操作方便如果没有它那么每次清空服务器数据集或者存储过程的时候还要去遍历找一下
* 这个操作可能比较复杂 从减少代码复杂度的角度看还是很有必要的
*/
private static java.util.Map<String, TableDataWrapper> globalDsCache = new java.util.HashMap<String, TableDataWrapper>();
private static java.util.Map<String, String> dsNameChangedMap = new HashMap<String, String>();
private static Map<String, TableDataWrapper> globalDsCache = new java.util.HashMap<String, TableDataWrapper>();
private static Set<NameChangeBean> dsNameChangedSet = new LinkedHashSet<>();
private static List<ChangeListener> globalDsListeners = new ArrayList<>();
private static Map<String, List<ChangeListener>> dsListenersMap = new ConcurrentHashMap<>();
@ -123,7 +125,7 @@ public abstract class DesignTableDataManager {
public static void envChange() {
columnCache.clear();
dsListenersMap.clear();
dsNameChangedMap.clear();
dsNameChangedSet.clear();
clearGlobalDs();
}
@ -136,17 +138,17 @@ public abstract class DesignTableDataManager {
public static void fireDSChanged(Map<String, String> dsNameChangedMap) {
clearGlobalDs();
if (!dsNameChangedMap.isEmpty()) {
setDsNameChangedMap(dsNameChangedMap);
setDsNameChangedSet(dsNameChangedMap);
}
fireDsChanged();
dsNameChangedMap.clear();
}
private static void setDsNameChangedMap(Map<String, String> map) {
private static void setDsNameChangedSet(Map<String, String> map) {
Iterator iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = (String) iterator.next();
dsNameChangedMap.put(key, map.get(key));
dsNameChangedSet.add(new NameChangeBean(key, map.get(key)));
}
}
@ -157,15 +159,21 @@ public abstract class DesignTableDataManager {
* @return 是则返回true
*/
public static boolean isDsNameChanged(String oldDsName) {
return dsNameChangedMap.containsKey(oldDsName);
for (NameChangeBean bean : dsNameChangedSet) {
if (ComparatorUtils.equals(oldDsName, bean.getOldName())) {
return true;
}
}
return false;
}
public static String getChangedDsNameByOldDsName(String oldDsName) {
if (isDsNameChanged(oldDsName)) {
return dsNameChangedMap.get(oldDsName);
} else {
return StringUtils.EMPTY;
public static String getChangedDsNameByOldDsName(String dsName) {
for (NameChangeBean bean : dsNameChangedSet) {
if (ComparatorUtils.equals(dsName, bean.getOldName())) {
dsName = bean.getChangedName();
}
}
return dsName;
}
public static void addGlobalDsChangeListener(ChangeListener l) {

27
designer-base/src/main/java/com/fr/design/data/NameChangeBean.java

@ -0,0 +1,27 @@
package com.fr.design.data;
public class NameChangeBean {
private String oldName;
private String changedName;
public NameChangeBean(String oldName, String changedName) {
this.oldName = oldName;
this.changedName = changedName;
}
public String getOldName() {
return oldName;
}
public void setOldName(String oldName) {
this.oldName = oldName;
}
public String getChangedName() {
return changedName;
}
public void setChangedName(String changedName) {
this.changedName = changedName;
}
}

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

@ -0,0 +1,136 @@
package com.fr.design.data;
import com.fr.base.io.IOFile;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.JTemplate;
import com.fr.esd.core.strategy.config.StrategyConfig;
import com.fr.esd.core.strategy.config.StrategyConfigHelper;
import com.fr.esd.core.strategy.config.service.StrategyConfigService;
import com.fr.esd.core.strategy.persistence.StrategyConfigsAttr;
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.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author rinoux
* @version 10.0
* Created by rinoux on 2020/10/28
*/
public class StrategyConfigAttrUtils {
/**
* 获取当前编辑模版的数据集缓存配置属性
*
* @return
*/
private static StrategyConfigsAttr getStrategyConfigsAttr() {
StrategyConfigsAttr attr;
JTemplate<?, ?> jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (jTemplate != null) {
IOFile ioFile = (IOFile) jTemplate.getTarget();
attr = ioFile.getAttrMark(StrategyConfigsAttr.ATTR_MARK);
if (attr == null) {
attr = new StrategyConfigsAttr();
ioFile.addAttrMark(attr);
}
//新建模版此时不存在,不需要注册钩子
if (attr.getXmlSavedHook() == null && WorkContext.getWorkResource().exist(jTemplate.getPath())) {
attr.setXmlSavedHook(new StrategyConfigsAttrSavedHook(jTemplate.getPath(), attr));
}
return attr;
} else {
throw new IllegalStateException("[ESD]No editing template found.");
}
}
/**
* 获取模版数据集配置
*
* @param dsName
* @return
*/
public static StrategyConfig getStrategyConfig(String dsName) {
return getStrategyConfigsAttr().getStrategyConfig(dsName);
}
/**
* 移除模版数据集配置
*
* @param dsName
* @return
*/
public static StrategyConfig removeStrategyConfig(String dsName) {
return getStrategyConfigsAttr().removeStrategyConfig(dsName);
}
/**
* 添加模版数据集配置
*
* @param strategyConfig
*/
public static void addStrategyConfig(StrategyConfig strategyConfig) {
getStrategyConfigsAttr().addStrategyConfig(strategyConfig);
}
private static class StrategyConfigsAttrSavedHook implements XMLSavedHook<StrategyConfigsAttr> {
private static final long serialVersionUID = -8843201977112289321L;
private final String tplPath;
private final Map<String, StrategyConfig> origStrategyConfigs;
public StrategyConfigsAttrSavedHook(String tplPath, StrategyConfigsAttr raw) {
this.tplPath = tplPath;
this.origStrategyConfigs = new HashMap<>();
this.initOrigStrategyConfigs(raw);
}
private void initOrigStrategyConfigs(StrategyConfigsAttr raw) {
origStrategyConfigs.clear();
raw.getStrategyConfigs().forEach((k, v) -> {
try {
origStrategyConfigs.put(k, v.clone());
} catch (CloneNotSupportedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
});
}
@Override
public void doAfterSaved(StrategyConfigsAttr saved) {
FineLoggerFactory.getLogger().info("[ESD]Write StrategyConfigsAttr done, now check change.");
Set<String> dsNames = new HashSet<>();
dsNames.addAll(origStrategyConfigs.keySet());
dsNames.addAll(saved.getStrategyConfigs().keySet());
if (StringUtils.isNotEmpty(tplPath)) {
dsNames.forEach(dsName -> {
if (StringUtils.isNotEmpty(dsName)) {
StrategyEventsNotifier.compareAndFireConfigEvents(origStrategyConfigs.get(dsName), saved.getStrategyConfig(dsName), new DSMapping(tplPath, new DsNameTarget(dsName)));
}
});
}
initOrigStrategyConfigs(saved);
}
}
}

117
designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java

@ -1,12 +1,12 @@
package com.fr.design.data.datapane;
import com.fr.base.TableData;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.data.core.DataCoreUtils;
import com.fr.data.core.db.DBUtils;
import com.fr.data.core.db.TableProcedure;
import com.fr.data.core.db.dialect.Dialect;
import com.fr.data.core.db.dialect.DialectFactory;
import com.fr.data.impl.Connection;
import com.fr.data.impl.DBTableData;
import com.fr.data.operator.DataOperator;
import com.fr.design.DesignerEnvManager;
@ -19,7 +19,7 @@ import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.data.tabledata.Prepare4DataSourceChange;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.icombobox.FilterableComboBoxModel;
import com.fr.design.gui.icombobox.SearchPreTaskTreeComboBox;
import com.fr.design.gui.icombobox.TableSearchTreeComboBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxEditor;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
@ -40,11 +40,6 @@ import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.connection.DBConnectAuth;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.util.Collections;
import java.util.concurrent.CancellationException;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
@ -58,21 +53,20 @@ import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.CancellationException;
/**
* @author zhou
@ -97,41 +91,12 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
/**
* 表名
*/
protected SearchPreTaskTreeComboBox tableNameComboBox;
private static final ExecutorService SERVICE = Executors.newSingleThreadExecutor(new NamedThreadFactory("ChoosePane"));
protected TableSearchTreeComboBox tableNameComboBox;
private SwingWorker populateWorker;
private SwingWorker<List<String>, Void> initWorker;
private PopupMenuListener popupMenuListener = new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
FutureTask<Void> task = new FutureTask<Void>(new Callable<Void>() {
@Override
public Void call() throws Exception {
calculateTableDataNames();
return null;
}
});
tableNameComboBox.setPreSearchTask(task);
SERVICE.submit(task);
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// Do nothing
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
// Do nothing
}
};
private PopupMenuListener listener = new PopupMenuListener() {
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
@ -181,7 +146,7 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
schemaBox = new StringUIComboBox();
schemaBox.setEditor(new ComboBoxEditor());
tableNameComboBox = new SearchPreTaskTreeComboBox(new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer, false);
tableNameComboBox = new TableSearchTreeComboBox(this, new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer);
tableNameComboBox.setEditable(true);
tableNameComboBox.setRenderer(listCellRenderer);
registerDSChangeListener();
@ -198,7 +163,6 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
});
schemaBox.addPopupMenuListener(listener);
addFocusListener();
this.tableNameComboBox.addPopupMenuListener(popupMenuListener);
}
protected void addDSBoxListener() {
@ -355,7 +319,7 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
GUICoreUtils.setSelectedItemQuietly(tableNameComboBox, -1);
}
protected com.fr.data.impl.Connection getConnection() {
public Connection getConnection() {
String selectedDSName = this.getDSName();
if (StringUtils.isEmpty(selectedDSName)) {
return null; // peter:选中了当前的零长度的节点,直接返回.
@ -455,56 +419,6 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
return "choosepane";
}
protected void calculateTableDataNames() {
JTree tree = tableNameComboBox.getTree();
if (tree == null) {
return;
}
DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) tree.getModel().getRoot();
rootTreeNode.removeAllChildren();
String selectedDSName = this.getDSName();
com.fr.data.impl.Connection selectedDatabase = this.getConnection();
if (selectedDatabase == null) {
return;
}
try {
String schema = StringUtils.isEmpty(this.schemaBox.getSelectedItem()) ? null : this.schemaBox.getSelectedItem();
TableProcedure[] sqlTableArray = DataCoreUtils.getTables(selectedDatabase, TableProcedure.TABLE, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace());
if (sqlTableArray.length > 0) {
ExpandMutableTreeNode tableTreeNode = new ExpandMutableTreeNode(selectedDSName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_Table"));
rootTreeNode.add(tableTreeNode);
for (int i = 0; i < sqlTableArray.length; i++) {
ExpandMutableTreeNode tableChildTreeNode = new ExpandMutableTreeNode(sqlTableArray[i]);
tableTreeNode.add(tableChildTreeNode);
}
}
TableProcedure[] sqlViewArray = DataCoreUtils.getTables(selectedDatabase, TableProcedure.VIEW, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace());
if (sqlViewArray.length > 0) {
ExpandMutableTreeNode viewTreeNode = new ExpandMutableTreeNode(selectedDSName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_View"));
rootTreeNode.add(viewTreeNode);
for (int i = 0; i < sqlViewArray.length; i++) {
ExpandMutableTreeNode viewChildTreeNode = new ExpandMutableTreeNode(sqlViewArray[i]);
viewTreeNode.add(viewChildTreeNode);
}
}
((DefaultTreeModel) tree.getModel()).reload();
// daniel 展开所有tree
TreeNode root = (TreeNode) tree.getModel().getRoot();
TreePath parent = new TreePath(root);
TreeNode node = (TreeNode) parent.getLastPathComponent();
for (Enumeration e = node.children(); e.hasMoreElements(); ) {
TreeNode n = (TreeNode) e.nextElement();
TreePath path = parent.pathByAddingChild(n);
tree.expandPath(path);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Failed"), JOptionPane.ERROR_MESSAGE);
}
}
/**
* 创建选中的数据集数据
*
@ -558,23 +472,24 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
return tableData;
}
protected String getDSName() {
public String getDSName() {
return this.dsNameComboBox.getSelectedItem();
}
public String getSchema() {
return this.schemaBox.getSelectedItem();
}
protected void failedToFindTable() {
// Do nothing
}
protected String getTableName() {
String tableName = "";
Object obj = this.tableNameComboBox.getSelectedItemObject();
if (obj == null) {
obj = this.tableNameComboBox.getSelectedItem();
Object obj = this.tableNameComboBox.getSelectedItem();
if (obj == null) {
obj = this.tableNameComboBox.getEditor().getItem();
}
}
if (obj instanceof TreePath) {
Object tp = ((ExpandMutableTreeNode) ((TreePath) obj).getLastPathComponent()).getUserObject();
if (tp instanceof TableProcedure) {

2
designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java

@ -83,7 +83,7 @@ public class ChoosePaneSupportFormula extends ChoosePane {
*
* @return
*/
protected String getDSName() {
public String getDSName() {
String selectedDSName = null;
String item = Utils.objectToString(this.dsNameComboBox.getEditor().getItem());
// 没有选中的列表项 那么看看是不是手输值

226
designer-base/src/main/java/com/fr/design/data/datapane/ESDStrategyConfigPane.java

@ -0,0 +1,226 @@
package com.fr.design.data.datapane;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.esd.common.CacheConstants;
import com.fr.esd.core.strategy.config.StrategyConfig;
import com.fr.esd.core.strategy.config.StrategyConfigHelper;
import com.fr.esd.util.ESDUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.swing.AbstractAction;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author rinoux
* @version 10.0
* Created by rinoux on 2020/7/22
*/
public class ESDStrategyConfigPane extends BasicBeanPane<StrategyConfig> {
private static final String CRON_HELP_URL = "http://help.fanruan.com/finereport/doc-view-693.html";
private UIRadioButton selectAutoUpdate;
private UIRadioButton selectBySchema;
private UICheckBox shouldEvolve;
private UILabel updateIntervalCheckTips;
private UITextField updateInterval;
private UITextField schemaTime;
private ActionLabel actionLabel;
private UILabel schemaTimeCheckTips;
private final boolean global;
private StrategyConfig strategyConfig;
public ESDStrategyConfigPane(boolean global) {
this.global = global;
init();
}
private void init() {
setLayout(FRGUIPaneFactory.createM_BorderLayout());
this.selectAutoUpdate = new UIRadioButton(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Every_Interval"));
this.updateInterval = new UITextField(4);
this.shouldEvolve = new UICheckBox(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Auto_Evolved_Strategy"), false);
this.shouldEvolve.setEnabled(false);
this.updateIntervalCheckTips = new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Error_Interval_Format"));
this.updateIntervalCheckTips.setForeground(Color.RED);
this.updateIntervalCheckTips.setVisible(false);
this.selectBySchema = new UIRadioButton(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cron"));
this.schemaTime = new UITextField(10);
this.schemaTimeCheckTips = new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Error_Time_Format"));
this.schemaTimeCheckTips.setVisible(false);
this.schemaTimeCheckTips.setForeground(Color.RED);
this.selectAutoUpdate.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
ESDStrategyConfigPane.this.selectBySchema.setSelected(!ESDStrategyConfigPane.this.selectAutoUpdate.isSelected());
ESDStrategyConfigPane.this.schemaTime.setEnabled(false);
ESDStrategyConfigPane.this.updateInterval.setEnabled(true);
ESDStrategyConfigPane.this.shouldEvolve.setEnabled(true);
}
});
this.selectBySchema.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
ESDStrategyConfigPane.this.selectAutoUpdate.setSelected(!ESDStrategyConfigPane.this.selectBySchema.isSelected());
ESDStrategyConfigPane.this.schemaTime.setEnabled(true);
ESDStrategyConfigPane.this.updateInterval.setEnabled(false);
ESDStrategyConfigPane.this.shouldEvolve.setEnabled(false);
}
});
JPanel pane = FRGUIPaneFactory.createVerticalTitledBorderPane(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cache_Update_Strategy"));
add(pane, BorderLayout.NORTH);
JPanel row1 = GUICoreUtils.createFlowPane(new Component[]{
this.selectAutoUpdate,
this.updateInterval,
new UILabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Minute_Update_Cache")),
this.shouldEvolve,
this.updateIntervalCheckTips
}, 0, 5);
pane.add(row1);
ActionLabel actionLabel = new ActionLabel(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cron_Help"));
actionLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().browse(new URI(CRON_HELP_URL));
} catch (Exception exp) {
FineLoggerFactory.getLogger().error(exp.getMessage(), e);
}
}
});
JPanel row2 = GUICoreUtils.createFlowPane(new Component[]{
this.selectBySchema,
this.schemaTime,
actionLabel,
this.schemaTimeCheckTips
}, 0, 5);
pane.add(row2);
}
public void populateBean(StrategyConfig ob) {
if (ob == null && !global) {
ob = StrategyConfigHelper.createStrategyConfig(true, false, true);
}
this.strategyConfig = ob;
this.updateInterval.setText(ob.getUpdateInterval() <= 0 ? "0" : String.valueOf(ob.getUpdateInterval() / (double) CacheConstants.MILLIS_OF_MINUTE));
this.schemaTime.setText(StringUtils.join(",", ob.getUpdateSchema().toArray(new String[0])));
this.shouldEvolve.setSelected(ob.shouldEvolve());
this.selectBySchema.setSelected(ob.isScheduleBySchema());
this.selectAutoUpdate.setSelected(!ob.isScheduleBySchema());
if (global) {
//使用全局配置,禁用面板编辑
disablePane();
} else {
setSchemaEnable(!this.selectAutoUpdate.isSelected());
}
}
private void disablePane() {
this.selectAutoUpdate.setEnabled(false);
this.updateInterval.setEnabled(false);
this.shouldEvolve.setEnabled(false);
this.selectBySchema.setEnabled(false);
this.schemaTime.setEnabled(false);
}
private void setSchemaEnable(boolean enable) {
this.updateInterval.setEnabled(!enable);
this.shouldEvolve.setEnabled(!enable);
this.schemaTime.setEnabled(enable);
}
public StrategyConfig updateBean() {
StrategyConfig config = null;
if (!this.global) {
try {
//这里是new的config
config = this.strategyConfig.clone();
if (this.selectBySchema.isSelected()) {
List<String> schemaTimes = new ArrayList<>();
String text = this.schemaTime.getText();
if (ESDUtils.checkUpdateTimeSchema(text)) {
if (ESDUtils.isCronExpression(text)) {
schemaTimes.add(text);
} else {
Collections.addAll(schemaTimes, text.split(","));
}
} else {
this.schemaTimeCheckTips.setVisible(true);
throw new IllegalArgumentException("[ESD]Update schema time format error.");
}
config.setScheduleBySchema(true);
config.setUpdateSchema(schemaTimes);
} else {
String interval = this.updateInterval.getText();
if (checkUpdateInterval(interval)) {
long intervalMillis = StringUtils.isEmpty(interval) ? 0 : (long) (Double.parseDouble(interval) * CacheConstants.MILLIS_OF_MINUTE);
config.setUpdateInterval(intervalMillis);
} else {
this.updateIntervalCheckTips.setVisible(true);
throw new IllegalArgumentException("[ESD]Error update interval format.");
}
config.setShouldEvolve(this.shouldEvolve.isSelected());
config.setScheduleBySchema(false);
}
} catch (CloneNotSupportedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
return config;
}
private boolean checkUpdateInterval(String intervalValue) {
try {
return !StringUtils.isEmpty(intervalValue) && !(Double.parseDouble(intervalValue) <= 0);
} catch (NumberFormatException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return false;
}
protected String title4PopupWindow() {
return InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Cache_Strategy_Config_Title");
}
}

99
designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java

@ -1,36 +1,44 @@
package com.fr.design.data.datapane;
import com.fr.base.TableData;
import com.fr.base.TableDataBean;
import com.fr.config.RemoteConfigEvent;
import com.fr.data.TableDataSource;
import com.fr.data.api.StoreProcedureAssist;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.design.data.BasicTableDataUtils;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.NameInspector;
import com.fr.design.gui.controlpane.JListControlPane;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.i18n.Toolkit;
import com.fr.event.EventDispatcher;
import com.fr.file.ProcedureConfig;
import com.fr.file.TableDataConfig;
import com.fr.file.TableDataOperator;
import com.fr.file.TableDataOperatorImpl;
import com.fr.general.ComparatorUtils;
import com.fr.general.NameObject;
import com.fr.log.FineLoggerFactory;
import com.fr.rpc.ExceptionHandler;
import com.fr.rpc.RPCInvokerExceptionInfo;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.third.org.apache.commons.collections4.MapUtils;
import com.fr.workspace.WorkContext;
import javax.swing.*;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* TableDataList Pane.
@ -46,15 +54,12 @@ public class TableDataPaneListPane extends JListControlPane implements TableData
@Override
public void propertyChange() {
isNamePermitted = true;
String tempName = getEditingName();
if (ComparatorUtils.equals(tempName, selectedName)) {
//说明双击之后又取消了,啥也不用做
if (!checkName()) {
isNamePermitted = false;
return;
}
Set<String> allDSNames = DesignTableDataManager.getGlobalDataSet().keySet();
String[] allListNames = nameableList.getAllNames();
allListNames[editingIndex] = StringUtils.EMPTY;
String tempName = getEditingName();
Object editingType = getEditingType();
if (!BasicTableDataUtils.checkName(tempName)) {
@ -64,35 +69,36 @@ public class TableDataPaneListPane extends JListControlPane implements TableData
return;
}
if (StringUtils.isEmpty(tempName)) {
isNamePermitted = false;
nameableList.stopEditing();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TableDataPaneListPane.this),
Toolkit.i18nText("Fine-Design_Basic_Table_Data_Empty_Name_Tips"),
Toolkit.i18nText("Fine-Design_Report_Alert"),
JOptionPane.WARNING_MESSAGE);
setIllegalIndex(editingIndex);
return;
}
boolean isRepeated = isNameRepeated(new Collection[]{allDSNames, Arrays.asList(allListNames)}, tempName);
if (isRepeated) {
isNamePermitted = false;
nameableList.stopEditing();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TableDataPaneListPane.this), Toolkit.i18nText("Fine-Design_Basic_Table_Data_Duplicate_Name_Tips", tempName));
setIllegalIndex(editingIndex);
} else if (editingType instanceof StoreProcedure && isIncludeUnderline(tempName)) {
if (editingType instanceof StoreProcedure && isIncludeUnderline(tempName)) {
isNamePermitted = false;
nameableList.stopEditing();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TableDataPaneListPane.this), Toolkit.i18nText("Fine-Design_Basic_Stored_Procedure_Name_Tips"));
setIllegalIndex(editingIndex);
return;
}
if (nameableList.getSelectedValue() instanceof ListModelElement) {
rename(selectedName, isRepeated ? NameInspector.ILLEGAL_NAME_HOLDER : tempName);
rename(selectedName, tempName);
}
}
});
}
@Override
public String getEmptyNameTip() {
return Toolkit.i18nText("Fine-Design_Basic_Table_Data_Empty_Name_Tips");
}
@Override
public String getDuplicatedNameTip() {
return Toolkit.i18nText("Fine-Design_Basic_Table_Data_Duplicate_Name_Tips", getEditingName());
}
@Override
public Collection getExtraItemsToCheckNameRepeat() {
return DesignTableDataManager.getGlobalDataSet().keySet();
}
@Override
public void rename(String oldName, String newName) {
//如果a改成了b,b又被改成了c,就认为是a改成了c
@ -231,15 +237,40 @@ public class TableDataPaneListPane extends JListControlPane implements TableData
@Override
public void update(TableDataConfig tableDataConfig) {
tableDataConfig.removeAllTableData();
ProcedureConfig.getInstance().removeAllProcedure();
Nameable[] tableDataArray = this.update();
Map<String, TableData> tableDataMap = new LinkedHashMap<String, TableData>();
List<TableDataBean> tableDataBeans = new ArrayList<>();
Map<String, String> map = MapUtils.invertMap(getDsNameChangedMap());
for (int i = 0; i < tableDataArray.length; i++) {
NameObject nameObject = (NameObject) tableDataArray[i];
tableDataMap.put(nameObject.getName(), (TableData) nameObject.getObject());
String oldName = map.get(nameObject.getName());
if (oldName == null) {
oldName = StringUtils.EMPTY;
}
tableDataBeans.add(new TableDataBean(nameObject.getName(), oldName, (TableData) nameObject.getObject()));
}
try {
WorkContext.getCurrent().get(TableDataOperator.class, new ExceptionHandler() {
@Override
public Object callHandler(RPCInvokerExceptionInfo exceptionInfo) {
// 走老的方式
return saveByOldWay(tableDataBeans);
}
}).saveTableData(new ArrayList<>(tableDataConfig.getTableDatas().keySet()), tableDataBeans);
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.fire(RemoteConfigEvent.EDIT, TableDataConfig.getInstance().getNameSpace());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private boolean saveByOldWay(List<TableDataBean> tableDataBean) {
try {
return TableDataOperatorImpl.getInstance().saveTableData(tableDataBean);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return false;
}
tableDataConfig.setTableDatas(tableDataMap);
}
@Override

797
designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java

@ -2,60 +2,89 @@ package com.fr.design.data.datapane;
import com.fr.base.TableData;
import com.fr.data.TableDataSource;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.TableDataSourceDependent;
import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.UpdateAction;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.BasicTableDataTreePane;
import com.fr.design.data.BasicTableDataUtils;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.StrategyConfigAttrUtils;
import com.fr.design.data.tabledata.StoreProcedureWorkerListener;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.DBTableDataPane;
import com.fr.design.data.tabledata.wrapper.AbstractTableDataWrapper;
import com.fr.design.data.tabledata.wrapper.TableDataWrapper;
import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper;
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.fun.TableDataPaneProcessor;
import com.fr.design.gui.ibutton.UIHeadGroup;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.icon.IconPathConstants;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.menu.LineSeparator;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.SeparatorDef;
import com.fr.design.menu.ToolBarDef;
import com.fr.esd.core.strategy.config.StrategyConfig;
import com.fr.esd.core.strategy.config.StrategyConfigHelper;
import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.esd.query.StrategicTableData;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralContext;
import com.fr.general.IOUtils;
import com.fr.general.NameObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.injectable.PluginModule;
import com.fr.plugin.manage.PluginFilter;
import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.workspace.WorkContext;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.ToolTipManager;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.dnd.DnDConstants;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
public class TableDataTreePane extends BasicTableDataTreePane {
private static TableDataTreePane singleton = new TableDataTreePane();
private static final TableDataTreePane singleton = new TableDataTreePane();
public static final int PLUGIN_LISTENER_PRIORITY = 1;
@ -77,31 +106,45 @@ public class TableDataTreePane extends BasicTableDataTreePane {
}
private TableDataSourceOP op;
private TableDataTree dataTree;
private TableDataTree tableDataTree;
private EditAction editAction;
private RemoveAction removeAction;
private EsdOnAction esdAction;
private EsdOffAction esdOffAction;
private PreviewTableDataAction previewTableDataAction;
private JPanel serverDatasetAuthTipJPanel = new JPanel();
private TableDataTreePane() {
initPane();
}
private void initPane() {
this.setLayout(new BorderLayout(4, 0));
this.setBorder(null);
dataTree = new TableDataTree();
ToolTipManager.sharedInstance().registerComponent(dataTree);
//TableDataTree
tableDataTree = new TableDataTree();
ToolTipManager.sharedInstance().registerComponent(tableDataTree);
ToolTipManager.sharedInstance().setDismissDelay(3000);
ToolTipManager.sharedInstance().setInitialDelay(0);
addMenuDef = new MenuDef(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Action_Add"));
addMenuDef.setIconPath(IconPathConstants.ADD_POPMENU_ICON_PATH);
addMenuDef = new MenuDef(Toolkit.i18nText("Fine-Design_Basic_Action_Add"));
addMenuDef.setIconPath(IconPathConstants.ADD_POPMENU_ICON_PATH);
createAddMenuDef();
// 创建插件监听
createPluginListener();
editAction = new EditAction();
removeAction = new RemoveAction();
previewTableDataAction = new PreviewTableDataAction(dataTree);
previewTableDataAction = new PreviewTableDataAction(tableDataTree);
connectionTableAction = new ConnectionTableAction();
esdAction = new EsdOnAction();
esdOffAction = new EsdOffAction();
toolbarDef = new ToolBarDef();
toolbarDef.addShortCut(addMenuDef, SeparatorDef.DEFAULT, editAction, removeAction, SeparatorDef.DEFAULT, previewTableDataAction, connectionTableAction);
toolbarDef.addShortCut(addMenuDef, SeparatorDef.DEFAULT, editAction, removeAction, SeparatorDef.DEFAULT, previewTableDataAction, connectionTableAction, esdAction, esdOffAction);
UIToolbar toolBar = ToolBarDef.createJToolBar();
toolBar.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR));
toolBar.setBorderPainted(true);
@ -111,33 +154,72 @@ public class TableDataTreePane extends BasicTableDataTreePane {
toolbarPane.add(toolBar, BorderLayout.CENTER);
this.add(toolbarPane, BorderLayout.NORTH);
UIScrollPane scrollPane = new UIScrollPane(dataTree);
UIScrollPane scrollPane = new UIScrollPane(tableDataTree);
scrollPane.setBorder(null);
initbuttonGroup();
initServerDatasetAuthTipJPanel();
initButtonGroup();
JPanel jPanel = new JPanel(new BorderLayout(0, 0));
JPanel buttonPane = new JPanel(new GridLayout());
JPanel buttonPane = new JPanel(FRGUIPaneFactory.createBorderLayout());
buttonPane.add(buttonGroup, BorderLayout.CENTER);
buttonPane.add(serverDatasetAuthTipJPanel, BorderLayout.SOUTH);
jPanel.add(buttonPane, BorderLayout.NORTH);
jPanel.add(scrollPane, BorderLayout.CENTER);
this.add(jPanel, BorderLayout.CENTER);
dataTree.addMouseListener(new MouseAdapter() {
tableDataTree.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
checkButtonEnabled();
}
});
dataTree.addKeyListener(getTableTreeNodeListener(editAction, previewTableDataAction, removeAction, op, dataTree));
tableDataTree.addKeyListener(getTableTreeNodeListener(editAction, previewTableDataAction, removeAction, op, tableDataTree));
// TreeCellEditor
dataTree.setEditable(true);
TableDataTreeCellEditor treeCellEditor = new TableDataTreeCellEditor(new UITextField(), dataTree, this);
tableDataTree.setEditable(true);
TableDataTreeCellEditor treeCellEditor = new TableDataTreeCellEditor(new UITextField(), tableDataTree, this);
treeCellEditor.addCellEditorListener(treeCellEditor);
dataTree.setCellEditor(treeCellEditor);
new TableDataTreeDragSource(dataTree, DnDConstants.ACTION_COPY);
tableDataTree.setCellEditor(treeCellEditor);
new TableDataTreeDragSource(tableDataTree, DnDConstants.ACTION_COPY);
checkButtonEnabled();
}
private void createPluginListener() {
private void initServerDatasetAuthTipJPanel() {
String datasetAuthTip = Toolkit.i18nText("Fine-Design_Server_Dataset_Auth_Tip");
List<String> lineTips = new ArrayList(Arrays.asList(datasetAuthTip.split("\n")));
if (datasetAuthTip.endsWith("\n")) {
lineTips.add(StringUtils.EMPTY);
}
serverDatasetAuthTipJPanel = new JPanel();
serverDatasetAuthTipJPanel.setLayout(new GridLayout(lineTips.size(), 1));
for (int i = 0; i < lineTips.size(); i++) {
String lineTip = lineTips.get(i);
List<JLabel> jLabels = new ArrayList<>();
JLabel lineJLabel = new JLabel(lineTip);
lineJLabel.setForeground(Color.lightGray);
jLabels.add(lineJLabel);
if (i == (lineTips.size() - 1)) {
JLabel jLabel = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Alphafine_No_Remind"));
jLabel.setForeground(Color.blue);
jLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
DesignerEnvManager.getEnvManager().setShowServerDatasetAuthTip(false);
serverDatasetAuthTipJPanel.setVisible(false);
}
});
jLabels.add(jLabel);
}
serverDatasetAuthTipJPanel.add(getLineTipJPanel(jLabels));
}
}
private JPanel getLineTipJPanel(List<JLabel> jLabels) {
JPanel jPanel = new JPanel(FRGUIPaneFactory.createLabelFlowLayout());
for (JLabel jLabel : jLabels) {
jPanel.add(jLabel);
}
return jPanel;
}
private void createPluginListener() {
//菜单栏监听
GeneralContext.listenPluginRunningChanged(new PluginEventListener(PLUGIN_LISTENER_PRIORITY) {
@ -157,69 +239,113 @@ public class TableDataTreePane extends BasicTableDataTreePane {
});
}
protected void checkButtonEnabled() {
super.checkButtonEnabled(editAction, previewTableDataAction, removeAction, op, dataTree);
}
/**
* 刷新
*/
@Override
public void refreshDockingView() {
populate(new TableDataSourceOP(tc));
this.checkButtonEnabled();
}
protected void initbuttonGroup() {
// Icon[] iconArray = {BaseUtils.readIcon("/com/fr/design/images/data/datasource.png"), BaseUtils.readIcon("/com/fr/design/images/data/dock/serverdatabase.png")};
final Integer[] modeArray = {TEMPLATE_TABLE_DATA, SERVER_TABLE_DATA};
String[] textArray = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Source_Type_Template"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_DS_Server_TableData")};
buttonGroup = new UIHeadGroup(textArray) {
public void tabChanged(int index) {
if (op != null) {
op.setDataMode(modeArray[buttonGroup.getSelectedIndex()]);
addMenuDef.setEnabled(modeArray[buttonGroup.getSelectedIndex()] == TEMPLATE_TABLE_DATA ? true : false);
refreshDockingView();
@Override
public final void createAddMenuDef() {
TableDataNameObjectCreator[] creators = TableDataCreatorProducer.getInstance().createReportTableDataCreator();
for (final TableDataNameObjectCreator creator : creators) {
if (creator.shouldInsertSeparator()) {
addMenuDef.addShortCut(new LineSeparator());
}
addMenuDef.addShortCut(new AddAction() {
@Override
protected String getTDName() {
return creator.menuName();
}
@Override
protected Icon getTDIcon() {
return creator.menuIcon();
}
@Override
protected String getNamePrefix() {
return creator.getPrefix();
}
@Override
protected TemplateTableDataWrapper getTableDataInstance() {
TableData tableData = (TableData) creator.createObject();
//11中所有数据集都是StrategicTableData的子类
if (tableData instanceof StrategicTableData) {
StrategicTableData std = (StrategicTableData) tableData;
tableData = StrategicTableData.Binder
.bind(std)
.setDsName(createDsName(creator.getPrefix()))
.setScope(StrategicTableData.Scope.TEMPLATE)
.done();
}
return new TemplateTableDataWrapper(tableData);
}
});
}
};
buttonGroup.setNeedLeftRightOutLine(false);
}
/**
* 编辑面板
*
* @param uPanel 面板
* @param tableDataPane 面板
* @param originalName 原始名字
*/
public void dgEdit(final AbstractTableDataPane<?> uPanel, String originalName, boolean isUpdate) {
uPanel.addStoreProcedureWorkerListener(new StoreProcedureWorkerListener() {
@Override
public void dgEdit(final AbstractTableDataPane<?> tableDataPane, String originalName, boolean isUpdate) {
tableDataPane.addStoreProcedureWorkerListener(new StoreProcedureWorkerListener() {
public void fireDoneAction() {
if (dataTree.getSelectionPath() == null) {
dataTree.refresh();
if (tableDataTree.getSelectionPath() == null) {
tableDataTree.refresh();
} else {
Object object = dataTree.getSelectionPath().getLastPathComponent();
int[] rows = dataTree.getSelectionRows();
dataTree.refreshChildByName(object.toString());
dataTree.setSelectionRows(rows);
Object object = tableDataTree.getSelectionPath().getLastPathComponent();
int[] rows = tableDataTree.getSelectionRows();
tableDataTree.refreshChildByName(object.toString());
tableDataTree.setSelectionRows(rows);
}
}
});
final BasicPane.NamePane nPanel = uPanel.asNamePane();
nPanel.setObjectName(originalName);
final NamePane tdNamePanel = tableDataPane.asNamePane();
tdNamePanel.setObjectName(originalName);
final String oldName = originalName;
final BasicDialog dg;
allDSNames = DesignTableDataManager.getAllDSNames(tc.getBook());
dg = nPanel.showLargeWindow(SwingUtilities.getWindowAncestor(TableDataTreePane.this), new DialogActionAdapter() {
final BasicDialog dg = tdNamePanel.showLargeWindow(SwingUtilities.getWindowAncestor(TableDataTreePane.this), new DialogActionAdapter() {
@Override
public void doOk() {
DesignTableDataManager.setThreadLocal(DesignTableDataManager.NO_PARAMETER);
tc.renameTableData(oldName, nPanel.getObjectName(), false);
tc.renameTableData(oldName, tdNamePanel.getObjectName(), false);
TableDataSource tds = tc.getBook();
TableData td = uPanel.updateBean();
TableData td = tableDataPane.updateBean();
if (td instanceof TableDataSourceDependent) {
((TableDataSourceDependent) td).setTableDataSource(tds);
}
String tdName = nPanel.getObjectName();
String tdName = tdNamePanel.getObjectName();
//模版还没保存的时候不知道后缀,不能设置到策略配置里面
if (tableDataPane instanceof DBTableDataPane) {
StrategyConfig editingConfig = ((DBTableDataPane) tableDataPane).updateStrategyConfig();
if (editingConfig != null) {
editingConfig.setDsName(tdName);
if (!ComparatorUtils.equals(oldName, tdName)) {
//重命名
StrategyConfigAttrUtils.removeStrategyConfig(oldName);
}
StrategyConfigAttrUtils.addStrategyConfig(editingConfig);
}
((DBTableData) td).setDsName(tdName);
}
tds.putTableData(tdName, td);
Map<String, String> map = new HashMap<String, String>();
if (!ComparatorUtils.equals(oldName, tdName)) {
@ -227,83 +353,42 @@ public class TableDataTreePane extends BasicTableDataTreePane {
}
fireDSChanged(map);
tc.fireTargetModified();
tc.tableDataParametersChanged(oldName, tdName, td);
int[] rows = dataTree.getSelectionRows();
dataTree.refreshChildByName(tdName);
dataTree.setSelectionRows(rows);
}
});
nPanel.addPropertyChangeListener(new PropertyChangeAdapter() {
@Override
public void propertyChange() {
doPropertyChange(dg, nPanel, oldName);
}
});
dg.setVisible(true);
}
private class EditAction extends UpdateAction {
public EditAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Edit"));
this.setMnemonic('E');
this.setSmallIcon("/com/fr/design/images/control/edit");
}
tc.parameterChanged();
int[] rows = tableDataTree.getSelectionRows();
tableDataTree.refreshChildByName(tdName);
tableDataTree.setSelectionRows(rows);
public void actionPerformed(ActionEvent e) {
final NameObject selectedNO = dataTree.getSelectedNameObject();
if (selectedNO == null) {
return;
}
DesignTableDataManager.removeSelectedColumnNames(selectedNO.getName());
dgEdit(((AbstractTableDataWrapper) selectedNO.getObject()).creatTableDataPane(), selectedNO.getName(), false);
}
}
private class RemoveAction extends UpdateAction {
//单独编辑数据集关闭,修改缓存配置状态,刷新下一键开启/关闭按钮
checkButtonEnabled();
public RemoveAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"));
this.setMnemonic('R');
this.setSmallIcon("/com/fr/design/images/control/remove");
if (listener != null) {
listener.doOk();
}
@Override
public void actionPerformed(ActionEvent e) {
NameObject selectedNO = dataTree.getSelectedNameObject();
if (selectedNO == null) {
return;
}
int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + ":" + selectedNO.getName() + "?",
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (returnVal == JOptionPane.OK_OPTION) {
// richer:这个地方为什么要在DataSourceTree里面去remove呢?多此一举吧
op.removeAction(selectedNO.getName());
dataTree.refresh();
// Richie:默认最后一行获得焦点.
dataTree.requestFocus();
dataTree.setSelectionRow(dataTree.getRowCount() - 1);
fireDSChanged();
checkButtonEnabled();
DesignTableDataManager.removeSelectedColumnNames(selectedNO.getName());
DesignModelAdapter.getCurrentModelAdapter().removeTableDataParameters(selectedNO.getName());
@Override
public void doCancel() {
super.doCancel();
if (listener != null) {
listener.doCancel();
}
}
});
tdNamePanel.addPropertyChangeListener(new PropertyChangeAdapter() {
@Override
public void propertyChange() {
doPropertyChange(dg, tdNamePanel, oldName);
}
private void populate(TableDataSourceOP op) {
this.op = op;
dataTree.populate(op);
checkButtonEnabled();
});
dg.setVisible(true);
}
/**
* @return
*/
public TableDataTree getDataTree() {
return dataTree;
@Override
public void removeTableData(String sourceName) {
TableDataSource tds = this.tc.getBook();
tds.removeTableData(sourceName);
this.tableDataTree.refresh();
}
/**
@ -312,6 +397,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
* @param srcName 数据集来源(比如报表块就是报表块的名称)
* @param tableDataSource 数据集
*/
@Override
public Map<String, String> addTableData(String srcName, TableDataSource tableDataSource, boolean isCover) {
Map<String, String> tdNameMap = new HashMap<>();
allDSNames = DesignTableDataManager.getAllDSNames(tc.getBook());
@ -322,39 +408,63 @@ public class TableDataTreePane extends BasicTableDataTreePane {
String tdName = (String) tdIterator.next();
String oldName = tdName;
TableData td = tableDataSource.getTableData(tdName);
boolean isDsNameRepeaded = isDsNameRepeaded(tdName);
tdName = BasicTableDataUtils.getTableDataName(isCover, tds, tdName, srcName, isDsNameRepeaded);
boolean isDsNameRepeated = isDsNameRepeaded(tdName);
tdName = BasicTableDataUtils.getTableDataName(isCover, tds, tdName, srcName, isDsNameRepeated);
tds.putTableData(tdName, td);
if (!ComparatorUtils.equals(oldName, tdName)) {
tdNameMap.put(oldName, tdName);
}
}
tc.parameterChanged();
dataTree.refresh();
tableDataTree.refresh();
return Collections.unmodifiableMap(tdNameMap);
}
/**
* 合并数据集
*
* @param srcName 数据集来源(比如报表块就是报表块的名称)
* @param tableDataSource 数据集
*/
@Override
public void removeTableData(String sourceName) {
public Map<String, String> addTableData(String srcName, TableDataSource tableDataSource) {
Map<String, String> tdNameMap = new HashMap<>();
allDSNames = DesignTableDataManager.getAllDSNames(tc.getBook());
DesignTableDataManager.setThreadLocal(DesignTableDataManager.NO_PARAMETER);
TableDataSource tds = tc.getBook();
tds.removeTableData(sourceName);
dataTree.refresh();
Iterator<String> tdIterator = tableDataSource.getTableDataNameIterator();
while (tdIterator.hasNext()) {
String tdName = tdIterator.next();
String oldName = tdName;
TableData td = tableDataSource.getTableData(tdName);
if (tds.getTableData(tdName) != null || isDsNameRepeaded(tdName)) {
//如果有同名的就拼上来源名称
tdName = srcName + tdName;
}
int i = 0;
while (tds.getTableData(tdName) != null) {
i++;//如果拼上名字后依然已经存在就加编号
tdName += i;
}
tds.putTableData(tdName, td);
if (!ComparatorUtils.equals(oldName, tdName)) {
tdNameMap.put(oldName, tdName);
}
@Override
public void checkEnable() {
this.checkButtonEnabled();
}
tc.parameterChanged();
tableDataTree.refresh();
return Collections.unmodifiableMap(tdNameMap);
}
@Override
public void addDataPane(final AbstractTableDataPane<?> uPanel, String paneName) {
final NamePane nPanel = uPanel.asNamePane();
nPanel.setObjectName(paneName);
final String oldName = paneName;
allDSNames = DesignTableDataManager.getAllDSNames(tc.getBook());
DesignTableDataManager.setThreadLocal(DesignTableDataManager.NO_PARAMETER);
tc.renameTableData(oldName, nPanel.getObjectName(), false);
tc.renameTableData(paneName, nPanel.getObjectName(), false);
TableDataSource tds = tc.getBook();
TableData td = uPanel.updateBean();
if (td instanceof TableDataSourceDependent) {
@ -363,14 +473,429 @@ public class TableDataTreePane extends BasicTableDataTreePane {
String tdName = nPanel.getObjectName();
tds.putTableData(tdName, td);
Map<String, String> map = new HashMap<String, String>();
if (!ComparatorUtils.equals(oldName, tdName)) {
map.put(oldName, tdName);
if (!ComparatorUtils.equals(paneName, tdName)) {
map.put(paneName, tdName);
}
fireDSChanged(map);
tc.fireTargetModified();
tc.tableDataParametersChanged(oldName, tdName, td);
int[] rows = dataTree.getSelectionRows();
dataTree.refreshChildByName(tdName);
dataTree.setSelectionRows(rows);
tc.parameterChanged();
int[] rows = tableDataTree.getSelectionRows();
tableDataTree.refreshChildByName(tdName);
tableDataTree.setSelectionRows(rows);
}
@Override
public TableDataTree getDataTree() {
return this.tableDataTree;
}
private void populate(TableDataSourceOP op) {
this.op = op;
tableDataTree.populate(op);
checkButtonEnabled();
}
private void resetAddMenuDef() {
this.addMenuDef.clearShortCuts();
this.createAddMenuDef();
}
private void checkButtonEnabled() {
super.checkButtonEnabled(editAction, previewTableDataAction, removeAction, op, tableDataTree);
this.checkESDComponentsEnabled();
}
private void checkESDComponentsEnabled() {
if (buttonGroup.getSelectedIndex() == 1) {
//切换到服务器数据集的tab,禁用
esdAction.setEnabled(false);
esdOffAction.setEnabled(false);
return;
}
new SwingWorker<ButtonStatus, Void>() {
@Override
protected ButtonStatus doInBackground() throws Exception {
ButtonStatus btnStatus = new ButtonStatus();
Map<DBTableData, ESDStatus> statusMap = checkCanBeEsdBatchEnableStatus();
if (statusMap.size() == 0) {
//没有db数据集
return btnStatus;
} else {
int canTurnOnCount = 0;
int canTurnOffCount = 0;
for (ESDStatus status : statusMap.values()) {
switch (status) {
case GLOBAL_ON:
case GLOBAL_OFF:
case SINGLE_OFF:
canTurnOnCount++;
break;
case SINGLE_ON:
canTurnOffCount++;
break;
default:
break;
}
}
btnStatus.setOnStatus(canTurnOnCount > 0);
btnStatus.setOffStatus(canTurnOffCount > 0);
}
return btnStatus;
}
@Override
protected void done() {
try {
ButtonStatus buttonStatus = get();
esdAction.setEnabled(buttonStatus.isOnStatus());
esdOffAction.setEnabled(buttonStatus.isOffStatus());
} catch (InterruptedException | ExecutionException e) {
FineLoggerFactory.getLogger().error("get esd status of ds error for " + e.getMessage(), e);
}
}
}.execute();
}
private static class ButtonStatus {
private boolean onStatus = false;
private boolean offStatus = false;
public boolean isOnStatus() {
return onStatus;
}
public void setOnStatus(boolean onStatus) {
this.onStatus = onStatus;
}
public boolean isOffStatus() {
return offStatus;
}
public void setOffStatus(boolean offStatus) {
this.offStatus = offStatus;
}
}
//模版数据集
private void initButtonGroup() {
final Integer[] modeArray = {TEMPLATE_TABLE_DATA, SERVER_TABLE_DATA};
String[] textArray = {Toolkit.i18nText("Fine-Design_Basic_Tabledata_Source_Type_Template"), Toolkit.i18nText("Fine-Design_Basic_DS_Server_TableData")};
buttonGroup = new UIHeadGroup(textArray) {
public void tabChanged(int index) {
if (isShowServerDatasetAuthTipJPanel(textArray[index])) {
serverDatasetAuthTipJPanel.setVisible(true);
} else {
serverDatasetAuthTipJPanel.setVisible(false);
}
if (op != null) {
op.setDataMode(modeArray[buttonGroup.getSelectedIndex()]);
addMenuDef.setEnabled(modeArray[buttonGroup.getSelectedIndex()] == TEMPLATE_TABLE_DATA);
refreshDockingView();
}
}
private boolean isShowServerDatasetAuthTipJPanel(String name) {
if (ComparatorUtils.equals(name, Toolkit.i18nText("Fine-Design_Basic_DS_Server_TableData"))
&& DesignerEnvManager.getEnvManager().isShowServerDatasetAuthTip()
&& !WorkContext.getCurrent().isLocal()) {
return true;
}
return false;
}
};
buttonGroup.setNeedLeftRightOutLine(false);
}
private TableDataWrapper findTableDataWrapper(TreePath treePath) {
if (treePath != null) {
ExpandMutableTreeNode selectedTreeNode = (ExpandMutableTreeNode) treePath.getLastPathComponent();
Object selectedUserObject = selectedTreeNode.getUserObject();
NameObject nameObject = null;
if (selectedUserObject instanceof NameObject) {
nameObject = (NameObject) selectedUserObject;
} else {
selectedTreeNode = (ExpandMutableTreeNode) selectedTreeNode.getParent();
selectedUserObject = selectedTreeNode.getUserObject();
if (selectedUserObject instanceof NameObject) {
nameObject = (NameObject) selectedUserObject;
}
}
if (nameObject != null && nameObject.getObject() instanceof TableDataWrapper) {
return (TableDataWrapper) nameObject.getObject();
}
}
return null;
}
private String getTplPath() {
return HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getPath();
}
enum ESDStatus {
GLOBAL_ON,
GLOBAL_OFF,
SINGLE_ON,
SINGLE_OFF;
}
private Map<DBTableData, ESDStatus> checkCanBeEsdBatchEnableStatus() {
//<数据集, 是否可以被单独开启>
Map<DBTableData, ESDStatus> result = new HashMap<>();
for (int i = 0; i < tableDataTree.getRowCount(); i++) {
TreePath treePath = tableDataTree.getPathForRow(i);
TableDataWrapper wrapper = findTableDataWrapper(treePath);
if (wrapper.getTableData() instanceof DBTableData) {
DBTableData td = (DBTableData) wrapper.getTableData();
StrategyConfig config = StrategyConfigAttrUtils.getStrategyConfig(wrapper.getTableDataName());
if (config == null) {
result.put(td, td.isShare() ? ESDStatus.SINGLE_ON : ESDStatus.SINGLE_OFF);
} else {
if (config.isUseGlobal()) {
if (StrategyConfigHelper.recommended(getTplPath())) {
result.put(td, ESDStatus.GLOBAL_ON);
} else {
result.put(td, ESDStatus.GLOBAL_OFF);
}
} else {
if (config.enabled()) {
result.put(td, ESDStatus.SINGLE_ON);
} else {
result.put(td, ESDStatus.SINGLE_OFF);
}
}
}
}
}
return result;
}
private class EsdOnAction extends AbstractESDAction {
@Override
public String getName() {
return Toolkit.i18nText("Fine-Design_ESD_Batch_Enable");
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/control/batch_esd_on.png");
}
@Override
public void doWithTableDataWrapper(TableDataWrapper wrapper) {
String dsName = wrapper.getTableDataName();
if (wrapper.getTableData() instanceof DBTableData) {
StrategyConfig strategyConfig = getOrCreateStrategyConfig(dsName);
strategyConfig.setEnable(true);
strategyConfig.setUseGlobal(false);
StrategyConfigAttrUtils.addStrategyConfig(strategyConfig);
DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified();
}
}
}
private @NotNull StrategyConfig getOrCreateStrategyConfig(String dsName) {
StrategyConfig config = StrategyConfigAttrUtils.getStrategyConfig(dsName);
if (config == null) {
config = StrategyConfigHelper.createStrategyConfig(true);
config.setDsName(dsName);
}
return config;
}
private String createDsName(String prefix) {
int count = 1;
allDSNames = DesignTableDataManager.getAllDSNames(tc.getBook());
while (isDsNameRepeaded(prefix + count)) {
count++;
}
return prefix + count;
}
private class EsdOffAction extends AbstractESDAction {
@Override
public String getName() {
return Toolkit.i18nText("Fine-Design_ESD_Batch_Disable");
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/control/batch_esd_off.png");
}
@Override
public void doWithTableDataWrapper(TableDataWrapper wrapper) {
String dsName = wrapper.getTableDataName();
if (wrapper.getTableData() instanceof DBTableData) {
((DBTableData) wrapper.getTableData()).setShare(false);
StrategyConfig strategyConfig = getOrCreateStrategyConfig(dsName);
strategyConfig.setEnable(false);
strategyConfig.setUseGlobal(false);
StrategyConfigAttrUtils.addStrategyConfig(strategyConfig);
DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified();
}
}
}
private abstract class AbstractESDAction extends UpdateAction {
public abstract String getName();
public abstract Icon getIcon();
public abstract void doWithTableDataWrapper(TableDataWrapper tableDataWrapper);
public AbstractESDAction() {
this.setName(getName());
this.setMnemonic('R');
this.setSmallIcon(getIcon());
}
@Override
public void actionPerformed(ActionEvent e) {
List<TableDataWrapper> tableDataWrapperList = new ArrayList<>();
for (int i = 0; i < tableDataTree.getRowCount(); i++) {
TreePath treePath = tableDataTree.getPathForRow(i);
TableDataWrapper wrapper = findTableDataWrapper(treePath);
if (wrapper != null) {
tableDataWrapperList.add(wrapper);
}
}
if (tableDataWrapperList.isEmpty()) {
return;
}
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
for (TableDataWrapper tableDataWrapper : tableDataWrapperList) {
doWithTableDataWrapper(tableDataWrapper);
}
return null;
}
@Override
protected void done() {
refreshDockingView();
}
}.execute();
}
}
/**
* 新建数据集
* <p>
* 抽象化支持不同类型数据集创建
*/
private abstract class AddAction extends UpdateAction {
protected abstract String getTDName();
protected abstract Icon getTDIcon();
protected abstract String getNamePrefix();
protected abstract TemplateTableDataWrapper getTableDataInstance();
public AddAction() {
this.setName(this.getTDName());
this.setSmallIcon(this.getTDIcon());
}
@Override
public void actionPerformed(ActionEvent e) {
dgEdit(getTableDataInstance().creatTableDataPane(), createDsName(getNamePrefix()), false);
}
}
private class EditAction extends UpdateAction {
public EditAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Edit"));
this.setMnemonic('E');
this.setSmallIcon(IOUtils.readIcon(IconPathConstants.TD_EDIT_ICON_PATH));
}
@Override
public void actionPerformed(ActionEvent e) {
final NameObject selectedNO = tableDataTree.getSelectedNameObject();
if (selectedNO == null) {
return;
}
String dsName = selectedNO.getName();
DesignTableDataManager.removeSelectedColumnNames(dsName);
AbstractTableDataWrapper wrapper = (AbstractTableDataWrapper) selectedNO.getObject();
AbstractTableDataPane<?> tableDataPane = wrapper.creatTableDataPane();
//下面创建creatTableDataPane后会直接populate,所以populate时不能用后设置的一些参数,比如name
dgEdit(tableDataPane, dsName, false);
}
}
private class RemoveAction extends UpdateAction {
public RemoveAction() {
this.setName(Toolkit.i18nText("Fine-Design_Basic_Remove"));
this.setMnemonic('R');
this.setSmallIcon(IOUtils.readIcon(IconPathConstants.TD_REMOVE_ICON_PATH));
}
@Override
public void actionPerformed(ActionEvent e) {
NameObject selectedNO = tableDataTree.getSelectedNameObject();
if (selectedNO == null) {
return;
}
int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + ":" + selectedNO.getName() + "?",
Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (returnVal == JOptionPane.OK_OPTION) {
// richer:这个地方为什么要在DataSourceTree里面去remove呢?多此一举吧
op.removeAction(selectedNO.getName());
tableDataTree.refresh();
// Richie:默认最后一行获得焦点.
tableDataTree.requestFocus();
tableDataTree.setSelectionRow(tableDataTree.getRowCount() - 1);
fireDSChanged();
checkButtonEnabled();
//删掉缓存配置
StrategyConfigAttrUtils.removeStrategyConfig(selectedNO.getName());
// 如果一个模版是平台开启,这个数据集的配置不会存xml,预览模版时直接从全局配置copy,这样
// 导致删除的时候StrategyConfigsAttrSavedHook没有通过前后配置比较感知数据集被删除,因此不会发出事件让其失效
// 这里额外发出一次数据集修改事件
StrategyEventsNotifier.modifyDataSet(new DSMapping(getTplPath(), new DsNameTarget(selectedNO.getName())));
DesignTableDataManager.removeSelectedColumnNames(selectedNO.getName());
DesignModelAdapter.getCurrentModelAdapter().removeTableDataParameters(selectedNO.getName());
}
}
}
@Override
public void checkEnable() {
this.checkButtonEnabled();
}
}

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

@ -9,6 +9,7 @@ import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.file.TableDataConfig;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
@ -80,12 +81,13 @@ public class TreeTableDataComboBox extends UIComboBox {
}
public void setSelectedTableDataByName(String name) {
refresh();
TableDataWrapper tableDataWrapper;
if (res_map.get(name) != null) {
tableDataWrapper = res_map.get(name);
} else {
String changeName = DesignTableDataManager.getChangedDsNameByOldDsName(name);
if (StringUtils.isNotEmpty(changeName)) {
tableDataWrapper = res_map.get(changeName);
} else {
tableDataWrapper = res_map.get(name);
}
this.getModel().setSelectedItem(tableDataWrapper);
}

24
designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java

@ -64,7 +64,7 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
tableFlowPane.add(tableDataNameComboBox);
tableDataNameComboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
tdChange();
tdChange(true);
}
});
tableFlowPane.add(new PreviewLabel(this));
@ -73,19 +73,21 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
this.add(centerPane, BorderLayout.CENTER);
parentMarkRadio = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Build_Tree_Accord_Parent_Marked_Filed"), true);
lengthMarkRadio = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Build_Tree_Accord_Marked_Filed_Length"));
parentMarkRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
parentMarkRadio.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (isBuildByParentFiled()) {
makeParentEnable();
tdChange();
tdChange(false);
}
}
});
lengthMarkRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
lengthMarkRadio.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (!isBuildByParentFiled()) {
makeLengthEnable();
tdChange();
tdChange(false);
}
}
});
@ -169,7 +171,7 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
}
private void tdChange() {
private void tdChange(boolean isChangeDS) {
TableDataWrapper tableDataWrappe = this.tableDataNameComboBox.getSelectedItem();
if (tableDataWrappe == null) {
return;
@ -186,8 +188,10 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
String[] columnNames = new String[len];
namelist.toArray(columnNames);
for (int i = 0; i < valueEditorPanes.length; i++) {
if (isChangeDS || isNoSelectedColumnName(valueEditorPanes[i])) {
valueEditorPanes[i].setEditors(new Editor[]{new ColumnNameEditor(columnNames), new ColumnIndexEditor(len)}, columnNames[0]);
}
}
} catch (Exception e) {
for (int i = 0; i < valueEditorPanes.length; i++) {
valueEditorPanes[i].setEditors(new Editor[]{new ColumnNameEditor(), new ColumnIndexEditor()}, 1);
@ -197,6 +201,10 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
}
}
private boolean isNoSelectedColumnName(ValueEditorPane valueEditorPane) {
return (Integer) valueEditorPane.update() == -1;
}
@Override
protected String title4PopupWindow() {
return "TreeTableDataDictionay";

147
designer-base/src/main/java/com/fr/design/data/datapane/connect/AdvancePane.java

@ -0,0 +1,147 @@
package com.fr.design.data.datapane.connect;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.pool.DBCPConnectionPoolAttr;
import com.fr.design.dialog.BasicPane;
import com.fr.design.editor.editor.IntegerEditor;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.stable.StringUtils;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
/**
* @author xiqiu
* @date 2021/11/22
* @description
*/
public class AdvancePane extends BasicPane {
private IntegerEditor DBCP_MAX_ACTIVE = new IntegerEditor();
private UIComboBox DBCP_TESTONBORROW = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")});
private IntegerEditor DBCP_MAX_WAIT = new IntegerEditor();
private SpecialUITextField DBCP_VALIDATION_QUERY = new SpecialUITextField();
public AdvancePane() {
DBCP_VALIDATION_QUERY.addFocusListener(new JTextFieldHintListener(DBCP_VALIDATION_QUERY));
;
double p = TableLayout.PREFERRED;
DBCP_VALIDATION_QUERY.setColumns(15);
double[] rowSizeDbcp = {p, p, p, p};
double[] columnDbcp = {p, p};
Component[][] comps = {
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Active") + ":", SwingConstants.RIGHT), DBCP_MAX_ACTIVE},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Validation_Query") + ":", SwingConstants.RIGHT), DBCP_VALIDATION_QUERY},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Borrow") + ":", SwingConstants.RIGHT), DBCP_TESTONBORROW},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Max_Wait_Time") + ":", SwingConstants.RIGHT), DBCP_MAX_WAIT}
};
JPanel contextPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSizeDbcp, columnDbcp, 11, 11);
this.add(contextPane);
this.setPreferredSize(new Dimension(630, 120));
this.setLayout(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
}
public void populate(JDBCDatabaseConnection jdbcDatabase) {
DBCPConnectionPoolAttr dbcpAttr = jdbcDatabase.getDbcpAttr();
if (dbcpAttr == null) {
dbcpAttr = new DBCPConnectionPoolAttr();
jdbcDatabase.setDbcpAttr(dbcpAttr);
}
this.DBCP_MAX_ACTIVE.setValue(dbcpAttr.getMaxActive());
this.DBCP_MAX_WAIT.setValue(dbcpAttr.getMaxWait());
this.DBCP_VALIDATION_QUERY.setText(dbcpAttr.getValidationQuery());
this.DBCP_TESTONBORROW.setSelectedIndex(dbcpAttr.isTestOnBorrow() ? 1 : 0);
}
public void update(JDBCDatabaseConnection jdbcDatabase) {
DBCPConnectionPoolAttr dbcpAttr = jdbcDatabase.getDbcpAttr();
if (dbcpAttr == null) {
dbcpAttr = new DBCPConnectionPoolAttr();
jdbcDatabase.setDbcpAttr(dbcpAttr);
}
dbcpAttr.setMaxActive(this.DBCP_MAX_ACTIVE.getValue().intValue());
dbcpAttr.setMaxWait(this.DBCP_MAX_WAIT.getValue().intValue());
dbcpAttr.setValidationQuery(this.DBCP_VALIDATION_QUERY.getText());
dbcpAttr.setTestOnBorrow(this.DBCP_TESTONBORROW.getSelectedIndex() == 0 ? false : true);
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Advanced_Setup");
}
private class JTextFieldHintListener implements FocusListener {
private SpecialUITextField textField;
public JTextFieldHintListener(SpecialUITextField jTextField) {
this.textField = jTextField;
}
@Override
public void focusGained(FocusEvent e) {
//获取焦点时,清空提示内容
String temp = textField.getText();
textField.setForeground(Color.BLACK);
textField.setTextOrigin(temp);
}
@Override
public void focusLost(FocusEvent e) {
//失去焦点时,没有输入内容,显示提示内容
String temp = textField.getTextOrigin();
textField.setText(temp);
}
}
private class SpecialUITextField extends UITextField {
@Override
public String getText() {
String text = super.getText();
if (isUseless(text)) {
return StringUtils.EMPTY;
}
return text;
}
@Override
public void setText(String text) {
if (isUseless(text)) {
this.setForeground(Color.GRAY);
super.setText(Toolkit.i18nText("Fine-Design_Dbcp_Default_Query"));
} else {
this.setForeground(Color.BLACK);
super.setText(text);
}
}
public String getTextOrigin() {
return super.getText();
}
public void setTextOrigin(String text) {
super.setText(text);
}
private boolean isUseless(String text) {
return text == null || text.isEmpty() || Toolkit.i18nText("Fine-Design_Dbcp_Default_Query").equals(text);
}
}
}

50
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java

@ -5,20 +5,13 @@ import com.fr.data.impl.AbstractDatabaseConnection;
import com.fr.data.impl.Connection;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.design.DesignerEnvManager;
import com.fr.design.actions.server.ConnectionListAction;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.editlock.ConnectionLockChangeChecker;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UILockButton;
import com.fr.design.mainframe.DesignerContext;
import com.fr.file.ConnectionConfig;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.connection.DBConnectAuth;
import com.fr.report.LockItem;
@ -133,48 +126,7 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
return;
}
// 锁定成功,执行后续操作
final ConnectionListPane connectionListPane = new ConnectionListPane();
final ConnectionConfig connectionConfig = ConnectionConfig.getInstance();
ConnectionConfig cloned = connectionConfig.mirror();
connectionListPane.populate(cloned);
final BasicDialog connectionListDialog = connectionListPane.showLargeWindow(
SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this), null);
connectionListDialog.addDialogActionListener(new DialogActionAdapter() {
public void doOk() {
if (!connectionListPane.isNamePermitted()) {
connectionListDialog.setDoOKSucceed(false);
return;
}
Configurations.modify(new WorkerFacade(ConnectionConfig.class) {
@Override
public void run() {
connectionListPane.update(connectionConfig);
}
}.addCallBack(new CallBackAdaptor() {
@Override
public boolean beforeCommit() {
//如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面
return ConnectionListAction.doWithDatasourceManager(connectionConfig, connectionListPane, connectionListDialog);
}
@Override
public void afterCommit() {
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 关闭定义数据连接页面,为其解锁
EditLockUtils.unlock(LockItem.CONNECTION);
}
}));
}
@Override
public void doCancel() {
// 关闭定义数据连接页面,为其解锁
super.doCancel();
EditLockUtils.unlock(LockItem.CONNECTION);
}
});
connectionListDialog.setVisible(true);
ConnectionListPane.showDialog(SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this));
refreshItems();
}

48
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java

@ -0,0 +1,48 @@
package com.fr.design.data.datapane.connect;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.mainframe.DesignerContext;
import com.fr.file.ConnectionConfig;
import com.fr.report.LockItem;
/**
* @author hades
* @version 11.0
* Created by hades on 2021/9/8
*/
public class ConnectionListDialogActionAdapter extends DialogActionAdapter {
private final ConnectionManagerPane connectionManagerPane;
private final BasicDialog connectionListDialog;
private final ConnectionConfig connectionConfig;
public ConnectionListDialogActionAdapter(ConnectionManagerPane connectionManagerPane,
BasicDialog connectionListDialog,
ConnectionConfig connectionConfig) {
this.connectionManagerPane = connectionManagerPane;
this.connectionListDialog = connectionListDialog;
this.connectionConfig = connectionConfig;
}
@Override
public void doOk() {
if (!connectionManagerPane.isNamePermitted()) {
connectionListDialog.setDoOKSucceed(false);
return;
}
connectionManagerPane.update(connectionConfig);
DesignerContext.getDesignerBean("databasename").refreshBeanElement();
// 关闭定义数据连接页面,为其解锁
EditLockUtils.unlock(LockItem.CONNECTION);
}
@Override
public void doCancel() {
// 关闭定义数据连接页面,为其解锁
super.doCancel();
EditLockUtils.unlock(LockItem.CONNECTION);
}
}

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

@ -1,27 +1,35 @@
package com.fr.design.data.datapane.connect;
import com.fr.config.RemoteConfigEvent;
import com.fr.data.impl.Connection;
import com.fr.data.impl.ConnectionBean;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.JNDIDatabaseConnection;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.fun.ConnectionProvider;
import com.fr.design.gui.controlpane.JListControlPane;
import com.fr.design.gui.controlpane.NameObjectCreator;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.i18n.Toolkit;
import com.fr.event.EventDispatcher;
import com.fr.file.ConnectionConfig;
import com.fr.general.ComparatorUtils;
import com.fr.file.ConnectionOperator;
import com.fr.file.ConnectionOperatorImpl;
import com.fr.general.NameObject;
import com.fr.log.FineLoggerFactory;
import com.fr.rpc.ExceptionHandler;
import com.fr.rpc.RPCInvokerExceptionInfo;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.third.org.apache.commons.collections4.MapUtils;
import com.fr.workspace.WorkContext;
import javax.swing.SwingUtilities;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -41,36 +49,39 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
this.addEditingListener(new PropertyChangeAdapter() {
public void propertyChange() {
isNamePermitted = true;
String[] allListNames = nameableList.getAllNames();
allListNames[nameableList.getSelectedIndex()] = StringUtils.EMPTY;
String tempName = getEditingName();
if (StringUtils.isEmpty(tempName)) {
nameableList.stopEditing();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(ConnectionListPane.this), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Connection_Empty_Name"));
setIllegalIndex(editingIndex);
if (!checkName()) {
isNamePermitted = false;
return;
}
if (!ComparatorUtils.equals(tempName, selectedName)
&& isNameRepeated(new List[]{Arrays.asList(allListNames)}, tempName)) {
isNamePermitted = false;
nameableList.stopEditing();
String message = Toolkit.i18nText("Fine-Design_Basic_Connection_Duplicate_Name", tempName);
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(ConnectionListPane.this), message);
setIllegalIndex(editingIndex);
rename(selectedName, getEditingName());
}
if (isNamePermitted && !ComparatorUtils.equals(tempName, selectedName)) {
rename(selectedName, tempName);
});
}
}
});
@Override
public String getEmptyNameTip() {
return Toolkit.i18nText("Fine-Design_Basic_Connection_Empty_Name");
}
@Override
public String getDuplicatedNameTip() {
return Toolkit.i18nText("Fine-Design_Basic_Connection_Duplicate_Name", getEditingName());
}
protected void rename(String oldName, String newName) {
renameMap.remove(selectedName);
renameMap.put(selectedName, newName);
//如果a改成了b,b又被改成了c,就认为是a改成了c
for (Map.Entry<String, String> entry : renameMap.entrySet()) {
if (StringUtils.equals(oldName, entry.getValue())) {
oldName = entry.getKey();
break;
}
}
if (StringUtils.equals(oldName, newName)) {
//a -> b;b -> a,说明没改
renameMap.remove(oldName);
} else {
renameMap.put(oldName, newName);
}
}
/**
@ -151,15 +162,52 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
public void update(ConnectionConfig connectionConfig) {
// Nameable[]居然不能强转成NameObject[],一定要这么写...
Nameable[] res = this.update();
NameObject[] res_array = new NameObject[res.length];
java.util.Arrays.asList(res).toArray(res_array);
connectionConfig.removeAllConnection();
List<ConnectionBean> connectionBeans = new ArrayList<>();
Map<String, String> map = MapUtils.invertMap(getRenameMap());
for (int i = 0; i < res.length; i++) {
NameObject nameObject = (NameObject) res[i];
String oldName = map.get(nameObject.getName());
if (oldName == null) {
oldName = StringUtils.EMPTY;
}
connectionBeans.add(new ConnectionBean(nameObject.getName(), oldName, (Connection) nameObject.getObject()));
}
try {
WorkContext.getCurrent().get(ConnectionOperator.class, new ExceptionHandler() {
@Override
public Object callHandler(RPCInvokerExceptionInfo exceptionInfo) {
return saveByOldWay(connectionBeans);
}
}).saveConnection(new ArrayList<>(connectionConfig.getConnections().keySet()), connectionBeans);
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.fire(RemoteConfigEvent.EDIT, ConnectionConfig.getInstance().getNameSpace());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
for (int i = 0; i < res_array.length; i++) {
NameObject nameObject = res_array[i];
connectionConfig.addConnection(nameObject.getName(), (Connection) nameObject.getObject());
private boolean saveByOldWay(List<ConnectionBean> connectionBeans) {
try {
return ConnectionOperatorImpl.getInstance().saveConnection(connectionBeans);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return false;
}
}
public static void showDialog(Window parent) {
final ConnectionConfig connectionConfig = ConnectionConfig.getInstance();
final ConnectionManagerPane connectionManagerPane = new ConnectionManagerPane() {
@Override
public void complete() {
ConnectionConfig cloned = connectionConfig.mirror();
populate(cloned);
}
};
final BasicDialog connectionListDialog = connectionManagerPane.showLargeWindow(parent, null);
connectionListDialog.addDialogActionListener(new ConnectionListDialogActionAdapter(connectionManagerPane, connectionListDialog, connectionConfig));
connectionListDialog.setVisible(true);
}
@Override

35
designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java

@ -20,6 +20,7 @@ import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Window;
@ -45,13 +46,8 @@ public class DBCPAttrPane extends BasicPane {
private static final int EMPTY_FETCHSIZE = -2;
// carl:DBCP的一些属性
private IntegerEditor DBCP_INITIAL_SIZE = new IntegerEditor();
private IntegerEditor DBCP_MAX_ACTIVE = new IntegerEditor();
private IntegerEditor DBCP_MAX_IDLE = new IntegerEditor();
private IntegerEditor DBCP_MIN_IDLE = new IntegerEditor();
private IntegerEditor DBCP_MAX_WAIT = new IntegerEditor();
private UITextField DBCP_VALIDATION_QUERY = new UITextField();
private UIComboBox DBCP_TESTONBORROW = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")});
private UIComboBox DBCP_TESTONRETURN = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")});
private UIComboBox DBCP_TESTWHILEIDLE = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Basic_No"), Toolkit.i18nText("Fine-Design_Basic_Yes")});
@ -75,25 +71,19 @@ public class DBCPAttrPane extends BasicPane {
defaultPane = this;
// JPanel northFlowPane
northFlowPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr"));
northFlowPane.setPreferredSize(new Dimension(630, 320));
northFlowPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr"));
northFlowPane.setPreferredSize(new Dimension(630, 330));
defaultPane.add(northFlowPane, BorderLayout.NORTH);
DBCP_VALIDATION_QUERY.setColumns(15);
// ContextPane
double f = TableLayout.FILL;
// double p = TableLayout.PREFERRED;
double[] rowSize = {f, f, f, f, f, f, f, f, f, f, f, f};
double[] rowSize = {f, f, f, f, f, f, f};
double[] columnSize = {f, f};
Component[][] comps = {
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Initial_Size") + ":", SwingConstants.RIGHT), DBCP_INITIAL_SIZE},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Active") + ":", SwingConstants.RIGHT), DBCP_MAX_ACTIVE},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Idle") + ":", SwingConstants.RIGHT), DBCP_MAX_IDLE},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Min_Idle") + ":", SwingConstants.RIGHT), DBCP_MIN_IDLE},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Max_Wait_Time") + ":", SwingConstants.RIGHT), DBCP_MAX_WAIT},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Validation_Query") + ":", SwingConstants.RIGHT), DBCP_VALIDATION_QUERY},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Borrow") + ":", SwingConstants.RIGHT), DBCP_TESTONBORROW},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Return") + ":", SwingConstants.RIGHT), DBCP_TESTONRETURN},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_While_Idle") + ":", SwingConstants.RIGHT), DBCP_TESTWHILEIDLE},
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Evictionruns_millis") + ":", SwingConstants.RIGHT),
@ -102,8 +92,13 @@ public class DBCPAttrPane extends BasicPane {
{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Mix_Evictable_Idle_Time_Millis") + ":", SwingConstants.RIGHT),
DBCP_MINEVICTABLEIDLETIMEMILLIS}};
JPanel contextPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSize, columnSize, 10, 4);
JPanel contextPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSize, columnSize, 10, 10);
northFlowPane.add(contextPane);
JPanel boxFlowInnerContainer = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 5, 5);
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Dbcp_Warning"));
uiLabel.setForeground(Color.RED);
boxFlowInnerContainer.add(uiLabel);
northFlowPane.add(boxFlowInnerContainer);
}
public void populate(JDBCDatabaseConnection jdbcDatabase) {
@ -113,12 +108,7 @@ public class DBCPAttrPane extends BasicPane {
jdbcDatabase.setDbcpAttr(dbcpAttr);
}
this.DBCP_INITIAL_SIZE.setValue(dbcpAttr.getInitialSize());
this.DBCP_MAX_ACTIVE.setValue(dbcpAttr.getMaxActive());
this.DBCP_MAX_IDLE.setValue(dbcpAttr.getMaxIdle());
this.DBCP_MAX_WAIT.setValue(dbcpAttr.getMaxWait());
this.DBCP_MIN_IDLE.setValue(dbcpAttr.getMinIdle());
this.DBCP_VALIDATION_QUERY.setText(dbcpAttr.getValidationQuery());
this.DBCP_TESTONBORROW.setSelectedIndex(dbcpAttr.isTestOnBorrow() ? 1 : 0);
this.DBCP_TESTONRETURN.setSelectedIndex(dbcpAttr.isTestOnReturn() ? 1 : 0);
this.DBCP_TESTWHILEIDLE.setSelectedIndex(dbcpAttr.isTestWhileIdle() ? 1 : 0);
this.DBCP_MINEVICTABLEIDLETIMEMILLIS.setValue(dbcpAttr.getMinEvictableIdleTimeMillis() / TIME_MULTIPLE);
@ -141,12 +131,7 @@ public class DBCPAttrPane extends BasicPane {
jdbcDatabase.setDbcpAttr(dbcpAttr);
}
dbcpAttr.setInitialSize(this.DBCP_INITIAL_SIZE.getValue().intValue());
dbcpAttr.setMaxActive(this.DBCP_MAX_ACTIVE.getValue().intValue());
dbcpAttr.setMaxIdle(this.DBCP_MAX_IDLE.getValue().intValue());
dbcpAttr.setMaxWait(this.DBCP_MAX_WAIT.getValue().intValue());
dbcpAttr.setMinIdle(this.DBCP_MIN_IDLE.getValue().intValue());
dbcpAttr.setValidationQuery(this.DBCP_VALIDATION_QUERY.getText());
dbcpAttr.setTestOnBorrow(this.DBCP_TESTONBORROW.getSelectedIndex() == 0 ? false : true);
dbcpAttr.setTestOnReturn(this.DBCP_TESTONRETURN.getSelectedIndex() == 0 ? false : true);
dbcpAttr.setTestWhileIdle(this.DBCP_TESTWHILEIDLE.getSelectedIndex() == 0 ? false : true);
dbcpAttr.setMinEvictableIdleTimeMillis(((Number) this.DBCP_MINEVICTABLEIDLETIMEMILLIS.getValue()).intValue() * TIME_MULTIPLE);

44
designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java

@ -14,11 +14,11 @@ import com.fr.data.solution.processor.SolutionProcessor;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.scrollruler.ModLineBorder;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.rpc.ExceptionHandler;
@ -34,6 +34,7 @@ import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
@ -60,6 +61,8 @@ import java.util.concurrent.ExecutionException;
* Database Connection pane.
*/
public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connection> extends BasicBeanPane<com.fr.data.impl.Connection> {
private static int MAX_MAIN_PANEL_HEIGHT = 430;
private static int MAX_MAIN_PANEL_WIDTH = 675;
private UILabel message;
private UIButton okButton;
@ -305,6 +308,10 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
protected abstract E updateSubDatabaseConnectionBean();
protected JPanel getAdvancePane() {
throw new UnsupportedOperationException();
}
protected void initComponents() {
message = new UILabel();
uiLabel = new UILabel();
@ -330,15 +337,14 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
// Center
mainPanel = mainPanel();
northPane.add(mainPanel, BorderLayout.CENTER);
JPanel advancedPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
advancedPanel.setBorder(BorderFactory.createTitledBorder(
new ModLineBorder(ModLineBorder.TOP),
Toolkit.i18nText("Fine-Design_Basic_Advanced")
));
JPanel advancedPanel = FRGUIPaneFactory.createTopVerticalTitledBorderPane(Toolkit.i18nText("Fine-Design_Basic_Advanced"));
if (mainPanel instanceof JDBCDefPane) {
ActionLabel actionLabel = new ActionLabel(Toolkit.i18nText("Fine-Design_Basic_Advanced_Setup"));
mainPanel.setPreferredSize(new Dimension(MAX_MAIN_PANEL_WIDTH, 280));
advancedPanel.setPreferredSize(new Dimension(MAX_MAIN_PANEL_WIDTH, 210));
northPane.add(mainPanel, BorderLayout.CENTER);
ActionLabel actionLabel = new ActionLabel(Toolkit.i18nText("Fine-Design_Advanced_More_Settings"));
actionLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
JDialog wDialog = createJDialog();
if (wDialog != null) {
@ -349,10 +355,24 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
JPanel actionLabelPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
actionLabelPanel.setBorder(BorderFactory.createEmptyBorder(2, 4, 4, 20));
actionLabelPanel.add(actionLabel, BorderLayout.WEST);
JPanel advancePane = getAdvancePane();
if (advancePane != null) {
advancedPanel.add(advancePane);
}
advancedPanel.add(actionLabelPanel);
} else {
//非jdbc配置布局保持不变
advancedPanel.setPreferredSize(new Dimension(MAX_MAIN_PANEL_WIDTH, 60));
if (mainPanel.getPreferredSize().height > MAX_MAIN_PANEL_HEIGHT || mainPanel.getPreferredSize().width > MAX_MAIN_PANEL_WIDTH) {
UIScrollPane jp = new
UIScrollPane(mainPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jp.setPreferredSize(new Dimension(MAX_MAIN_PANEL_WIDTH, MAX_MAIN_PANEL_HEIGHT));
northPane.add(jp, BorderLayout.CENTER);
} else {
mainPanel.setPreferredSize(new Dimension(MAX_MAIN_PANEL_WIDTH, MAX_MAIN_PANEL_HEIGHT));
northPane.add(mainPanel, BorderLayout.CENTER);
}
// ChartSet
String[] defaultEncode = new String[]{Toolkit.i18nText("Fine-Design_Encode_Auto")};
charSetComboBox = new UIComboBox(ArrayUtils.addAll(defaultEncode, EncodeConstants.ENCODING_ARRAY));
@ -406,6 +426,7 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
public static class JDBC extends DatabaseConnectionPane<JDBCDatabaseConnection> {
private static JDBCDefPane jdbcDefPane = new JDBCDefPane();
private static DBCPAttrPane dbcpAttrPane = new DBCPAttrPane();
private static AdvancePane advancePane = new AdvancePane();
@Override
protected JPanel mainPanel() {
@ -425,15 +446,22 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
protected void populateSubDatabaseConnectionBean(JDBCDatabaseConnection ob) {
jdbcDefPane.populate(ob);
dbcpAttrPane.populate(jdbcDefPane.getJDBCDatabase());
advancePane.populate(jdbcDefPane.getJDBCDatabase());
}
@Override
protected JDBCDatabaseConnection updateSubDatabaseConnectionBean() {
JDBCDatabaseConnection jdbcDatabaseConnection = jdbcDefPane.update();
dbcpAttrPane.update(jdbcDatabaseConnection);
advancePane.update(jdbcDatabaseConnection);
return jdbcDatabaseConnection;
}
@Override
protected JPanel getAdvancePane() {
return advancePane;
}
@Override
protected String title4PopupWindow() {
return "JDBC";

259
designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java

@ -1,10 +1,13 @@
package com.fr.design.data.datapane.connect;
import com.fr.base.GraphHelper;
import com.fr.data.driver.DriverLoader;
import com.fr.data.driver.config.DriverLoaderConfig;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.design.border.UITitledBorder;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxUI;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ipasswordfield.UIPasswordFieldWithFixedLength;
@ -16,11 +19,13 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.utils.BrowseUtils;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.general.CloudCenter;
import com.fr.general.ComparatorUtils;
import com.fr.i18n.UrlI18nManager;
import com.fr.stable.ArrayUtils;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.third.guava.collect.HashBiMap;
import com.fr.workspace.WorkContext;
import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
@ -28,6 +33,8 @@ import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.basic.ComboPopup;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@ -45,6 +52,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -101,8 +109,55 @@ public class JDBCDefPane extends JPanel {
private JDBCDatabaseConnection jdbcDatabase;
private boolean needRefresh = true;
private UIComboBox driverManageBox;
private ActionLabel driverManageLabel;
private UIComboBox driverLoaderBox;
ActionListener driverManageListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean selectSelfDefine = isSelfDefine();
driverManageLabel.setVisible(selectSelfDefine);
driverLoaderBox.setVisible(selectSelfDefine);
driverComboBox.setVisible(!selectSelfDefine);
odbcTipsLink.setVisible(driverComboBox.isVisible() && ComparatorUtils.equals("sun.jdbc.odbc.JdbcOdbcDriver", driverComboBox.getSelectedItem()));
}
};
ActionListener dbtypeActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
urlTextField.setText(StringUtils.EMPTY);
driverComboBox.removeAllItems();
driverManageBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Default"));
if (driverLoaderBox.getItemCount() > 0) {
driverLoaderBox.setSelectedIndex(0);
}
if (ComparatorUtils.equals(dbtypeComboBox.getSelectedItem(), StringUtils.EMPTY)) {
driverComboBox.setSelectedItem(StringUtils.EMPTY);
return;
}
DriverURLName[] dus = jdbcMap.get(dbtypeComboBox.getSelectedItem());
for (int i = 0, len = dus.length; i < len; i++) {
driverComboBox.addItem(dus[i].getDriver());
if (i == 0) {
driverComboBox.setSelectedItem(dus[i].getDriver());
urlTextField.setText(dus[i].getURL());
}
}
// 更改数据库类型后 数据库名称置空和之前逻辑保持一致
if (needRefresh) {
jdbcDatabase.setDatabase(StringUtils.EMPTY);
}
changePane(dbtypeComboBox.getSelectedItem());
JDBCConnectionDef.getInstance().setConnection((String) dbtypeComboBox.getSelectedItem(), jdbcDatabase);
DatabaseConnectionPane.JDBC.getAdvancedAttrPane().populate(jdbcDatabase);
}
};
private HashBiMap<String, String> nameAndRepresent;
public JDBCDefPane() {
initMap();
this.setBorder(UITitledBorder.createBorderWithTitle("JDBC" + ":"));
this.setLayout(FRGUIPaneFactory.createLabelFlowLayout());
JPanel innerthis = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
@ -115,7 +170,15 @@ public class JDBCDefPane extends JPanel {
}
dbtypeComboBox.addActionListener(dbtypeActionListener);
dbtypeComboBox.setMaximumRowCount(10);
driverLoaderBox = new SpecialUIComboBox();
refreshDriverLoader();
driverLoaderBox.setPreferredSize(new Dimension(200, driverLoaderBox.getPreferredSize().height));
driverLoaderBox.setEditable(false);
driverManageBox = new UIComboBox();
refreshDriverManage(true);
driverManageBox.setEditable(false);
driverManageBox.addActionListener(driverManageListener);
driverLoaderBox.setVisible(isSelfDefine());
driverComboBox = new UIComboBox();
driverComboBox.setEditable(true);
driverComboBox.addActionListener(driverListener);
@ -159,13 +222,37 @@ public class JDBCDefPane extends JPanel {
odbcTipsLink.setPreferredSize(new Dimension(GraphHelper.getWidth(Toolkit.i18nText("Fine-Design_Basic_Odbc_Tips")), odbcTipsLink.getPreferredSize().height));
odbcTipsLink.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
String url = UrlI18nManager.getInstance().getI18nUrl("odbc.help");
String url = CloudCenter.getInstance().acquireUrlByKind("odbc.help");
BrowseUtils.browser(url);
}
});
driverManageLabel = new ActionLabel(Toolkit.i18nText("Fine-Design_Driver_Manage_Add_Driver")) {
@Override
public void paintComponent(Graphics _gfx) {
super.paintComponent(_gfx);
_gfx.setColor(Color.blue);
_gfx.drawLine(0, this.getHeight() - 1, GraphHelper.getWidth(this.getText()), this.getHeight() - 1);
}
};
driverManageLabel.setPreferredSize(new Dimension(GraphHelper.getWidth(Toolkit.i18nText("Fine-Design_Driver_Manage_Add_Driver")), driverManageLabel.getPreferredSize().height));
driverManageLabel.setVisible(isSelfDefine());
driverManageLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
String url = CloudCenter.getInstance().acquireUrlByKind("driver.add.help");
BrowseUtils.browser(url);
}
});
odbcTipsPane.add(driverManageLabel);
odbcTipsPane.add(odbcTipsLink);
JPanel driverComboBoxAndTips = new JPanel(new BorderLayout());
driverComboBoxAndTips.add(driverComboBox, BorderLayout.WEST);
JPanel normalFlowInnerContainer_s_pane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 5, 0);
normalFlowInnerContainer_s_pane.add(driverManageBox);
normalFlowInnerContainer_s_pane.add(driverComboBox);
normalFlowInnerContainer_s_pane.add(driverLoaderBox);
driverComboBoxAndTips.add(normalFlowInnerContainer_s_pane, BorderLayout.WEST);
driverComboBoxAndTips.add(odbcTipsPane, BorderLayout.CENTER);
JPanel hostPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane();
@ -225,7 +312,71 @@ public class JDBCDefPane extends JPanel {
innerthis.add(centerPanel);
}
private void refreshDriverLoader() {
Set<String> representSet = nameAndRepresent.values();
driverLoaderBox.clearBoxItems();
for (String represent : representSet) {
driverLoaderBox.addItem(represent);
}
}
private String getRepresent(String driverClass, String driverName) {
return driverClass + "(" + driverName + ")";
}
private boolean isSelfDefine() {
return ComparatorUtils.equals(Toolkit.i18nText("Fine-Design_Driver_Manage_Self_Define"), driverManageBox.getSelectedItem());
}
private void refreshDriverManage(boolean addSelfDefine) {
driverManageBox.clearBoxItems();
driverManageBox.addItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Default"));
if (addSelfDefine) {
driverManageBox.addItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Self_Define"));
}
}
private void initMap() {
Map<String, DriverLoader> driverLoaders = DriverLoaderConfig.getInstance().getDriverLoaders();
nameAndRepresent = getDriverLoaderAndRepresent(driverLoaders);
}
private HashBiMap<String, String> getDriverLoaderAndRepresent(Map<String, DriverLoader> driverLoaders) {
HashBiMap<String, String> driverHashBiMap = HashBiMap.create();
if (WorkContext.getCurrent().isWarDeploy()) {
return driverHashBiMap;
}
// name 是唯一的,name+driver自然也是唯一的
for (DriverLoader driverLoader : driverLoaders.values()) {
driverHashBiMap.put(driverLoader.getName(), getRepresent(driverLoader.getDriverClass(), driverLoader.getName()));
}
return driverHashBiMap;
}
protected JDBCDatabaseConnection getJDBCDatabase() {
return this.jdbcDatabase;
}
private void changePane(Object dbType) {
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = {p, f, 22};
if (ComparatorUtils.equals(dbType, OTHER_DB) || ComparatorUtils.equals(dbType, "Access") || ComparatorUtils.equals(dbType, "SQLite")) {
if (this.centerPanel.getComponentCount() != partComponents.length * 2) {
centerPanel.removeAll();
TableLayoutHelper.addComponent2ResultPane(partComponents, new double[]{p, p, p, p, p}, columnSize, centerPanel);
}
} else if (this.centerPanel.getComponentCount() != allComponents.length * 2) {
centerPanel.removeAll();
TableLayoutHelper.addComponent2ResultPane(allComponents, new double[]{p, p, p, p, p, p, p, p}, columnSize, centerPanel);
}
}
public void populate(JDBCDatabaseConnection jdbcDatabase) {
// 单例对象,重新打开的时候并不会新建,但是由于driverloaderbox里面需要是动态内容,因此需要进行刷新动作
initMap();
refreshDriverLoader();
needRefresh = false;
if (jdbcDatabase == null) {
jdbcDatabase = new JDBCDatabaseConnection();
@ -255,7 +406,24 @@ public class JDBCDefPane extends JPanel {
this.dbtypeComboBox.setSelectedItem(OTHER_DB);
}
}
// jdbcDatabase.getDriverSource() 只会是空或者是有值,但是为了保险起见,还是应该做个处理
String driverSource = jdbcDatabase.getDriverSource();
if (driverSource == null) {
driverSource = StringUtils.EMPTY;
}
if (driverSource.isEmpty()) {
refreshDriverManage(!nameAndRepresent.isEmpty());
this.driverManageBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Default"));
this.driverComboBox.setSelectedItem(jdbcDatabase.getDriver());
} else {
refreshDriverManage(true);
this.driverManageBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Self_Define"));
String represent = getRepresent(jdbcDatabase.getDriver(), jdbcDatabase.getDriverSource());
if (!nameAndRepresent.containsValue(represent)) {
this.driverLoaderBox.addItem(represent);
}
this.driverLoaderBox.setSelectedItem(represent);
}
this.urlTextField.setText(jdbcDatabase.getURL());
this.userNameTextField.setText(jdbcDatabase.getUser());
this.passwordTextField.setText(jdbcDatabase.getPassword());
@ -268,31 +436,10 @@ public class JDBCDefPane extends JPanel {
needRefresh = false;
}
protected JDBCDatabaseConnection getJDBCDatabase() {
return this.jdbcDatabase;
}
private void changePane(Object dbType) {
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = {p, f, 22};
if (ComparatorUtils.equals(dbType, OTHER_DB) || ComparatorUtils.equals(dbType, "Access") || ComparatorUtils.equals(dbType, "SQLite")) {
if (this.centerPanel.getComponentCount() != partComponents.length * 2) {
centerPanel.removeAll();
TableLayoutHelper.addComponent2ResultPane(partComponents, new double[]{p, p, p, p, p}, columnSize, centerPanel);
}
} else if (this.centerPanel.getComponentCount() != allComponents.length * 2) {
centerPanel.removeAll();
TableLayoutHelper.addComponent2ResultPane(allComponents, new double[]{p, p, p, p, p, p, p, p}, columnSize, centerPanel);
}
}
public JDBCDatabaseConnection update() {
if (jdbcDatabase == null) {
jdbcDatabase = new JDBCDatabaseConnection();
}
Object driveItem = this.driverComboBox.getSelectedItem();
jdbcDatabase.setDriver(driveItem == null ? null : driveItem.toString().trim());
jdbcDatabase.setURL(this.urlTextField.getText().trim());
jdbcDatabase.setUser(this.userNameTextField.getText().trim());
jdbcDatabase.setPassword(new String(this.passwordTextField.getPassword()).trim());
@ -304,36 +451,30 @@ public class JDBCDefPane extends JPanel {
jdbcDatabase.setNewCharsetName(EncodeConstants.ENCODING_GBK);
jdbcDatabase.setOriginalCharsetName(((String) this.charSetComboBox.getSelectedItem()));
}
return jdbcDatabase;
}
ActionListener dbtypeActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
urlTextField.setText(StringUtils.EMPTY);
driverComboBox.removeAllItems();
if (ComparatorUtils.equals(dbtypeComboBox.getSelectedItem(), StringUtils.EMPTY)) {
driverComboBox.setSelectedItem(StringUtils.EMPTY);
return;
String driverLoader = (String) this.driverLoaderBox.getSelectedItem();
if (driverLoader == null) {
driverLoader = StringUtils.EMPTY;
}
DriverURLName[] dus = jdbcMap.get(dbtypeComboBox.getSelectedItem());
for (int i = 0, len = dus.length; i < len; i++) {
driverComboBox.addItem(dus[i].getDriver());
if (i == 0) {
driverComboBox.setSelectedItem(dus[i].getDriver());
urlTextField.setText(dus[i].getURL());
if (isSelfDefine()) {
String[] split = driverLoader.split("\\(");
if (split.length > 1) {
String name = split[1];
if (name.length() > 0) {
jdbcDatabase.setDriverSource(name.substring(0, name.length() - 1));
} else {
jdbcDatabase.setDriverSource(StringUtils.EMPTY);
}
} else {
jdbcDatabase.setDriverSource(StringUtils.EMPTY);
}
// 更改数据库类型后 数据库名称置空和之前逻辑保持一致
if (needRefresh) {
jdbcDatabase.setDatabase(StringUtils.EMPTY);
jdbcDatabase.setDriver(split[0]);
} else {
Object driveItem = this.driverComboBox.getSelectedItem();
jdbcDatabase.setDriver(driveItem == null ? null : driveItem.toString().trim());
jdbcDatabase.setDriverSource(StringUtils.EMPTY);
}
changePane(dbtypeComboBox.getSelectedItem());
JDBCConnectionDef.getInstance().setConnection((String) dbtypeComboBox.getSelectedItem(), jdbcDatabase);
DatabaseConnectionPane.JDBC.getAdvancedAttrPane().populate(jdbcDatabase);
return jdbcDatabase;
}
};
ActionListener driverListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
@ -579,4 +720,22 @@ public class JDBCDefPane extends JPanel {
private String driver;
private String url;
}
private static class SpecialUIComboBox extends UIComboBox {
@Override
public ComboBoxUI getUIComboBoxUI() {
return new SpecialUIComboBoxUI();
}
}
private static class SpecialUIComboBoxUI extends UIComboBoxUI {
@Override
public ComboPopup createPopup() {
return createHorizontalNeverUIComboPopUp();
}
}
}

37
designer-base/src/main/java/com/fr/design/data/tabledata/strategy/StrategyConfigHandler.java

@ -0,0 +1,37 @@
package com.fr.design.data.tabledata.strategy;
import com.fr.esd.core.strategy.config.StrategyConfig;
import com.fr.esd.query.StrategicTableData;
/**
* @author rinoux
* @version 10.0
* Created by rinoux on 2021/3/19
*/
public abstract class StrategyConfigHandler<T extends StrategicTableData> {
private final T tableData;
public StrategyConfigHandler(T tableData) {
this.tableData = tableData;
}
protected T getTableData() {
return tableData;
}
/**
* 查找配置
*
* @return 缓存配置
*/
public abstract StrategyConfig find();
/**
* 保存配置
*
* @param config 缓存配置
*/
public abstract void save(T saved, StrategyConfig config);
}

551
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java

@ -1,6 +1,5 @@
package com.fr.design.data.tabledata.tabledatapane;
import com.fr.base.BaseUtils;
import com.fr.base.Parameter;
import com.fr.base.ParameterHelper;
import com.fr.data.core.db.TableProcedure;
@ -13,16 +12,22 @@ import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.UpdateAction;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.StrategyConfigAttrUtils;
import com.fr.design.data.datapane.ESDStrategyConfigPane;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane.DoubleClickSelectedNodeOnTreeListener;
import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.data.datapane.preview.sql.PreviewPerformedSqlPane;
import com.fr.design.data.datapane.sqlpane.SQLEditPane;
import com.fr.design.data.tabledata.strategy.StrategyConfigHandler;
import com.fr.design.data.tabledata.tabledatapane.db.StrategyConfigFrom;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.fun.DBTableDataMenuHandler;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itableeditorpane.ParameterTableModel;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
@ -30,11 +35,20 @@ import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
import com.fr.design.gui.syntax.ui.rtextarea.RTextScrollPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.menu.SeparatorDef;
import com.fr.design.menu.ToolBarDef;
import com.fr.design.utils.ParameterUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.esd.core.strategy.config.StrategyConfig;
import com.fr.esd.core.strategy.config.StrategyConfigHelper;
import com.fr.esd.core.strategy.config.service.StrategyConfigService;
import com.fr.esd.data.db.DBTableDataSavedHook;
import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.esd.query.StrategicTableData;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.general.sql.SqlUtils;
@ -43,6 +57,7 @@ import com.fr.script.Calculator;
import com.fr.stable.ArrayUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import javax.swing.BorderFactory;
import javax.swing.Box;
@ -57,6 +72,7 @@ import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
@ -64,25 +80,45 @@ import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
/**
* @author rinoux
* @version 10.0
* Created by rinoux on 2020/7/22
*/
public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
private static final int BOTTOM = 6;
private static final String PREVIEW_BUTTON = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview");
private static final String REFRESH_BUTTON = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Refresh");
private static final String PREVIEW_BUTTON = Toolkit.i18nText("Fine-Design_Basic_Preview");
private static final String REFRESH_BUTTON = Toolkit.i18nText("Fine-Design_Basic_Refresh");
private ConnectionTableProcedurePane connectionTableProcedurePane;
private UITableEditorPane<ParameterProvider> editorPane;
private DBTableDataMenuHandler dbTableDataMenuHandler;
private SQLEditPane sqlTextPane;
private UICheckBox isShareCheckBox;
private MaxMemRowCountPanel maxPanel;
private String pageQuery = null;
private String pageQuery;
private DBTableData dbTableData;
//ESD
private UILabel esdSettingsLabel;
private UIComboBox esdConfigOption;
private UICheckBox esdEnabled;
private UIButton esdSettingsBtn;
private UILabel barErrorTips;
//配置
private StrategyConfig strategyConfig;
private StrategyConfigHandler<DBTableData> configHandler;
public DBTableDataPane() {
init();
initMainSplitPane();
}
private void init() {
this.setLayout(new BorderLayout(4, 4));
setLayout(new BorderLayout(4, 4));
sqlTextPane = new SQLEditPane();
sqlTextPane.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL);
this.sqlTextPane = new SQLEditPane();
this.sqlTextPane.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL);
ParameterTableModel model = new ParameterTableModel() {
@Override
@ -90,25 +126,27 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
return ArrayUtils.add(super.createDBTableAction(), new RefreshAction());
}
};
editorPane = new UITableEditorPane<ParameterProvider>(model);
editorPane = new UITableEditorPane<>(model);
// 左边的Panel,上面是选择DatabaseConnection的ComboBox,下面DatabaseConnection对应的Table
connectionTableProcedurePane = new ConnectionTableProcedurePane() {
this.connectionTableProcedurePane = new ConnectionTableProcedurePane() {
@Override
protected void filter(Connection connection, String conName, List<String> nameList) {
connection.addConnection(nameList, conName, new Class[]{JDBCDatabaseConnection.class, JNDIDatabaseConnection.class});
connection.addConnection(nameList, conName, new Class[]{
JDBCDatabaseConnection.class,
JNDIDatabaseConnection.class
});
}
@Override
protected void addKeyMonitor() {
searchField.addKeyListener(new KeyListener() {
this.searchField.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
//do nothing
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
@ -117,45 +155,44 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
}
}
@Override
public void keyReleased(KeyEvent e) {
//do nothing
}
});
}
};
connectionTableProcedurePane.addDoubleClickListener(new DoubleClickSelectedNodeOnTreeListener() {
this.connectionTableProcedurePane.addDoubleClickListener(new ConnectionTableProcedurePane.DoubleClickSelectedNodeOnTreeListener() {
@Override
public void actionPerformed(TableProcedure target) {
Document document = sqlTextPane.getDocument();
Document document = DBTableDataPane.this.sqlTextPane.getDocument();
try {
document.insertString(sqlTextPane.getCaretPosition(), target.toString(), null);
document.insertString(DBTableDataPane.this.sqlTextPane.getCaretPosition(), target.toString(), null);
} catch (BadLocationException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
// 这里开始作色,本来可以给sqlTextPane添加DocumentListener来实现的,
// 后来发现insertString的时候,锁定了JTextPane,不能调用setXXX来作色,先这样了.
// sqlTextPane.syntaxTexts();
sqlTextPane.requestFocus();
DBTableDataPane.this.sqlTextPane.requestFocus();
}
});
sqlTextPane.addFocusListener(new FocusListener() {
this.sqlTextPane.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
// do nothing
barErrorTips.setVisible(false);
}
@Override
public void focusLost(FocusEvent e) {
if (isPreviewOrRefreshButton(e)) {
checkParameter();
if (DBTableDataPane.this.isPreviewOrRefreshButton(e)) {
DBTableDataPane.this.checkParameter();
}
}
});
}
private void initMainSplitPane() {
Box box = new Box(BoxLayout.Y_AXIS);
@ -165,106 +202,189 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
northPane.add(editToolBar, BorderLayout.CENTER);
northPane.setBorder(BorderFactory.createEmptyBorder(0, 0, BOTTOM, 0));
RTextScrollPane sqlTextScrollPane = new RTextScrollPane(sqlTextPane);
RTextScrollPane sqlTextScrollPane = new RTextScrollPane(this.sqlTextPane);
sqlTextScrollPane.setLineNumbersEnabled(true);
sqlTextScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
sqlTextScrollPane.setPreferredSize(new Dimension(680, 600));
JPanel paraMeanPane = new JPanel(new BorderLayout());
paraMeanPane.setPreferredSize(new Dimension(680, 90));
UILabel paraMean = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Param_DES"));
UILabel paraMean = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Datasource_Param_DES"));
paraMeanPane.add(paraMean, BorderLayout.CENTER);
box.add(northPane);
box.add(sqlTextScrollPane);
box.add(paraMeanPane);
box.add(editorPane);
box.add(this.editorPane);
JPanel sqlSplitPane = new JPanel(new BorderLayout(4, 4));
sqlSplitPane.add(box, BorderLayout.CENTER);
box.setMinimumSize(new Dimension(300, 400));
// 防止数据连接名过长时影响 split pane 分割效果
// 本界面中给MaxMemRowCountPanel留的空间太小,造成MaxMemRowCountPanel显示异常,这边减小一点最小宽度,拉长MaxMemRowCountPanel
connectionTableProcedurePane.setMinimumSize(new Dimension(230, 400));
connectionTableProcedurePane.setMaximumSize(new Dimension(500, 400));
// 使用SplitPane
JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, connectionTableProcedurePane, sqlSplitPane);
this.connectionTableProcedurePane.setMinimumSize(new Dimension(230, 400));
this.connectionTableProcedurePane.setMaximumSize(new Dimension(500, 400));
JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, this.connectionTableProcedurePane, sqlSplitPane);
mainSplitPane.setBorder(BorderFactory.createLineBorder(GUICoreUtils.getTitleLineBorderColor()));
mainSplitPane.setOneTouchExpandable(true);
this.add(mainSplitPane, BorderLayout.CENTER);
}
public DBTableDataPane() {
init();
initMainSplitPane();
add(mainSplitPane, BorderLayout.CENTER);
}
private boolean isPreviewOrRefreshButton(FocusEvent e) {
if (e.getOppositeComponent() != null) {
String name = e.getOppositeComponent().getName();
return ComparatorUtils.equals(name, PREVIEW_BUTTON) || ComparatorUtils.equals(name, REFRESH_BUTTON);
return (ComparatorUtils.equals(name, PREVIEW_BUTTON) || ComparatorUtils.equals(name, REFRESH_BUTTON));
}
return false;
}
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_DS-Database_Query");
return Toolkit.i18nText("Fine-Design_Basic_DS-Database_Query");
}
private void refresh() {
private void refreshParameters() {
String[] paramTexts = new String[2];
paramTexts[0] = SqlUtils.tryPureSqlText(sqlTextPane.getText());
paramTexts[1] = SqlUtils.tryPureSqlText(pageQuery);
List<ParameterProvider> existParameterList = editorPane.update();
Parameter[] ps = existParameterList == null ? new Parameter[0] : existParameterList.toArray(new Parameter[0]);
editorPane.populate(ParameterUtils.analyzeAndUnionParameters(paramTexts, ps));
paramTexts[0] = SqlUtils.tryPureSqlText(this.sqlTextPane.getText());
paramTexts[1] = SqlUtils.tryPureSqlText(this.pageQuery);
List<ParameterProvider> existParameterList = this.editorPane.update();
Parameter[] ps = (existParameterList == null) ? new Parameter[0] : existParameterList.toArray(new Parameter[0]);
this.editorPane.populate(ParameterUtils.analyzeAndUnionParameters(paramTexts, ps));
}
private JToolBar createToolBar() {
// p:工具栏.
ToolBarDef toolBarDef = new ToolBarDef();
toolBarDef.addShortCut(new PreviewAction());
toolBarDef.addShortCut(new PreviewPerformedSQLAction());
toolBarDef.addShortCut(SeparatorDef.DEFAULT);
toolBarDef.addShortCut(new EditPageQueryAction());
dbTableDataMenuHandler = ExtraDesignClassManager.getInstance().getSingle(DBTableDataMenuHandler.MARK_STRING);
if (dbTableDataMenuHandler != null) {
this.dbTableDataMenuHandler = ExtraDesignClassManager.getInstance().getSingle("DBTableDataMenuHandler");
if (this.dbTableDataMenuHandler != null) {
toolBarDef.addShortCut(SeparatorDef.DEFAULT);
toolBarDef.addShortCut(dbTableDataMenuHandler.createQueryAction());
toolBarDef.addShortCut(this.dbTableDataMenuHandler.createQueryAction());
}
isShareCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Is_Share_DBTableData"));
isShareCheckBox.setBackground(Color.WHITE);
maxPanel = new MaxMemRowCountPanel();
maxPanel.setBorder(null);
UIToolbar editToolBar = ToolBarDef.createJToolBar();
toolBarDef.updateToolBar(editToolBar);
editToolBar.add(isShareCheckBox);
editToolBar.add(maxPanel);
//esd相关组件初始化
createToolbarEsdComponents(editToolBar);
return editToolBar;
}
private void createToolbarEsdComponents(final UIToolbar editToolBar) {
this.esdSettingsLabel = new UILabel(Toolkit.i18nText("Fine-Design_ESD_Cache_Settings"));
this.esdConfigOption = new UIComboBox(StrategyConfigFrom.values());
this.esdEnabled = new UICheckBox(Toolkit.i18nText("Fine-Design_ESD_Enable_Cache"));
this.barErrorTips = new UILabel();
this.barErrorTips.setForeground(Color.RED);
this.barErrorTips.setVisible(false);
esdSettingsBtn = new UIButton(Toolkit.i18nText("Fine-Design_ESD_Strategy_Config"));
esdSettingsBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final boolean global = globalOptionSelected();
final ESDStrategyConfigPane strategyConfigPane = new ESDStrategyConfigPane(global);
StrategyConfig populateStrategyConfig;
if (global) {
populateStrategyConfig = StrategyConfigService.getGlobalConfig();
} else {
populateStrategyConfig = strategyConfig;
}
//显示对应的配置
strategyConfigPane.populateBean(populateStrategyConfig);
BasicDialog dlg = strategyConfigPane.showMediumWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
super.doOk();
if (!global) {
//点击策略配置面板的确定,重新设置策略配置
strategyConfig = strategyConfigPane.updateBean();
// TODO: 2021/3/12 这个直接使用不太好
}
}
});
dlg.setAlwaysOnTop(true);
dlg.setVisible(true);
}
});
this.esdConfigOption.setSelectedIndex(StrategyConfigFrom.GLOBAL.getIndex());
this.esdConfigOption.addActionListener(e -> setEsdEnabled());
//工具栏加上esd相关组件
editToolBar.add(this.esdSettingsLabel);
editToolBar.add(this.esdConfigOption);
editToolBar.add(this.esdEnabled);
editToolBar.add(this.esdSettingsBtn);
editToolBar.add(this.barErrorTips);
}
private boolean globalOptionSelected() {
return esdConfigOption.getSelectedIndex() == StrategyConfigFrom.GLOBAL.getIndex();
}
private void setEsdEnableStatus(boolean selected, boolean enabled) {
this.esdEnabled.setSelected(selected);
this.esdEnabled.setEnabled(enabled);
}
private void setEsdEnabled() {
boolean useIndividualConfig = !this.globalOptionSelected();
if (useIndividualConfig) {
if (this.strategyConfig == null) {
//新建的数据集,选择单独时,可用但是不勾选
setEsdEnableStatus(false, true);
} else {
setEsdEnableStatus(!this.strategyConfig.isUseGlobal() && this.strategyConfig.enabled(), true);
}
} else {
//判断是不是模版数据集
switch (this.dbTableData.getScope()) {
case TEMPLATE:
String tplPath = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getEditingFILE().getPath();
setEsdEnableStatus(StrategyConfigService.isTemplateEnabled(tplPath), false);
break;
case SERVER:
//不会走到这里
default:
break;
}
}
}
public StrategyConfig updateStrategyConfig() {
return this.strategyConfig;
}
private void checkParameter() {
String[] paramTexts = new String[2];
paramTexts[0] = sqlTextPane.getText();
paramTexts[1] = pageQuery;
paramTexts[0] = this.sqlTextPane.getText();
paramTexts[1] = this.pageQuery;
Parameter[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false);
if (parameters.length < 1 && editorPane.update().size() < 1) {
if (parameters.length < 1 && this.editorPane.update().size() < 1) {
return;
}
boolean isIn = true;
List<ParameterProvider> list = editorPane.update();
List<String> name = new ArrayList<String>();
for (int i = 0; i < list.size(); i++) {
name.add(list.get(i).getName());
List<ParameterProvider> list = this.editorPane.update();
List<String> name = new ArrayList<>();
for (ParameterProvider parameter : list) {
name.add(parameter.getName());
}
for (int i = 0; i < parameters.length; i++) {
if (!name.contains(parameters[i].getName())) {
for (Parameter parameter : parameters) {
if (!name.contains(parameter.getName())) {
isIn = false;
break;
}
@ -272,101 +392,162 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
if (list.size() == parameters.length && isIn) {
return;
}
// bug:34175 删了是否刷新对话框, 均直接刷新
refresh();
refreshParameters();
}
@Override
public void populateBean(DBTableData dbtabledata) {
this.dbTableData = dbtabledata;
if (dbTableDataMenuHandler != null) {
dbTableDataMenuHandler.populate(dbtabledata);
public void populateBean(DBTableData dbTableData) {
this.dbTableData = dbTableData;
if (this.dbTableDataMenuHandler != null) {
this.dbTableDataMenuHandler.populate(dbTableData);
}
ParameterProvider[] parameters = null;
Calculator c = Calculator.createCalculator();
parameters = dbtabledata.getParameters(c);
editorPane.populate(parameters);
ParameterProvider[] parameters = dbTableData.getParameters(c);
this.editorPane.populate(parameters);
com.fr.data.impl.Connection db = null;
String query = null;
boolean isShare = false;
int maxMemeryRow = -1;
db = dbtabledata.getDatabase();
query = dbtabledata.getQuery();
isShare = dbtabledata.isShare();
maxMemeryRow = dbtabledata.getMaxMemRowCount();
this.pageQuery = dbtabledata.getPageQuerySql();
Connection db = dbTableData.getDatabase();
String query = dbTableData.getQuery();
this.pageQuery = dbTableData.getPageQuerySql();
this.connectionTableProcedurePane.setSelectedDatabaseConnection(db);
this.sqlTextPane.setText(query);
this.sqlTextPane.requestFocus();
this.sqlTextPane.moveCaretPosition(this.sqlTextPane.getCaretPosition());
isShareCheckBox.setSelected(isShare);
maxPanel.setValue(maxMemeryRow);
switch (dbTableData.getScope()) {
case TEMPLATE:
this.configHandler = new TemplateStrategyConfigHandler(dbTableData);
break;
case SERVER:
//服务器数据集
default:
//新建服务器数据集
this.configHandler = new ServerStrategyConfigHandler(dbTableData);
break;
}
//设置esd相关组件显示状态
populateESDComponents();
}
private void populateESDComponents() {
//查找映射的配置
this.strategyConfig = configHandler.find();
boolean shouldEnable = false;
StrategyConfigFrom from = StrategyConfigFrom.GLOBAL;
if (this.strategyConfig != null) {
if (this.strategyConfig.enabled()) {
shouldEnable = true;
}
if (!this.strategyConfig.isUseGlobal()) {
from = StrategyConfigFrom.INDIVIDUAL;
}
}
//服务器数据集不允许设置来源,只能单独配置
if (dbTableData.getScope() != StrategicTableData.Scope.TEMPLATE) {
from = StrategyConfigFrom.INDIVIDUAL;
this.esdConfigOption.setEnabled(false);
}
this.esdEnabled.setSelected(shouldEnable);
this.esdConfigOption.setSelectedIndex(from.getIndex());
}
@Override
public DBTableData updateBean() {
updateDBTableData();
internalUpdateStrategyConfig();
return this.dbTableData;
}
private void internalUpdateStrategyConfig() {
//这边只修改enable和useGlobal
boolean global = globalOptionSelected();
boolean enable = this.esdEnabled.isSelected();
//未开启缓存的,如果选择了单独配置,需要创建配置
if (this.strategyConfig == null && !global) {
this.strategyConfig = StrategyConfig.createDefault();
}
//设置配置来源和开启状态
if (this.strategyConfig != null) {
this.strategyConfig.setEnable(enable);
this.strategyConfig.setUseGlobal(global);
}
//保存
this.configHandler.save(this.dbTableData, this.strategyConfig);
}
private void updateDBTableData() {
String dbName = this.connectionTableProcedurePane.getSelectedDatabaseConnnectonName();
if (StringUtils.isBlank(dbName) || StringUtils.isBlank(this.sqlTextPane.getText())) {
try {
throw new Exception(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Connect_SQL_Cannot_Null") + ".");
} catch (Exception ignore) {
// JOptionPane.showMessageDialog(DBTableDataPane.this,
// com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Connect_SQL_Cannot_Null") + ".");
throw new Exception(Toolkit.i18nText("Fine-Design_Basic_Connect_SQL_Cannot_Null") + ".");
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
// 保存前 刷新下参数列表 保证获取到最新的参数
refresh();
List<ParameterProvider> parameterList = editorPane.update();
Parameter[] parameters = parameterList.toArray(new Parameter[parameterList.size()]);
refreshParameters();
List<ParameterProvider> parameterList = this.editorPane.update();
ParameterProvider[] parameters = parameterList.toArray(new ParameterProvider[0]);
dbTableData.setDatabase(new NameDatabaseConnection(dbName));
// p:必须先设置Parameters数组,因为setQuery里面会自动设置的
dbTableData.setParameters(parameters);
dbTableData.setQuery(this.sqlTextPane.getText());
dbTableData.setQuery(this.sqlTextPane.getText().trim());
dbTableData.setShare(isShareCheckBox.isSelected());
dbTableData.setMaxMemRowCount(maxPanel.getValue());
dbTableData.setPageQuerySql(this.pageQuery);
if (dbTableDataMenuHandler != null) {
dbTableDataMenuHandler.update();
if (this.dbTableDataMenuHandler != null) {
this.dbTableDataMenuHandler.update();
}
return dbTableData;
}
protected class RefreshAction extends UITableEditAction {
public RefreshAction() {
this.setName(REFRESH_BUTTON);
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/control/refresh.png"));
setName(REFRESH_BUTTON);
setSmallIcon(IOUtils.readIcon("/com/fr/design/images/control/refresh.png"));
}
@Override
public void actionPerformed(ActionEvent e) {
refresh();
DBTableDataPane.this.refreshParameters();
}
@Override
public void checkEnabled() {
// do nothing
}
}
private class PreviewAction extends UpdateAction {
public PreviewAction() {
this.setName(PREVIEW_BUTTON);
this.setMnemonic('P');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_file/preview.png"));
setName(PREVIEW_BUTTON);
setMnemonic('P');
setSmallIcon(IOUtils.readIcon("/com/fr/design/images/m_file/preview.png"));
}
@Override
public void actionPerformed(ActionEvent evt) {
checkParameter();
DBTableDataPane.this.checkParameter();
PreviewTablePane.previewTableData(DBTableDataPane.this.updateBean());
}
}
@ -387,14 +568,14 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
private class EditPageQueryAction extends UpdateAction {
public EditPageQueryAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Layer_Page_Report_Page_Query"));
this.setName(Toolkit.i18nText("Fine-Design_Basic_Layer_Page_Report_Page_Query"));
this.setMnemonic('L');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_file/text.png"));
this.setSmallIcon(IOUtils.readIcon("/com/fr/design/images/m_file/text.png"));
}
@Override
public void actionPerformed(ActionEvent e) {
final QueryPane pane = new QueryPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Layer_Page_Report_Define_Page_Query_SQL"));
final QueryPane pane = new QueryPane(Toolkit.i18nText("Fine-Design_Basic_Layer_Page_Report_Define_Page_Query_SQL"));
pane.populate(pageQuery);
BasicDialog dialog = pane.showWindow(DesignerContext.getDesignerFrame());
dialog.addDialogActionListener(new DialogActionAdapter() {
@ -408,9 +589,9 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
}
}
private class QueryPane extends BasicPane {
private static class QueryPane extends BasicPane {
private SQLEditPane pageQueryPane;
private String title;
private final String title;
public QueryPane(String title) {
this.title = title;
@ -427,21 +608,135 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
if (StringUtils.isBlank(text)) {
return;
}
pageQueryPane.setText(text);
this.pageQueryPane.setText(text);
}
public String update() {
String text = pageQueryPane.getText();
String text = this.pageQueryPane.getText();
if (StringUtils.isBlank(text)) {
return null;
} else {
return text;
}
return text;
}
@Override
protected String title4PopupWindow() {
return title;
return this.title;
}
}
/**
* 服务器数据集配置处理器
*/
private static class ServerStrategyConfigHandler extends StrategyConfigHandler<DBTableData> {
private final String origName;
private final String origConnection;
private final String origQuery;
public ServerStrategyConfigHandler(DBTableData tableData) {
super(tableData);
this.origName = tableData.getDsName();
this.origConnection = tableData.getDatabase().toString();
this.origQuery = tableData.getQuery();
}
@Override
public StrategyConfig find() {
StrategyConfig strategyConfig = null;
if (getTableData() != null) {
strategyConfig = getTableData().getStrategyConfig();
if (strategyConfig == null) {
//共享数据集
if (getTableData().isShare()) {
strategyConfig = StrategyConfigHelper.createStrategyConfig(true, false, true);
}
}
}
return strategyConfig;
}
@Override
public void save(DBTableData saved, StrategyConfig strategyConfig) {
String conn = saved.getDatabase().toString();
String query = saved.getQuery();
//检查数据链接和sql是否修改,如果修改需要触发缓存监听事件
if (!conn.equals(origConnection) || !query.equals(origQuery)) {
if (StringUtils.isNotEmpty(origName)) {
//新建数据集的origName为null,不用触发
StrategyEventsNotifier.modifyDataSet(DSMapping.ofServerDS(new DsNameTarget(origName)));
}
}
//配置变动事件
try {
final StrategyConfig orig = getTableData().getStrategyConfig();
saved.setStrategyConfig(strategyConfig.clone());
StrategyEventsNotifier.compareAndFireConfigEvents(orig, strategyConfig, DSMapping.ofServerDS(new DsNameTarget(saved.getDsName())));
} catch (CloneNotSupportedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
/**
* 模版数据集配置处理器
*/
private static class TemplateStrategyConfigHandler extends StrategyConfigHandler<DBTableData> {
public TemplateStrategyConfigHandler(DBTableData tableData) {
super(tableData);
}
@Override
public StrategyConfig find() {
StrategyConfig strategyConfig = null;
String tplPath = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getEditingFILE().getPath();
if (getTableData() != null && StringUtils.isNotEmpty(tplPath)) {
//设置保存数据集的事件检查钩子
//新建模版此时不存在,不需要注册钩子
if (getTableData().getXmlSavedHook() == null && WorkContext.getWorkResource().exist(tplPath)) {
getTableData().setXmlSavedHook(new DBTableDataSavedHook(tplPath, getTableData()));
}
//获取当前的缓存配置,没有就创建一份
String dsName = getTableData().getDsName();
//这里为了之前兼容插件创建的配置,缓存配置不在DBTableData,而是从模版attr读取
strategyConfig = StrategyConfigAttrUtils.getStrategyConfig(dsName);
if (useGlobal(getTableData(), strategyConfig)) {
//使用全局配置
strategyConfig = StrategyConfigHelper.createStrategyConfig(true);
} else if (strategyConfig == null && getTableData().isShare()) {
//没有配置时,使用共享数据集兼容配置
strategyConfig = StrategyConfigHelper.createStrategyConfig(true, false, true);
}
}
return strategyConfig;
}
private boolean useGlobal(DBTableData dbTableData, StrategyConfig strategyConfig) {
//非共享且配置为空或者指定使用全局配置时,检查是否全局开启
if (strategyConfig == null) {
return !dbTableData.isShare();
} else {
return strategyConfig.isUseGlobal();
}
}
@Override
public void save(DBTableData saved, StrategyConfig config) {
//DBTableDataSavedHook处理了
}
}
}

3
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java

@ -8,10 +8,12 @@ import com.fr.data.impl.NameDatabaseConnection;
import com.fr.data.impl.storeproc.ProcedureDataModel;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.data.operator.DataOperator;
import com.fr.design.DesignModelAdapter;
import com.fr.design.actions.UpdateAction;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane.DoubleClickSelectedNodeOnTreeListener;
import com.fr.design.data.datapane.sqlpane.SQLEditPane;
@ -291,6 +293,7 @@ public class ProcedureDataPane extends AbstractTableDataPane<StoreProcedure> imp
sp.setCalculating(false);
doAfterProcudureDone();
fireDSChanged();
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter());
}
};

33
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/db/StrategyConfigFrom.java

@ -0,0 +1,33 @@
package com.fr.design.data.tabledata.tabledatapane.db;
import com.fr.design.i18n.Toolkit;
public enum StrategyConfigFrom {
GLOBAL(0, Toolkit.i18nText("Fine-Design_ESD_Use_Global_Settings")),
INDIVIDUAL(1, Toolkit.i18nText("Fine-Design_ESD_Use_Individual_Settings"));
int index;
String displayText;
StrategyConfigFrom(int index, String displayText) {
this.index = index;
this.displayText = displayText;
}
public int getIndex() {
return this.index;
}
public String getDisplayText() {
return this.displayText;
}
public String toString() {
return getDisplayText();
}
}

5
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java

@ -26,6 +26,8 @@ import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.authority.user.UserAuthority;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
@ -175,7 +177,8 @@ public abstract class TableDataFactory {
public static String[] getSortOfChineseNameOfServerData(TableDataConfig tableDataConfig) {
clearAll();
try {
java.util.Iterator<String> nameIt = tableDataConfig.getTableDatas().keySet().iterator();
UserAuthority userAuthority = WorkContext.getCurrent().get(UserAuthority.class);
Iterator<String> nameIt = userAuthority.getAuthServerDataSetNames().iterator();
while (nameIt.hasNext()) {
String name = nameIt.next();
addName(name, tableDataConfig.getTableData(name));

17
designer-base/src/main/java/com/fr/design/dialog/BasicPane.java

@ -8,9 +8,14 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Window;
@Open
public abstract class BasicPane extends JPanel {
@ -262,6 +267,10 @@ public abstract class BasicPane extends JPanel {
public void checkValid() throws Exception {
}
public boolean confirmContinueBeforeDoOK() {
return true;
}
public static class NamePane extends BasicPane {
private UITextField nameTextField;
private UILabel Name;
@ -390,6 +399,10 @@ public abstract class BasicPane extends JPanel {
BasicPane.this.checkValid();
}
public boolean confirmContinueBeforeDoOK() {
return BasicPane.this.confirmContinueBeforeDoOK();
}
}
private class UnsizedDialog extends UIDialog {

22
designer-base/src/main/java/com/fr/design/dialog/UIDialog.java

@ -33,6 +33,7 @@ public abstract class UIDialog extends JDialog {
private BasicPane pane;
private java.util.List<DialogActionListener> listeners = new ArrayList<DialogActionListener>();
private boolean isDoOKSucceed;
private boolean needExceptionCheck = true;
public UIDialog(Frame parent) {
@ -151,6 +152,10 @@ public abstract class UIDialog extends JDialog {
});
}
public void setNeedExceptionCheck(boolean needExceptionCheck) {
this.needExceptionCheck = needExceptionCheck;
}
/**
* 添加监听器
@ -172,10 +177,21 @@ public abstract class UIDialog extends JDialog {
* 确定操作
*/
public void doOK() {
//由于checkValid不可以加入自定义的弹窗以及操作,添加一个接口
if (!confirmContinueBeforeDoOK()) {
return;
}
try {
checkValid();
} catch (Exception exp) {
FineJOptionPane.showMessageDialog(this, exp.getMessage());
if (needExceptionCheck) {
FineJOptionPane.showMessageDialog(
this,
exp.getMessage(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.WARNING_MESSAGE);
}
return;
}
@ -249,6 +265,10 @@ public abstract class UIDialog extends JDialog {
*/
public abstract void checkValid() throws Exception;
public boolean confirmContinueBeforeDoOK() {
return true;
}
public void setButtonEnabled(boolean b) {
this.okButton.setEnabled(b);
}

7
designer-base/src/main/java/com/fr/design/event/ComponentChangeListener.java

@ -0,0 +1,7 @@
package com.fr.design.event;
import java.awt.*;
public interface ComponentChangeListener {
void initListener(Container changedComponent);
}

6
designer-base/src/main/java/com/fr/design/event/ComponentChangeObserver.java

@ -0,0 +1,6 @@
package com.fr.design.event;
public interface ComponentChangeObserver {
void registerChangeListener(ComponentChangeListener uiChangeableListener);
}

29
designer-base/src/main/java/com/fr/design/extra/PluginInstalledPane.java

@ -60,11 +60,14 @@ public class PluginInstalledPane extends PluginAbstractViewPane {
public void actionPerformed(ActionEvent e) {
PluginView plugin = controlPane.getSelectedPlugin();
if (plugin != null) {
boolean isActive = plugin.isActive();
PluginMarker pluginMarker = PluginMarker.create(plugin.getID(), plugin.getVersion());
final String modifyMessage = isActive ? com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Been_Actived") : com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Been_Disabled");
if (isActive) {
PluginManager.getController().forbid(pluginMarker, new PluginTaskCallback() {
PluginContext pluginContext = getPluginContextByView(plugin);
if (pluginContext == null) {
return;
}
boolean running = pluginContext.isRunning();
final String modifyMessage = running ? com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Been_Actived") : com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Been_Disabled");
if (running) {
PluginManager.getController().forbidPersistently(pluginContext.getMarker(), new PluginTaskCallback() {
@Override
public void done(PluginTaskResult result) {
if (result.isSuccess()) {
@ -75,7 +78,7 @@ public class PluginInstalledPane extends PluginAbstractViewPane {
}
});
} else {
PluginManager.getController().enable(pluginMarker, new PluginTaskCallback() {
PluginManager.getController().enablePersistently(pluginContext.getMarker(), new PluginTaskCallback() {
@Override
public void done(PluginTaskResult result) {
if (result.isSuccess()) {
@ -145,13 +148,25 @@ public class PluginInstalledPane extends PluginAbstractViewPane {
}
private void changeTextForButton(PluginView plugin) {
if (plugin.isActive()) {
PluginContext pluginContext = getPluginContextByView(plugin);
if (pluginContext == null) {
return;
}
if (pluginContext.isRunning()) {
disableButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Disable"));
} else {
disableButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Active"));
}
}
private PluginContext getPluginContextByView(PluginView pluginView) {
if (pluginView != null) {
PluginMarker pluginMarker = PluginMarker.create(pluginView.getID(), pluginView.getVersion());
return PluginManager.getContext(pluginMarker);
}
return null;
}
@Override
protected String title4PopupWindow() {
return "Installed";

34
designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java

@ -25,6 +25,8 @@ import com.fr.plugin.manage.control.PluginTask;
import com.fr.plugin.manage.control.PluginTaskCallback;
import com.fr.plugin.manage.control.PluginTaskResult;
import com.fr.plugin.view.PluginView;
import com.fr.plugin.xml.PluginElementName;
import com.fr.plugin.xml.PluginXmlElement;
import com.fr.stable.StringUtils;
import javax.swing.JOptionPane;
@ -91,15 +93,37 @@ public class PluginOperateUtils {
public static void setPluginActive(String pluginInfo, JSCallback jsCallback) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginContext plugin = PluginManager.getContext(pluginMarker);
boolean active = plugin.isActive();
PluginTaskCallback modifyStatusCallback = new ModifyStatusCallback(active, jsCallback);
if (active) {
PluginManager.getController().forbid(pluginMarker, modifyStatusCallback);
boolean isRunning = plugin.isRunning();
PluginTaskCallback modifyStatusCallback = new ModifyStatusCallback(isRunning, jsCallback);
if (isRunning) {
PluginXmlElement forbidReminder = plugin.getXml().getElement(PluginElementName.ForbidReminder);
if (forbidReminder != null && forbidReminder.getContent() != null) {
// 禁用前提示
int rv = FineJOptionPane.showConfirmDialog(
null,
forbidReminder.getContent(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
PluginManager.getController().forbidPersistently(pluginMarker, modifyStatusCallback);
}
} else {
PluginManager.getController().enable(pluginMarker, modifyStatusCallback);
// 正常禁用
PluginManager.getController().forbidPersistently(pluginMarker, modifyStatusCallback);
}
} else {
PluginManager.getController().enablePersistently(pluginMarker, modifyStatusCallback);
}
}
});
}
public static void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSCallback jsCallback) {

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

@ -80,11 +80,13 @@ public class PluginUtils {
public static String transPluginsToString(List<PluginContext> plugins) throws Exception {
JSONArray jsonArray = new JSONArray();
for (PluginContext plugin : plugins) {
if (VersionIntervalType.isSupported(plugin.supportCurrentFRVersion())) {
JSONObject jo = new JSONObject();
jo.put("id", plugin.getID());
jo.put("version", plugin.getVersion());
jsonArray.put(jo);
}
}
return jsonArray.toString();
}
@ -267,7 +269,8 @@ public class PluginUtils {
jo.put("vendor", pluginContext.getVendor());
jo.put("price", pluginContext.getPrice());
jo.put("requiredJarTime", pluginContext.getRequiredJarTime());
jo.put("active", pluginContext.isActive());
// 前端需求的active实际上是插件的运行状态,通过isRunning()获取
jo.put("active", pluginContext.isRunning());
jo.put("hidden", pluginContext.isHidden());
jo.put("free", pluginContext.isFree());
jo.put("licDamaged", pluginContext.isLicDamaged());

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

@ -251,7 +251,11 @@ public class HistoryTemplateListCache implements CallbackEvent {
for (int i = 0; i < vCount; i++) {
JTemplate overTemplate = historyList.get(i);
if (overTemplate.getEditingFILE().exists() && overTemplate.isALLSaved() && overTemplate != editingTemplate) {
boolean replaceWithJVirtualTemplate = overTemplate.getEditingFILE().exists()
&& overTemplate.isALLSaved()
&& overTemplate != editingTemplate
&& overTemplate.checkEnable();
if (replaceWithJVirtualTemplate) {
closeVirtualSelectedReport(overTemplate);
historyList.set(i, new JVirtualTemplate(overTemplate.getEditingFILE()));
}

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

@ -4,7 +4,6 @@ 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.base.mode.DesignModeContext;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.imenu.UIMenuItem;
@ -17,6 +16,7 @@ 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;
@ -269,7 +269,7 @@ public class MutilTempalteTabPane extends JComponent {
private String tempalteShowName(JTemplate<?, ?> template) {
String name = template.getTemplateName();
String name = TemplateUtils.createLockeTemplatedName(template, template.getTemplateName());
if (!template.isSaved() && !name.endsWith(" *")) {
name += " *";
}
@ -732,6 +732,16 @@ public class MutilTempalteTabPane extends JComponent {
}
}
/**
* 后台关闭当前编辑模板
*/
public void closeCurrentTpl(){
JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
this.setIsCloseCurrent(true);
this.closeFormat(jTemplate);
this.closeSpecifiedTemplate(jTemplate);
}
/**
* 关闭模板
*
@ -766,8 +776,8 @@ public class MutilTempalteTabPane extends JComponent {
// 如果关闭的模板是当前选中的模板,则重新激活当前 selectIndex 的模板;
// selectIndex 没有变化,但是对应的模板已经变成了前一张模板
if (closeIconIndex == selectedIndex || isCloseCurrent) {
// 如果 closeIconIndex 是最后一个被渲染画出的,那么预览上一个,防止数组越界
if (closeIconIndex >= maxPaintIndex) {
// 如果当前关闭的模板在最右侧,那么预览上一个,防止数组越界
if (selectedIndex >= maxPaintIndex) {
// selectIndex 不会 <0 因为如果关闭的是打开的最后一个模板,那么关闭之后 openedTemplate.isEmpty() = true
selectedIndex--;
}

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

@ -12,20 +12,28 @@ import com.fr.design.gui.itree.filetree.TemplateFileTree;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.lock.LockInfoUtils;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.lock.LockInfoDialog;
import com.fr.design.mainframe.JTemplate;
import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.file.filetree.IOFileNodeFilter;
import com.fr.form.fit.web.editpreview.FileLockStateObservable;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.base.UserInfo;
import com.fr.stable.ArrayUtils;
import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import com.fr.report.lock.LockInfoOperator;
import java.util.UUID;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
@ -47,6 +55,10 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Objects;
import java.util.Observable;
import java.util.Observer;
import org.jetbrains.annotations.Nullable;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
import static javax.swing.JOptionPane.YES_NO_OPTION;
@ -76,6 +88,13 @@ public class TemplateTreePane extends JPanel implements FileOperations {
scrollPane.setBorder(null);
contentPane.add(scrollPane, BorderLayout.CENTER);
FileLockStateObservable.getInstance().addObserver(new Observer() {
@Override
public void update(Observable o, Object arg) {
TemplateTreePane.this.refresh();
}
});
/*
* Tree.MouseAdapter
*/
@ -103,6 +122,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
if (toolBarStateChangeListener != null) {
toolBarStateChangeListener.stateChange();
}
DesignerFrameFileDealerPane.getInstance().refreshRightToolBarBy(reportletsTree.getSelectedFileNode());
}
};
// lx: add mouse listener
@ -202,20 +222,47 @@ public class TemplateTreePane extends JPanel implements FileOperations {
@Override
public void openFile() {
// 判断是否是远程设计的锁定文件
if (!WorkContext.getCurrent().isLocal()) {
FileNode node = reportletsTree.getSelectedFileNode();
if (node == null) {
return;
}
String reportPath = reportletsTree.getSelectedTemplatePath();
final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath);
String lock = node.getLock();
if (lock != null && !lock.equals(node.getUserID())) {
boolean showLockInfo = LockInfoUtils.isCompatibleOperator()
|| LockInfoUtils.unableGetLockInfo()
|| WorkContext.getCurrent().get(LockInfoOperator.class).isTplUnLocked(selectedFilePath)
? (lock != null && !lock.equals(node.getUserID()))
: WorkContext.getCurrent().get(LockInfoOperator.class).isTplLocked(selectedFilePath);
if (showLockInfo) {
UserInfo userInfo = WorkContext.getCurrent().get(LockInfoOperator.class).getUserInfo(selectedFilePath);
node.setLock(UUID.randomUUID().toString());
// 对于开发者预览占位锁定 定位到tab中
checkDevelopForBiddenTemplate(selectedFilePath);
LockInfoDialog.show(userInfo);
return;
} else {
node.setLock(null);
}
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(selectedFilePath, false)));
}
String reportPath = reportletsTree.getSelectedTemplatePath();
final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath);
private void checkDevelopForBiddenTemplate(String selectedFilePath) {
JTemplate<?, ?> template = getOpenedTemplate(selectedFilePath);
if (template != null && template.isForbidden()) {
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(selectedFilePath, false)));
}
}
@Nullable
private JTemplate<?, ?> getOpenedTemplate(String path) {
for (JTemplate<?, ?> template : HistoryTemplateListCache.getInstance().getHistoryList()) {
if (ComparatorUtils.equals(template.getEditingFILE().getPath(), path)) {
return template;
}
}
return null;
}
/**
* 打开文件夹
@ -240,6 +287,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
// 刷新远程文件夹权限
NodeAuthProcessor.getInstance().refresh();
reportletsTree.refresh();
DesignerFrameFileDealerPane.getInstance().refreshRightToolBarBy(null);
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_File_Tree_Refresh_Successfully") + "!");
}

1689
designer-base/src/main/java/com/fr/design/formula/FRFormulaLexer.java

File diff suppressed because it is too large Load Diff

48
designer-base/src/main/java/com/fr/design/formula/FormulaChecker.java

@ -0,0 +1,48 @@
package com.fr.design.formula;
import com.fr.design.formula.exception.FormulaExceptionTipsProcessor;
import com.fr.design.i18n.Toolkit;
import com.fr.parser.FRParser;
import com.fr.script.checker.FunctionCheckerDispatcher;
import com.fr.script.checker.result.FormulaCheckResult;
import com.fr.script.checker.result.FormulaCoordinates;
import com.fr.stable.StringUtils;
import com.fr.stable.script.Expression;
import com.fr.stable.script.Node;
import com.fr.third.antlr.TokenStreamRecognitionException;
import java.io.StringReader;
/**
* @author Hoky
* @date 2021/9/28
*/
public class FormulaChecker {
public static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula");
public static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula");
private static FormulaExceptionTipsProcessor processor = FormulaExceptionTipsProcessor.getProcessor();
public static FormulaCheckResult check(String formulaText) {
if (StringUtils.isEmpty(formulaText) || formulaText.equals(Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Tips"))) {
return new FormulaCheckResult(true, VALID_FORMULA, FormulaCoordinates.INVALID, true);
}
//过滤一些空格等符号
StringReader in = new StringReader(formulaText);
//此lexer为公式校验定制
FRFormulaLexer lexer = new FRFormulaLexer(in);
FRParser parser = new FRParser(lexer);
try {
Expression expression = parser.parse();
Node node = expression.getConditionalExpression();
boolean valid = FunctionCheckerDispatcher.getInstance().getFunctionChecker(node).checkFunction(formulaText, node);
return new FormulaCheckResult(valid, valid ? Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula") :
Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"), FormulaCoordinates.INVALID, true);
} catch (Exception e) {
if (e instanceof TokenStreamRecognitionException) {
return processor.getExceptionTips(((TokenStreamRecognitionException) e).recog);
}
return processor.getExceptionTips(e);
}
}
}

11
designer-base/src/main/java/com/fr/design/formula/FormulaCheckerException.java

@ -0,0 +1,11 @@
package com.fr.design.formula;
public class FormulaCheckerException extends Exception {
public FormulaCheckerException() {
}
public FormulaCheckerException(String message) {
super(message);
}
}

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

@ -2,32 +2,79 @@ package com.fr.design.formula;
import com.fr.base.BaseFormula;
import com.fr.base.BaseUtils;
import com.fr.base.Parameter;
import com.fr.base.ParameterMapNameSpace;
import com.fr.base.TableDataNameSpace;
import com.fr.base.Utils;
import com.fr.base.io.IOFile;
import com.fr.data.TableDataSource;
import com.fr.design.actions.UpdateAction;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
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.autocomplete.CompletionCellRenderer;
import com.fr.design.gui.autocomplete.CompletionProvider;
import com.fr.design.gui.autocomplete.DefaultCompletionProvider;
import com.fr.design.gui.autocomplete.FormulaCompletion;
import com.fr.design.gui.autocomplete.FormulaPaneAutoCompletion;
import com.fr.design.gui.ibutton.UIButton;
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.ilist.QuickList;
import com.fr.design.gui.itableeditorpane.ParameterTableModel;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
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.parameter.ParameterInputPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.FArray;
import com.fr.log.FineLoggerFactory;
import com.fr.parser.FRLexer;
import com.fr.parser.FRParser;
import com.fr.parser.ArrayExpression;
import com.fr.parser.BlockIntervalLiteral;
import com.fr.parser.ColumnRowRangeInPage;
import com.fr.parser.NumberLiteral;
import com.fr.parser.SheetIntervalLiteral;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.report.core.namespace.SimpleCellValueNameSpace;
import com.fr.script.Calculator;
import com.fr.script.ScriptConstants;
import com.fr.script.checker.result.FormulaCheckResult;
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.stable.script.ColumnRowRange;
import com.fr.stable.script.Expression;
import javax.swing.*;
import com.fr.stable.script.Node;
import com.fr.stable.script.Tiny;
import com.fr.stable.script.TinyHunter;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
@ -37,9 +84,15 @@ import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
@ -52,10 +105,16 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 公式编辑面板
@ -63,21 +122,35 @@ import java.util.List;
* @editor zhou
* @since 2012-3-29下午1:50:53
*/
@EnableMetrics
public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public static final int DEFUAL_FOMULA_LENGTH = 103;
public static final String ELLIPSIS = "...";
public static final char KEY_CODE_A = 'A';
public static final char KEY_CODE_Z = 'z';
public static final String NEWLINE = "\n";
public static final String FORMULA_ICON = "/com/fr/design/images/m_file/formula.png";
public static final String PARAM_ICON = "/com/fr/design/images/m_file/param.png";
private VariableTreeAndDescriptionArea variableTreeAndDescriptionArea;
private RSyntaxTextArea formulaTextArea;
private UITextField keyWordTextField = new UITextField(18);
private int currentPosition = 0;
private int beginPosition = 0;
private int insertPosition = 0;
protected static UICheckBox autoCompletionCheck;
protected static UICheckBox checkBeforeColse;
private JList tipsList;
private JPopupMenu popupMenu;
protected DefaultListModel listModel = new DefaultListModel();
private int ifHasBeenWriten = 0;
private DefaultListModel functionTypeListModel = new DefaultListModel();
private QuickList functionTypeList;
private DefaultListModel functionNameModel;
private JList functionNameList;
private UITableEditorPane<ParameterProvider> editor4CalPane;
private FormulaPaneAutoCompletion autoCompletion;
private DefaultCompletionProvider completionProvider;
private static final Map<String, String> PARAM_PREFIX_MAP = new HashMap<>();
public FormulaPane() {
initComponents();
@ -86,6 +159,20 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void initFormulaTextAreaKeyListener() {
formulaTextArea.addKeyListener(this);
formulaTextArea.addKeyListener(new KeyAdapter() {
//用来判断一下是不是组合键
@Override
public void keyTyped(KeyEvent e) {
if (inKeyCodeRange(e) && autoCompletionCheck.isSelected()) {
autoCompletion.doCompletion();
}
}
private boolean inKeyCodeRange(KeyEvent e) {
return (e.getKeyChar() >= KEY_CODE_A && e.getKeyChar() <= KEY_CODE_Z);
}
@Override
public void keyReleased(KeyEvent e) {
formulaTextArea.setForeground(Color.black);
String text = formulaTextArea.getText();
@ -121,7 +208,9 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
beginPosition = getBeginPosition();
insertPosition = beginPosition;
firstStepToFindTips(beginPosition);
fixFunctionNameList();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
}
}
});
@ -151,7 +240,9 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String toFind = keyWordTextField.getText();
search(toFind, false);
fixFunctionNameList();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
e.consume();
}
}
@ -160,28 +251,35 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void initTipsPane() {
// tipsPane
JPanel tipsPane = new JPanel(new BorderLayout(4, 4));
this.add(tipsPane, BorderLayout.EAST);
JPanel containerSPane = new JPanel(new BorderLayout(4, 1));
JPanel labelPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0), true);
JPanel searchPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0), true);
containerSPane.setPreferredSize(new Dimension(892, 23));
this.add(containerSPane, BorderLayout.NORTH);
JPanel searchPane = new JPanel(new BorderLayout(4, 4));
searchPane.add(keyWordTextField, BorderLayout.CENTER);
UIButton searchButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Search"));
UILabel formulaLabel = new UILabel(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Input_Formula_In_The_Text_Area_Below") + ":");
formulaLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
labelPane.add(formulaLabel, BorderLayout.WEST);
keyWordTextField.setPreferredSize(new Dimension(240, 23));
searchPane.add(keyWordTextField, BorderLayout.EAST);
searchPane.add(searchButton, BorderLayout.EAST);
tipsPane.add(searchPane, BorderLayout.NORTH);
containerSPane.add(labelPane, BorderLayout.WEST);
containerSPane.add(searchPane, BorderLayout.EAST);
initKeyWordTextFieldKeyListener();
tipsList = new JList(listModel);
tipsList.addMouseListener(new DoubleClick());
UIScrollPane tipsScrollPane = new UIScrollPane(tipsList);
tipsScrollPane.setPreferredSize(new Dimension(170, 75));
tipsScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
tipsPane.add(tipsScrollPane, BorderLayout.CENTER);
searchButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
searchButton.addActionListener(e -> {
String toFind = keyWordTextField.getText();
search(toFind, false);
popTips();
formulaTextArea.requestFocusInWindow();
fixFunctionNameList();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
});
}
@ -192,6 +290,11 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
initTextPane();
initTipsPane();
initVariableTreeAndDescriptionArea();
refocusInWindow();
}
public void refocusInWindow() {
SwingUtilities.invokeLater(() -> formulaTextArea.requestFocusInWindow());
}
private void initVariableTreeAndDescriptionArea() {
@ -203,31 +306,122 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
// text
JPanel textPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.add(textPane, BorderLayout.CENTER);
JPanel checkBoxandbuttonPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
UILabel formulaLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Input_Formula_In_The_Text_Area_Below") + ":"
+ " ");
formulaLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
JPanel checkBoxandbuttonPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane();
initFormulaTextArea();
UIScrollPane formulaTextAreaScrollPane = new UIScrollPane(formulaTextArea);
formulaTextAreaScrollPane.setBorder(null);
textPane.add(formulaLabel, BorderLayout.NORTH);
textPane.add(formulaTextAreaScrollPane, BorderLayout.CENTER);
textPane.add(checkBoxandbuttonPane, BorderLayout.SOUTH);
UIButton checkValidButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Check_Valid"));
UIButton calButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Button"));
checkValidButton.addActionListener(checkValidActionListener);
calButton.addActionListener(calculateActionListener);
//靠左流式布局
JPanel checkBoxPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
checkBoxPane.setPreferredSize(new Dimension(450, 30));
checkBoxandbuttonPane.add(checkBoxPane, BorderLayout.WEST);
checkBoxandbuttonPane.add(checkValidButton, BorderLayout.EAST);
//靠右流式布局
JPanel buttonPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane();
buttonPane.add(checkValidButton, BorderLayout.EAST);
buttonPane.add(calButton, BorderLayout.EAST);
checkBoxandbuttonPane.add(buttonPane, BorderLayout.EAST);
if (autoCompletionCheck == null) {
autoCompletionCheck = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_AutoCompletion"));
autoCompletionCheck.setSelected(true);
}
if (checkBeforeColse == null) {
checkBeforeColse = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Before_Closed"));
checkBeforeColse.setSelected(true);
}
checkBoxPane.add(autoCompletionCheck, BorderLayout.WEST);
checkBoxPane.add(checkBeforeColse, BorderLayout.WEST);
extendCheckBoxPane(checkBoxPane);
ParameterTableModel model = new ParameterTableModel(0);
editor4CalPane = new UITableEditorPane<>(model);
formulaTextArea.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
// 获得焦点时 安装
if (autoCompletion == null && autoCompletionCheck.isSelected()) {
installAutoCompletion();
}
}
@Override
public void focusLost(FocusEvent e) {
// 失去焦点时 卸载
uninstallAutoCompletion();
}
});
}
private CompletionProvider createCompletionProvider() {
if (completionProvider == null) {
completionProvider = new DefaultCompletionProvider();
NameAndDescription[] nameAndDescriptions = FunctionConstants.ALL.getDescriptions();
for (NameAndDescription nameAndDescription : nameAndDescriptions) {
completionProvider.addCompletion(new FormulaCompletion(completionProvider, nameAndDescription.getName(), BaseUtils.readIcon(FORMULA_ICON)));
}
VariableResolver variableResolver = VariableResolver.DEFAULT;
List<String> allParameters = new ArrayList<>();
allParameters.addAll(Arrays.asList(variableResolver.resolveCurReportVariables()));
allParameters.addAll(Arrays.asList(variableResolver.resolveColumnNames()));
allParameters.addAll(Arrays.asList(variableResolver.resolveGlobalParameterVariables()));
allParameters.addAll(Arrays.asList(variableResolver.resolveReportParameterVariables()));
allParameters.addAll(Arrays.asList(variableResolver.resolveTableDataParameterVariables()));
//先把参数前缀拿出来
for (String parameter : allParameters) {
String paramWithoutPre;
if (parameter.startsWith("$$")) {
paramWithoutPre = parameter.substring(2);
PARAM_PREFIX_MAP.put(paramWithoutPre, "$$");
} else if (parameter.startsWith("$")) {
paramWithoutPre = parameter.substring(1);
PARAM_PREFIX_MAP.put(paramWithoutPre, "$");
} else {
paramWithoutPre = parameter;
PARAM_PREFIX_MAP.put(paramWithoutPre, StringUtils.EMPTY);
}
completionProvider.addCompletion(new FormulaCompletion(completionProvider, paramWithoutPre, BaseUtils.readIcon(PARAM_ICON)));
}
return completionProvider;
}
return completionProvider;
}
public static boolean containsParam(String param) {
return PARAM_PREFIX_MAP.containsKey(param);
}
public static String getParamPrefix(String param) {
return PARAM_PREFIX_MAP.getOrDefault(param, StringUtils.EMPTY);
}
private void uninstallAutoCompletion() {
if (autoCompletion != null) {
autoCompletion.uninstall();
autoCompletion = null;
}
}
private void installAutoCompletion() {
CompletionProvider provider = createCompletionProvider();
autoCompletion = new FormulaPaneAutoCompletion(provider);
autoCompletion.setListCellRenderer(new CompletionCellRenderer());
autoCompletion.install(formulaTextArea);
autoCompletion.installVariableTree(variableTreeAndDescriptionArea);
}
protected void extendCheckBoxPane(JPanel checkBoxPane) {
// do nothing
}
@ -274,6 +468,9 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
if (ComparatorUtils.equals((String) listModel.getElementAt(index), doublePressContent)) {
doubleClickActuator(doublePressContent);
}
if (popupMenu != null) {
popupMenu.setVisible(false);
}
}
}
}
@ -281,7 +478,9 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void singleClickActuator(String currentLineContent) {
refreshDescriptionTextArea(currentLineContent);
formulaTextArea.requestFocusInWindow();
fixFunctionNameList();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
}
private void doubleClickActuator(String currentLineContent) {
@ -345,23 +544,24 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
beginPosition = getBeginPosition();
insertPosition = beginPosition;
firstStepToFindTips(beginPosition);
fixFunctionNameList();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
ifHasBeenWriten = 1;
}
}
}
private void fixFunctionNameList() {
if (tipsList.getSelectedValue() != null) {
private void fixFunctionNameList(String functionName) {
int signOfContinue = 1;
int indexOfFunction = 0;
boolean found = false;
for (int i = 0; i < functionTypeListModel.size(); i++) {
int signOfType = 0;
FunctionGroup functionType = (FunctionGroup) functionTypeListModel.getElementAt(i);
NameAndDescription[] nads = functionType.getDescriptions();
if (signOfContinue == 1) {
functionNameModel.removeAllElements();
String functionName = ((String) tipsList.getSelectedValue());
for (int k = 0; k < nads.length; k++) {
functionNameModel.addElement(nads[k]);
if (functionName.equals(nads[k].getName()))//若相等,找出显示的函数的index,setSelectedIndex()
@ -369,6 +569,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
signOfType = 1;
signOfContinue = 0;
indexOfFunction = k;
found = true;
}
}
@ -378,10 +579,12 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
}
}
if (found) {
functionNameList.setSelectedIndex(indexOfFunction);
functionNameList.ensureIndexIsVisible(indexOfFunction);
} else {
functionTypeList.setSelectedIndex(0);
}
}
private int getBeginPosition() {
@ -432,9 +635,17 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
// do nothing
}
private void popTips() {
popupMenu = new JPopupMenu();
JScrollPane tipsScrollPane = new JScrollPane(tipsList);
popupMenu.add(tipsScrollPane);
tipsScrollPane.setPreferredSize(new Dimension(240, 146));
tipsScrollPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
popupMenu.show(keyWordTextField, 0, 23);
}
protected void search(String keyWord, boolean findDescription) {
listModel.removeAllElements();
keyWord = removeAllSpace(keyWord);
if (keyWord.length() != 0) {
NameAndDescription[] descriptions = FunctionConstants.ALL.getDescriptions();
@ -550,7 +761,9 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
beginPosition = getBeginPosition();
insertPosition = beginPosition;
firstStepToFindTips(beginPosition);
fixFunctionNameList();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
ifHasBeenWriten = 1;
} else {
this.formulaTextArea.setText(content);
@ -558,7 +771,9 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
beginPosition = getBeginPosition();
insertPosition = beginPosition;
firstStepToFindTips(beginPosition);
fixFunctionNameList();
if (tipsList.getSelectedValue() != null) {
fixFunctionNameList(tipsList.getSelectedValue().toString());
}
ifHasBeenWriten = 1;
}
}
@ -585,39 +800,247 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
// check valid
private ActionListener checkValidActionListener = new ActionListener() {
private final ActionListener checkValidActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// Execute Formula default cell element.
String formulaText = formulaTextArea.getText().trim();
FormulaCheckResult checkResult = FormulaChecker.check(formulaText);
confirmCheckResult(checkResult, checkResult.getTips());
}
};
if (formulaText != null && formulaText.length() > 0) {
StringReader in = new StringReader(formulaText);
private void calculateFormula() {
String formulaText = formulaTextArea.getText().trim();
String unSupportFormula = containsUnsupportedSimulationFormulas(formulaText);
if (unSupportFormula != null) {
showMessageDialog(Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas") + ":" + unSupportFormula, false);
return;
}
FRLexer lexer = new FRLexer(in);
FRParser parser = new FRParser(lexer);
String messageTips;
FormulaCheckResult checkResult = FormulaChecker.check(formulaText);
if (checkResult.grammarValid()) {
messageTips = checkResult.getTips() + NEWLINE;
Map<String, Object> paramsMap = setParamsIfExist(formulaText);
Calculator calculator = Calculator.createCalculator();
ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(paramsMap);
calculator.pushNameSpace(parameterMapNameSpace);
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (currentEditingTemplate != null) {
IOFile file = (IOFile) currentEditingTemplate.getTarget();
calculator.setAttribute(TableDataSource.KEY, file);
calculator.pushNameSpace(TableDataNameSpace.getInstance());
calculator.pushNameSpace(SimpleCellValueNameSpace.getInstance());
}
Expression expression = null;
BaseFormula baseFormula = BaseFormula.createFormulaBuilder().build(formulaText);
Object calResult;
try {
expression = parser.parse();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
// alex:继续往下面走,expression为null时告知不合法公式
calResult = calculator.evalValue(baseFormula);
String objectToString = EssentialUtils.objectToString(calResult);
String result = objectToString.length() > DEFUAL_FOMULA_LENGTH ?
objectToString.substring(0, DEFUAL_FOMULA_LENGTH - ELLIPSIS.length()) + ELLIPSIS : objectToString;
messageTips = messageTips + Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Result") + ":" + result;
} catch (Exception ce) {
//模拟计算如果出现错误,则抛出错误
calResult = ce.getMessage();
FineLoggerFactory.getLogger().error(ce.getMessage(), ce);
messageTips = messageTips + Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Error") + ":" + calResult;
}
FineLoggerFactory.getLogger().info("value:{}", calResult);
} else {
messageTips = checkResult.getTips();
}
if (checkResult.isValid()) {
showMessageDialog(messageTips, checkResult.isValid());
} else {
confirmCheckResult(checkResult, messageTips);
}
}
FineJOptionPane.showMessageDialog(
private final ActionListener calculateActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
calculateFormula();
}
};
private boolean confirmCheckResult(FormulaCheckResult checkResult, String messageTips) {
if (checkResult.isValid()) {
showMessageDialog(checkResult.getTips(), checkResult.isValid());
} else {
int columns = checkResult.getFormulaCoordinates().getColumns();
String position = StringUtils.EMPTY;
if (columns >= 0) {
position = Toolkit.i18nText("Fine-Design_Basic_Formula_The") + columns
+ Toolkit.i18nText("Fine-Design_Basic_Formula_Error_Position") + " ";
}
int confirmDialog = FineJOptionPane.showConfirmDialog(
FormulaPane.this,
/*
* alex:仅仅只需要根据expression是否为null作合法性判断
* 不需要eval
* TODO 但有个问题,有些函数的参数个数是有规定的,何以判别之
*/
(expression != null ? com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula") : com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula")) + ".",
position + messageTips,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.INFORMATION_MESSAGE);
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
new String[]{Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Result"), Toolkit.i18nText("Fine-Design_Basic_Formula_Continue")},
Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Result"));
if (confirmDialog == 0) {
formulaTextArea.setCaretPosition(Math.max(columns, 0));
formulaTextArea.requestFocus();
return false;
}
}
return true;
}
private void showMessageDialog(String message, boolean formulaValid) {
if (formulaValid) {
FineJOptionPane.showMessageDialog(
FormulaPane.this,
message);
} else {
FineJOptionPane.showMessageDialog(
FormulaPane.this,
message,
Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.WARNING_MESSAGE);
}
}
private String containsUnsupportedSimulationFormulas(String formulaText) {
try {
Expression expression = Calculator.createCalculator().parse(formulaText);
UnsupportedFormulaScanner scanner = new UnsupportedFormulaScanner();
if (!scanner.travelFormula(expression.getConditionalExpression())) {
return scanner.getUnSupportFormula();
}
UnsupportedSimulationNodeHunter unsupportedSimulationFormulaHunter = new UnsupportedSimulationNodeHunter();
expression.traversal4Tiny(unsupportedSimulationFormulaHunter);
return unsupportedSimulationFormulaHunter.isSupported() ? null : unsupportedSimulationFormulaHunter.getUnSupportedNode();
} catch (Exception e) {
FineLoggerFactory.getLogger().error("", e);
}
return null;
}
@Override
public boolean confirmContinueBeforeDoOK() {
if (checkBeforeColse.isSelected()) {
String formula = formulaTextArea.getText().trim();
FormulaCheckResult checkResult = FormulaChecker.check(formula);
if (!checkResult.isValid()) {
return confirmCheckResult(checkResult, checkResult.getTips());
}
}
return true;
}
private Map<String, Object> setParamsIfExist(String formulaText) {
Map<String, Object> parameterMap = new HashMap<>();
try {
Calculator calculator = Calculator.createCalculator();
Expression expression = calculator.parse(formulaText);
ParameterCellHunter parameterCellHunter = new ParameterCellHunter();
expression.traversal4Tiny(parameterCellHunter);
Parameter[] parameters = parameterCellHunter.getParameterBooty();
if (parameters.length < 1 && editor4CalPane.update().size() < 1) {
return parameterMap;
}
ParameterInputPane pPane = new ParameterInputPane(parameters);
pPane.showSmallWindow(new JFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
parameterMap.putAll(pPane.update());
}
}).setVisible(true);
//过滤出数组参数,如:[1,2]
for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
if (entry.getValue().toString().startsWith("[") && entry.getValue().toString().endsWith("]")) {
Expression parse = calculator.parse(entry.getValue());
ArrayExpression arrayExpression = (ArrayExpression) parse.getConditionalExpression();
Node[] arrays = arrayExpression.getArrays();
List<Object> arrayList = new ArrayList<>();
for (Node array : arrays) {
if (array instanceof NumberLiteral) {
arrayList.add(NumberFormat.getInstance().parse(array.toString()));
} else {
arrayList.add(array);
}
}
FArray<Object> fArray = new FArray<>(arrayList);
parameterMap.put(entry.getKey(), fArray);
} else if (Utils.isNumeric(entry.getValue().toString())) {
try {
Number number = NumberFormat.getInstance().parse(entry.getValue().toString());
parameterMap.put(entry.getKey(), number);
} catch (Exception e) {
FineLoggerFactory.getLogger().warn("", e);
}
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error("", e);
}
return parameterMap;
}
private static class ParameterCellHunter extends TinyHunter {
private final Set<Parameter> parameterList = new HashSet<>();
Parameter[] getParameterBooty() {
return parameterList.toArray(new Parameter[0]);
}
public void hunter4Tiny(Tiny tiny) {
String statement = tiny.getStatement();
if (StringUtils.isNotBlank(statement) && statement.startsWith(ScriptConstants.DETAIL_TAG)) {
if (statement.startsWith(ScriptConstants.SUMMARY_TAG)) {
parameterList.add(new Parameter(statement));
} else {
parameterList.add(new Parameter(statement.substring(1)));
}
} else if (tiny.getClass() == ColumnRowRange.class ||
tiny.getClass() == SheetIntervalLiteral.class || tiny.getClass() == BlockIntervalLiteral.class) {
parameterList.add(new Parameter(tiny.toString()));
}
}
}
private static class UnsupportedSimulationNodeHunter extends TinyHunter {
private boolean supported = true;
private String unSupportedNode;
private String[] curReportVariables;
public UnsupportedSimulationNodeHunter() {
curReportVariables = VariableResolver.DEFAULT.resolveCurReportVariables();
}
public boolean isSupported() {
return supported;
}
public String getUnSupportedNode() {
return unSupportedNode;
}
public void hunter4Tiny(Tiny tiny) {
if (tiny.getClass() == ColumnRowRangeInPage.class || tiny.getClass() == CRAddress.class
|| Arrays.asList(curReportVariables).contains(tiny.toString())) {
supported = false;
unSupportedNode = tiny.toString();
}
}
}
};
public class VariableTreeAndDescriptionArea extends JPanel {
@ -757,7 +1180,8 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void initDescriptionTextArea() {
// Description
descriptionTextArea = new UITextArea(16, 27);
descriptionTextArea = new UITextArea();
descriptionTextArea.setPreferredSize(new Dimension(350, 200));
UIScrollPane desScrollPane = new UIScrollPane(descriptionTextArea);
desScrollPane.setBorder(null);
@ -805,7 +1229,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) variablesTree.getLastSelectedPathComponent();
Object selectedValue = selectedTreeNode.getUserObject();
Object selectedParentValue = ((DefaultMutableTreeNode)selectedTreeNode.getParent()).getUserObject();
Object selectedParentValue = ((DefaultMutableTreeNode) selectedTreeNode.getParent()).getUserObject();
if (selectedValue == null) {
return;
@ -885,7 +1309,6 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
};
basicPane.setLayout(FRGUIPaneFactory.createBorderLayout());
UITextArea desArea = new UITextArea();
// desArea。setEnabled(false);
desArea.setText(this.getTextAreaText());
basicPane.add(new UIScrollPane(desArea), BorderLayout.CENTER);
BasicDialog dialog = basicPane.showWindow(DesignerContext.getDesignerFrame());
@ -958,6 +1381,11 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
};
public void refreshText(String line) {
fixFunctionNameList(line);
refreshDescriptionTextArea(line);
}
public void populate(VariableResolver variableResolver) {
// varibale tree.
DefaultTreeModel variableModel = (DefaultTreeModel) variablesTree.getModel();
@ -1010,6 +1438,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
/**
* 把以关键词开头的和不以关键词开头的分别按照字母表顺序排序
*
* @param o1 待比较对象1
* @param o2 待比较对象2
* @return 比较结果1表示 o1 > o2, -1表示 o1 < o2, 0表示 o1 = o2
@ -1092,12 +1521,12 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
buffer.append(name.toUpperCase());
buffer.append("\"");
buffer.append("|");
buffer.append("\n");
buffer.append(NEWLINE);
buffer.append("\"");
buffer.append(name.toLowerCase());
buffer.append("\"");
buffer.append("|");
buffer.append("\n");
buffer.append(NEWLINE);
}
FineLoggerFactory.getLogger().debug(buffer.toString());
}

9
designer-base/src/main/java/com/fr/design/formula/FormulaPaneWhenReserveFormula.java

@ -3,11 +3,10 @@ package com.fr.design.formula;
import com.fr.base.BaseFormula;
import com.fr.design.gui.icheckbox.UICheckBox;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.BorderLayout;
/**
* @author richie
@ -41,8 +40,8 @@ public class FormulaPaneWhenReserveFormula extends FormulaPane {
reserveCheckBox4Write = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Write_Save_Formula"));
reserveCheckBox4Write.setSelected(false);
checkBoxPane.add(reserveCheckBox4Result, BorderLayout.CENTER);
checkBoxPane.add(reserveCheckBox4Write, BorderLayout.SOUTH);
checkBoxPane.add(reserveCheckBox4Result, BorderLayout.WEST);
checkBoxPane.add(reserveCheckBox4Write, BorderLayout.WEST);
}
@Override

54
designer-base/src/main/java/com/fr/design/formula/UnsupportedFormulaScanner.java

@ -0,0 +1,54 @@
package com.fr.design.formula;
import com.fr.parser.BinaryExpression;
import com.fr.parser.DatasetFunctionCall;
import com.fr.parser.FunctionCall;
import com.fr.stable.script.Node;
import java.util.Arrays;
/**
* @author Hoky
* @date 2021/8/30
*/
public class UnsupportedFormulaScanner {
public final static String[] UNSUPPORTED_FORMULAS = new String[]{"PROPORTION", "TOIMAGE",
"WEBIMAGE", "SORT", "CROSSLAYERTOTAL", "CIRCULAR", "LAYERTOTAL", "MOM", "HIERARCHY",
"FILENAME", "FILESIZE", "FILETYPE", "TREELAYER", "GETUSERDEPARTMENTS", "GETUSERJOBTITLES"};
private String unSupportFormula = "";
public boolean travelFormula(Node node) {
if (node instanceof FunctionCall) {
if (isUnsupportedFomula(((FunctionCall) node).getName())) {
unSupportFormula = ((FunctionCall) node).getName();
return false;
} else {
for (Node argument : ((FunctionCall) node).getArguments()) {
if (!travelFormula(argument)) {
return false;
}
}
}
} else if (node instanceof BinaryExpression) {
for (Node array : ((BinaryExpression) node).getNodes()) {
if (!travelFormula(array)) {
return false;
}
}
} else if (node instanceof DatasetFunctionCall) {
DatasetFunctionCall datasetFunctionCall = (DatasetFunctionCall) node;
unSupportFormula = datasetFunctionCall.getSourceName() + "." + datasetFunctionCall.getFnName() + "()";
return false;
}
return true;
}
public String getUnSupportFormula() {
return unSupportFormula;
}
private static boolean isUnsupportedFomula(String formula) {
return Arrays.asList(UNSUPPORTED_FORMULAS).contains(formula.toUpperCase());
}
}

48
designer-base/src/main/java/com/fr/design/formula/exception/FormulaExceptionTipsProcessor.java

@ -0,0 +1,48 @@
package com.fr.design.formula.exception;
import com.fr.design.formula.FormulaChecker;
import com.fr.design.formula.exception.function.FormulaCheckWrongFunction;
import com.fr.design.formula.exception.function.MismatchedCharFunction;
import com.fr.design.formula.exception.function.MismatchedTokenFunction;
import com.fr.design.formula.exception.function.NoViableAltForCharFunction;
import com.fr.design.formula.exception.function.NoViableAltFunction;
import com.fr.script.checker.exception.FunctionCheckWrongException;
import com.fr.script.checker.result.FormulaCheckResult;
import com.fr.script.checker.result.FormulaCoordinates;
import com.fr.third.antlr.MismatchedCharException;
import com.fr.third.antlr.MismatchedTokenException;
import com.fr.third.antlr.NoViableAltException;
import com.fr.third.antlr.NoViableAltForCharException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
/**
* @author Hoky
* @date 2021/10/26
*/
public class FormulaExceptionTipsProcessor {
private static final Map<Class, Function<Exception, FormulaCheckResult>> EXCEPTION_TIPS = new ConcurrentHashMap<>();
private static final FormulaExceptionTipsProcessor PROCESSOR = new FormulaExceptionTipsProcessor();
static {
EXCEPTION_TIPS.put(FunctionCheckWrongException.class, FormulaCheckWrongFunction.getFunction());
EXCEPTION_TIPS.put(MismatchedCharException.class, MismatchedCharFunction.getFunction());
EXCEPTION_TIPS.put(MismatchedTokenException.class, MismatchedTokenFunction.getFunction());
EXCEPTION_TIPS.put(NoViableAltException.class, NoViableAltFunction.getFunction());
EXCEPTION_TIPS.put(NoViableAltForCharException.class, NoViableAltForCharFunction.getFunction());
}
public FormulaCheckResult getExceptionTips(Exception e) {
return EXCEPTION_TIPS.getOrDefault(e.getClass(),
e1 -> new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false))
.apply(e);
}
public static FormulaExceptionTipsProcessor getProcessor() {
return PROCESSOR;
}
}

14
designer-base/src/main/java/com/fr/design/formula/exception/function/FormulaCheckConstants.java

@ -0,0 +1,14 @@
package com.fr.design.formula.exception.function;
/**
* @author Hoky
* @date 2021/10/28
*/
public class FormulaCheckConstants {
public static final String COLON = ":";
public static final String LEFT = "(";
public static final String COMMON = ",";
public static final String RIGHT = ")";
public static final String BLANK = " ";
public static final String SINGLE_QUOTES = "'";
}

80
designer-base/src/main/java/com/fr/design/formula/exception/function/FormulaCheckWrongFunction.java

@ -0,0 +1,80 @@
package com.fr.design.formula.exception.function;
import com.fr.design.i18n.Toolkit;
import com.fr.script.checker.exception.FunctionCheckWrongException;
import com.fr.script.checker.result.FormulaCheckResult;
import com.fr.script.checker.result.FormulaCoordinates;
import com.fr.script.rules.FunctionParameterType;
import com.fr.script.rules.FunctionRule;
import com.fr.stable.StringUtils;
import java.util.List;
import java.util.function.Function;
/**
* @author Hoky
* @date 2021/10/26
*/
public class FormulaCheckWrongFunction implements Function<Exception, FormulaCheckResult> {
private final static FormulaCheckWrongFunction FUNCTION = new FormulaCheckWrongFunction();
@Override
public FormulaCheckResult apply(Exception e) {
if (e instanceof FunctionCheckWrongException) {
FunctionCheckWrongException ce = (FunctionCheckWrongException) e;
List<FunctionRule> rules = ce.getRules();
String functionName = ce.getFunctionName();
StringBuilder errorMsg = new StringBuilder(functionName + Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + FormulaCheckConstants.COLON);
for (int i = 0; i < rules.size(); i++) {
errorMsg.append(FormulaCheckConstants.LEFT);
if (rules.get(i).getParameterList().isEmpty()) {
errorMsg.append(Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param"));
}
for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) {
errorMsg.append(getTypeString(functionParameterType)).append(FormulaCheckConstants.COMMON);
}
if (FormulaCheckConstants.COMMON.equals(errorMsg.charAt(errorMsg.length() - 1) + StringUtils.EMPTY)) {
errorMsg.deleteCharAt(errorMsg.length() - 1);
}
errorMsg.append(FormulaCheckConstants.RIGHT);
if (i != rules.size() - 1) {
errorMsg.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or"));
}
}
return new FormulaCheckResult(false, errorMsg.toString(), new FormulaCoordinates(1, indexPosition(ce.getFormulaText(), ce.getNode().toString())), true);
}
return new FormulaCheckResult(false, StringUtils.EMPTY, new FormulaCoordinates(-1, -1), true);
}
private static String getTypeString(FunctionParameterType type) {
switch (type) {
case NUMBER:
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number");
case STRING:
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String");
case ANY:
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any");
case DATE:
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date");
case BOOLEAN:
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean");
case ARRAY:
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array");
}
return StringUtils.EMPTY;
}
public static Function<Exception, FormulaCheckResult> getFunction() {
return FUNCTION;
}
private int indexPosition(String formulaText, String invalidFormula) {
//处理一下自己FunctionCall自己拼的逗号逻辑
if (invalidFormula.contains(",")) {
invalidFormula = invalidFormula.substring(0, invalidFormula.indexOf(","));
}
int index = formulaText.indexOf(invalidFormula);
return index;
}
}

95
designer-base/src/main/java/com/fr/design/formula/exception/function/MismatchedCharFunction.java

@ -0,0 +1,95 @@
package com.fr.design.formula.exception.function;
import com.fr.design.formula.FormulaChecker;
import com.fr.design.i18n.Toolkit;
import com.fr.script.checker.result.FormulaCheckResult;
import com.fr.script.checker.result.FormulaCoordinates;
import com.fr.third.antlr.MismatchedCharException;
import java.util.function.Function;
/**
* @author Hoky
* @date 2021/10/28
*/
public class MismatchedCharFunction implements Function<Exception, FormulaCheckResult> {
private final static MismatchedCharFunction FUNCTION = new MismatchedCharFunction();
@Override
public FormulaCheckResult apply(Exception e) {
if (e instanceof MismatchedCharException) {
MismatchedCharException charException = (MismatchedCharException) e;
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1);
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false);
}
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false);
}
public static Function<Exception, FormulaCheckResult> getFunction() {
return FUNCTION;
}
private String getMessage(MismatchedCharException charException) {
StringBuffer sb = new StringBuffer();
switch (charException.mismatchType) {
case 1:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ");
appendCharName(sb, charException.expecting);
break;
case 2:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting_Anything") + ": ")
.append(FormulaCheckConstants.BLANK)
.append(FormulaCheckConstants.SINGLE_QUOTES);
appendCharName(sb, charException.expecting);
sb.append("';").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_GotItAnyway"));
break;
case 3:
case 4:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ").append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token"));
if (charException.mismatchType == 4) {
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not"));
}
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range")).append(": ");
appendCharName(sb, charException.expecting);
sb.append("..");
appendCharName(sb, charException.upper);
break;
case 5:
case 6:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ")
.append(charException.mismatchType == 6 ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not") : FormulaCheckConstants.BLANK)
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ONE_OF")).append(" (");
int[] elems = charException.set.toArray();
for (int i = 0; i < elems.length; ++i) {
appendCharName(sb, elems[i]);
}
break;
default:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_Char"));
}
return sb.toString();
}
private void appendCharName(StringBuffer sb, int c) {
switch (c) {
case 9:
sb.append("'\\t'");
break;
case 10:
sb.append("'\\n'");
break;
case 13:
sb.append("'\\r'");
break;
case 65535:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_EOF"));
break;
default:
sb.append((char) c);
}
}
}

110
designer-base/src/main/java/com/fr/design/formula/exception/function/MismatchedTokenFunction.java

@ -0,0 +1,110 @@
package com.fr.design.formula.exception.function;
import com.fr.design.formula.FormulaChecker;
import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import com.fr.script.checker.result.FormulaCheckResult;
import com.fr.script.checker.result.FormulaCoordinates;
import com.fr.stable.StringUtils;
import com.fr.third.antlr.MismatchedTokenException;
import java.lang.reflect.Field;
import java.util.function.Function;
/**
* @author Hoky
* @date 2021/10/28
*/
public class MismatchedTokenFunction implements Function<Exception, FormulaCheckResult> {
private final static MismatchedTokenFunction FUNCTION = new MismatchedTokenFunction();
public static final String NULL_STRING = "null";
@Override
public FormulaCheckResult apply(Exception e) {
if (e instanceof MismatchedTokenException) {
MismatchedTokenException charException = (MismatchedTokenException) e;
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1);
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false);
}
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false);
}
public static Function<Exception, FormulaCheckResult> getFunction() {
return FUNCTION;
}
public String getMessage(MismatchedTokenException exception) {
StringBuilder sb = new StringBuilder();
Object fieldValue = getFieldValue(exception, "tokenText");
String tokenText = fieldValue == null ? NULL_STRING : fieldValue.toString();
switch (exception.mismatchType) {
case 1:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ")
.append(tokenName(exception.expecting, exception));
break;
case 2:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting_Anything") + ": ")
.append(tokenName(exception.expecting, exception))
.append("; ")
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_GotItAnyway"));
break;
case 3:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ")
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token"))
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range"))
.append(": ")
.append(tokenName(exception.expecting, exception))
.append("..")
.append(tokenName(exception.upper, exception));
break;
case 4:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ")
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Token"))
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not"))
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_In_Range"))
.append(": ")
.append(tokenName(exception.expecting, exception))
.append("..")
.append(tokenName(exception.upper, exception));
break;
case 5:
case 6:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Expecting") + ": ")
.append(exception.mismatchType == 6 ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Not") : FormulaCheckConstants.BLANK)
.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ONE_OF")).append("(");
int[] elms = exception.set.toArray();
for (int i = 0; i < elms.length; ++i) {
sb.append(' ');
sb.append(tokenName(elms[i], exception));
}
break;
default:
sb.append(Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_Token"));
}
return sb.toString();
}
private String tokenName(int tokenType, MismatchedTokenException exception) {
if (tokenType == 0) {
return "<Set of tokens>";
} else {
String[] tokenNames = (String[]) getFieldValue(exception, "tokenNames");
return tokenType >= 0 && tokenType < tokenNames.length ? TranslateTokenUtils.translateToken(tokenNames[tokenType]) : "<" + tokenType + ">";
}
}
private Object getFieldValue(Object object, String fieldName) {
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(object);
} catch (Exception e) {
FineLoggerFactory.getLogger().warn(e.getMessage(), e);
return StringUtils.EMPTY;
}
}
}

44
designer-base/src/main/java/com/fr/design/formula/exception/function/NoViableAltForCharFunction.java

@ -0,0 +1,44 @@
package com.fr.design.formula.exception.function;
import com.fr.design.formula.FormulaChecker;
import com.fr.design.i18n.Toolkit;
import com.fr.script.checker.result.FormulaCheckResult;
import com.fr.script.checker.result.FormulaCoordinates;
import com.fr.third.antlr.NoViableAltForCharException;
import java.util.function.Function;
/**
* @author Hoky
* @date 2021/10/28
*/
public class NoViableAltForCharFunction implements Function<Exception, FormulaCheckResult> {
private final static NoViableAltForCharFunction FUNCTION = new NoViableAltForCharFunction();
@Override
public FormulaCheckResult apply(Exception e) {
if (e instanceof NoViableAltForCharException) {
NoViableAltForCharException charException = (NoViableAltForCharException) e;
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(charException.line, charException.column - 1);
return new FormulaCheckResult(false, getMessage(charException), formulaCoordinates, false);
}
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false);
}
public static Function<Exception, FormulaCheckResult> getFunction() {
return FUNCTION;
}
public String getMessage(NoViableAltForCharException exception) {
String mesg = Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_Char") + ": ";
if (exception.foundChar >= ' ' && exception.foundChar <= '~') {
mesg = mesg + '\'';
mesg = mesg + exception.foundChar;
mesg = mesg + '\'';
} else {
mesg = mesg + exception.foundChar;
}
return mesg;
}
}

41
designer-base/src/main/java/com/fr/design/formula/exception/function/NoViableAltFunction.java

@ -0,0 +1,41 @@
package com.fr.design.formula.exception.function;
import com.fr.design.formula.FormulaChecker;
import com.fr.design.i18n.Toolkit;
import com.fr.script.checker.result.FormulaCheckResult;
import com.fr.script.checker.result.FormulaCoordinates;
import com.fr.third.antlr.NoViableAltException;
import com.fr.third.antlr.TreeParser;
import java.util.function.Function;
/**
* @author Hoky
* @date 2021/10/28
*/
public class NoViableAltFunction implements Function<Exception, FormulaCheckResult> {
private final static NoViableAltFunction FUNCTION = new NoViableAltFunction();
@Override
public FormulaCheckResult apply(Exception e) {
if (e instanceof NoViableAltException) {
NoViableAltException altException = (NoViableAltException) e;
FormulaCoordinates formulaCoordinates = new FormulaCoordinates(altException.line, altException.column - 1);
return new FormulaCheckResult(false, getMessage(altException), formulaCoordinates, false);
}
return new FormulaCheckResult(false, FormulaChecker.INVALID_FORMULA, FormulaCoordinates.INVALID, false);
}
public static Function<Exception, FormulaCheckResult> getFunction() {
return FUNCTION;
}
public String getMessage(NoViableAltException exception) {
if (exception.token != null) {
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_Token") + ": " + exception.token.getText();
} else {
return exception.node == TreeParser.ASTNULL ? Toolkit.i18nText("Fine-Design_Basic_Formula_Check_End_Of_Subtree") :
Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Unexpected_AST_Node") + ": " + exception.node.toString();
}
}
}

96
designer-base/src/main/java/com/fr/design/formula/exception/function/TranslateTokenUtils.java

@ -0,0 +1,96 @@
package com.fr.design.formula.exception.function;
import com.fr.design.i18n.Toolkit;
/**
* @author Hoky
* @date 2021/11/30
*/
public class TranslateTokenUtils {
public static String translateToken(String token) {
switch (token) {
case ("RPAREN"):
return ")";
case ("LPAREN"):
return "(";
case ("COMMA"):
return ",";
case ("COLON"):
return ":";
case ("EOF"):
return Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Mismatched_EOF");
case ("DOT"):
return ".";
case ("FLOT_NUM"):
return Toolkit.i18nText("Fine-Design_Basic_Formula_Float_Number");
case ("LOR"):
return "||";
case ("LAND"):
return "&&";
case ("EQUAL"):
return "=";
case ("EQUAL2"):
return "=";
case ("NOT_EQUAL"):
return "!=";
case ("NOT_EQUAL2"):
return "!=";
case ("GE"):
return ">=";
case ("LE"):
return "<=";
case ("LT"):
return "<";
case ("PLUS"):
return "+";
case ("MINUS"):
return "-";
case ("STAR"):
return "*";
case ("DIV"):
return "/";
case ("MOD"):
return "%";
case ("POWER"):
return "^";
case ("LNOT"):
return "!";
case ("WAVE"):
return "~";
case ("LBRACK"):
return "[";
case ("SEMI"):
return ";";
case ("RBRACK"):
return "]";
case ("LCURLY"):
return "{";
case ("RCURLY"):
return "}";
case ("DCOLON"):
return ";";
case ("INT_NUM"):
return Toolkit.i18nText("Fine-Design_Basic_Formula_Integer");
case ("CR_ADRESS"):
return "\n";
case ("SHARP"):
return "#";
case ("AT"):
return "@";
case ("QUESTION"):
return "?";
case ("BOR"):
return "||";
case ("BAND"):
return "&&";
case ("Char"):
return Toolkit.i18nText("Fine-Design_Basic_Formula_Character");
case ("DIGIT"):
return Toolkit.i18nText("Fine-Design_Basic_Formula_Digital");
case ("XDIGIT"):
return Toolkit.i18nText("Fine-Design_Basic_Formula_Hexadecimal_Digital");
default:
return token;
}
}
}

19
designer-base/src/main/java/com/fr/design/fun/PcFitProvider.java

@ -0,0 +1,19 @@
package com.fr.design.fun;
import com.fr.stable.fun.mark.Mutable;
public interface PcFitProvider extends Mutable {
String XML_TAG = "PcFitProvider";
int CURRENT_LEVEL = 1;
//设计器上看到的选项
String getContentDisplayValue();
//返回给前端的值
int getContentDisplayKey();
//设计器上的提示信息
String getContentDisplayTip();
}

9
designer-base/src/main/java/com/fr/design/fun/PreviewProvider.java

@ -2,6 +2,7 @@ package com.fr.design.fun;
import com.fr.design.mainframe.JTemplate;
import com.fr.stable.Filter;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.mark.Mutable;
import java.util.Map;
@ -62,5 +63,13 @@ public interface PreviewProvider extends Mutable, Filter<JTemplate> {
*/
String getActionType();
/**
* 下拉弹出菜单的提示
* @return 弹出菜单的提示
*/
default String tooltipForPopItem() {
return StringUtils.EMPTY;
}
}

19
designer-base/src/main/java/com/fr/design/fun/impl/AbstractPcFitProvider.java

@ -0,0 +1,19 @@
package com.fr.design.fun.impl;
import com.fr.design.fun.PcFitProvider;
import com.fr.stable.fun.mark.API;
@API(level = PcFitProvider.CURRENT_LEVEL)
public abstract class AbstractPcFitProvider implements PcFitProvider {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
@Override
public String mark4Provider() {
return getClass().getName();
}
}

28
designer-base/src/main/java/com/fr/design/fun/impl/DesignerStartWithEmptyFile.java

@ -0,0 +1,28 @@
package com.fr.design.fun.impl;
import com.fr.file.FILE;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.record.analyzer.EnableMetrics;
/**
* Created by rinoux on 2016/12/16.
*/
@EnableMetrics
public class DesignerStartWithEmptyFile extends AbstractDesignerStartOpenFileProcessor {
private static final DesignerStartWithEmptyFile INSTANCE = new DesignerStartWithEmptyFile();
private DesignerStartWithEmptyFile() {
}
public static DesignerStartWithEmptyFile getInstance() {
return INSTANCE;
}
@Override
@Focus(id = "com.fr.dzstartemptyfile", text = "Fine_Design_Start_Empty_File", source = Original.REPORT)
public FILE fileToShow() {
return null;
}
}

1003
designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaAutoCompletePopupWindow.java

File diff suppressed because it is too large Load Diff

22
designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaCompletion.java

@ -0,0 +1,22 @@
package com.fr.design.gui.autocomplete;
import javax.swing.Icon;
/**
* @author Hoky
* @date 2021/11/5
*/
public class FormulaCompletion extends BasicCompletion {
private Icon icon;
public FormulaCompletion(CompletionProvider provider, String replacementText, Icon icon) {
super(provider, replacementText);
this.icon = icon;
}
@Override
public Icon getIcon() {
return icon;
}
}

1311
designer-base/src/main/java/com/fr/design/gui/autocomplete/FormulaPaneAutoCompletion.java

File diff suppressed because it is too large Load Diff

28
designer-base/src/main/java/com/fr/design/gui/autocomplete/ParameterizedCompletionContext.java

@ -16,16 +16,34 @@ import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea;
import com.fr.design.gui.syntax.ui.rtextarea.ChangeableHighlightPainter;
import com.fr.log.FineLoggerFactory;
import javax.swing.*;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.*;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.text.Highlighter.Highlight;
import javax.swing.text.Highlighter.HighlightPainter;
import java.awt.*;
import java.awt.event.*;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
@ -41,7 +59,7 @@ import java.util.List;
* @author Robert Futrell
* @version 1.0
*/
class ParameterizedCompletionContext {
public class ParameterizedCompletionContext {
/**
* The parent window.

52
designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java

@ -1,10 +1,12 @@
package com.fr.design.gui.controlpane;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.ModNameActionListener;
import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.form.event.Listener;
import com.fr.general.ComparatorUtils;
@ -12,6 +14,7 @@ import com.fr.general.IOUtils;
import com.fr.invoke.Reflect;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import javax.swing.DefaultListCellRenderer;
@ -23,12 +26,16 @@ import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.util.Collection;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
public abstract class JListControlPane extends JControlPane implements ListControlPaneProvider {
private static final String LIST_NAME = "JControl_List";
@ -424,4 +431,47 @@ public abstract class JListControlPane extends JControlPane implements ListContr
}
public boolean checkName() {
String tempName = getEditingName();
if (ComparatorUtils.equals(tempName, selectedName)) {
return false;
}
if (StringUtils.isEmpty(tempName)) {
nameableList.stopEditing();
showWarningDialog(getEmptyNameTip());
setIllegalIndex(editingIndex);
return false;
}
String[] allListNames = nameableList.getAllNames();
allListNames[editingIndex] = StringUtils.EMPTY;
if (isNameRepeated(new Collection[]{getExtraItemsToCheckNameRepeat(), Arrays.asList(allListNames)}, tempName)) {
nameableList.stopEditing();
showWarningDialog(getDuplicatedNameTip());
setIllegalIndex(editingIndex);
return false;
}
return true;
}
public String getEmptyNameTip() {
return Toolkit.i18nText("Fine-Design_Basic_Not_Null_Des");
}
public String getDuplicatedNameTip() {
return StringUtils.EMPTY;
}
public Collection getExtraItemsToCheckNameRepeat() {
return new ArrayList();
}
private void showWarningDialog(String tip) {
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(JListControlPane.this),
tip,
Toolkit.i18nText("Fine-Design_Basic_Alert"),
WARNING_MESSAGE);
}
}

8
designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java

@ -331,7 +331,7 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li
width = Math.max(width, calculateUIListMaxCellWidth(uiList.getModel(), uiList.getFontMetrics(uiList.getFont())));
}
iterator = nameEdListMap.entrySet().iterator();
width += 40;
width += 30;
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane wrapperPane = entry.getValue();
@ -351,7 +351,8 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li
} else {
text = element.toString();
}
width = Math.max(width, fontMetrics.stringWidth(text));
//增加 10px 的左右间隔
width = Math.max(width, fontMetrics.stringWidth(text) + 10);
}
}
return width;
@ -541,7 +542,8 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li
label.setBackground(Color.WHITE);
label.setForeground(Color.decode("#333334"));
label.setFont(label.getFont().deriveFont(11F));
label.setPreferredSize(new Dimension(224, 26));
//预留 10px 的纵向滚动条的宽度
label.setPreferredSize(new Dimension(214, 26));
this.nameEdList = nameEdList;
this.add(label, BorderLayout.NORTH);
this.add(this.nameEdList, BorderLayout.CENTER);

23
designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java

@ -3,6 +3,8 @@ package com.fr.design.gui.frpane;
import com.fr.design.dialog.BasicPane;
import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
import com.fr.design.event.ComponentChangeListener;
import com.fr.design.event.ComponentChangeObserver;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.stable.StringUtils;
@ -24,6 +26,16 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane {
private AttributeChangeListener listener;
private String globalName = "";
private boolean autoFireAttributesChanged = true;
public boolean isAutoFireAttributesChanged() {
return this.autoFireAttributesChanged;
}
public void setAutoFireAttributesChanged(boolean autoFireAttributesChanged) {
this.autoFireAttributesChanged = autoFireAttributesChanged;
}
protected AbstractAttrNoScrollPane() {
initAll();
}
@ -93,6 +105,15 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane {
}
});
}
if(tmpComp instanceof ComponentChangeObserver){
ComponentChangeObserver uiChangeableObserver = ((ComponentChangeObserver)tmpComp);
uiChangeableObserver.registerChangeListener(new ComponentChangeListener() {
@Override
public void initListener(Container changedComponent) {
AbstractAttrNoScrollPane.this.initListener(changedComponent);
}
});
}
}
}
@ -127,10 +148,12 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane {
public void attributeChanged() {
synchronized (this) {
if (listener != null) {
if (autoFireAttributesChanged) {
listener.attributeChange();
}
}
}
}
/**
* 返回图标的路径

47
designer-base/src/main/java/com/fr/design/gui/frpane/AttributeChangeUtils.java

@ -0,0 +1,47 @@
package com.fr.design.gui.frpane;
import java.awt.Component;
import java.awt.Container;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/9/17
*/
public class AttributeChangeUtils {
private static AbstractAttrNoScrollPane findNearestAttrNoScrollPaneAncestor(Component c) {
for(Container p = c.getParent(); p != null; p = p.getParent()) {
if (p instanceof AbstractAttrNoScrollPane) {
return (AbstractAttrNoScrollPane) p;
}
}
return null;
}
public static void changeComposedUI(Component composedComponent, boolean fireMiddleStateChanged, UIChangeAction action) {
AbstractAttrNoScrollPane attrPane = findNearestAttrNoScrollPaneAncestor(composedComponent);
boolean oldAutoFire = true;
if (!fireMiddleStateChanged) {
// 禁止属性面板自动处理属性更新
if (attrPane != null) {
oldAutoFire = attrPane.isAutoFireAttributesChanged();
attrPane.setAutoFireAttributesChanged(false);
}
}
// 更新UI
action.changeComposedUI();
if (!fireMiddleStateChanged) {
// 恢复属性面板自动处理属性更新
if (attrPane != null) {
attrPane.setAutoFireAttributesChanged(oldAutoFire);
}
}
}
public interface UIChangeAction {
void changeComposedUI();
}
}

29
designer-base/src/main/java/com/fr/design/gui/frpane/JTreeAutoBuildPane.java

@ -27,13 +27,16 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.stable.StringUtils;
import java.awt.*;
import javax.swing.JPanel;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.List;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class JTreeAutoBuildPane extends BasicPane implements PreviewLabel.Previewable, EditOrNewLabel.Editable {
private TreeTableDataComboBox treeTableDataComboBox;
@ -239,12 +242,22 @@ public class JTreeAutoBuildPane extends BasicPane implements PreviewLabel.Previe
rtd = treeTableDataComboBox.getSelcetedTableData();
name = treeTableDataComboBox.getSelectedItem().getTableDataName();
}
final String tableDataName = name;
AbstractTableDataWrapper atdw = new TemplateTableDataWrapper(rtd, "");
tdtp.dgEdit(atdw.creatTableDataPane(), name);
tdtp.showEditPane(atdw.creatTableDataPane(), name, new BasicTableDataTreePane.TableDataTreePaneListener() {
@Override
public void doOk() {
// 去除缓存列,后面刷新会重新选中
DesignTableDataManager.removeSelectedColumnNames(tableDataName);
treeTableDataComboBox.refresh();
treeTableDataComboBox.setSelectedTableDataByName(name);
textPane.populate(1);
valuePane.populate(1);
treeTableDataComboBox.setSelectedTableDataByName(tableDataName);
}
@Override
public void doCancel() {
}
});
}
}

14
designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java

@ -127,7 +127,7 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
buildBox.setSelectedIndex(1);
TableDataDictionary dictionary = treeEditor.getDictionary();
autoBuildPane.populate(dictionary);
} else if (treeEditor.isLayerBuild()) {
} else if (treeEditor.isFastLayerBuild()) {
buildBox.setSelectedIndex(0);
java.util.List<LayerConfig> layerConfigList = treeEditor.getLayerConfigs();
LayerConfig[] layerConfigs = new LayerConfig[layerConfigList.size()];
@ -156,12 +156,12 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
if (buildBox.getSelectedIndex() == 1) {
TableDataDictionary dictionary = this.autoBuildPane.update();
te.setAutoBuild(true);
te.setLayerBuild(false);
te.setFastLayerBuild(false);
te.setDictionary(dictionary);
te.setNodeOrDict(dictionary);
} else if (buildBox.getSelectedIndex() == 2) {
te.setAutoBuild(false);
te.setLayerBuild(false);
te.setFastLayerBuild(false);
NameObject no = this.controlPane.update();
if (no != null) {
TreeEditor editor = (TreeEditor) no.getObject();
@ -181,7 +181,7 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
} else {
LayerConfig[] configs = (LayerConfig[]) layerDataControlPane.update().getObject();
te.setAutoBuild(false);
te.setLayerBuild(true);
te.setFastLayerBuild(true);
te.setLayerConfigs(Arrays.asList(configs));
}
return te;
@ -215,12 +215,12 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
if (buildBox.getSelectedIndex() == 1) {
TableDataDictionary dictionary = this.autoBuildPane.update();
tcb.setAutoBuild(true);
tcb.setLayerBuild(false);
tcb.setFastLayerBuild(false);
tcb.setDictionary(dictionary);
tcb.setNodeOrDict(dictionary);
} else if (buildBox.getSelectedIndex() == 2) {
tcb.setAutoBuild(false);
tcb.setLayerBuild(false);
tcb.setFastLayerBuild(false);
NameObject no = this.controlPane.update();
if (no != null) {
if (no.getObject() instanceof TreeComboBoxEditor) {
@ -244,7 +244,7 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
}else {
LayerConfig[] configs = (LayerConfig[]) layerDataControlPane.update().getObject();
tcb.setAutoBuild(false);
tcb.setLayerBuild(true);
tcb.setFastLayerBuild(true);
tcb.setLayerConfigs(Arrays.asList(configs));
}
return tcb;

12
designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPane.java

@ -21,6 +21,8 @@ public class UITabbedPane extends JTabbedPane{
private String classPath; //panel对象的类名
private String tabName; //Tab名称
private int tabSize = 0;
private Color tabBorderColor;
public UITabbedPane() {
super();
}
@ -93,6 +95,16 @@ public class UITabbedPane extends JTabbedPane{
public int getTabSize(){
return tabSize;
}
public Color getTabBorderColor() {
return tabBorderColor;
}
public void setTabBorderColor(Color tabBorderColor) {
this.tabBorderColor = tabBorderColor;
repaint();
}
@Override
/**
* 获取UI对象

21
designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPaneUI.java

@ -31,9 +31,20 @@ public class UITabbedPaneUI extends BasicTabbedPaneUI {
private int addX = -1;
private int addY = -1;
private int rollover = -1;
private Color tabBorderColor = new Color(143, 160, 183);
private final Color DEFAULT_TAB_BORDER_COLOR = new Color(143, 160, 183);
private Color[] tabSelectedColor = {UIConstants.NORMAL_BLUE, UIConstants.NORMAL_BLUE, UIConstants.NORMAL_BLUE};
public Color getTabBorderColor() {
Color color = null;
if (tabPane instanceof UITabbedPane) {
color = ((UITabbedPane) tabPane).getTabBorderColor();
}
if (color == null) {
color = DEFAULT_TAB_BORDER_COLOR;
}
return color;
}
/**
* 创建UI对象
*
@ -252,9 +263,9 @@ public class UITabbedPaneUI extends BasicTabbedPaneUI {
private void drawUITabBorder(Graphics g, int tabPlacement, int x, int y, int w, int h,
boolean isSelected, boolean isEnabled, boolean isRollover) {
if (!isEnabled) {
drawUITabBorder(g, tabBorderColor, x, y, w, h, tabPlacement);
drawUITabBorder(g, getTabBorderColor(), x, y, w, h, tabPlacement);
} else if (isSelected || isRollover) {
drawSelectedUITabBorder(g, tabBorderColor, x, y, w, h, tabPlacement);
drawSelectedUITabBorder(g, getTabBorderColor(), x, y, w, h, tabPlacement);
if (isRollover && canClose()) {
closeX = x + w - closeIcon.getIconWidth() - 3;
closeY = 0;
@ -269,7 +280,7 @@ public class UITabbedPaneUI extends BasicTabbedPaneUI {
closeIcon.paintIcon(tabPane, g, closeX, closeY);
}
} else {
drawUITabBorder(g, tabBorderColor, x, y, w, h, tabPlacement);
drawUITabBorder(g, getTabBorderColor(), x, y, w, h, tabPlacement);
}
}
@ -322,7 +333,7 @@ public class UITabbedPaneUI extends BasicTabbedPaneUI {
}
private void drawUIContentBorder(Graphics g, int x, int y, int w, int h) {
g.setColor(tabBorderColor);
g.setColor(getTabBorderColor());
g.drawRect(x, y, w - 3, h - 3);
// Shadow
g.setColor(new Color(204, 204, 204));

11
designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java

@ -10,6 +10,7 @@ import com.fr.design.gui.ispinner.UIBasicSpinner;
import com.fr.design.gui.itextfield.UINumberField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.GeneralUtils;
import com.fr.stable.AssistUtils;
import com.fr.stable.StringUtils;
@ -27,6 +28,7 @@ import java.math.BigDecimal;
* For input Number.
*/
public abstract class UnitInputPane extends BasicPane {
private static final double MAX_NUM = 3000.0D;
private static final double NUM_POINT = 0.000001;
private int scale = -1;
String title;
@ -46,7 +48,7 @@ public abstract class UnitInputPane extends BasicPane {
centerPane.add(titleLabel);
// Denny:在对话框中加入JSpinner对象
numberFieldSpinner = new UIBasicSpinner(new SpinnerNumberModel(0, 0, 999, 1));
numberFieldSpinner = new UIBasicSpinner(new SpinnerNumberModel(0, 0, MAX_NUM, 1));
GUICoreUtils.setColumnForSpinner(numberFieldSpinner, 24);
numberFieldSpinner.setPreferredSize(new Dimension(60, 20));
numberFieldSpinner.setMinimumSize(new Dimension(60, 20));
@ -71,11 +73,11 @@ public abstract class UnitInputPane extends BasicPane {
public void populate(float floatValue) {
popValue = floatValue;
numberFieldSpinner.setModel(new SpinnerNumberModel(0.00, 0.00, 999.00, 0.01));
numberFieldSpinner.setModel(new SpinnerNumberModel(0.00, 0.00, MAX_NUM, 0.01));
JFormattedTextField temp = GUICoreUtils.getSpinnerTextField(numberFieldSpinner);
addChangeListener(temp);
BigDecimal de = new BigDecimal(floatValue + "");
BigDecimal de = new BigDecimal(GeneralUtils.objectToString(floatValue));
if (scale > 0) {
floatValue = de.setScale(scale, BigDecimal.ROUND_DOWN).floatValue();
} else {
@ -108,7 +110,8 @@ public abstract class UnitInputPane extends BasicPane {
if (temp.getText().length() == 0) {
return 0;
}
BigDecimal de = new BigDecimal(temp.getText());
BigDecimal de = new BigDecimal(GeneralUtils.objectToString(temp.getValue()));
if (scale > 0) {
return de.setScale(scale, BigDecimal.ROUND_DOWN).floatValue();
} else {

50
designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java

@ -3,6 +3,8 @@ package com.fr.design.gui.ibutton;
import com.fr.design.constants.UIConstants;
import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
@ -24,7 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver, UIObserver {
private static final long serialVersionUID = 1L;
private static final int TEXT_LENGTH = 3;
private static final int BUTTON_SIZE = 2;
@ -37,6 +39,9 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
private boolean isToolBarComponent = false;
private boolean isClick;
private UIObserverListener uiObserverListener;
private boolean autoFireStateChanged = true;
public UIButtonGroup(String[] textArray) {
this(textArray, null);
}
@ -72,7 +77,7 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
if (globalNameListener != null) {
globalNameListener.setGlobalName(buttonGroupName);
}
setSelectedWithFireChanged(index);
setSelectedIndex(index, autoFireStateChanged);
}
};
}
@ -108,7 +113,7 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
if (globalNameListener != null) {
globalNameListener.setGlobalName(buttonGroupName);
}
setSelectedWithFireChanged(index);
setSelectedIndex(index, autoFireStateChanged);
}
};
}
@ -175,7 +180,7 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
if (globalNameListener != null) {
globalNameListener.setGlobalName(buttonGroupName);
}
setSelectedWithFireChanged(index);
setSelectedIndex(index, autoFireStateChanged);
}
};
}
@ -253,6 +258,10 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
g2d.setClip(oldClip);
}
public void setAutoFireStateChanged(boolean autoFireStateChanged) {
this.autoFireStateChanged = autoFireStateChanged;
}
/**
* setSelectedItem
*
@ -287,13 +296,14 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
return selectedIndex;
}
protected void setSelectedWithFireChanged(int newSelectedIndex) {
protected void setSelectedIndex(int newSelectedIndex, boolean fireChanged) {
if (selectedIndex != newSelectedIndex) {
selectedIndex = newSelectedIndex;
for (int i = 0; i < labelButtonList.size(); i++) {
if (i == selectedIndex) {
labelButtonList.get(i).setSelectedWithFireListener(true);
} else {
labelButtonList.get(i).setSelected(false);
labelButtonList.get(i).setSelected(i == selectedIndex, false);
}
if (fireChanged) {
fireStateChanged();
}
}
}
@ -304,10 +314,7 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
* @param newSelectedIndex
*/
public void setSelectedIndex(int newSelectedIndex) {
selectedIndex = newSelectedIndex;
for (int i = 0; i < labelButtonList.size(); i++) {
labelButtonList.get(i).setSelected(i == selectedIndex);
}
setSelectedIndex(newSelectedIndex, false);
}
private void fireStateChanged() {
@ -322,6 +329,9 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
((ChangeListener) listeners[i + 1]).stateChanged(e);
}
}
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
}
/**
@ -364,14 +374,24 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
return true;
}
@Override
public void registerChangeListener(UIObserverListener listener) {
this.uiObserverListener = listener;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
/**
* @param l
*/
public void addChangeListener(ChangeListener l) {
listenerList.add(ChangeListener.class, l);
for (int i = 0; i < labelButtonList.size(); i++) {
labelButtonList.get(i).addChangeListener(l);
listenerList.add(ChangeListener.class, l);
}
}
@ -379,9 +399,9 @@ public class UIButtonGroup<T> extends JPanel implements GlobalNameObserver {
* @param l
*/
public void removeChangeListener(ChangeListener l) {
listenerList.remove(ChangeListener.class, l);
for (int i = 0; i < labelButtonList.size(); i++) {
labelButtonList.get(i).removeChangeListener(l);
listenerList.remove(ChangeListener.class, l);
}
}

13
designer-base/src/main/java/com/fr/design/gui/ibutton/UIColorButton.java

@ -136,6 +136,7 @@ public class UIColorButton extends UIButton implements PopupHider, UIObserver, G
}
popupWin = this.getColorControlWindow();
popupWin.setColor(color);
GUICoreUtils.showPopupMenu(popupWin, this, POPUP_MENU_SHIFT, this.getSize().height);
}
@ -154,7 +155,14 @@ public class UIColorButton extends UIButton implements PopupHider, UIObserver, G
protected ColorControlWindow getColorControlWindow() {
//find parant.
if (this.popupWin == null) {
this.popupWin = new ColorControlWindow(UIColorButton.this) {
this.popupWin = initColorControlWindow();
}
return popupWin;
}
protected ColorControlWindow initColorControlWindow(){
return new ColorControlWindow(UIColorButton.this) {
@Override
protected void colorChanged() {
UIColorButton.this.setColor(this.getColor());
@ -163,9 +171,6 @@ public class UIColorButton extends UIButton implements PopupHider, UIObserver, G
};
}
return popupWin;
}
/**
* 添加监听
*

36
designer-base/src/main/java/com/fr/design/gui/ibutton/UINoThemeColorButton.java

@ -0,0 +1,36 @@
package com.fr.design.gui.ibutton;
import com.fr.design.gui.ipoppane.PopupHider;
import com.fr.design.style.color.ColorControlWindow;
import javax.swing.Icon;
public class UINoThemeColorButton extends UIColorButton{
public UINoThemeColorButton(Icon icon) {
super(icon);
}
protected ColorControlWindow initColorControlWindow(){
return new NoThemeColorControlWindow(this);
}
private class NoThemeColorControlWindow extends ColorControlWindow{
public NoThemeColorControlWindow(PopupHider popupHider) {
super(popupHider);
}
protected boolean supportThemeColor(){
return false;
}
@Override
protected void colorChanged() {
UINoThemeColorButton.this.setColor(this.getColor());
}
}
}

9
designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java

@ -63,13 +63,8 @@ public class UITabGroup extends UIButtonGroup<Integer> {
}
@Override
protected void setSelectedWithFireChanged(int newSelectedIndex) {
if (selectedIndex != newSelectedIndex) {
selectedIndex = newSelectedIndex;
for (int i = 0; i < labelButtonList.size(); i++) {
labelButtonList.get(i).setSelected(i == selectedIndex);
}
}
protected void setSelectedIndex(int newSelectedIndex, boolean fireChanged) {
super.setSelectedIndex(newSelectedIndex, false);
tabChanged(newSelectedIndex);
}
}

6
designer-base/src/main/java/com/fr/design/gui/ibutton/UIToggleButton.java

@ -142,10 +142,12 @@ public class UIToggleButton extends UIButton implements GlobalNameObserver{
}
}
public void setSelectedWithFireListener(boolean isSelected) {
public void setSelected(boolean isSelected, boolean fireChanged) {
if (this.isSelected != isSelected) {
this.isSelected = isSelected;
if (fireChanged) {
fireSelectedChanged();
}
refresh(isSelected);
}
}
@ -175,7 +177,7 @@ public class UIToggleButton extends UIButton implements GlobalNameObserver{
@Override
public void mouseClicked(MouseEvent e) {
if (isEnabled() && !isEventBannded) {
setSelectedWithFireListener(!isSelected());
setSelected(!isSelected(), true);
}
}
};

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

@ -58,7 +58,7 @@ public class UICheckBox extends JCheckBox implements UIObserver, GlobalNameObser
super(locText, b);
setUI(new UICheckBoxUI());
initListener();
this.markMnemonic=markMnemonic;
this.markMnemonic = markMnemonic;
}
public UICheckBox(String text, Icon icon) {
@ -100,6 +100,10 @@ public class UICheckBox extends JCheckBox implements UIObserver, GlobalNameObser
}
public void removeChangeListener() {
uiObserverListener = null;
}
@Override
public void setGlobalName(String name) {
checkboxName = name;

34
designer-base/src/main/java/com/fr/design/gui/icombobox/ColorSchemeComboBox.java

@ -2,19 +2,18 @@ package com.fr.design.gui.icombobox;
import com.fr.base.ChartColorMatching;
import com.fr.base.ChartPreStyleConfig;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.chart.ThemedChartSeriesColor;
import com.fr.cert.token.lang.Collections;
import com.fr.chart.base.ChartConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.chart.mode.ChartEditContext;
import com.fr.general.GeneralUtils;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
@ -23,6 +22,12 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Bjorn
@ -65,7 +70,22 @@ public class ColorSchemeComboBox extends UIComboBox {
Iterator names = config.names();
if (preDefined) {
colorSchemes.put(Toolkit.i18nText("Fine-Design_Chart_Predefined"), null);
if (ChartEditContext.supportTheme()) {
ColorInfo colorInfo = new ColorInfo();
List<Color> list = new ArrayList<>();
colorInfo.setColors(list);
TemplateTheme templateTheme = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getTemplateTheme();
ThemedChartSeriesColor themedChartSeriesColor = templateTheme.getChartStyle().getThemedChartSeriesColor();
if (themedChartSeriesColor.isCombineColor()) {
colorInfo.setGradient(false);
list.addAll(templateTheme.getColorScheme().getColors());
} else {
colorInfo.setGradient(true);
list.add(themedChartSeriesColor.getBeginColor());
list.add(themedChartSeriesColor.getEndColor());
}
colorSchemes.put(Toolkit.i18nText("Fine-Design_Chart_Follow_Theme"), colorInfo);
}
} else {
//添加默认的方案和第一个方案
String defaultName = config.getCurrentStyle();
@ -133,7 +153,7 @@ public class ColorSchemeComboBox extends UIComboBox {
if (selectedIndex == itemCount - 2) {
return SelectType.COMBINATION_COLOR;
}
if (selectedIndex == 0) {
if (selectedIndex == 0 && ChartEditContext.supportTheme()) {
return SelectType.DEFAULT;
}
return SelectType.NORMAL;

4
designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java

@ -248,7 +248,7 @@ public class FRTreeComboBox extends UIComboBox {
private static TreePopup treePopup;
private static class FRTreeComboBoxUI extends BasicComboBoxUI implements MouseListener{
protected static class FRTreeComboBoxUI extends BasicComboBoxUI implements MouseListener{
private boolean isRollover = false;
public FRTreeComboBoxUI() {
@ -535,7 +535,7 @@ public class FRTreeComboBox extends UIComboBox {
public class FrTreeSearchComboBoxEditor extends UIComboBoxEditor implements DocumentListener {
private volatile boolean setting = false;
private FRTreeComboBox comboBox;
private Object item;
protected Object item;
public FrTreeSearchComboBoxEditor(FRTreeComboBox comboBox) {
super();

77
designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java

@ -1,77 +0,0 @@
package com.fr.design.gui.icombobox;
import com.fr.log.FineLoggerFactory;
import javax.swing.JTree;
import javax.swing.SwingWorker;
import javax.swing.tree.TreeCellRenderer;
import java.util.concurrent.FutureTask;
/**
* 模糊搜索前需执行完前置任务的TreeComboBox
* @author Lucian.Chen
* @version 10.0
* Created by Lucian.Chen on 2021/4/14
*/
public class SearchPreTaskTreeComboBox extends FRTreeComboBox {
/**
* 模糊搜索前任务
*/
private FutureTask<Void> preSearchTask;
public SearchPreTaskTreeComboBox(JTree tree, TreeCellRenderer renderer, boolean editable) {
super(tree, renderer, editable);
}
public FutureTask<Void> getPreSearchTask() {
return preSearchTask;
}
public void setPreSearchTask(FutureTask<Void> preSearchTask) {
this.preSearchTask = preSearchTask;
}
protected UIComboBoxEditor createEditor() {
return new SearchPreTaskComboBoxEditor(this);
}
private class SearchPreTaskComboBoxEditor extends FrTreeSearchComboBoxEditor {
public SearchPreTaskComboBoxEditor(FRTreeComboBox comboBox) {
super(comboBox);
}
protected void changeHandler() {
if (isSetting()) {
return;
}
setPopupVisible(true);
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() {
FutureTask<Void> task = getPreSearchTask();
try {
// 确保模糊搜索前任务执行完成后,再进行模糊搜索
if (task != null) {
task.get();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
if (task != null) {
// 任务执行后置空,否则会被别的操作重复触发
setPreSearchTask(null);
}
return null;
}
@Override
protected void done() {
// 模糊搜索
search();
}
}.execute();
}
}
}

217
designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java

@ -0,0 +1,217 @@
package com.fr.design.gui.icombobox;
import com.fr.data.core.DataCoreUtils;
import com.fr.data.core.db.TableProcedure;
import com.fr.data.impl.Connection;
import com.fr.design.DesignerEnvManager;
import com.fr.design.data.datapane.ChoosePane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.mainframe.DesignerContext;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Filter;
import com.fr.stable.StringUtils;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.SwingWorker;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.event.MouseEvent;
import java.util.Enumeration;
/**
* 实现模糊搜索表名的FRTreeComboBox
* FRTreeComboBox搜索后滚动到首个匹配节点
* SearchFRTreeComboBox显示所有匹配的节点
*
* @author Lucian.Chen
* @version 10.0
* Created by Lucian.Chen on 2021/4/14
*/
public class TableSearchTreeComboBox extends FRTreeComboBox {
// 持有父容器,需要实时获取其他组件值
private final ChoosePane parent;
public TableSearchTreeComboBox(ChoosePane parent, JTree tree, TreeCellRenderer renderer) {
super(tree, renderer);
this.parent = parent;
setUI(new TableSearchTreeComboBoxUI());
}
protected UIComboBoxEditor createEditor() {
return new TableSearchComboBoxEditor(this);
}
@Override
protected String pathToString(TreePath path) {
Object obj = ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject();
if (obj instanceof TableProcedure) {
return ((TableProcedure) obj).getName();
}
return super.pathToString(path);
}
@Override
public void setSelectedItemString(String _name) {
super.setSelectedItemString(_name);
// 会因为连续两次选中的值一致,导致未触发编辑框联动
this.getEditor().setItem(_name);
}
/**
* 执行模糊搜索
*/
private void searchExecute() {
UIComboBoxEditor searchEditor = (UIComboBoxEditor) this.getEditor();
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() {
processTableDataNames(
parent.getDSName(),
parent.getConnection(),
parent.getSchema(),
createFilter((String) searchEditor.getItem()));
return null;
}
@Override
protected void done() {
expandTree();
// 输入框获取焦点
searchEditor.getEditorComponent().requestFocus();
}
}.execute();
}
private TableNameFilter createFilter(String text) {
return StringUtils.isEmpty(text) ? EMPTY_FILTER : new TableNameFilter(text);
}
/**
* 查询数据库表并构建节点目录
*
* @param databaseName 数据库名
* @param connection 数据连接
* @param schema 模式
* @param filter 模糊搜索过滤器
*/
private void processTableDataNames(String databaseName, Connection connection, String schema, TableNameFilter filter) {
if (tree == null) {
return;
}
DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) tree.getModel().getRoot();
rootTreeNode.removeAllChildren();
if (connection == null) {
return;
}
try {
schema = StringUtils.isEmpty(schema) ? null : schema;
TableProcedure[] sqlTableArray = DataCoreUtils.getTables(connection, TableProcedure.TABLE, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace());
if (ArrayUtils.isNotEmpty(sqlTableArray)) {
ExpandMutableTreeNode tableTreeNode = new ExpandMutableTreeNode(databaseName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_Table"));
rootTreeNode.add(tableTreeNode);
addArrayNode(tableTreeNode, sqlTableArray, filter);
}
TableProcedure[] sqlViewArray = DataCoreUtils.getTables(connection, TableProcedure.VIEW, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace());
if (ArrayUtils.isNotEmpty(sqlViewArray)) {
ExpandMutableTreeNode viewTreeNode = new ExpandMutableTreeNode(databaseName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_View"));
rootTreeNode.add(viewTreeNode);
addArrayNode(viewTreeNode, sqlViewArray, filter);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Failed"), JOptionPane.ERROR_MESSAGE);
}
}
private void addArrayNode(ExpandMutableTreeNode rootNode, TableProcedure[] sqlArray, TableNameFilter filter) {
if (sqlArray != null) {
for (TableProcedure procedure : sqlArray) {
if (filter.accept(procedure)) {
ExpandMutableTreeNode viewChildTreeNode = new ExpandMutableTreeNode(procedure);
rootNode.add(viewChildTreeNode);
}
}
}
}
/**
* 展开节点
*/
private void expandTree() {
((DefaultTreeModel) tree.getModel()).reload();
// daniel 展开所有tree
TreeNode root = (TreeNode) tree.getModel().getRoot();
TreePath parent = new TreePath(root);
TreeNode node = (TreeNode) parent.getLastPathComponent();
for (Enumeration e = node.children(); e.hasMoreElements(); ) {
TreeNode n = (TreeNode) e.nextElement();
TreePath path = parent.pathByAddingChild(n);
tree.expandPath(path);
}
}
private static final TableNameFilter EMPTY_FILTER = new TableNameFilter() {
public boolean accept(TableProcedure procedure) {
return true;
}
};
/**
* 表名模糊搜索实现
*/
private static class TableNameFilter implements Filter<TableProcedure> {
private String searchFilter;
public TableNameFilter() {
}
public TableNameFilter(String searchFilter) {
this.searchFilter = searchFilter.toLowerCase().trim();
}
// 表名匹配
@Override
public boolean accept(TableProcedure procedure) {
return procedure.getName().toLowerCase().contains(searchFilter);
}
}
/**
* 重写FRTreeComboBoxUI实现点击下拉时触发模糊搜索
*/
private class TableSearchTreeComboBoxUI extends FRTreeComboBoxUI {
@Override
public void mouseClicked(MouseEvent e) {
searchExecute();
}
}
/**
* 重写输入框编辑器实现输入框模糊搜索逻辑
*/
private class TableSearchComboBoxEditor extends FrTreeSearchComboBoxEditor {
public TableSearchComboBoxEditor(FRTreeComboBox comboBox) {
super(comboBox);
}
@Override
protected void changeHandler() {
if (isSetting()) {
return;
}
setPopupVisible(true);
this.item = textField.getText();
searchExecute();
}
}
}

14
designer-base/src/main/java/com/fr/design/gui/imenu/UIPopupMenu.java

@ -8,8 +8,10 @@ import javax.swing.*;
import com.fr.design.constants.UIConstants;
public class UIPopupMenu extends JPopupMenu{
private static final float REC = 8f;
private static final float DEFAULT_REC = 8f;
private boolean onlyText = false;
private float rec = DEFAULT_REC;
public static UIPopupMenu EMPTY = new UIPopupMenu();
public UIPopupMenu() {
super();
@ -19,8 +21,7 @@ public class UIPopupMenu extends JPopupMenu{
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Shape shape = null;
shape = new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), REC, REC);
Shape shape = new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), rec, rec);
g2d.setClip(shape);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g2d);
@ -29,10 +30,9 @@ public class UIPopupMenu extends JPopupMenu{
@Override
protected void paintBorder(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int rec = (int) REC;
g2d.setColor(UIConstants.UIPOPUPMENU_LINE_COLOR);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, rec, rec);
g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, (int) rec, (int) rec);
}
@Override
@ -46,4 +46,8 @@ public class UIPopupMenu extends JPopupMenu{
public void setOnlyText(boolean onlyText) {
this.onlyText = onlyText;
}
public void setRadius(float radius) {
this.rec = radius;
}
}

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

@ -31,22 +31,22 @@ public class ProgressDialog extends UIDialog {
super(parent);
setUndecorated(true);
setSize(parent.getSize());
setLocationRelativeTo(null);
setLocation(parent.getLocation());
OSSupportCenter.buildAction(new OSBasedAction() {
@Override
public void execute(Object... objects) {
setOpacity(0.5f);
}
}, SupportOSImpl.OPACITY);
initComponent();
initComponent(parent);
}
private void initComponent() {
private void initComponent(Frame parent) {
centerDialog = new JDialog(this);
centerDialog.setSize(new Dimension(482, 124));
centerDialog.setUndecorated(true);
GUICoreUtils.centerWindow(centerDialog);
centerDialog.setLocationRelativeTo(parent);
JPanel panel = new JPanel();
panel.setBorder(new UIProgressBorder(3, UIConstants.DEFAULT_BG_RULER, 14, 46, 47, 37, 47));
panel.setLayout(new BorderLayout(4, 15));

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

@ -73,6 +73,12 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver
textField.setValue(defaultValue);
}
public UISpinner(double minValue, double maxValue, double dierta, double defaultValue, boolean fillNegativeNumber) {
init(minValue, maxValue, dierta);
textField.setValue(defaultValue);
textField.canFillNegativeNumber(fillNegativeNumber);
}
protected void init(double minValue, double maxValue, double dierta) {
this.minValue = minValue;
this.maxValue = maxValue;

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

@ -153,4 +153,12 @@ public class UITableEditorPane<T> extends BasicPane {
tableModel.stopCellEditing();
}
/**
* 设置表头是否可以改变大小
*/
public void setHeaderResizing(boolean resizingAllowed){
editTable.getTableHeader().setResizingAllowed(resizingAllowed);
}
}

5
designer-base/src/main/java/com/fr/design/gui/itextfield/UIAutoCompletionField.java

@ -256,11 +256,10 @@ public class UIAutoCompletionField extends UITextField implements DocumentListen
*
*/
public void setText(String t) {
if (this.isOpen == true) {
if (!UIAutoCompletionField.this.isShowing()) {
boolean unavailable = !this.isEnabled() && !this.isEditable();
if (unavailable) {
return;
}
}
try {
Document doc = getDocument();
if (doc instanceof AbstractDocument) {

18
designer-base/src/main/java/com/fr/design/gui/itoolbar/UIToolbar.java

@ -2,9 +2,12 @@ package com.fr.design.gui.itoolbar;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.JTemplate;
import java.awt.Component;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JToolBar;
public class UIToolbar extends JToolBar {
@ -35,13 +38,18 @@ public class UIToolbar extends JToolBar {
}
}
public void refreshUIToolBar() {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (template != null) {
public Map<Component, Boolean> getComponentState() {
Map<Component, Boolean> componentState = new HashMap<>();
for (int i = 0; i < getComponentCount(); i++) {
Component component = getComponents()[i];
component.setEnabled(template.checkEnable());
Component component = getComponent(i);
componentState.put(component, component.isEnabled());
}
return componentState;
}
public static void resetComponentState(Map<Component, Boolean> componentState) {
for (Component component : componentState.keySet()) {
component.setEnabled(componentState.get(component));
}
}
}

2
designer-base/src/main/java/com/fr/design/gui/itree/filetree/EnvFileTree.java

@ -67,7 +67,7 @@ public class EnvFileTree extends RefreshableJTree {
String lock = node.getLock();
String name = node.getName();
if (treeNode.hasFullAuthority()) {
if (lock != null && !node.getUserID().equals(lock)) {
if (lock != null && !lock.equals(node.getUserID())) {
name = name + Toolkit.i18nText("Fine-Design_Basic_Template_Status_Locked", "(", ")");
}
this.setIcon(FileTreeIcon.getIcon(node));

23
designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileTreeIcon.java

@ -2,6 +2,7 @@ package com.fr.design.gui.itree.filetree;
import com.fr.base.BaseUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.icon.LocalFileIcon;
import com.fr.design.icon.LockIcon;
import com.fr.design.fun.ReportSupportedFileUIProvider;
import com.fr.file.filetree.FileNode;
@ -19,6 +20,8 @@ public class FileTreeIcon {
private FileTreeIcon() {
}
public static final String FILE_LOCKED_ICON_PATH = "/com/fr/design/images/gui/file_lock.png";
public static final Icon BLANK_IMAGE_ICON = BaseUtils.readIcon("/com/fr/design/images/gui/blank.gif");
public static final Icon FOLDER_IMAGE_ICON = BaseUtils.readIcon("/com/fr/design/images/gui/folder.png");
@ -48,6 +51,9 @@ public class FileTreeIcon {
public static final Icon MODERN_CHT_FILE_IMAGE_ICON =
BaseUtils.readIcon("/com/fr/design/images/gui/modern_style_cht_file_icon_16x16.png");
public static final Icon CPTX_ICON = BaseUtils.readIcon("/com/fr/nx/app/designer/cptx_file_icon.png");
public static final Icon CPTX_LOCKED_ICON = BaseUtils.readIcon("/com/fr/nx/app/designer/cptx_file_icon_locked.png");
public static final LockIcon FOLDER_LOCK_ICON =
new LockIcon(BaseUtils.readImage("/com/fr/design/images/gui/fold.png"));
public static final LockIcon FILE_LOCK_ICON =
@ -108,6 +114,7 @@ public class FileTreeIcon {
public final static int CPT_FILE = 11; //.cpt
public final static int FRM_FILE = 12; //.form .frm
public final static int CHT_FILE = 13; //.chart .cht
public final static int CPTX_FILE = 14; //.cptx
public static Icon getIcon(File file) {
return FileTreeIcon.getIcon(file, false);
@ -149,7 +156,7 @@ public class FileTreeIcon {
if (node.isDirectory()) {
return FileTreeIcon.FOLDER_IMAGE_ICON;
}
return getLocalFileIcon(path);
return getLocalFileIcon(path, isShowLock);
}
}
if (node.isDirectory()) {
@ -159,12 +166,12 @@ public class FileTreeIcon {
}
}
private static Icon getLocalFileIcon(String path) {
Icon icon = getExtraIcon(path, false);
private static Icon getLocalFileIcon(String path, boolean isShowLock) {
Icon icon = getExtraIcon(path, isShowLock);
if (icon != null) {
return icon;
}
return FileSystemView.getFileSystemView().getSystemIcon(new File(path));
return new LocalFileIcon(FileSystemView.getFileSystemView().getSystemIcon(new File(path)), isShowLock);
}
private static Icon getRemoteFileIcon(FileNode node, boolean isShowLock) {
@ -252,6 +259,12 @@ public class FileTreeIcon {
} else {
return FileTreeIcon.MODERN_CPT_FILE_IMAGE_ICON;
}
} else if (fileType == CPTX_FILE) {
if (isLocked) {
return FileTreeIcon.CPTX_LOCKED_ICON;
} else {
return FileTreeIcon.CPTX_ICON;
}
} else if (fileType == FRM_FILE) { //form frm
if (isLocked) {
return FileTreeIcon.FRM_FILE_LOCK_ICON;
@ -314,6 +327,8 @@ public class FileTreeIcon {
return BMP_FILE;
} else if (fileName.endsWith(".cpt")) {
return CPT_FILE;
} else if (fileName.endsWith(".cptx")) {
return CPTX_FILE;
} else if (fileName.endsWith(".frm") || fileName.endsWith(".form")) {
return FRM_FILE;
} else if (fileName.endsWith(".cht") || fileName.endsWith(".chart")) {

2
designer-base/src/main/java/com/fr/design/gui/itree/filetree/ReportletPane.java

@ -53,7 +53,7 @@ public class ReportletPane extends BasicPane {
centerPane.add(cardPane, BorderLayout.CENTER);
cardPane.setLayout(card = new CardLayout());
templateReportletTree = new TemplateFileTree();
IOFileNodeFilter filter = new IOFileNodeFilter(new String[]{".cpt", ".class", ".frm", ".form"});
IOFileNodeFilter filter = new IOFileNodeFilter(new String[]{".cpt", ".class", ".frm", ".form", ".cptx"});
templateReportletTree.setFileNodeFilter(filter);
cardPane.add(t_panel = new JScrollPane(templateReportletTree), "TEMPLATE");
classReportletTree = new ClassFileTree();

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

Loading…
Cancel
Save