Browse Source

Merge branch 'release/11.0' of https://code.fineres.com/scm/~levy.xie/design into newui

newui
Levy.Xie-解安森 5 months ago
parent
commit
3e19432256
  1. 3
      build.gradle
  2. 1
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  3. 61
      designer-base/src/main/java/com/fr/design/carton/CartonConstants.java
  4. 10
      designer-base/src/main/java/com/fr/design/carton/CartonThreadExecutorPool.java
  5. 147
      designer-base/src/main/java/com/fr/design/carton/CartonUtils.java
  6. 186
      designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java
  7. 4
      designer-base/src/main/java/com/fr/design/carton/FeedbackToolboxDialog.java
  8. 37
      designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java
  9. 174
      designer-base/src/main/java/com/fr/design/carton/latency/DesignerLatencyMetric.java
  10. 65
      designer-base/src/main/java/com/fr/design/carton/latency/LatencyLevel.java
  11. 1
      designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java
  12. 35
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleEditPane.java
  13. 2
      designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java
  14. 4
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  15. 2
      designer-base/src/main/java/com/fr/design/editlock/EditLockChangeChecker.java
  16. 4
      designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java
  17. 3
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java
  18. 1
      designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java
  19. 2
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  20. 16
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  21. 3
      designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStyleDefinePane.java
  22. 3
      designer-base/src/main/java/com/fr/design/mainframe/mobile/utils/DesignerUtils.java
  23. 9
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/MonitorAdvice.java
  24. 12
      designer-base/src/main/java/com/fr/design/style/background/image/ImagePreviewPane.java
  25. 1
      designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java
  26. 2
      designer-base/src/main/java/com/fr/design/utils/DesignUtils.java
  27. 14
      designer-base/src/main/java/com/fr/design/utils/gui/AdjustWorkBookDefaultStyleUtils.java
  28. 2
      designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java
  29. 6
      designer-base/src/main/java/com/fr/design/write/submit/DBManipulationPane.java
  30. 18
      designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/DesktopWidgetStyleEditPane.java
  31. 15
      designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditPane.java
  32. 3
      designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties
  33. 3
      designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties
  34. 5
      designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties
  35. 3
      designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties
  36. 3
      designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties
  37. 2
      designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java
  38. 2
      designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/AbstractChartTypePane.java
  39. 2
      designer-form/src/main/java/com/fr/design/widget/ui/designer/ComboBoxDefinePane.java
  40. 48
      designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java
  41. 2
      designer-form/src/main/java/com/fr/design/widgettheme/ParaEditorSettingPane.java
  42. 16
      designer-form/src/main/java/com/fr/design/widgettheme/processor/WidgetThemeCreatorPaneAdder.java
  43. 17
      designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java
  44. 7
      designer-realize/src/main/java/com/fr/design/present/PresentPane.java
  45. 1
      designer-realize/src/main/java/com/fr/design/widget/ui/MultiFileEditorPane.java
  46. 3
      designer-realize/src/main/java/com/fr/grid/selection/CellSelection.java
  47. 4
      designer-realize/src/main/java/com/fr/start/MainDesigner.java

3
build.gradle

@ -79,7 +79,8 @@ allprojects {
implementation 'com.fr.third:fine-third:' + frVersion
implementation 'com.fr.core:fine-core:' + frDevVersion
implementation 'com.fr.activator:fine-activator:' + frVersion
implementation 'com.fr.datasource:fine-datasource:' + frVersion
implementation 'com.fr.datasource:fine-datasource-api:4.1-SNAPSHOT'
implementation 'com.fr.datasource:fine-datasource-core:4.1-SNAPSHOT'
implementation 'com.fr.decision:fine-decision:' + frVersion
implementation 'com.fr.schedule:fine-schedule:' + frVersion
implementation 'com.fr.report:engine-report:' + frDevVersion

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

@ -1906,6 +1906,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
.init("jdkHome", (e) -> this.jdkHome = e.getElementValue())
.init("lastBBSTime", DesignerEnvManager.this::readLastBBSTime)
.init("lastBBSNewsTime", DesignerEnvManager.this::readLastBBSNewsTime)
.init("uuid", DesignerEnvManager.this::readUUID)
.init("ActivationKey", DesignerEnvManager.this::readActiveKey)
.init("status", DesignerEnvManager.this::readActiveStatus)
.init(CAS_PARAS, DesignerEnvManager.this::readHttpsParas)

61
designer-base/src/main/java/com/fr/design/carton/CartonConstants.java

@ -0,0 +1,61 @@
package com.fr.design.carton;
import com.fr.stable.ProductConstantsBase;
import com.fr.stable.StableUtils;
import java.text.SimpleDateFormat;
/**
* 卡顿常量类管理
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/07/04
*/
public class CartonConstants {
public static final String TIME = "time";
public static final String APPID = "appId";
public static final String USERID = "userId";
public static final String LOCAL = "local";
public static final String REMOTE = "remote";
public static final String OPERANDS_NUM = "operands";
public static final String DESIGN_METHOD = "designMethod";
public static final String DESIGNER_VERSION = "designerVersion";
public static final String DESIGNER_ID = "designerId";
public static final String EASY_CHECKER_FILE_NAME = "easy_check_log.csv";
public static final String TIMER_CHECKER_FILE_NAME = "timer_check_log.csv";
/**
* 开启间隔检测后两次检测的相隔时间ms
*/
public static final long CHECK_INTERVAL_MS = 100;
/**
* 最大的事件允许执行时间超过该时间则打印堆栈等相关信息
*/
public static final long UNREASONABLE_DISPATCH_DURATION_MS = 1500;
/**
* UI检测采样频率
*/
public static final int LATENCY_SAMPLING_FREQUENCY = 100;
/**
* 输出日志所在地址
*/
public static final String JOURNAL_FILE_PATH = StableUtils.pathJoin(ProductConstantsBase.getEnvHome(), "journal_log");
/**
* 日期事件格式
*/
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* Designer4Debug类名
*/
public static final String DEBUG_MAIN_CLASS_NAME = "com.fr.start.Designer4Debug";
}

10
designer-base/src/main/java/com/fr/design/carton/CartonThreadExecutorPool.java

@ -57,18 +57,18 @@ public class CartonThreadExecutorPool extends ThreadPoolExecutor {
private void examineHang() {
StackTraceElement[] currentStack = eventThread.getStackTrace();
if (lastReportedStack!=null && EventDispatchThreadHangMonitor.stacksEqual(currentStack, lastReportedStack)) {
if (lastReportedStack!=null && CartonUtils.stacksEqual(currentStack, lastReportedStack)) {
return;
}
lastReportedStack = currentStack;
String stackTrace = EventDispatchThreadHangMonitor.stackTraceToString(currentStack);
String stackTrace = CartonUtils.stackTraceToString(currentStack);
JSONObject jsonObject = new JSONObject();
jsonObject.put(Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), simpleDateFormatThreadSafe.format(System.currentTimeMillis()));
jsonObject.put(Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "swingWorker_" + hangNumber);
jsonObject.put(Toolkit.i18nText("Fine-Design_Basic_Carton_Duration_Task_Execute"), timeSoFar() + "ms");
jsonObject.put(Toolkit.i18nText("Fine-Design_Basic_Carton_Stack_Info"), stackTrace);
EventDispatchThreadHangMonitor.outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.TIMER_CHECK_FLAG);
EventDispatchThreadHangMonitor.checkForDeadlock();
CartonUtils.outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.TIMER_CHECK_FLAG);
CartonUtils.checkForDeadlock();
}
}
@ -129,7 +129,7 @@ public class CartonThreadExecutorPool extends ThreadPoolExecutor {
jsonObject.put(Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "swingWorker_" + concurrentHashMap.get(currentThreadId).hangNumber);
jsonObject.put(Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Start_Time"), simpleDateFormatThreadSafe.format(concurrentHashMap.get(currentThreadId).startTime));
jsonObject.put(Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), runTime + "ms");
EventDispatchThreadHangMonitor.outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.EASY_CHECK_FLAG);
CartonUtils.outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.EASY_CHECK_FLAG);
}
concurrentHashMap.remove(currentThreadId);

147
designer-base/src/main/java/com/fr/design/carton/CartonUtils.java

