From 7f70d695d6d9e226c9a5ec0b75dd7290e3690fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=2EYing-=E5=BA=94=E5=BF=97=E6=B5=A9?= Date: Fri, 14 Apr 2023 11:08:09 +0800 Subject: [PATCH 01/10] =?UTF-8?q?REPORT-83195=20=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E7=82=B9=E4=BC=98=E5=8C=96-=E4=BF=9D=E5=AD=98=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/mainframe/JTemplate.java | 115 ++++++++++++++---- .../com/fr/design/worker/save/SaveWorker.java | 51 +++++--- .../fr/design/worker/save/type/SaveType.java | 50 ++++++++ .../worker/save/type/SaveTypeWorker.java | 75 ++++++++++++ 4 files changed, 255 insertions(+), 36 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/worker/save/type/SaveType.java create mode 100644 designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index 0082e091f3..229ba848d8 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -61,6 +61,8 @@ import com.fr.design.utils.DesignUtils; import com.fr.design.worker.save.CallbackSaveWorker; import com.fr.design.worker.save.EmptyCallBackSaveWorker; import com.fr.design.worker.save.SaveFailureHandler; +import com.fr.design.worker.save.type.SaveType; +import com.fr.design.worker.save.type.SaveTypeWorker; import com.fr.design.write.submit.DBManipulationInWidgetEventPane; import com.fr.design.write.submit.DBManipulationPane; import com.fr.event.EventDispatcher; @@ -1687,24 +1689,7 @@ public abstract class JTemplate> if (!editingFILE.exists()) { return saveAs(showLoc); } - - CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { - @Override - public Boolean call() throws Exception { - return saveRealFileByWorker(); - } - }, this); - - worker.addSuccessCallback(new Runnable() { - @Override - public void run() { - callBackForSave(); - //在保存后的回调中执行预编译流程 - CptCompileUtil.compile(JTemplate.this); - } - }); - - return worker; + return getSaveCallBackSaveWorker(); } /** @@ -1750,6 +1735,8 @@ public abstract class JTemplate> } } + + private CallbackSaveWorker saveAs(boolean showLoc) { FILE editingFILE = this.getEditingFILE(); if (editingFILE == null) { @@ -1771,7 +1758,6 @@ public abstract class JTemplate> // 目标文件 editingFILE = fileChooser.getSelectedFILE(); } - FILE finalEditingFILE = editingFILE; CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { @Override @@ -1872,10 +1858,95 @@ public abstract class JTemplate> return saveAs(true); } + /** + * 获取保存用到的saveWorker + */ + private CallbackSaveWorker getSaveCallBackSaveWorker() { + CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { + @Override + public Boolean call() throws Exception { + return saveRealFileByWorker(); + } + }, this); + + worker.addSuccessCallback(new Runnable() { + @Override + public void run() { + callBackForSave(); + //在保存后的回调中执行预编译流程 + CptCompileUtil.compile(JTemplate.this); + } + }); + return worker; + } + + /** + * 获取保存的类别执行的callable + */ + private Callable getSaveTypeCallable() { + return () -> { + fireJTemplateSaveBefore(); + FILE editingFILE = getEditingFILE(); + // carl:editingFILE没有,当然不存了,虽然不会有这种情况 + if (editingFILE == null) { + return SaveType.TypeEnum.EMPTY; + } + // 检查一下editingFILE是不是已存在的文件,如果不存在则用saveAs + if (!editingFILE.exists()) { + return SaveType.TypeEnum.SAVE_AS; + } + return SaveType.TypeEnum.SAVE; + }; + } + + /** + * 根据保存类型获取对应的saveWorker + * + * @param saveType 保存类型 + */ + private CallbackSaveWorker getSaveTypeWorker(SaveType saveType) { + CallbackSaveWorker callbackSaveWorker; + switch (saveType.getType()) { + case EMPTY: + callbackSaveWorker = new EmptyCallBackSaveWorker(); + break; + case SAVE: + callbackSaveWorker = getSaveCallBackSaveWorker(); + break; + default: + callbackSaveWorker = saveAs(true); + } + return callbackSaveWorker; + } + + + @Override public void saveDirectly() { - CallbackSaveWorker worker = save(); - worker.start(getRuntimeId()); + new SaveTypeWorker(getSaveTypeCallable(), this) { + @Override + protected void done() { + try { + SaveType saveType = get(); + CallbackSaveWorker callbackSaveWorker = getSaveTypeWorker(saveType); + //告诉一下后面执行的saveWorker,当前判断文件是否存在的操作是否已经进行了开始转圈的那个等待动画,避免重复 + callbackSaveWorker.setSlowly(saveType.isSlowly()); + callbackSaveWorker.start(getRuntimeId()); + //如果是空也就是不保存,需要恢复一下界面(如果saveTypeWorker里进行了操作的话) + if (callbackSaveWorker instanceof EmptyCallBackSaveWorker) { + setSaving(false); + if (saveType.isSlowly()) { + if (ComparatorUtils.equals(getName(), HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getName())) { + DesignerContext.getDesignerFrame().getCenterTemplateCardPane().hideCover(); + } + } + DesignerFrameFileDealerPane.getInstance().stateChange(); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.start(); } @Override @@ -1979,7 +2050,7 @@ public abstract class JTemplate> public void setDesignerUIMode() { DesignerUIModeConfig.getInstance().setAbsoluteMeasureUIMode(); } - + /** * 判断当前的模板是否是有效的模板 * diff --git a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java index 60d797c3e9..188aedacb9 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java @@ -5,12 +5,15 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrameFileDealerPane; import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.JTemplate; +import com.fr.design.ui.util.UIUtil; import com.fr.design.worker.WorkerManager; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; + import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; + +import com.fr.third.org.apache.commons.lang3.time.StopWatch; + import javax.swing.SwingWorker; /** @@ -34,6 +37,14 @@ public class SaveWorker extends SwingWorker { private boolean slowly; + public boolean isSlowly() { + return slowly; + } + + public void setSlowly(boolean slowly) { + this.slowly = slowly; + } + public SaveWorker(Callable callable, JTemplate template) { this.callable = callable; this.template = template; @@ -47,10 +58,11 @@ public class SaveWorker extends SwingWorker { @Override protected void done() { try { - success = get(); + success = get(); } catch (Exception e) { processResult(); FineLoggerFactory.getLogger().error(e.getMessage(), e); + WorkerManager.getInstance().removeWorker(taskName); SaveFailureHandler.getInstance().process(e); return; } @@ -62,6 +74,7 @@ public class SaveWorker extends SwingWorker { // 恢复界面 if (slowly && ComparatorUtils.equals(this.template.getName(), HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getName())) { DesignerContext.getDesignerFrame().getCenterTemplateCardPane().hideCover(); + slowly = false; } DesignerFrameFileDealerPane.getInstance().stateChange(); WorkerManager.getInstance().removeWorker(taskName); @@ -69,21 +82,31 @@ public class SaveWorker extends SwingWorker { public void start(String taskName) { this.taskName = taskName; + StopWatch stopWatch = StopWatch.createStarted(); this.template.setSaving(true); this.execute(); // worker纳入管理 WorkerManager.getInstance().registerWorker(taskName, this); - try { - this.get(TIME_OUT, TimeUnit.MILLISECONDS); - } catch (TimeoutException timeoutException) { - slowly = true; - // 开始禁用 - EastRegionContainerPane.getInstance().updateAllPropertyPane(); - DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showCover(); - DesignerFrameFileDealerPane.getInstance().stateChange(); - } catch (Exception exception) { - FineLoggerFactory.getLogger().error(exception.getMessage(), exception); - WorkerManager.getInstance().removeWorker(taskName); + if (!slowly) { + new Thread(() -> { + while (true) { + if (stopWatch.getTime() > TIME_OUT || isDone()) { + if (!isDone()) { + slowly = true; + UIUtil.invokeLaterIfNeeded(() -> { + // 开始禁用 + if (slowly) { + EastRegionContainerPane.getInstance().updateAllPropertyPane(); + DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showCover(); + DesignerFrameFileDealerPane.getInstance().stateChange(); + } + }); + } + stopWatch.stop(); + break; + } + } + }).start(); } } } diff --git a/designer-base/src/main/java/com/fr/design/worker/save/type/SaveType.java b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveType.java new file mode 100644 index 0000000000..63cf6c4c7e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveType.java @@ -0,0 +1,50 @@ +package com.fr.design.worker.save.type; + +/** + * 保存的类别 + * + * @author John.Ying + * @since 11.0 + * Created on 2023/4/14 + */ +public class SaveType { + + private TypeEnum type; + //保存时间是否慢(是否展示了保存中的UI界面) + private boolean slowly; + + public TypeEnum getType() { + return type; + } + + public void setType(TypeEnum saveType) { + this.type = saveType; + } + + public boolean isSlowly() { + return slowly; + } + + public void setSlowly(boolean slowly) { + this.slowly = slowly; + } + + /** + * 保存类型:save or saveAs or empty + */ + public enum TypeEnum { + /** + * 保存 + */ + SAVE, + /** + * 另存 + */ + SAVE_AS, + /** + * 空保存 + */ + EMPTY; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java new file mode 100644 index 0000000000..e087f701f7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java @@ -0,0 +1,75 @@ +package com.fr.design.worker.save.type; + + +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrameFileDealerPane; +import com.fr.design.mainframe.EastRegionContainerPane; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.ui.util.UIUtil; +import com.fr.third.org.apache.commons.lang3.time.StopWatch; + +import javax.swing.SwingWorker; +import java.util.concurrent.Callable; + +/** + * 判断保存类别时执行的worker + * + * @author John.Ying + * @since 11.0 + * Created on 2023/4/14 + */ +public class SaveTypeWorker extends SwingWorker { + + private final Callable callable; + + private static final int TIME_OUT = 400; + + private final JTemplate template; + + private final SaveType saveType; + + public SaveTypeWorker(Callable callable, JTemplate template) { + this.callable = callable; + this.template = template; + this.saveType = new SaveType(); + } + + @Override + protected SaveType doInBackground() throws Exception { + this.saveType.setType(callable.call()); + return this.saveType; + } + + @Override + protected void done() { + + } + + /** + * 启动saveTypeWorker + */ + public void start() { + StopWatch stopWatch = StopWatch.createStarted(); + this.template.setSaving(true); + this.execute(); + new Thread(() -> { + while (true) { + //大于最大等待时间或者worker已经完成该线程都要结束循环 + if (stopWatch.getTime() > TIME_OUT || isDone()) { + //如果是大于最大等待时间结束的,就需要进行等待中界面的覆盖 + if (!isDone()) { + saveType.setSlowly(true); + UIUtil.invokeLaterIfNeeded(() -> { + // 开始禁用 + EastRegionContainerPane.getInstance().updateAllPropertyPane(); + DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showCover(); + DesignerFrameFileDealerPane.getInstance().stateChange(); + }); + } + stopWatch.stop(); + break; + } + } + }).start(); + } +} From 437c05bbc0959de6b61fa468c2877f77338e6988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=2EYing-=E5=BA=94=E5=BF=97=E6=B5=A9?= Date: Fri, 14 Apr 2023 11:39:01 +0800 Subject: [PATCH 02/10] =?UTF-8?q?REPORT-83195=20=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E7=82=B9=E4=BC=98=E5=8C=96-=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E5=88=9D=E6=AC=A1=E6=B7=BB=E5=8A=A0=E5=9B=BE=E8=A1=A8=E5=8D=A1?= =?UTF-8?q?=E6=AD=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/mainframe/ChartPropertyPane.java | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java index 4efe977ff3..8e6b80c53a 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java @@ -9,6 +9,7 @@ import com.fr.base.chart.BaseChartCollection; import com.fr.chart.chartattr.ChartCollection; import com.fr.chart.charttypes.ChartTypeManager; import com.fr.chartx.attr.ChartProvider; +import com.fr.decision.webservice.v10.map.geojson.helper.GEOJSONHelper; import com.fr.design.ChartTypeInterfaceManager; import com.fr.design.designer.TargetComponent; import com.fr.design.gui.chart.BaseChartPropertyPane; @@ -19,6 +20,7 @@ import com.fr.design.utils.gui.GUICoreUtils; import javax.swing.BorderFactory; import javax.swing.Icon; +import javax.swing.SwingWorker; import java.awt.BorderLayout; import java.awt.Component; @@ -95,16 +97,25 @@ public class ChartPropertyPane extends BaseChartPropertyPane { * @param ePane 面板 */ public void populateChartPropertyPane(ChartCollection collection, TargetComponent ePane) { - String chartID = collection.getSelectedChartProvider(ChartProvider.class).getID(); - updateChartEditPane(collection.getSelectedChartProvider(ChartProvider.class).getID()); - setSupportCellData(true); - this.container.setEPane(ePane); - - if (ChartTypeManager.getInstance().chartExit(chartID)) { - chartEditPane.populate(collection); - } else { - GUICoreUtils.setEnabled(chartEditPane, false); - } + new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + GEOJSONHelper.getInstance(); + return null; + } + @Override + protected void done() { + String chartID = collection.getSelectedChartProvider(ChartProvider.class).getID(); + updateChartEditPane(collection.getSelectedChartProvider(ChartProvider.class).getID()); + setSupportCellData(true); + container.setEPane(ePane); + if (ChartTypeManager.getInstance().chartExit(chartID)) { + chartEditPane.populate(collection); + } else { + GUICoreUtils.setEnabled(chartEditPane, false); + } + } + }.execute(); } /** From 808f940df284f1f95e0d4550383f65dedba6ec64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=2EYing-=E5=BA=94=E5=BF=97=E6=B5=A9?= Date: Fri, 14 Apr 2023 13:41:06 +0800 Subject: [PATCH 03/10] =?UTF-8?q?REPORT-83195=20=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E7=82=B9=E4=BC=98=E5=8C=96-=E5=BC=80=E5=8F=91=E8=80=85?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/carton/SwitchForSwingChecker.java | 74 ++++++++- .../design/carton/developer/AwtEventInfo.java | 73 +++++++++ .../developer/EventDispatchDeveloperMode.java | 146 ++++++++++++++++++ 3 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/carton/developer/AwtEventInfo.java create mode 100644 designer-base/src/main/java/com/fr/design/carton/developer/EventDispatchDeveloperMode.java 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 683179293e..837bdb1c8b 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,6 +1,7 @@ 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; @@ -29,11 +30,22 @@ 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标签 */ @@ -249,11 +261,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter { */ public static void initThreadMonitoring () { String mainClass = System.getProperty("sun.java.command"); - //判断一下,如果是以Designer4Debug启动,就不注册代码,不然会覆盖掉SwingExplorer,导致其无法使用 - if (!StringUtils.equals(mainClass, DEBUG_MAIN_CLASS_NAME)) { - EventDispatchThreadHangMonitor.initMonitoring(); - AppContext.getAppContext().put(SwingWorker.class, CartonThreadExecutorPool.getTimerThreadExecutorPool()); - } + MainClassType.getMainClassType(mainClass).initEventQueue(); } /** @@ -309,4 +317,60 @@ 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("true", 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; + } + + 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 new file mode 100644 index 0000000000..77274a36ab --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/carton/developer/AwtEventInfo.java @@ -0,0 +1,73 @@ +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 new file mode 100644 index 0000000000..4fd136da37 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/carton/developer/EventDispatchDeveloperMode.java @@ -0,0 +1,146 @@ +package com.fr.design.carton.developer; + + +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 Timer 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(); + 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; + final boolean daemon = true; + timer = new Timer("EventDispatchDeveloperMode", daemon); + timer.schedule(new HangChecker(), initialDelayMs, CHECK_INTERVAL_MS); + } + + /** + * /消除Timer + */ + public void stopTimer() { + if (timer != null) { + timer.cancel(); + } + } + + /** + * /定时执行的任务 + */ + public class HangChecker extends TimerTask { + @Override + public void run() { + synchronized (dispatches) { + //如果链表为空定时检测就不进行 + if (dispatches.isEmpty()) { + return; + } + dispatches.getLast().checkForHang(); + } + } + } + + /** + * 消除模态框影响 + */ + public void startFilterModalWindow() { + ScheduledExecutorService scheduledExecutorService = FineExecutors.newSingleThreadScheduledExecutor(); + scheduledExecutorService.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + UIUtil.invokeLaterIfNeeded(() -> { + //不用干事,切个片就可以 + }); + } + }, 0, 10, TimeUnit.MILLISECONDS); + } +} From c600233de6061525f41c6945b1414e1217899f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=2EYing-=E5=BA=94=E5=BF=97=E6=B5=A9?= Date: Fri, 14 Apr 2023 15:08:58 +0800 Subject: [PATCH 04/10] =?UTF-8?q?REPORT-83195=20=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E7=82=B9=E4=BC=98=E5=8C=96-=E6=A0=B9=E6=8D=AE=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E6=8F=90=E7=A4=BA=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../developer/EventDispatchDeveloperMode.java | 37 ++++++++----------- .../com/fr/design/worker/save/SaveWorker.java | 37 +++++++++---------- .../worker/save/type/SaveTypeWorker.java | 10 ++++- 3 files changed, 42 insertions(+), 42 deletions(-) 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 index 4fd136da37..a87e900ac1 100644 --- 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 @@ -1,6 +1,7 @@ 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; @@ -33,7 +34,9 @@ public final class EventDispatchDeveloperMode extends EventQueue { */ public static final long CHECK_INTERVAL_MS = 5; - private Timer timer; + private static final int CORE_THREAD_SIZE = 5; + + private ScheduledExecutorService timer; /** * edt事件最大允许的时间 @@ -76,6 +79,7 @@ public final class EventDispatchDeveloperMode extends EventQueue { 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 {}" @@ -99,26 +103,8 @@ public final class EventDispatchDeveloperMode extends EventQueue { */ public void initTimer() { final long initialDelayMs = 0; - final boolean daemon = true; - timer = new Timer("EventDispatchDeveloperMode", daemon); - timer.schedule(new HangChecker(), initialDelayMs, CHECK_INTERVAL_MS); - } - - /** - * /消除Timer - */ - public void stopTimer() { - if (timer != null) { - timer.cancel(); - } - } - - /** - * /定时执行的任务 - */ - public class HangChecker extends TimerTask { - @Override - public void run() { + timer = FineExecutors.newScheduledThreadPool(CORE_THREAD_SIZE); + timer.schedule(() -> { synchronized (dispatches) { //如果链表为空定时检测就不进行 if (dispatches.isEmpty()) { @@ -126,6 +112,15 @@ public final class EventDispatchDeveloperMode extends EventQueue { } dispatches.getLast().checkForHang(); } + }, initialDelayMs, TimeUnit.MILLISECONDS); + } + + /** + * /消除Timer + */ + public void stopTimer() { + if (timer != null) { + timer.shutdown(); } } diff --git a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java index 188aedacb9..cd1fcb3dd0 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java @@ -7,6 +7,7 @@ import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.JTemplate; import com.fr.design.ui.util.UIUtil; import com.fr.design.worker.WorkerManager; +import com.fr.design.worker.save.type.SaveTypeWorker; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; @@ -87,26 +88,24 @@ public class SaveWorker extends SwingWorker { this.execute(); // worker纳入管理 WorkerManager.getInstance().registerWorker(taskName, this); - if (!slowly) { - new Thread(() -> { - while (true) { - if (stopWatch.getTime() > TIME_OUT || isDone()) { - if (!isDone()) { - slowly = true; - UIUtil.invokeLaterIfNeeded(() -> { - // 开始禁用 - if (slowly) { - EastRegionContainerPane.getInstance().updateAllPropertyPane(); - DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showCover(); - DesignerFrameFileDealerPane.getInstance().stateChange(); - } - }); - } - stopWatch.stop(); - break; + SaveTypeWorker.saveTypePool.execute(() -> { + while (true) { + if (stopWatch.getTime() > TIME_OUT || isDone()) { + if (!isDone()) { + slowly = true; + UIUtil.invokeLaterIfNeeded(() -> { + // 开始禁用 + if (slowly) { + EastRegionContainerPane.getInstance().updateAllPropertyPane(); + DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showCover(); + DesignerFrameFileDealerPane.getInstance().stateChange(); + } + }); } + stopWatch.stop(); + break; } - }).start(); - } + } + }); } } diff --git a/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java index e087f701f7..b004dea7d2 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java @@ -1,6 +1,7 @@ package com.fr.design.worker.save.type; +import com.fr.concurrent.FineExecutors; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrameFileDealerPane; import com.fr.design.mainframe.EastRegionContainerPane; @@ -10,6 +11,7 @@ import com.fr.third.org.apache.commons.lang3.time.StopWatch; import javax.swing.SwingWorker; import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; /** * 判断保存类别时执行的worker @@ -20,6 +22,8 @@ import java.util.concurrent.Callable; */ public class SaveTypeWorker extends SwingWorker { + public static final ExecutorService saveTypePool = FineExecutors.newSingleThreadExecutor(); + private final Callable callable; private static final int TIME_OUT = 400; @@ -28,6 +32,8 @@ public class SaveTypeWorker extends SwingWorker { private final SaveType saveType; + + public SaveTypeWorker(Callable callable, JTemplate template) { this.callable = callable; this.template = template; @@ -52,7 +58,7 @@ public class SaveTypeWorker extends SwingWorker { StopWatch stopWatch = StopWatch.createStarted(); this.template.setSaving(true); this.execute(); - new Thread(() -> { + saveTypePool.execute(() -> { while (true) { //大于最大等待时间或者worker已经完成该线程都要结束循环 if (stopWatch.getTime() > TIME_OUT || isDone()) { @@ -70,6 +76,6 @@ public class SaveTypeWorker extends SwingWorker { break; } } - }).start(); + }); } } From e2c4db30a80b8686c87b9ee7b151bf6456f21a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=2EYing-=E5=BA=94=E5=BF=97=E6=B5=A9?= Date: Fri, 14 Apr 2023 15:10:03 +0800 Subject: [PATCH 05/10] =?UTF-8?q?REPORT-83195=20=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E7=82=B9=E4=BC=98=E5=8C=96-=E6=A0=B9=E6=8D=AE=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E6=8F=90=E7=A4=BA=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/carton/developer/EventDispatchDeveloperMode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index a87e900ac1..5381ff7ff2 100644 --- 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 @@ -34,7 +34,7 @@ public final class EventDispatchDeveloperMode extends EventQueue { */ public static final long CHECK_INTERVAL_MS = 5; - private static final int CORE_THREAD_SIZE = 5; + private static final int CORE_THREAD_SIZE = 1; private ScheduledExecutorService timer; From 135f588ff103020ae0f75b28ff8bcdedd714c1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=2EYing-=E5=BA=94=E5=BF=97=E6=B5=A9?= Date: Fri, 14 Apr 2023 15:15:38 +0800 Subject: [PATCH 06/10] =?UTF-8?q?REPORT-83195=20=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E7=82=B9=E4=BC=98=E5=8C=96-=E6=A0=B9=E6=8D=AE=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E6=8F=90=E7=A4=BA=E4=BF=AE=E6=94=B9=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/design/carton/SwitchForSwingChecker.java | 5 +++-- .../src/main/java/com/fr/design/worker/save/SaveWorker.java | 2 +- .../java/com/fr/design/worker/save/type/SaveTypeWorker.java | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) 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 837bdb1c8b..2f884bc301 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 @@ -58,6 +58,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter { * 简单记录事件执行时间的开关 */ private static boolean easyChecker = false; + /** * 一个标识位用于区分耗时任务时长检测(简单检测)和timer检测 */ @@ -331,7 +332,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter { MAIN(NORMAL_MAIN_CLASS_NAME) { @Override void initEventQueue() { - if (StringUtils.equals("true", System.getProperty(CARTON_DEVELOPER_JVM_PARAM))) { + if (StringUtils.equals(TURE_JVM, System.getProperty(CARTON_DEVELOPER_JVM_PARAM))) { EventDispatchDeveloperMode.INSTANCE.initMonitoring(); } else { EventDispatchThreadHangMonitor.initMonitoring(); @@ -353,7 +354,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter { MainClassType(String classPath) { this.classPath = classPath; } - + public static final String TURE_JVM = "true"; String classPath; /** diff --git a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java index cd1fcb3dd0..83b7c50d49 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java @@ -88,7 +88,7 @@ public class SaveWorker extends SwingWorker { this.execute(); // worker纳入管理 WorkerManager.getInstance().registerWorker(taskName, this); - SaveTypeWorker.saveTypePool.execute(() -> { + SaveTypeWorker.SAVE_TYPE_POOL.execute(() -> { while (true) { if (stopWatch.getTime() > TIME_OUT || isDone()) { if (!isDone()) { diff --git a/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java index b004dea7d2..d415537eb4 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/save/type/SaveTypeWorker.java @@ -22,7 +22,7 @@ import java.util.concurrent.ExecutorService; */ public class SaveTypeWorker extends SwingWorker { - public static final ExecutorService saveTypePool = FineExecutors.newSingleThreadExecutor(); + public static final ExecutorService SAVE_TYPE_POOL = FineExecutors.newSingleThreadExecutor(); private final Callable callable; @@ -58,7 +58,7 @@ public class SaveTypeWorker extends SwingWorker { StopWatch stopWatch = StopWatch.createStarted(); this.template.setSaving(true); this.execute(); - saveTypePool.execute(() -> { + SAVE_TYPE_POOL.execute(() -> { while (true) { //大于最大等待时间或者worker已经完成该线程都要结束循环 if (stopWatch.getTime() > TIME_OUT || isDone()) { From 855a032de3113a05f41ba3d2984c17ac767c41fc Mon Sep 17 00:00:00 2001 From: "Destiny.Lin" Date: Fri, 14 Apr 2023 15:26:09 +0800 Subject: [PATCH 07/10] =?UTF-8?q?REPORT-93901=20=E6=89=93=E5=BC=80js?= =?UTF-8?q?=E9=AB=98=E7=BA=A7=E7=BC=96=E8=BE=91=E7=95=8C=E9=9D=A2=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E5=8D=A1=E6=AD=BB=E9=9C=80=E9=87=8D=E5=90=AF?= =?UTF-8?q?=20&=20REPORT-83195=20=E5=8D=A1=E9=A1=BF=E7=82=B9=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20=E5=8D=A1=E9=A1=BF/=E5=8D=A1=E6=AD=BB=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JSContentWithDescriptionPane.java | 62 +++++++++++++------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java index 8e8ef45b9f..dc74d7e991 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java @@ -50,6 +50,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.concurrent.ExecutionException; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; @@ -59,6 +60,7 @@ import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTree; +import javax.swing.SwingWorker; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TreeSelectionEvent; @@ -352,27 +354,51 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi private void doHelpDocumentSearch() { Object value = interfaceNameList.getSelectedValue(); if (value != null) { - String url = CloudCenter.getInstance().acquireUrlByKind("af.doc_search", DOCUMENT_SEARCH_URL) + value.toString(); - try { - String result = HttpToolbox.get(url); - JSONObject jsonObject = new JSONObject(result); - JSONArray jsonArray = jsonObject.optJSONArray("list"); - if (jsonArray != null) { - DefaultListModel helpDOCModel = (DefaultListModel) helpDOCList.getModel(); - helpDOCModel.clear(); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject resultJSONObject = jsonArray.optJSONObject(i); - String docURL = resultJSONObject.optString("url"); - String name = resultJSONObject.optString("title").trim(); - HelpDocument helpDocument = new HelpDocument(docURL, name); - helpDOCModel.addElement(helpDocument); + new SwingWorker, Void>() { + @Override + protected List doInBackground() throws Exception { + List helpDocuments = new ArrayList<>(); + updateHelpDocuments(value, helpDocuments); + return helpDocuments; + } + + @Override + protected void done() { + try { + List helpDocuments = get(); + DefaultListModel helpDOCModel = (DefaultListModel) helpDOCList.getModel(); + helpDOCModel.clear(); + for (HelpDocument helpDocument : helpDocuments) { + helpDOCModel.addElement(helpDocument); + } + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); } } - } catch (JSONException e) { - FineLoggerFactory.getLogger().debug(e.getMessage(), e); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + + }.execute(); + } + } + + private void updateHelpDocuments(Object value, List helpDocuments) { + String url = CloudCenter.getInstance().acquireUrlByKind("af.doc_search", DOCUMENT_SEARCH_URL) + value.toString(); + try { + String result = HttpToolbox.get(url); + JSONObject jsonObject = new JSONObject(result); + JSONArray jsonArray = jsonObject.optJSONArray("list"); + if (jsonArray != null) { + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject resultJSONObject = jsonArray.optJSONObject(i); + String docURL = resultJSONObject.optString("url"); + String name = resultJSONObject.optString("title").trim(); + HelpDocument helpDocument = new HelpDocument(docURL, name); + helpDocuments.add(helpDocument); + } } + } catch (JSONException e) { + FineLoggerFactory.getLogger().debug(e.getMessage(), e); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); } } From f44541c77e9f786b3221945f71b24194d71dd9fd Mon Sep 17 00:00:00 2001 From: "Destiny.Lin" Date: Fri, 14 Apr 2023 15:29:13 +0800 Subject: [PATCH 08/10] =?UTF-8?q?REPORT-93901=20=E6=89=93=E5=BC=80js?= =?UTF-8?q?=E9=AB=98=E7=BA=A7=E7=BC=96=E8=BE=91=E7=95=8C=E9=9D=A2=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E5=8D=A1=E6=AD=BB=E9=9C=80=E9=87=8D=E5=90=AF?= =?UTF-8?q?=20&=20REPORT-83195=20=E5=8D=A1=E9=A1=BF=E7=82=B9=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20=E5=8D=A1=E9=A1=BF/=E5=8D=A1=E6=AD=BB=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/javascript/JSContentWithDescriptionPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java index dc74d7e991..3be90999f1 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java @@ -372,7 +372,7 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi helpDOCModel.addElement(helpDocument); } } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); + FineLoggerFactory.getLogger().error(e.getMessage(), e); } } From 0671f5442e72d333d871cfaaf7e88c944ade9fc6 Mon Sep 17 00:00:00 2001 From: "Destiny.Lin" Date: Fri, 14 Apr 2023 15:44:28 +0800 Subject: [PATCH 09/10] =?UTF-8?q?REPORT-93901=20=E6=89=93=E5=BC=80js?= =?UTF-8?q?=E9=AB=98=E7=BA=A7=E7=BC=96=E8=BE=91=E7=95=8C=E9=9D=A2=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E5=8D=A1=E6=AD=BB=E9=9C=80=E9=87=8D=E5=90=AF?= =?UTF-8?q?=20&=20REPORT-83195=20=E5=8D=A1=E9=A1=BF=E7=82=B9=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20=E5=8D=A1=E9=A1=BF/=E5=8D=A1=E6=AD=BB=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/javascript/JSContentWithDescriptionPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java index 3be90999f1..e2a8dd0d5c 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java @@ -356,7 +356,7 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi if (value != null) { new SwingWorker, Void>() { @Override - protected List doInBackground() throws Exception { + protected List doInBackground() { List helpDocuments = new ArrayList<>(); updateHelpDocuments(value, helpDocuments); return helpDocuments; From 5155311b6e203d96432a8db4019fd75b05b6bd9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=2EYing-=E5=BA=94=E5=BF=97=E6=B5=A9?= Date: Fri, 14 Apr 2023 16:04:58 +0800 Subject: [PATCH 10/10] =?UTF-8?q?REPORT-83195=20=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E7=82=B9=E4=BC=98=E5=8C=96-=E5=9B=9E=E9=80=80=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=E5=BC=80=E5=8F=91=E8=80=85=E6=A8=A1=E5=BC=8F=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81=EF=BC=8C=E8=AE=BE=E8=AE=A1=E6=9C=89?= =?UTF-8?q?=E7=82=B9=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/carton/SwitchForSwingChecker.java | 75 +--------- .../design/carton/developer/AwtEventInfo.java | 73 --------- .../developer/EventDispatchDeveloperMode.java | 141 ------------------ 3 files changed, 5 insertions(+), 284 deletions(-) delete mode 100644 designer-base/src/main/java/com/fr/design/carton/developer/AwtEventInfo.java delete mode 100644 designer-base/src/main/java/com/fr/design/carton/developer/EventDispatchDeveloperMode.java 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 2f884bc301..683179293e 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 77274a36ab..0000000000 --- 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 5381ff7ff2..0000000000 --- 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); - } -}