diff --git a/designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java b/designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java index 2f884bc30..683179293 100644 --- a/designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java +++ b/designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java @@ -1,7 +1,6 @@ package com.fr.design.carton; -import com.fr.design.carton.developer.EventDispatchDeveloperMode; import com.fr.design.i18n.Toolkit; import com.fr.general.GeneralUtils; import com.fr.json.JSON; @@ -30,22 +29,11 @@ import java.util.Map; import java.util.Date; import java.util.Calendar; - public class SwitchForSwingChecker implements XMLReadable, XMLWriter { /** * Designer4Debug类名 */ private static final String DEBUG_MAIN_CLASS_NAME = "com.fr.start.Designer4Debug"; - - /** - * 真正主类 - */ - private static final String NORMAL_MAIN_CLASS_NAME = "com.fr.start.MainDesigner"; - - /** - * 开发者模式jvm参数 - */ - private static final String CARTON_DEVELOPER_JVM_PARAM = "cartonDeveloper"; /** * XML标签 */ @@ -58,7 +46,6 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter { * 简单记录事件执行时间的开关 */ private static boolean easyChecker = false; - /** * 一个标识位用于区分耗时任务时长检测(简单检测)和timer检测 */ @@ -262,7 +249,11 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter { */ public static void initThreadMonitoring () { String mainClass = System.getProperty("sun.java.command"); - MainClassType.getMainClassType(mainClass).initEventQueue(); + //判断一下,如果是以Designer4Debug启动,就不注册代码,不然会覆盖掉SwingExplorer,导致其无法使用 + if (!StringUtils.equals(mainClass, DEBUG_MAIN_CLASS_NAME)) { + EventDispatchThreadHangMonitor.initMonitoring(); + AppContext.getAppContext().put(SwingWorker.class, CartonThreadExecutorPool.getTimerThreadExecutorPool()); + } } /** @@ -318,60 +309,4 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter { writer.end(); } - /** - * 根据程序启动类路径进行区分 - * - * @author John.Ying - * @since 11.0 - * Created on 2023/4/14 - */ - enum MainClassType { - /** - * 用mainDesigner启动 - */ - MAIN(NORMAL_MAIN_CLASS_NAME) { - @Override - void initEventQueue() { - if (StringUtils.equals(TURE_JVM, System.getProperty(CARTON_DEVELOPER_JVM_PARAM))) { - EventDispatchDeveloperMode.INSTANCE.initMonitoring(); - } else { - EventDispatchThreadHangMonitor.initMonitoring(); - AppContext.getAppContext().put(SwingWorker.class, CartonThreadExecutorPool.getTimerThreadExecutorPool()); - } - } - }, - - /** - * designer4debug启动 - */ - DEBUG_MAIN(DEBUG_MAIN_CLASS_NAME) { - @Override - void initEventQueue() { - - } - }; - - MainClassType(String classPath) { - this.classPath = classPath; - } - public static final String TURE_JVM = "true"; - String classPath; - - /** - * 初始化重写的EDT - */ - abstract void initEventQueue(); - - /** - * @param classPath 启动类路径 - */ - static MainClassType getMainClassType(String classPath) { - for (MainClassType mainClassType : MainClassType.values()) { - if (StringUtils.equals(classPath, mainClassType.classPath)) { - return mainClassType; - } - } - return MAIN; - } - } } diff --git a/designer-base/src/main/java/com/fr/design/carton/developer/AwtEventInfo.java b/designer-base/src/main/java/com/fr/design/carton/developer/AwtEventInfo.java deleted file mode 100644 index 77274a36a..000000000 --- a/designer-base/src/main/java/com/fr/design/carton/developer/AwtEventInfo.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.fr.design.carton.developer; - -import java.awt.AWTEvent; - -/** - * EDT事件的包装类,用来额外处理信息 - * - * @author John.Ying - * @since 11.0 - * Created on 2023/4/14 - */ -public class AwtEventInfo { - //获取执行该事件的线程 - private final Thread eventDispatchThread = Thread.currentThread(); - //在队列中等待执行的事件最后未执行的时间,当有一个事件执行完后就遍历dispatches给该值赋当前时间 - private long lastDispatchTimeMillis = System.currentTimeMillis(); - //事件开始的时间 - private final long startDispatchTimeMillis = System.currentTimeMillis(); - //awt事件 - private AWTEvent awtEvent; - //事件堆栈 - private StackTraceElement[] stackTrace; - - /** - * 检查是否要给堆栈赋值 - */ - public void checkForHang() { - if (isNeedToStackTrace()) { - this.stackTrace = eventDispatchThread.getStackTrace(); - } - } - - /** - * 是否需要赋值堆栈满足 - * 耗时>20ms - */ - private boolean isNeedToStackTrace() { - return (System.currentTimeMillis() - startDispatchTimeMillis) > EventDispatchDeveloperMode.MAX_TIME - && stackTrace == null; - } - - public Thread getEventDispatchThread() { - return eventDispatchThread; - } - - public long getLastDispatchTimeMillis() { - return lastDispatchTimeMillis; - } - - public void setLastDispatchTimeMillis(long lastDispatchTimeMillis) { - this.lastDispatchTimeMillis = lastDispatchTimeMillis; - } - - public long getStartDispatchTimeMillis() { - return startDispatchTimeMillis; - } - - public AWTEvent getAwtEvent() { - return awtEvent; - } - - public void setAwtEvent(AWTEvent awtEvent) { - this.awtEvent = awtEvent; - } - - public StackTraceElement[] getStackTrace() { - return stackTrace; - } - - public void setStackTrace(StackTraceElement[] stackTrace) { - this.stackTrace = stackTrace; - } -} diff --git a/designer-base/src/main/java/com/fr/design/carton/developer/EventDispatchDeveloperMode.java b/designer-base/src/main/java/com/fr/design/carton/developer/EventDispatchDeveloperMode.java deleted file mode 100644 index 5381ff7ff..000000000 --- a/designer-base/src/main/java/com/fr/design/carton/developer/EventDispatchDeveloperMode.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.fr.design.carton.developer; - - -import com.aspose.words.Run; -import com.fr.concurrent.FineExecutors; -import com.fr.design.carton.EventDispatchThreadHangMonitor; -import com.fr.design.ui.util.UIUtil; -import com.fr.log.FineLoggerFactory; - -import java.awt.AWTEvent; -import java.awt.EventQueue; -import java.awt.Toolkit; -import java.util.LinkedList; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * 开发者模式重写的EDT - * - * @author John.Ying - * @since 11.0 - * Created on 2023/4/14 - */ -public final class EventDispatchDeveloperMode extends EventQueue { - - /** - * 该链表为主要的实现定时任务的容器,在重写的dispatchEvent中由pre方法将DispatchInfo加入到链表,由post方法remove - */ - private final LinkedList dispatches = new LinkedList<>(); - /** - * 开启间隔检测后两次检测的相隔时间ms - */ - public static final long CHECK_INTERVAL_MS = 5; - - private static final int CORE_THREAD_SIZE = 1; - - private ScheduledExecutorService timer; - - /** - * edt事件最大允许的时间 - */ - public static final long MAX_TIME = 20; - public static final EventDispatchDeveloperMode INSTANCE = new EventDispatchDeveloperMode(); - - @Override - protected void dispatchEvent(AWTEvent event) { - try { - preDispatchEvent(event); - super.dispatchEvent(event); - } finally { - postDispatchEvent(); - } - } - - /** - * 事件分发前处理 - */ - private synchronized void preDispatchEvent(AWTEvent event) { - synchronized (dispatches) { - AwtEventInfo awtEventInfo = new AwtEventInfo(); - awtEventInfo.setAwtEvent(event); - dispatches.addLast(awtEventInfo); - } - } - - /** - * 事件分发后处理 - */ - private synchronized void postDispatchEvent() { - synchronized (dispatches) { - AwtEventInfo awtEventInfo = dispatches.removeLast(); - //嵌套最深的事件执行完毕后刷新链表中其他事件的lastDispatchTimeMillis - Thread currentEventDispatchThread = Thread.currentThread(); - for (AwtEventInfo info : dispatches) { - info.setLastDispatchTimeMillis(System.currentTimeMillis()); - } - long nowTime = System.currentTimeMillis(); - long totalTime = nowTime - awtEventInfo.getStartDispatchTimeMillis(); - long continuationTime = nowTime - awtEventInfo.getLastDispatchTimeMillis(); - //判断连续执行时间是否超过了20ms,超过了则进行提示 - if (continuationTime > MAX_TIME) { - FineLoggerFactory.getLogger() - .warn("awt event spend time more than 20ms, totalTime {} continuationTime {} the stack is {}" - , totalTime, continuationTime, EventDispatchThreadHangMonitor.stackTraceToStringForConsole(awtEventInfo.getStackTrace())); - } - } - } - - /** - * 将swing中默认的EventQueue换成自己的 - */ - public void initMonitoring() { - UIUtil.invokeLaterIfNeeded(() -> Toolkit.getDefaultToolkit().getSystemEventQueue().push(INSTANCE)); - initTimer(); - startFilterModalWindow(); - } - - /** - * Sets up a timer to check for hangs frequently. - * 初始化一个Timer - */ - public void initTimer() { - final long initialDelayMs = 0; - timer = FineExecutors.newScheduledThreadPool(CORE_THREAD_SIZE); - timer.schedule(() -> { - synchronized (dispatches) { - //如果链表为空定时检测就不进行 - if (dispatches.isEmpty()) { - return; - } - dispatches.getLast().checkForHang(); - } - }, initialDelayMs, TimeUnit.MILLISECONDS); - } - - /** - * /消除Timer - */ - public void stopTimer() { - if (timer != null) { - timer.shutdown(); - } - } - - /** - * 消除模态框影响 - */ - public void startFilterModalWindow() { - ScheduledExecutorService scheduledExecutorService = FineExecutors.newSingleThreadScheduledExecutor(); - scheduledExecutorService.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - UIUtil.invokeLaterIfNeeded(() -> { - //不用干事,切个片就可以 - }); - } - }, 0, 10, TimeUnit.MILLISECONDS); - } -}