@ -0,0 +1,147 @@
package com.fr.design.carton;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.text.SimpleDateFormat;
import static com.fr.design.carton.CartonConstants.EASY_CHECKER_FILE_NAME;
import static com.fr.design.carton.CartonConstants.JOURNAL_FILE_PATH;
import static com.fr.design.carton.CartonConstants.TIMER_CHECKER_FILE_NAME;
/**
* 设计器卡顿业务工具类
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/07/10
*/
public class CartonUtils {
/**
* 堆栈元素输出为文本
*
* @param stackTrace 堆栈元素
* @return 文本
*/
public static String stackTraceToString(StackTraceElement[] stackTrace) {
StringBuilder result = new StringBuilder();
for (StackTraceElement stackTraceElement : stackTrace) {
String indentation = " ";
result.append("~").append(indentation).append(stackTraceElement);
}
return result.toString();
}
/**
* 命令行显示堆栈信息
*
* @param stackTrace 堆栈元素
* @return 文本
*/
public static String stackTraceToStringForConsole(StackTraceElement[] stackTrace) {
StringBuilder result = new StringBuilder();
for (StackTraceElement stackTraceElement : stackTrace) {
String indentation = " ";
result.append("\r\n").append(indentation).append(stackTraceElement);
}
return result.toString();
}
/**
* 堆栈是否一致
*
* @param a 堆栈A
* @param b 堆栈B
* @return 是否一致
*/
public static boolean stacksEqual(@NotNull StackTraceElement[] a, @NotNull StackTraceElement[] b) {
if (!ArrayUtils.isSameLength(a, b)) {
return false;
}
for (int i = 0; i < a.length; ++i) {
if (!a[i].equals(b[i])) {
return false;
}
}
return true;
}
/**
* 检查死锁
*/
public static void checkForDeadlock() {
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
long[] threadIds = threadBean.findDeadlockedThreads();
if (threadIds == null) {
return;
}
FineLoggerFactory.getLogger().warn("deadlock detected involving the following threads:");
ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadIds, Integer.MAX_VALUE);
for (ThreadInfo info : threadInfos) {
FineLoggerFactory.getLogger().warn("Thread # {} {} ( {} ) waiting on {} held by {} {}", info.getThreadId(), info.getThreadName(),
info.getThreadState(), info.getLockName(), info.getLockOwnerName(), CartonUtils.stackTraceToStringForConsole(info.getStackTrace()));
}
}
/**
* 输出卡顿日志
*
* @param message 文本信息
* @param flag 类型true时为简单检查false时为定时检查
*/
public static void outPutJournalLog(String message, int flag) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String date = simpleDateFormat.format(System.currentTimeMillis());
String filename = flag == SwitchForSwingChecker.EASY_CHECK_FLAG ? EASY_CHECKER_FILE_NAME : TIMER_CHECKER_FILE_NAME;
String[] split = date.split("-");
int month = StringUtils.isEmpty(split[1]) ? -1 : Integer.parseInt(split[1]);
String dirPath = StableUtils.pathJoin(JOURNAL_FILE_PATH, split[0], "month-" + month, date);
File dirFile = new File(dirPath);
File file = new File(StableUtils.pathJoin(dirPath, filename));
try {
if (!file.exists()) {
if (!dirFile.exists()) {
dirFile.mkdirs();
}
file.createNewFile();
}
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file, true))) {
String outputMessage = message.replaceAll("~", "\r\n") + "," + "\r\n";
bufferedWriter.write(outputMessage);
}
} catch (IOException e) {
FineLoggerFactory.getLogger().error("output fail", e);
}
}
/**
* 用于判断是不是特定的堆栈
*/
public static boolean stackTraceElementIs(StackTraceElement e, String className, String methodName, boolean isNative) {
return e.getClassName().equals(className) && e.getMethodName().equals(methodName) && e.isNativeMethod() == isNative;
}
/**
* 用于判断某个堆栈是否在等待另一个事件
* 取当前堆栈前三层判断是是不是匹配等待堆栈的格式
*/
public static boolean isWaitingForNextEvent(StackTraceElement[] currentStack) {
return currentStack != null && currentStack.length >= 3 &&
stackTraceElementIs(currentStack[0], "java.lang.Object", "wait", true)
&& stackTraceElementIs(currentStack[1], "java.lang.Object", "wait", false)
&& stackTraceElementIs(currentStack[2], "java.awt.EventQueue", "getNextEvent", false);
}
}

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

@ -1,34 +1,26 @@
package com.fr.design.carton;
import com.fr.concurrent.FineExecutors;
import com.fr.design.carton.latency.DesignerLatencyMetric;
import com.fr.design.ui.util.UIUtil;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.ProductConstantsBase;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.SwingUtilities;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.AWTEvent;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static com.fr.design.carton.CartonConstants.CHECK_INTERVAL_MS;
import static com.fr.design.carton.CartonConstants.DATE_FORMAT;
import static com.fr.design.carton.CartonConstants.LATENCY_SAMPLING_FREQUENCY;
import static com.fr.design.carton.CartonConstants.UNREASONABLE_DISPATCH_DURATION_MS;
/**
* 参考自git swinghelper
* 用于卡顿检测
@ -38,31 +30,16 @@ import java.util.concurrent.TimeUnit;
*/
public final class EventDispatchThreadHangMonitor extends EventQueue {
/**
* 日期事件格式
*/
private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static final EventDispatchThreadHangMonitor INSTANCE = new EventDispatchThreadHangMonitor();
/**
* 一个timer
*/
private Timer timer;
/**
* 开启间隔检测后两次检测的相隔时间ms
*/
private static final long CHECK_INTERVAL_MS = 100;
/**
* 最大的事件允许执行时间超过该时间则打印堆栈等相关信息
*/
private static final long UNREASONABLE_DISPATCH_DURATION_MS = 1500;
/**
* 事件唯一编码用于方便日志的查看
*/
private static long hangCount = 0;
/**
* 输出日志所在地址
*/
private static final String JOURNAL_FILE_PATH = StableUtils.pathJoin(ProductConstantsBase.getEnvHome(), "journal_log");
private static long hangCount = 0;
/**
* 类似于一个开关当该值为默认的false启动时定时任务在窗口开启前都不会对执行的事件进行检查
*/
@ -103,43 +80,6 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
return hangCount++;
}
/**
* @param a can not be null
* @param b can not be null
* @return
*/
public static boolean stacksEqual(@NotNull StackTraceElement[] a, @NotNull StackTraceElement[] b) {
if (!ArrayUtils.isSameLength(a, b)) {
return false;
}
for (int i = 0; i < a.length; ++i) {
if (!a[i].equals(b[i])) {
return false;
}
}
return true;
}
/**
* 用于判断是不是特定的堆栈
*/
public static boolean stackTraceElementIs(StackTraceElement e, String className, String methodName, boolean isNative) {
return e.getClassName().equals(className) && e.getMethodName().equals(methodName) && e.isNativeMethod() == isNative;
}
/**
* 用于判断某个堆栈是否在等待另一个事件
* 取当前堆栈前三层判断是是不是匹配等待堆栈的格式
*/
public static boolean isWaitingForNextEvent(StackTraceElement[] currentStack) {
return currentStack != null && currentStack.length >= 3 &&
stackTraceElementIs(currentStack[0], "java.lang.Object", "wait", true)
&& stackTraceElementIs(currentStack[1], "java.lang.Object", "wait", false)
&& stackTraceElementIs(currentStack[2], "java.awt.EventQueue", "getNextEvent", false);
}
/**
* event事件的包装类
*/
@ -153,11 +93,13 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
//事件开始的时间
private final long startDispatchTimeMillis = System.currentTimeMillis();
//事件编号
private long hangNumber;
private final long hangNumber;
//构造函数,给当前对象赋一个递增的唯一编号
public DispatchInfo() {
public DispatchInfo() {
hangNumber = getHangCount();
}
//定时调度任务检测的入口,如果执行时间大于设定的值就进入examineHang()方法
public void checkForHang() {
if (timeSoFar() > UNREASONABLE_DISPATCH_DURATION_MS) {
@ -168,36 +110,38 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
private void examineHang() {
//获取执行线程的当前堆栈
StackTraceElement[] currentStack = eventDispatchThread.getStackTrace();
if (isWaitingForNextEvent(currentStack)) {
if (CartonUtils.isWaitingForNextEvent(currentStack)) {
return;
}
//某个事件执行时间很长,定时处理时可能会连续打很多个堆栈,对同一个事件的相同堆栈只打一次
if (lastReportedStack !=null && stacksEqual(lastReportedStack, currentStack)) {
if (lastReportedStack != null && CartonUtils.stacksEqual(lastReportedStack, currentStack)) {
return;
}
String stackTrace = stackTraceToString(currentStack);
String stackTrace = CartonUtils.stackTraceToString(currentStack);
lastReportedStack = currentStack;
JSONObject jsonObject = new JSONObject();
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), simpleDateFormat.format(System.currentTimeMillis()));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), DATE_FORMAT.format(System.currentTimeMillis()));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "eventQueue_" + hangNumber);
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Duration_Task_Execute"), timeSoFar() + "ms");
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Stack_Info"), stackTrace);
outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.TIMER_CHECK_FLAG);
checkForDeadlock();
CartonUtils.outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.TIMER_CHECK_FLAG);
CartonUtils.checkForDeadlock();
}
//记录连续运行了多长时间
private long timeSoFar() {
public long timeSoFar() {
return (System.currentTimeMillis() - lastDispatchTimeMillis);
}
//记录一个事件从被分发到结束的总运行时间
private long totalTime() {
public long totalTime() {
return (System.currentTimeMillis() - startDispatchTimeMillis);
}
//事件处理完后的时间判断
public void dispose() {
if (timeSoFar() > UNREASONABLE_DISPATCH_DURATION_MS) {
exportCartonLog(true);
} else if (lastReportedStack != null){
} else if (lastReportedStack != null) {
exportCartonLog(false);
}
}
@ -208,40 +152,15 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
*/
private void exportCartonLog(boolean flag) {
JSONObject jsonObject = new JSONObject();
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), simpleDateFormat.format(System.currentTimeMillis()));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), DATE_FORMAT.format(System.currentTimeMillis()));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "eventQueue_" + hangNumber);
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Start_Time"), simpleDateFormat.format(startDispatchTimeMillis));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Start_Time"), DATE_FORMAT.format(startDispatchTimeMillis));
if (flag) {
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), timeSoFar() + "ms");
} else {
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), totalTime() + "ms");
}
outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.EASY_CHECK_FLAG);
}
}
public static void outPutJournalLog(String message, int flag) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String date = simpleDateFormat.format(System.currentTimeMillis());
String filename = flag == SwitchForSwingChecker.EASY_CHECK_FLAG ? SwitchForSwingChecker.EASY_CHECKER_FILE_NAME: SwitchForSwingChecker.TIMER_CHECKER_FILE_NAME;
String[] split = date.split("-");
int month = StringUtils.isEmpty(split[1]) ? -1 : Integer.parseInt(split[1]);
String dirPath = StableUtils.pathJoin(JOURNAL_FILE_PATH, split[0], "month-" + month, date);
File dirFile = new File(dirPath);
File file = new File( StableUtils.pathJoin(dirPath, filename));
try {
if (!file.exists()) {
if (!dirFile.exists()) {
dirFile.mkdirs();
}
file.createNewFile();
}
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file, true));
String outputMessage = new StringBuilder(message.replaceAll("~", "\r\n")).append(",").append("\r\n").toString();
bufferedWriter.write(outputMessage);
bufferedWriter.close();
} catch (IOException e) {
FineLoggerFactory.getLogger().error("output fail", e);
CartonUtils.outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.EASY_CHECK_FLAG);
}
}
@ -325,8 +244,7 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
*/
@Override
protected void dispatchEvent(AWTEvent event) {
//如果两个开关都没开,那就不走重写方法了
if (!isEasyWitch() && !isTimerWitch()) {
if (!useCustomEventQueue()) {
super.dispatchEvent(event);
} else {
try {
@ -342,6 +260,18 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
}
}
private boolean useCustomEventQueue() {
// 开启性能监控或开启卡顿工具箱,则走自定义的EventQueue
return SwitchForSwingChecker.isLatencyMonitoring() ||
isEasyWitch() || isTimerWitch();
}
private boolean needSampling() {
// UI性能采样逻辑:开启采样并且符合采样频次
return SwitchForSwingChecker.isLatencyMonitoring()
&& (hangCount % LATENCY_SAMPLING_FREQUENCY == 0);
}
/**
* Starts tracking a dispatch.
*/
@ -357,6 +287,9 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
private synchronized void postDispatchEvent() {
synchronized (dispatches) {
DispatchInfo justFinishedDispatch = dispatches.removeLast();
if (needSampling()) {
DesignerLatencyMetric.getInstance().record(justFinishedDispatch.timeSoFar());
}
if (isEasyWitch()) {
justFinishedDispatch.dispose();
}
@ -370,39 +303,4 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
}
}
/**
* 检查死锁
*/
public static void checkForDeadlock() {
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
long[] threadIds = threadBean.findDeadlockedThreads();
if (threadIds == null) {
return;
}
FineLoggerFactory.getLogger().warn("deadlock detected involving the following threads:");
ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadIds, Integer.MAX_VALUE);
for (ThreadInfo info : threadInfos) {
FineLoggerFactory.getLogger().warn("Thread # {} {} ( {} ) waiting on {} held by {} {}", info.getThreadId(), info.getThreadName(),
info.getThreadState(), info.getLockName(), info.getLockOwnerName(), stackTraceToStringForConsole(info.getStackTrace()));
}
}
public static String stackTraceToString(StackTraceElement[] stackTrace) {
StringBuilder result = new StringBuilder();
for (StackTraceElement stackTraceElement : stackTrace) {
String indentation = " ";
result.append("~").append(indentation).append(stackTraceElement);
}
return result.toString();
}
public static String stackTraceToStringForConsole(StackTraceElement[] stackTrace) {
StringBuilder result = new StringBuilder();
for (StackTraceElement stackTraceElement : stackTrace) {
String indentation = " ";
result.append("\r\n").append(indentation).append(stackTraceElement);
}
return result.toString();
}
}

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

@ -50,6 +50,8 @@ import java.text.ParseException;
import java.util.List;
import java.util.Objects;
import static com.fr.design.carton.CartonConstants.JOURNAL_FILE_PATH;
public class FeedbackToolboxDialog extends JDialog {
private UIDatePicker uiDatePicker;
@ -148,7 +150,7 @@ public class FeedbackToolboxDialog extends JDialog {
//selectDate 2002-03-09例子
String[] split = selectDate.split("-");
int month = Integer.parseInt(split[1]);
String sourceFilePath = StableUtils.pathJoin(SwitchForSwingChecker.JOURNAL_FILE_PATH, split[0], "month-" + month, selectDate);
String sourceFilePath = StableUtils.pathJoin(JOURNAL_FILE_PATH, split[0], "month-" + month, selectDate);
File sourceFile = new File(sourceFilePath);
if (sourceFile.exists()) {
exportCartonLog(sourceFile, path, sourceFilePath);

37
designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java

@ -7,7 +7,6 @@ import com.fr.json.JSON;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ProductConstantsBase;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.xml.XMLPrintWriter;
@ -29,11 +28,13 @@ import java.util.Map;
import java.util.Date;
import java.util.Calendar;
import static com.fr.design.carton.CartonConstants.DEBUG_MAIN_CLASS_NAME;
import static com.fr.design.carton.CartonConstants.EASY_CHECKER_FILE_NAME;
import static com.fr.design.carton.CartonConstants.JOURNAL_FILE_PATH;
import static com.fr.design.carton.CartonConstants.TIMER_CHECKER_FILE_NAME;
public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
/**
* Designer4Debug类名
*/
private static final String DEBUG_MAIN_CLASS_NAME = "com.fr.start.Designer4Debug";
/**
* XML标签
*/
@ -46,18 +47,16 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
* 简单记录事件执行时间的开关
*/
private static boolean easyChecker = false;
/**
* UI性能监控埋点的开关
*/
private static boolean latencyMonitor = true;
/**
* 一个标识位用于区分耗时任务时长检测(简单检测)和timer检测
*/
public static final int TIMER_CHECK_FLAG = 0;
public static final int EASY_CHECK_FLAG = 1;
/**
* 日志存储地址
*/
public static final String JOURNAL_FILE_PATH = StableUtils.pathJoin(ProductConstantsBase.getEnvHome(), "journal_log");
public static final String EASY_CHECKER_FILE_NAME = "easy_check_log.csv";
public static final String TIMER_CHECKER_FILE_NAME = "timer_check_log.csv";
public static boolean isCheckerTimerSwitch() {
return checkerTimerSwitch;
}
@ -66,6 +65,13 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
return easyChecker;
}
/**
* 是否开启UI性能检测
*/
public static boolean isLatencyMonitoring() {
return latencyMonitor;
}
public static volatile SwitchForSwingChecker switchForSwingChecker = new SwitchForSwingChecker();
public static SwitchForSwingChecker getInstance() {
@ -137,7 +143,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
}
/**
*处理文件
* 处理文件
* 一共四种情况
* 两个文件都不存在
* 文件一存在文件二不存在
@ -224,7 +230,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
/**
* /埋点方法上传卡顿信息入口
date为 2022-09-08的格式
* date为 2022-09-08的格式
*/
public static List<CartonUploadMessage> uploadJournalLog(Date dateTime) {
List<CartonUploadMessage> res = new ArrayList<>();
@ -245,9 +251,8 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
/**
* 初始化监控任务主要是替换EventQueue以及SwingWorker执行任务的线程池
*
*/
public static void initThreadMonitoring () {
public static void initThreadMonitoring() {
String mainClass = System.getProperty("sun.java.command");
//判断一下,如果是以Designer4Debug启动,就不注册代码,不然会覆盖掉SwingExplorer,导致其无法使用
if (!StringUtils.equals(mainClass, DEBUG_MAIN_CLASS_NAME)) {
@ -293,6 +298,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
if (reader.isAttr()) {
checkerTimerSwitch = reader.getAttrAsBoolean("checkerTimerSwitch", false);
easyChecker = reader.getAttrAsBoolean("easyChecker", false);
latencyMonitor = reader.getAttrAsBoolean("latencyMonitor", true);
}
try {
initSwitchChecker();
@ -306,6 +312,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
writer.startTAG(XML_TAG);
writer.attr("checkerTimerSwitch", checkerTimerSwitch);
writer.attr("easyChecker", easyChecker);
writer.attr("latencyMonitor", latencyMonitor);
writer.end();
}

174
designer-base/src/main/java/com/fr/design/carton/latency/DesignerLatencyMetric.java

@ -0,0 +1,174 @@
package com.fr.design.carton.latency;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.config.MarketConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.carton.SwitchForSwingChecker;
import com.fr.design.mainframe.SiteCenterToken;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralUtils;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static com.fr.design.carton.CartonConstants.APPID;
import static com.fr.design.carton.CartonConstants.DESIGNER_ID;
import static com.fr.design.carton.CartonConstants.DESIGNER_VERSION;
import static com.fr.design.carton.CartonConstants.DESIGN_METHOD;
import static com.fr.design.carton.CartonConstants.LOCAL;
import static com.fr.design.carton.CartonConstants.OPERANDS_NUM;
import static com.fr.design.carton.CartonConstants.REMOTE;
import static com.fr.design.carton.CartonConstants.TIME;
import static com.fr.design.carton.CartonConstants.USERID;
/**
* 设计器延迟时间记录Metric
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/07/01
*/
public class DesignerLatencyMetric {
private String latencyUrl;
private ExecutorService executorService;
private ScheduledExecutorService scheduler;
private static final Map<LatencyLevel, AtomicInteger> LATENCY_CONTAINER = new ConcurrentHashMap<>();
private static final String DEFAULT_MONITOR_URL = "https://cloud.fanruan.com/api/monitor/";
private static final String LATENCY_TABLE_SUFFIX = "record_of_designer_latency/single";
private final static class InstanceHolder {
static final DesignerLatencyMetric INSTANCE = new DesignerLatencyMetric();
}
/**
* 获取单例
*/
public static DesignerLatencyMetric getInstance() {
return DesignerLatencyMetric.InstanceHolder.INSTANCE;
}
private DesignerLatencyMetric() {
}
/**
* 启动
*/
public void start() {
if (SwitchForSwingChecker.isLatencyMonitoring()) {
// 初始化容器
initializeContainer();
// 启动异步性能记录线程池
executorService = Executors.newFixedThreadPool(8);
// 启动定时埋点
this.scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("LatencyMetricWorker"));
this.scheduler.scheduleWithFixedDelay(this::collectAndSubmit, 60, 60, TimeUnit.MINUTES);
// 注册设计器工作目录切换事件监听
EventDispatcher.listen(WorkspaceEvent.BeforeSwitch, new Listener<Workspace>() {
@Override
public void on(Event event, Workspace param) {
collectAndSubmit();
}
});
FineLoggerFactory.getLogger().info("[Latency] designer latency metric started.");
}
}
/**
* 关闭
*/
public void stop() {
if (SwitchForSwingChecker.isLatencyMonitoring()) {
if (this.executorService != null) {
this.executorService.shutdown();
}
if (this.scheduler != null) {
this.scheduler.shutdown();
}
collectAndSubmit();
FineLoggerFactory.getLogger().info("[Latency] designer latency metric stopped.");
}
}
private String getLatencyUrl() {
if (StringUtils.isEmpty(latencyUrl)) {
String monitorEntry = CloudCenter.getInstance().acquireUrlByKind("cloud.monitor.api.entrypoint");
latencyUrl = (StringUtils.isNotEmpty(monitorEntry) ? monitorEntry : DEFAULT_MONITOR_URL)
+ LATENCY_TABLE_SUFFIX;
}
return latencyUrl;
}
private void initializeContainer() {
for (LatencyLevel level : LatencyLevel.values()) {
LATENCY_CONTAINER.put(level, new AtomicInteger());
}
}
private void resetContainer() {
LATENCY_CONTAINER.values().forEach(count -> count.set(0));
}
/**
* 记录性能信息
*/
public void record(long cost) {
executorService.submit(() -> {
try {
LatencyLevel level = LatencyLevel.measure(cost);
LATENCY_CONTAINER.computeIfAbsent(level, k -> new AtomicInteger()).incrementAndGet();
} catch (Throwable ignore) {
// 记录失败不影响业务
}
});
}
/**
* 汇总并提交性能监控埋点
*/
public void collectAndSubmit() {
Map<String, Object> para = new HashMap<>();
para.put("token", SiteCenterToken.generateToken());
para.put("content", collect());
try {
HttpToolbox.post(getLatencyUrl(), para);
FineLoggerFactory.getLogger().debug("[Latency] submit latency log to cloud.");
} catch (Throwable t) {
FineLoggerFactory.getLogger().debug(t,"[Latency] failed to submit latency log to cloud.");
}
resetContainer();
}
private JSONObject collect() {
JSONObject info = new JSONObject();
info.put(TIME, System.currentTimeMillis());
info.put(APPID, MarketConfig.getInstance().getCloudOperationMaintenanceId());
info.put(USERID, MarketConfig.getInstance().getBbsUid());
info.put(DESIGNER_ID, DesignerEnvManager.getEnvManager().getUUID());
info.put(DESIGNER_VERSION, GeneralUtils.getVersion());
info.put(DESIGN_METHOD, WorkContext.getCurrent().isLocal() ? LOCAL : REMOTE);
info.put(OPERANDS_NUM, LATENCY_CONTAINER.values().stream().mapToInt(AtomicInteger::get).sum());
for (Map.Entry<LatencyLevel, AtomicInteger> entry : LATENCY_CONTAINER.entrySet()) {
info.put(entry.getKey().getMark(), entry.getValue().get());
}
return info;
}
}

65
designer-base/src/main/java/com/fr/design/carton/latency/LatencyLevel.java

@ -0,0 +1,65 @@
package com.fr.design.carton.latency;
/**
* 卡顿等级
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/07/01
*/
public enum LatencyLevel {
// 非常流畅
FLASH(0, 50, "waitNum1"),
// 流畅
SMOOTH(50, 100, "waitNum2"),
// 轻微卡顿
SLIGHT(100, 200, "waitNum3"),
// 中等卡顿
MILD(200, 500, "waitNum4"),
// 明显卡顿
NOTICEABLE(500, 1000, "waitNum5"),
// 严重卡顿
SERVE(1000, 2000, "waitNum6"),
// 非常严重卡顿
EXTREME(2000, 3000, "waitNum7"),
// 极度卡顿
CRITICAL(3000, Long.MAX_VALUE, "waitNum8");
final long start;
final long end;
final String mark;
LatencyLevel(long start, long end, String mark) {
this.start = start;
this.end = end;
this.mark = mark;
}
public long getStart() {
return start;
}
public long getEnd() {
return end;
}
public String getMark() {
return mark;
}
/**
* 评估当前卡顿等级
*
* @param cost UI-EventQueue响应耗时
* @return 卡顿等级
*/
public static LatencyLevel measure(long cost) {
for (LatencyLevel level : LatencyLevel.values()) {
if (cost >= level.getStart() && cost < level.getEnd()) {
return level;
}
}
return CRITICAL;
}
}

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

@ -355,7 +355,6 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
*/
@Override
public void refresh() {
DBUtils.refreshDatabase();
String schema = StringUtils.isEmpty(schemaBox.getSelectedItem()) ? null : schemaBox.getSelectedItem();
DataCoreUtils.refreshTables(getConnection(), TableProcedure.TABLE, schema);
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Refresh_Successfully") + "!", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Refresh_Database"),

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

@ -1,5 +1,7 @@
package com.fr.design.data.datapane.preview.desensitization.view.rule;
import com.fine.swing.ui.layout.Column;
import com.fine.swing.ui.layout.Layouts;
import com.fr.data.desensitize.rule.base.DesensitizationCondition;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource;
@ -28,6 +30,10 @@ import java.awt.event.FocusListener;
import java.util.Arrays;
import java.util.Set;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* 脱敏规则编辑页
*
@ -157,26 +163,29 @@ public class DesensitizationRuleEditPane extends BasicBeanPane<DesensitizationRu
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane();
cardLayout = new CardLayout();
ruleConditionPane = new JPanel(cardLayout);
// 字符替换
JPanel characterReplacePane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane();
UILabel retainFrontLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_One") + StringUtils.BLANK);
retainFrontTextField = new UINumberField(5);
retainFrontTextField.addFocusListener(retainFrontListener);
UILabel retainBackLabel = new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Two") + StringUtils.BLANK);
retainBackTextField = new UINumberField(5);
retainBackTextField.addFocusListener(retainBackListener);
UILabel replaceLabel = new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Three") + StringUtils.BLANK);
firstSymbolTextField = new UITextField(10);
firstSymbolTextField.addFocusListener(firstSymbolListener);
characterReplacePane.add(retainFrontLabel);
characterReplacePane.add(retainFrontTextField);
characterReplacePane.add(retainBackLabel);
characterReplacePane.add(retainBackTextField);
characterReplacePane.add(replaceLabel);
characterReplacePane.add(firstSymbolTextField);
// 字符替换
Layouts.Cell<Column> column = column(
4,
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_One") + StringUtils.BLANK)),
cell(retainFrontTextField),
cell(new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Two") + StringUtils.BLANK)),
cell(retainBackTextField),
cell(new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Four") + StringUtils.BLANK))
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Three") + StringUtils.BLANK)),
cell(firstSymbolTextField)
)
);
// 整体替换
JPanel characterAllReplacePane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane();
UILabel allReplaceLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_All_Character_Replace_By") + StringUtils.BLANK);
@ -186,7 +195,7 @@ public class DesensitizationRuleEditPane extends BasicBeanPane<DesensitizationRu
characterAllReplacePane.add(allReplaceLabel);
characterAllReplacePane.add(secondSymbolTextField);
ruleConditionPane.add(characterReplacePane, DesensitizationRuleType.CHARACTER_REPLACE.getRuleTypeName());
ruleConditionPane.add(column.getComponent(), DesensitizationRuleType.CHARACTER_REPLACE.getRuleTypeName());
ruleConditionPane.add(characterAllReplacePane, DesensitizationRuleType.ALL_CHARACTERS_REPLACE.getRuleTypeName());
// 初始化状态为字符替换
switchRuleConditionPane(DesensitizationRuleType.CHARACTER_REPLACE);

2
designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java

@ -252,7 +252,7 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener {
private static Parameter[] processParameters(DBTableData tableData, Calculator calculator) {
ParameterProvider[] parameters = tableData.getParameters();
if (parameters == null || parameters.length == 0) {
tableData.setParameters(ParameterHelper.analyze4Parameters(tableData.getQuery(), false));
tableData.setParameters(ParameterHelper.analyze4Parameters(tableData.getQueryWithoutComments(), false));
return new Parameter[0];
}
return Parameter.providers2Parameter(Calculator.processParameters(calculator, parameters));

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

@ -304,8 +304,8 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> implemen
private void refreshParameters() {
String[] paramTexts = new String[2];
paramTexts[0] = SqlUtils.tryPureSqlText(this.sqlTextPane.getText());
paramTexts[1] = SqlUtils.tryPureSqlText(this.pageQuery);
paramTexts[0] = SqlUtils.clearSqlComments(this.sqlTextPane.getText());
paramTexts[1] = SqlUtils.clearSqlComments(this.pageQuery);
List<ParameterProvider> existParameterList = this.editorPane.update();
Parameter[] ps = (existParameterList == null) ? new Parameter[0] : existParameterList.toArray(new Parameter[0]);

2
designer-base/src/main/java/com/fr/design/editlock/EditLockChangeChecker.java

@ -32,7 +32,7 @@ public abstract class EditLockChangeChecker {
*/
public void start() {
this.scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("EditLockChangeChecker"));
this.scheduler.scheduleAtFixedRate(new Runnable() {
this.scheduler.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
// 判断是否为远程设计环境

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

@ -422,7 +422,9 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi
dialog.setVisible(true);
DesignerFrameFileDealerPane.getInstance().getSelectedOperation().refresh();
LocateAction.gotoEditingTemplateLeaf(targetFile);
SwingUtilities.invokeLater(() -> {
LocateAction.gotoEditingTemplateLeaf(targetFile);
});
}
}

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

@ -121,6 +121,9 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li
for (int i = 0, size = widget.getListenerSize(); i < size; i++) {
Listener listener = widget.getListener(i);
if (!listener.isDefault()) {
if (StringUtils.isEmpty(listener.getEventName())) {
continue;
}
String eventName = switchLang(listener.getEventName()) + (nameObjectList.size() + 1);
NameObject nameObject = new NameObject(eventName, listener);
nameObjectList.add(nameObject);

1
designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java

@ -77,6 +77,7 @@ public class DesignerMessageHelper {
String url = CloudCenter.getInstance().acquireUrlByKind("designer.message.push", "https://market.fanruan.com/api/v1/message/designer");
Map<String, String> params = new HashMap<>();
params.put("designerId", DesignerEnvManager.getEnvManager().getUUID());
params.put("lang", DesignerEnvManager.getEnvManager().getLanguage().toString());
String result = HttpToolbox.post(url, params);
JSONObject response = JSONFactory.createJSON(JSON.OBJECT, result);
String status = response.optString(STATUS);

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

@ -11,6 +11,7 @@ import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.core.ActionFactory;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.base.mode.DesignerMode;
import com.fr.design.carton.latency.DesignerLatencyMetric;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
@ -1161,6 +1162,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
});
DesignerEnvManager.getEnvManager().saveXMLFile();
DesignerLatencyMetric.getInstance().stop();
}
/**

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

@ -7,6 +7,7 @@ import com.fr.base.extension.FileExtension;
import com.fr.base.info.TemplateSaveInfoContext;
import com.fr.base.io.BaseBook;
import com.fr.base.iofile.attr.DesignBanCopyAttrMark;
import com.fr.base.iofile.attr.ForkIdAttrMark;
import com.fr.base.iofile.attr.TemplateIdAttrMark;
import com.fr.base.iofile.attr.TemplateThemeAttrMark;
import com.fr.base.svg.IconUtils;
@ -342,6 +343,18 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
generateTemplateId();
}
/**
* 如果没有 forkId, 则计算 forkId
* 要求在 templateId, 创建后执行
*/
protected void computeForkIdIfAbsent() {
ForkIdAttrMark forkIdAttrMark = this.template.getAttrMark(ForkIdAttrMark.XML_TAG);
if (forkIdAttrMark == null || StringUtils.isEmpty(forkIdAttrMark.getForkId())) {
this.template.addAttrMark(new ForkIdAttrMark(this.template.getTemplateID()));
}
}
/**
* 收集图表信息
*/
@ -970,6 +983,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
// 在保存之前,初始化 templateID
generateNewTemplateIdForSaveAs();
computeForkIdIfAbsent();
this.editingFILE = editingFILE;
TemplateSaveInfoContext.getInstance().startCollect(template);
@ -1862,6 +1876,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
// 在保存之前,初始化 templateID
generateNewTemplateIdForSaveAs();
computeForkIdIfAbsent();
this.editingFILE = editingFILE;
boolean result = this.saveToNewRealFile(oldName);
if (result) {

3
designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStyleDefinePane.java

@ -8,6 +8,7 @@ import com.fr.design.gui.icombobox.LineComboBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
@ -210,7 +211,7 @@ public class MobileStyleDefinePane extends BasicBeanPane<MobileStyle> {
private UILabel createConfigLabel(String title) {
UILabel label = new UILabel(title + ":", UILabel.RIGHT);
label.setPreferredSize(new Dimension(75, 20));
label.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane.configLabel"));
return label;
}

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

@ -4,6 +4,7 @@ import com.fr.design.constants.LayoutConstants;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.widget.UITitleSplitLine;
import com.fr.design.style.color.NewColorSelectBox;
@ -44,7 +45,7 @@ public class DesignerUtils {
public static UILabel createConfigLabel(String title) {
UILabel label = new UILabel(title, UILabel.RIGHT);
label.setPreferredSize(new Dimension(100, 20));
label.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.mainframe.mobile.utils.DesignerUtils.configLabel"));
return label;
}

9
designer-base/src/main/java/com/fr/design/record/analyzer/advice/MonitorAdvice.java

@ -88,8 +88,9 @@ public class MonitorAdvice implements DesignerAnalyzerAdvice {
MessageRecorderFactory.getInstance().syncSubmit(message);
}
}
} catch (Exception ignore) {
} catch (Exception ex) {
//埋点信息入库失败应该不能影响业务流程
FineLoggerFactory.getLogger().debug("[Metric] failed to log message.", ex);
} finally {
sessionBinder.detachSession();
}
@ -113,7 +114,11 @@ public class MonitorAdvice implements DesignerAnalyzerAdvice {
}
public static void recordSQLDetail(String uuid) {
DBMeterFactory.getMeter().submit(uuid);
try {
DBMeterFactory.getMeter().submit(uuid);
} catch (Exception e) {
FineLoggerFactory.getLogger().debug("[Metric] failed to log sql detail.", e);
}
}
public static void recordSQL(Compute once, MeasureObject measureObject) {

12
designer-base/src/main/java/com/fr/design/style/background/image/ImagePreviewPane.java

@ -9,6 +9,7 @@ import com.fr.base.Style;
import com.fr.design.gui.iscrollbar.UIScrollBar;
import com.fr.general.ImageWithSuffix;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.CoreGraphHelper;
import javax.swing.JComponent;
@ -92,9 +93,14 @@ public class ImagePreviewPane extends JComponent implements Scrollable, ImagePre
isLoading = false;
CoreGraphHelper.waitForImage(image);
imageWidth = image.getWidth(null);
imageHeight = image.getHeight(null);
if (image.getFineImage() != null && image.getImage() != null) {
try {
imageWidth = image.getWidth(null);
imageHeight = image.getHeight(null);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
this.setToolTipText("Image Size: " + imageWidth + "x" + imageHeight + "px");
}
fireChangeListener();

1
designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java

@ -13,6 +13,7 @@ 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.gui.itextfield.UITextField;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;

2
designer-base/src/main/java/com/fr/design/utils/DesignUtils.java

@ -329,7 +329,7 @@ public class DesignUtils {
@Override
protected FRFont compute() {
FRFont guiFRFont;
Locale defaultLocale = Locale.getDefault();
Locale defaultLocale = GeneralContext.getLocale();
// JDK9 之后宋体在计算label中字母的空间上出现问题,暂时先用雅黑兼容,以后再统一字体
if (StableUtils.getMajorJavaVersion() >= 9 && OperatingSystem.isWindows()) {
guiFRFont = getNamedFont("Microsoft YaHei");

14
designer-base/src/main/java/com/fr/design/utils/gui/AdjustWorkBookDefaultStyleUtils.java

@ -18,13 +18,23 @@ public class AdjustWorkBookDefaultStyleUtils {
private static final Color TEMPLATE_BACKGROUND = new Color(16, 11, 43);
private static final Color CELL_ELEMENT_BORDER = new Color(110, 110, 110);
private static final Color CELL_ELEMENT_FONT_FOREGROUND = Color.WHITE;
private static final Color CELL_ELEMENT_FONT_FOREGROUND_4_LIGHT_THEME = Color.BLACK;
private static Color currentStoryBack = null;
private static boolean isDarkTheme = true;
public static void setCurrentStoryBack(Color color) {
currentStoryBack = color;
}
public static void setIsDarkTheme(boolean isDarkTheme) {
AdjustWorkBookDefaultStyleUtils.isDarkTheme = isDarkTheme;
}
private static Color getCellForegroundColor() {
return isDarkTheme ? CELL_ELEMENT_FONT_FOREGROUND : CELL_ELEMENT_FONT_FOREGROUND_4_LIGHT_THEME;
}
private static Color getCurrentStoryBack() {
return currentStoryBack == null ? TEMPLATE_BACKGROUND : currentStoryBack;
}
@ -39,7 +49,7 @@ public class AdjustWorkBookDefaultStyleUtils {
public static Style adjustCellElement(Style style) {
if (DesignModeContext.isDuchampMode()) {
style = style.deriveFRFont(style.getFRFont().applyForeground(CELL_ELEMENT_FONT_FOREGROUND));
style = style.deriveFRFont(style.getFRFont().applyForeground(getCellForegroundColor()));
style = style.deriveBorder(0, CELL_ELEMENT_BORDER,
0, CELL_ELEMENT_BORDER,
0, CELL_ELEMENT_BORDER,
@ -49,7 +59,7 @@ public class AdjustWorkBookDefaultStyleUtils {
}
public static Color adjustCellElementFontForeground(Color color) {
return DesignModeContext.isDuchampMode() ? CELL_ELEMENT_FONT_FOREGROUND : color;
return DesignModeContext.isDuchampMode() ? getCellForegroundColor() : color;
}
public static void adjustFloatElement(FloatElement floatElement) {

2
designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java

@ -251,7 +251,6 @@ public class NumberEditorValidatePane extends JPanel {
allowNegativeCheckBox.setSelected(e.isAllowNegative());
if (AssistUtils.equals(e.getMaxValue(),Double.MAX_VALUE)) {
setMaxValueCheckBox.setSelected(false);
maxValueSpinner.setValue(Double.MAX_VALUE);
maxValueSpinner.setEnabled(false);
} else {
setMaxValueCheckBox.setSelected(true);
@ -261,7 +260,6 @@ public class NumberEditorValidatePane extends JPanel {
if (AssistUtils.equals(e.getMinValue(),-Double.MAX_VALUE)) {
setMinValueCheckBox.setSelected(false);
minValueSpinner.setValue(-Double.MAX_VALUE);
minValueSpinner.setEnabled(false);
} else {

6
designer-base/src/main/java/com/fr/design/write/submit/DBManipulationPane.java

@ -35,6 +35,7 @@ import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.CheckBoxList;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.javascript.JavaScriptActionPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
@ -318,7 +319,10 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
cr.setForeground(UIConstants.NORMAL_BACKGROUND);
JScrollPane jp = new JScrollPane(conditionsTree);
jp.setPreferredSize(FineUIScale.scale(new Dimension(0, 40)));
UIButton addSubmitConditionButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Set_Submit_Condition"));
addComponent(conditionPane, jp);
String submitCondition = Toolkit.i18nText("Fine-Design_Basic_Set_Submit_Condition");
UIButton addSubmitConditionButton = new UIButton(submitCondition);
addSubmitConditionButton.setToolTipText(submitCondition);
addSubmitConditionButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {

18
designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/DesktopWidgetStyleEditPane.java

@ -1,11 +1,15 @@
package com.fr.widgettheme.theme.edit.widget;
import com.fine.swing.ui.layout.Column;
import com.fr.base.background.ColorBackground;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.gui.icombobox.LineComboBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.design.utils.DesignUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.locale.InterProviderFactory;
import com.fr.stable.StringUtils;
import com.fr.util.ColorUtils;
@ -13,8 +17,6 @@ import com.fr.widgettheme.theme.widget.style.BorderStyle;
import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.widgettheme.util.WidgetStyleComponentCombiner;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
@ -22,6 +24,9 @@ import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import java.awt.Color;
import java.awt.Component;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
/**
* 桌面端主题面板
@ -52,7 +57,7 @@ public class DesktopWidgetStyleEditPane<T extends TemplateTheme> extends WidgetS
initFontNameSelectBox();
return new Component[][]{
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color")), colorSelectBox},
new Component[]{WidgetThemeDesignerUtils.createTopAlignmentLabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Widget_Background")), WidgetStyleComponentCombiner.combineWidgetBackgroundComponent(widgetBgColorSelectBox, widgetBgAlphaDragPane, colorSelectBox.getPreferredSize().width)},
new Component[]{WidgetThemeDesignerUtils.createTopAlignmentLabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Widget_Background")), initBackGroundComponent()},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Line")), lineComboBox},
new Component[]{null, lineComboColorSelectBox},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Radius")), borderRadiusSpinner},
@ -63,6 +68,13 @@ public class DesktopWidgetStyleEditPane<T extends TemplateTheme> extends WidgetS
};
}
private Column initBackGroundComponent() {
return column(10,
cell(widgetBgColorSelectBox),
cell(FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Form_Widget-Style_Alpha"))),
cell(widgetBgAlphaDragPane)).getComponent();
}
private void initSelectBackgroundColorBox() {
selectBackgroundColorBox = new NewColorSelectBox(140, true);
selectBackgroundColorBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR);

15
designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditPane.java

@ -1,5 +1,6 @@
package com.fr.widgettheme.theme.edit.widget;
import com.fine.swing.ui.layout.Column;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
@ -17,6 +18,7 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
@ -29,6 +31,9 @@ import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
/**
* 组件样式编辑基础类
@ -104,7 +109,7 @@ public class WidgetStyleEditPane<T extends TemplateTheme> extends BasicBeanPane<
public Component[][] generateComponent() {
return new Component[][]{
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color")), colorSelectBox},
new Component[]{WidgetThemeDesignerUtils.createTopAlignmentLabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Widget_Background")), WidgetStyleComponentCombiner.combineWidgetBackgroundComponent(widgetBgColorSelectBox, widgetBgAlphaDragPane, colorSelectBox.getPreferredSize().width)},
new Component[]{WidgetThemeDesignerUtils.createTopAlignmentLabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Widget_Background")), initBackGroundComponent()},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Line")), lineComboBox},
new Component[]{null, lineComboColorSelectBox},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Radius")), borderRadiusSpinner},
@ -113,6 +118,14 @@ public class WidgetStyleEditPane<T extends TemplateTheme> extends BasicBeanPane<
};
}
private Column initBackGroundComponent() {
return column(10,
cell(widgetBgColorSelectBox),
cell(FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Form_Widget-Style_Alpha"))),
cell(widgetBgAlphaDragPane)
).getComponent();
}
private void initCommonStyleEditor() {
colorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true);
colorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR);

3
designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties

@ -27,3 +27,6 @@ com.fr.design.file.MultiTemplateTabPane.popUpMenu=350*65
com.fr.design.data.datapane.preview.desensitization.view.rule.DesensitizationRuleChoosePane.ruleEditPane=800*600
com.fr.design.formula.FormulaPane=900*600
com.fr.design.formula.FormulaPaneWhenReserveFormula=1200*600
com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane.configLabel=130*20
com.fr.design.mainframe.mobile.utils.DesignerUtils.configLabel=140*20
com.fr.design.update.ui.dialog.UpdateMainDialog.updateButton=100*24

3
designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties

@ -26,3 +26,6 @@ com.fr.design.file.MultiTemplateTabPane.popUpMenu=240*65
com.fr.design.data.datapane.preview.desensitization.view.rule.DesensitizationRuleChoosePane.ruleEditPane=800*600
com.fr.design.formula.FormulaPane=900*600
com.fr.design.formula.FormulaPaneWhenReserveFormula=900*600
com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane.configLabel=100*20
com.fr.design.mainframe.mobile.utils.DesignerUtils.configLabel=130*20
com.fr.design.update.ui.dialog.UpdateMainDialog.updateButton=160*24

5
designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties

@ -14,7 +14,7 @@ com.fr.design.report.fit.firstColumn=130*20
com.fr.design.report.fit.column=100*20
com.fr.design.lock.LockInfoDialog=500*180
com.fr.design.mainframe.ForbiddenPane.refreshButton=80*24
com.fr.start.common.DesignerOpenEmptyPanel.createButton=70*24
com.fr.start.common.DesignerOpenEmptyPanel.createButton=90*24
com.fr.design.cell.expand.sort.pane=267*165
com.fr.design.sort.rule.item=125*20
com.fr.design.ds.column.sort.pane=250*180
@ -26,3 +26,6 @@ com.fr.design.file.MultiTemplateTabPane.popUpMenu=240*65
com.fr.design.data.datapane.preview.desensitization.view.rule.DesensitizationRuleChoosePane.ruleEditPane=800*600
com.fr.design.formula.FormulaPane=900*600
com.fr.design.formula.FormulaPaneWhenReserveFormula=900*600
com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane.configLabel=75*20
com.fr.design.mainframe.mobile.utils.DesignerUtils.configLabel=100*20
com.fr.design.update.ui.dialog.UpdateMainDialog.updateButton=80*24

3
designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties

@ -26,3 +26,6 @@ com.fr.design.report.WatermarkSettingPane=660*600
com.fr.design.file.MultiTemplateTabPane.popUpMenu=170*65
com.fr.design.formula.FormulaPane=900*600
com.fr.design.formula.FormulaPaneWhenReserveFormula=900*600
com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane.configLabel=75*20
com.fr.design.mainframe.mobile.utils.DesignerUtils.configLabel=100*20
com.fr.design.update.ui.dialog.UpdateMainDialog.updateButton=80*24

3
designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties

@ -25,3 +25,6 @@ com.fr.design.report.WatermarkSettingPane=720*600
com.fr.design.file.MultiTemplateTabPane.popUpMenu=170*65
com.fr.design.formula.FormulaPane=900*600
com.fr.design.formula.FormulaPaneWhenReserveFormula=900*600
com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane.configLabel=75*20
com.fr.design.mainframe.mobile.utils.DesignerUtils.configLabel=100*20
com.fr.design.update.ui.dialog.UpdateMainDialog.updateButton=80*24

2
designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java

@ -49,7 +49,7 @@ public class EnvChangeEntranceTest {
EasyMock.expect(selectedEnv.getRemindTime()).andReturn(null);
FunctionalHttpRequest request = EasyMock.mock(FunctionalHttpRequest.class);
EasyMock.expect(request.getServiceList()).andReturn(null);
EasyMock.expect(request.getServiceList(connectionInfo)).andReturn(null);
PowerMock.expectNew(FunctionalHttpRequest.class, connectionInfo).andReturn(request).anyTimes();
EasyMock.expect(request.getServerBranch()).andReturn(remoteBranch);

2
designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/AbstractChartTypePane.java

@ -100,7 +100,7 @@ public abstract class AbstractChartTypePane<T extends ChartProvider> extends Fur
}
}
double[] columnSize = {p, vs, f};
double[] columnSize = {f};
double[] rowSize = {p, p, p, p, p, p, p};
if (styleList != null && !styleList.isEmpty()) {

2
designer-form/src/main/java/com/fr/design/widget/ui/designer/ComboBoxDefinePane.java

@ -24,7 +24,7 @@ public class ComboBoxDefinePane extends DictEditorDefinePane<ComboBox> {
public Component[] createWaterMarkPane() {
waterMarkField = new UITextField();
return new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark")), waterMarkField};
return new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_PlaceHolder")), waterMarkField};
}
protected void populateSubDictionaryEditorBean(ComboBox ob){

48
designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java

@ -1,26 +1,20 @@
package com.fr.design.widgettheme;
import com.fine.swing.ui.layout.Column;
import com.fr.base.background.ColorBackground;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.design.gui.frpane.UIPercentDragPane;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UIToggleButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.utils.DesignUtils;
import com.fr.general.IOUtils;
import com.fr.util.ColorUtils;
import com.fr.widgettheme.theme.widget.style.BorderStyle;
import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import com.fr.widgettheme.theme.bean.ButtonBackground;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.design.gui.frpane.UIPercentDragPane;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UIToggleButton;
import com.fr.design.gui.icombobox.LineComboBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.style.FRFontPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
@ -28,10 +22,18 @@ import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.design.widget.ui.designer.component.UIBoundSpinner;
import com.fr.design.utils.DesignUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.form.ui.Widget;
import com.fr.general.FRFont;
import com.fr.general.IOUtils;
import com.fr.util.ColorUtils;
import com.fr.widgettheme.theme.bean.ButtonBackground;
import com.fr.widgettheme.theme.panel.ButtonStyleDefinedPane;
import com.fr.widgettheme.theme.widget.style.BorderStyle;
import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.widgettheme.util.WidgetStyleComponentCombiner;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
@ -45,6 +47,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
/**
* 样式设置pane抽象类
*
@ -68,7 +73,7 @@ public abstract class BaseStyleSettingPane<T extends Widget> extends BasicBeanPa
*/
protected NewColorSelectBox borderColorSelectBox;
// 圆角边框
protected UIBoundSpinner borderRadiusSpinner;
protected UISpinner borderRadiusSpinner;
// 字体详细设置
protected FRFontPane frFontPane;
// 按钮背景设置
@ -152,10 +157,19 @@ public abstract class BaseStyleSettingPane<T extends Widget> extends BasicBeanPa
paneMap.put(StyleSetting.FONT, frFontPane);
paneMap.put(StyleSetting.BTN_BACKGROUND, buttonStyleDefinedPane);
paneMap.put(StyleSetting.SELECT_COLOR, selectBgColorBox);
paneMap.put(StyleSetting.WIDGET_BACKGROUND, WidgetStyleComponentCombiner.combineWidgetBackgroundComponent(widgetBgColorSelectBox, widgetBgAlphaDragPane, WidgetThemeDisplayConstants.THEME_PC_WIDGET_BACKGROUND_WIDTH));
paneMap.put(StyleSetting.WIDGET_BACKGROUND, initBackGroundComponent());
paneMap.put(StyleSetting.ICON_COLOR, iconColorSelectBox);
}
private Column initBackGroundComponent() {
return column(
10,
cell(widgetBgColorSelectBox),
cell(FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Form_Widget-Style_Alpha"))),
cell(widgetBgAlphaDragPane)
).getComponent();
}
protected JPanel createHeadPane() {
UILabel headLabel = new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_Setting"));
String[] titles = new String[]{Toolkit.i18nText("Fine-Design_Widget_Follow_Theme"), Toolkit.i18nText("Fine-Design_Widget_Theme_Custom")};
@ -346,7 +360,7 @@ public abstract class BaseStyleSettingPane<T extends Widget> extends BasicBeanPa
private void initBorderPane() {
lineComboBox = new LineComboBox(WidgetThemeDisplayConstants.BORDER_LINE_STYLE_ARRAY);
borderColorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true);
borderRadiusSpinner = new UIBoundSpinner(0, Integer.MAX_VALUE, 1);
borderRadiusSpinner = new UISpinner(0, Integer.MAX_VALUE, 1);
lineComboBox.addItemListener(e -> borderColorSelectBox.setVisible(!Integer.valueOf(0).equals(e.getItem())));
}
}

2
designer-form/src/main/java/com/fr/design/widgettheme/ParaEditorSettingPane.java

@ -41,6 +41,7 @@ public class ParaEditorSettingPane<T extends Widget> extends EditorSettingPane<T
fontColorButton.setColor(textStyle.getFontColor());
bold.setSelected(textStyle.isBold());
italic.setSelected(textStyle.isItalic());
fontNameSelectBox.setSelectedItem(textStyle.getName());
}
@Override
@ -51,6 +52,7 @@ public class ParaEditorSettingPane<T extends Widget> extends EditorSettingPane<T
textStyle.setFontColor(fontColorButton.getColor());
textStyle.setBold(bold.isSelected());
textStyle.setItalic(italic.isSelected());
textStyle.setName((String) fontNameSelectBox.getSelectedItem());
paraEditorTheme.setTextStyle(textStyle);
}

16
designer-form/src/main/java/com/fr/design/widgettheme/processor/WidgetThemeCreatorPaneAdder.java

@ -1,8 +1,11 @@
package com.fr.design.widgettheme.processor;
import com.fr.design.widgettheme.common.SelectEditorSettingPane;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.widgettheme.common.ButtonSettingPane;
import com.fr.design.widgettheme.common.EditorSettingPane;
import com.fr.design.widgettheme.common.NormalButtonSettingPane;
import com.fr.design.widgettheme.common.SelectEditorSettingPane;
import com.fr.design.widgettheme.common.TreeEditorSettingPane;
import com.fr.form.parameter.FormSubmitButton;
import com.fr.form.ui.Button;
import com.fr.form.ui.CheckBox;
@ -21,10 +24,7 @@ import com.fr.form.ui.TreeEditor;
import com.fr.report.web.button.form.TreeNodeToggleButton;
import com.fr.report.web.button.write.AppendRowButton;
import com.fr.report.web.button.write.DeleteRowButton;
import com.fr.design.widgettheme.common.ButtonSettingPane;
import com.fr.design.widgettheme.common.EditorSettingPane;
import com.fr.design.widgettheme.common.NormalButtonSettingPane;
import com.fr.design.widgettheme.common.TreeEditorSettingPane;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import com.fr.widgettheme.utils.WidgetThemeServerUtils;
import java.util.Arrays;
@ -97,7 +97,7 @@ public class WidgetThemeCreatorPaneAdder {
}
private static <T> void acceptEditor(Class<?> creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = WidgetThemeServerUtils.isNewComboBoxTreeEditor(creator) || EDITOR_SET.contains(creator);
boolean accept = EDITOR_SET.contains(creator);
if (accept) {
insertShortCut(extraPaneList, new EditorSettingPane<>());
}
@ -126,7 +126,7 @@ public class WidgetThemeCreatorPaneAdder {
}
private static <T> void acceptSelect(Class<?> creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = SELECT_SET.contains(creator);
boolean accept = WidgetThemeServerUtils.isNewComboBoxTreeEditor(creator) || SELECT_SET.contains(creator);
if (accept) {
insertShortCut(extraPaneList, new SelectEditorSettingPane<>());
}

17
designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java

@ -6,20 +6,21 @@ import com.fr.design.actions.core.ActionFactory;
import com.fr.design.actions.form.FormECBackgroundAction;
import com.fr.design.actions.form.FormECColumnsAction;
import com.fr.design.actions.form.FormECFrozenAction;
import com.fr.design.designer.creator.XElementCase;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.event.TargetModifiedEvent;
import com.fr.design.event.TargetModifiedListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.fit.NewUIModeCellElementPainter;
import com.fr.design.fit.common.FormDesignerUtil;
import com.fr.design.gui.frpane.HyperlinkGroupPane;
import com.fr.design.mainframe.*;
import com.fr.design.mainframe.cell.QuickEditorRegion;
import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase;
import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef;
import com.fr.design.present.ConditionAttributesGroupPane;
import com.fr.design.utils.gui.AdjustWorkBookDefaultStyleUtils;
import com.fr.form.fit.common.LightTool;
import com.fr.form.main.Form;
import com.fr.grid.Grid;
@ -27,6 +28,7 @@ import com.fr.grid.GridColumn;
import com.fr.grid.GridCorner;
import com.fr.grid.GridRow;
import com.fr.page.ReportSettingsProvider;
import com.fr.report.cell.DefaultTemplateCellElement;
import com.fr.report.elementcase.TemplateElementCase;
import com.fr.report.worksheet.FormElementCase;
import com.fr.design.selection.SelectionEvent;
@ -34,7 +36,6 @@ import com.fr.design.selection.SelectionListener;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.Insets;
import java.awt.Rectangle;
/**
@ -69,6 +70,16 @@ public class FormElementCasePaneDelegate extends ElementCasePane<FormElementCase
}
}
});
// fvs根据主题样式创建默认单元格
if (DesignModeContext.isDuchampMode()) {
sheet.setDefaultCellElementSupplier(() -> {
DefaultTemplateCellElement defaultTemplateCellElement = DefaultThemedTemplateCellElementCase.createInstance();
// fvs调整单元格默认样式
AdjustWorkBookDefaultStyleUtils.adjustCellElement(defaultTemplateCellElement);
return defaultTemplateCellElement;
});
}
}
private Rectangle getBoundsLineRect(TemplateElementCase elementCase) {

7
designer-realize/src/main/java/com/fr/design/present/PresentPane.java

@ -52,10 +52,9 @@ public class PresentPane extends UIComboBoxPane<Present> {
@Override
public void populateBean(Present ob) {
if(ob == null) {
dictPresentPane.reset();
formulaPresentPane.reset();
barCodePane.reset();
currencyLinePane.reset();
for (FurtherBasicBeanPane<?> pane : cards) {
pane.reset();
}
}
super.populateBean(ob);
}

1
designer-realize/src/main/java/com/fr/design/widget/ui/MultiFileEditorPane.java

@ -40,6 +40,7 @@ public class MultiFileEditorPane extends FieldEditorDefinePane<MultiFileEditor>
UIComponentUtils.setLineWrap(singleFileCheckBox);
acceptType = new DictionaryComboBox(DictionaryConstants.acceptTypes, DictionaryConstants.fileTypeDisplays);
fileSizeField = new UISpinner(0, Integer.MAX_VALUE, 1, -1);
fileSizeField.setPreferredSize(new Dimension(140, 20));
JPanel fileSizePane = new JPanel(new BorderLayout());
UILabel fileTypeLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Utils_File_Type"));

3
designer-realize/src/main/java/com/fr/grid/selection/CellSelection.java

@ -32,6 +32,7 @@ import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase;
import com.fr.design.report.RowColumnPane;
import com.fr.design.selection.QuickEditor;
import com.fr.design.utils.gui.AdjustWorkBookDefaultStyleUtils;
import com.fr.grid.GridUtils;
import com.fr.report.cell.CellElement;
import com.fr.report.cell.DefaultTemplateCellElement;
@ -560,6 +561,8 @@ public class CellSelection extends Selection {
for (int i = 0; i < removeElementList.size(); i++) {
CellElement element = removeElementList.get(i);
element.setStyle(null);
// fvs调整单元格默认样式
AdjustWorkBookDefaultStyleUtils.adjustCellElement(element);
}
break;

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

@ -13,6 +13,7 @@ import com.fr.design.actions.server.ServerConfigManagerAction;
import com.fr.design.actions.server.TemplateThemeManagerAction;
import com.fr.design.actions.server.WidgetManagerAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.carton.latency.DesignerLatencyMetric;
import com.fr.design.carton.SwitchForSwingChecker;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.deeplink.DeepLinkManager;
@ -155,10 +156,11 @@ public class MainDesigner extends BaseDesigner {
ServerTray.init();
}
FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS));
DesignerStartupContext.getRecorder().stop();
SwitchForSwingChecker.initThreadMonitoring();
// new UiInspector();
// EdtInvocationManager.installEDTCheckers();
DesignerLatencyMetric.getInstance().start();
}
/**

Loading…
Cancel
Save