Browse Source

Pull request #16245: REPORT-144629 模板助手插件适配

Merge in DESIGN/design from ~LEO.QIN/design:fbp/feature to fbp/feature

* commit '7df0d58781f8ba4d57b977554aca46f31ca0ad70':
  REPORT-144629 模板助手插件适配 去除ByteBuddy
  REPORT-144629 模板助手插件适配 改一波代码质量
  REPORT-144629 模板助手插件适配,改动范围:https://kms.fineres.com/pages/viewpage.action?pageId=1191537310
fbp/feature
Leo.Qin-覃宇攀 5 days ago
parent
commit
60cb984858
  1. 7
      designer-base/src/main/java/com/fine/theme/light/ui/FineHeaderPaneUI.java
  2. 2
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTableModel.java
  3. 17
      designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java
  4. 13
      designer-base/src/main/java/com/fr/design/foldablepane/UIExpandablePane.java
  5. 1
      designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java
  6. 17
      designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java
  7. 19
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  8. 79
      designer-base/src/main/java/com/fr/design/mainframe/shadow/SCBridge4Designer.java
  9. 23
      designer-base/src/main/resources/com/fine/theme/icon/shadow/detect.svg
  10. 8
      designer-base/src/main/resources/com/fine/theme/icon/shadow/error.svg
  11. 13
      designer-base/src/main/resources/com/fine/theme/icon/shadow/risk.svg
  12. 5
      designer-base/src/main/resources/com/fine/theme/icon/shadow/success.svg
  13. 10
      designer-base/src/main/resources/com/fine/theme/icon/shadow/suggestion.svg
  14. 7
      designer-base/src/main/resources/com/fine/theme/light/ui/fine_light.icon.json
  15. 1
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties
  16. 1
      designer-base/src/test/java/com/fr/design/gui/storybook/components/ComboCheckBoxStoryBoard.java
  17. 4
      designer-base/src/test/java/com/fr/design/gui/storybook/components/ExpandablePaneStoryBoard.java
  18. 19
      designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java
  19. 2
      designer-chart/src/main/java/com/fr/van/chart/designer/type/AbstractVanChartTypePane.java
  20. 4
      designer-realize/src/main/java/com/fanruan/boot/init/DesignWorkContextComponent.java
  21. 14
      designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java
  22. 2
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/DesensitizationCellPane.java
  23. 116
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/action/DetectErrorShowAction.java
  24. 82
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/action/TemplateHelperAction.java
  25. 19
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/SCJumpHandler.java
  26. 71
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/SCJumpHandlerProvider.java
  27. 19
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/DefaultSCJumpHandler.java
  28. 172
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCCellSCJumpHandler.java
  29. 133
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCDataSourceRecordHandler.java
  30. 84
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCGlobalParameterJumpHandler.java
  31. 29
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCNxCompileJumperHandler.java
  32. 54
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCWatermarkJumpHandler.java
  33. 28
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCWebLinkJumpHandler.java
  34. 13
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/listener/AbstractSCJumperListener.java
  35. 11
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/listener/SCDefaultJumpListener.java
  36. 30
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/listener/SCJumperListener.java
  37. 46
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/DetectFailedPane.java
  38. 81
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/DetectNoErrorPane.java
  39. 35
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/OptimizationProgressPane.java
  40. 69
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/TemplateHelperShowPane.java
  41. 105
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/AbstractSCRecordItemPane.java
  42. 106
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/AbstractSCRecordItemPaneFactory.java
  43. 55
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCCellRecordItemPane.java
  44. 43
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCColumnRecordItemPane.java
  45. 43
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCDataSourceRecordItemPane.java
  46. 57
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCMessageRecordItemPane.java
  47. 42
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCRowRecordItemPane.java
  48. 40
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCWidgetRecordItemPane.java
  49. 57
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/table/AutoOptimizeDetectMultiTablePane.java
  50. 96
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/table/DetectMultiTablePane.java
  51. 61
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/table/DetectSingleTablePane.java
  52. 39
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/table/ProblemPositionPane.java
  53. 32
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/DetectMutiTableData.java
  54. 51
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/DetectSingleTableData.java
  55. 21
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/ProblemInformation.java
  56. 71
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/ProblemInformationFactory.java
  57. 48
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/SheetIndexToName.java
  58. 40
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/TemplateDetectResultData.java
  59. 40
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/impl/DefaultDetectMutiTableData.java
  60. 149
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/impl/DefaultDetectSingleTableData.java
  61. 58
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/impl/DefaultProblemInformation.java
  62. 50
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/impl/DefaultTemplateDetectResultData.java
  63. 357
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/SCDefaultSCTemplateHelper.java
  64. 115
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/SCDefaultSCTemplateHelperDetect.java
  65. 11
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/SCTemplateHelper.java
  66. 39
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/SCTemplateHelperDetect.java
  67. 33
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/adapter/SCDetectAdapter.java
  68. 248
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/adapter/impl/SCDefaultSCDetectAdapter.java
  69. 18
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/filter/SCRecordFilter.java
  70. 50
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/filter/impl/SCWatermarkFilter.java
  71. 60
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/icon/CountIcon.java
  72. 33
      designer-realize/src/main/java/com/fr/design/mainframe/shadow/utils/DesignerPaneUtil.java
  73. 90
      designer-realize/src/test/java/com/fr/design/shadow/SCDesignerMetricRecorderTest.java

7
designer-base/src/main/java/com/fine/theme/light/ui/FineHeaderPaneUI.java

@ -101,6 +101,13 @@ public class FineHeaderPaneUI extends PanelUI implements AnimatedPainter {
+ FineUIScale.scale(UIManager.getInt("ExpandablePane.HeaderPane.hGap"));
float titleY = (headerPane.getHeight() - (ascent + descent)) / 2.0f + ascent;
FlatUIUtils.setRenderingHints(g2d);
Icon icon = headerPane.getIcon();
if (icon != null) {
icon.paintIcon(c, g2d, (int) titleX, iconY);
titleX += icon.getIconWidth() + FineUIScale.scale(UIManager.getInt("ExpandablePane.HeaderPane.hGap") + UIManager.getInt("ExpandablePane.HeaderPane.iconGap"));
}
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.drawString(headerPane.getTitle(), titleX, titleY);

2
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTableModel.java

@ -21,7 +21,6 @@ import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableModelAdapter;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.stable.StringUtils;
@ -37,7 +36,6 @@ import javax.swing.UIManager;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableCellEditor;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;

17
designer-base/src/main/java/com/fr/design/foldablepane/HeaderPane.java

@ -2,6 +2,7 @@ package com.fr.design.foldablepane;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.UIManager;
@ -15,6 +16,7 @@ public class HeaderPane extends JPanel {
private boolean isShow;
private boolean isPressed = false;
private String title;
private Icon icon;
@Override
public String getUIClassID() {
@ -46,15 +48,24 @@ public class HeaderPane extends JPanel {
return title;
}
public HeaderPane() {
public HeaderPane(String title) {
this.isShow = true;
this.setForeground(UIManager.getColor("ExpandablePane.HeaderPane.foreground"));
this.setBorder(new ScaledEmptyBorder(17, 0, 17, 0));
}
public HeaderPane(String title) {
this();
public HeaderPane(String title, Icon icon) {
this(title);
this.title = title;
this.icon = icon;
}
public Icon getIcon() {
return icon;
}
public void setIcon(Icon icon) {
this.icon = icon;
}
}

13
designer-base/src/main/java/com/fr/design/foldablepane/UIExpandablePane.java

@ -4,6 +4,7 @@ import com.formdev.flatlaf.util.Animator;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.design.border.FineBorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
@ -29,6 +30,7 @@ public class UIExpandablePane extends JPanel {
private int fullHeight;
private final JPanel contentPanel;
private final String title;
private Icon icon;
public JPanel getContentPanel() {
return contentPanel;
@ -45,16 +47,25 @@ public class UIExpandablePane extends JPanel {
this(title, contentPanel, false);
}
public UIExpandablePane(String title, Icon icon, JPanel contentPanel) {
this(title, icon, contentPanel, false);
}
public UIExpandablePane(String title, JPanel contentPanel, boolean withUnderline) {
this(title, null, contentPanel, withUnderline);
}
public UIExpandablePane(String title, Icon icon, JPanel contentPanel, boolean withUnderline) {
super();
this.title = title;
this.contentPanel = contentPanel;
this.icon = icon;
initComponents(withUnderline);
}
private void initComponents(boolean withUnderline) {
this.setLayout(new BorderLayout());
HeaderPane headerPanel = new HeaderPane(title);
HeaderPane headerPanel = new HeaderPane(title, icon);
headerPanel.addMouseListener(new PanelAction());
setcontentPanelontentPanelBorder();
if (withUnderline) {

1
designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java

@ -15,7 +15,6 @@ import com.fr.stable.StringUtils;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;

17
designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java

@ -155,12 +155,29 @@ public class CenterRegionContainerPane extends JPanel {
//添加检测按钮
addCheckButton();
}
// 添加模板助手检测按钮
addShadowButton();
//添加分享按钮
addShareButton();
//添加插件中的按钮
addExtraButtons();
}
private void addShadowButton() {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (!JTemplate.isValid(jt)) {
return;
}
Component[] shadowButton = jt.createShadowButton();
if (shadowButton == null || shadowButton.length == 0) {
return;
}
combineUp.addSeparator(new Dimension(2, 16));
for (Component checkButton : shadowButton) {
combineUp.add(checkButton);
}
}
private void addExtraButtons() {

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

@ -51,6 +51,7 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.authority.JTemplateAuthorityChecker;
import com.fr.design.mainframe.chart.info.ChartInfoCollector;
import com.fr.design.mainframe.check.CheckButton;
import com.fr.design.mainframe.shadow.SCBridge4Designer;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
import com.fr.design.mainframe.template.info.TimeConsumeTimer;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
@ -103,9 +104,14 @@ import com.fr.widgettheme.designer.WidgetThemeDisplayAction;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
import javax.swing.undo.UndoManager;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.io.ByteArrayOutputStream;
import java.nio.file.Paths;
import java.util.Arrays;
@ -1601,6 +1607,14 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
return new UIButton[]{new CheckButton()};
}
/**
* 创建模板助手组件按钮
*/
public Component[] createShadowButton() {
return new Component[]{};
}
protected UIButton createTemplateThemeButton() {
UIButton button = new UIButton(new LazyIcon("template_theme"));
button.setToolTipText(getTemplateTheme().getName());
@ -1738,6 +1752,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
checkBeforeSave();
export();
this.editingFILE = editingFILE;
SCBridge4Designer.handleTemplateSave(this);
return true;
} else {
return false;

79
designer-base/src/main/java/com/fr/design/mainframe/shadow/SCBridge4Designer.java

@ -0,0 +1,79 @@
package com.fr.design.mainframe.shadow;
import com.fr.base.extension.FileExtension;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.log.FineLoggerFactory;
import com.fr.nx.analyze.shadow.manager.SCManager;
import com.fr.nx.analyze.shadow.manager.SCManagerFactory;
import com.fr.nx.analyze.shadow.metric.recorder.impl.SCDesignerMetricRecorder;
import com.fr.nx.analyze.shadow.template.SCTemplateHolder;
import com.fr.stable.project.ProjectConstants;
import org.jetbrains.annotations.NotNull;
import javax.swing.SwingWorker;
/**
* <p>监听器桥接类用于设计器环境
*
* @author Leo.Qin
* @since 10.0
* Created on 2021/8/24.
*/
public class SCBridge4Designer {
private SCBridge4Designer() {
}
/**
* 接受设计器中模版保存事件
*
* @param jTemplate 模版对象
*/
public static void handleTemplateSave(JTemplate<?, ?> jTemplate) {
Object tpl = jTemplate.getTarget();
SCTemplateHolder tplHolder = SCTemplateHolder.parse(tpl);
if (tplHolder == null) {
return;
}
String path = jTemplate.getPath();
if (path.startsWith(ProjectConstants.REPORTLETS_NAME)) {
path = path.substring(ProjectConstants.REPORTLETS_NAME.length() + 1);
final String workbookPath = path;
if (workbookPath.endsWith(FileExtension.CPTX.getExtension())) {
return;
}
// 另开线程执行编译优化(这是一个一次性线程,只会存在很短时间,是为了不阻塞设计器 UI)
SwingWorker<Boolean, Void> swingWorker = createSwingWorker(jTemplate, workbookPath, tplHolder);
swingWorker.execute();
}
}
private static @NotNull SwingWorker<Boolean, Void> createSwingWorker(JTemplate<?, ?> jTemplate, String workbookPath, SCTemplateHolder tplHolder) {
return new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
SCManager scManager = SCManagerFactory.sharedManager();
boolean existHistory = !scManager.hasHistoryShadowTemplate(workbookPath);
scManager.acquireShadowTemplate(
workbookPath,
tplHolder,
SCDesignerMetricRecorder.createOnSaveRecorder()
).get();
return existHistory;
}
@Override
protected void done() {
try {
//返回值代表是否是首次保存,目前没有用到,先记录一下,以免误解
get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
//在新的Thread线程中,refreshToolArea操作不能在edt线程中执行,会出现未知的错误。
DesignerContext.getDesignerFrame().resetToolkitByPlus(jTemplate);
}
};
}
}

23
designer-base/src/main/resources/com/fine/theme/icon/shadow/detect.svg

@ -0,0 +1,23 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_273_2804)">
<path d="M1.5 2C1.5 1.44772 1.94772 1 2.5 1L13.75 1C14.3023 1 14.75 1.44772 14.75 2V13.5C14.75 14.0523 14.3023 14.5 13.75 14.5H2.5C1.94772 14.5 1.5 14.0523 1.5 13.5V2Z"
fill="#5493F2"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M13.75 1.7H2.5C2.33431 1.7 2.2 1.83431 2.2 2V13.5C2.2 13.6657 2.33431 13.8 2.5 13.8H13.75C13.9157 13.8 14.05 13.6657 14.05 13.5V2C14.05 1.83431 13.9157 1.7 13.75 1.7ZM2.5 1C1.94772 1 1.5 1.44772 1.5 2V13.5C1.5 14.0523 1.94772 14.5 2.5 14.5H13.75C14.3023 14.5 14.75 14.0523 14.75 13.5V2C14.75 1.44772 14.3023 1 13.75 1H2.5Z"
fill="#105DD1"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M8.62295 5.13054L7.06394 12.2615C6.93472 12.8526 6.11103 12.9025 5.91139 12.3314L4.52972 8.37839H3.5C3.22386 8.37839 3 8.15453 3 7.87839C3 7.60225 3.22386 7.37839 3.5 7.37839H4.81364C5.0687 7.37839 5.29588 7.53965 5.38003 7.78042L6.38895 10.6669L7.99997 3.29797C8.13451 2.68261 9.00523 2.66383 9.1662 3.27278L10.9036 9.84501L12.0193 5.94362C12.0952 5.67812 12.372 5.52444 12.6375 5.60037C12.903 5.67629 13.0567 5.95307 12.9807 6.21857L11.4653 11.5178C11.2977 12.1039 10.4641 12.0955 10.3083 11.5061L8.62295 5.13054Z"
fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M14.7602 14.0243C15.8213 12.615 15.6984 10.5905 14.3999 9.29202C12.98 7.8721 10.692 7.85799 9.28948 9.26051C7.88696 10.663 7.90107 12.9511 9.32099 14.371C10.6194 15.6694 12.6437 15.7923 14.0531 14.7314L14.9371 15.6155C15.1324 15.8107 15.449 15.8107 15.6442 15.6155C15.8395 15.4202 15.8395 15.1036 15.6442 14.9083L14.7602 14.0243Z"
fill="#F6F9FE"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M13.9209 13.8921L14.161 13.5732C14.9962 12.4639 14.9051 10.8578 13.8696 9.82235C12.7364 8.68914 10.9233 8.68736 9.81981 9.79084C8.71633 10.8943 8.71811 12.7074 9.85132 13.8406C10.8867 14.8761 12.4927 14.9672 13.602 14.1322L13.9209 13.8921ZM14.7602 14.0243L15.6442 14.9083C15.8395 15.1036 15.8395 15.4202 15.6442 15.6155C15.449 15.8107 15.1324 15.8107 14.9371 15.6155L14.0531 14.7314C12.6437 15.7923 10.6194 15.6694 9.32099 14.371C7.90107 12.9511 7.88696 10.663 9.28948 9.26051C10.692 7.85799 12.98 7.8721 14.3999 9.29202C15.6984 10.5905 15.8213 12.615 14.7602 14.0243Z"
fill="#0A1C38" fill-opacity="0.9"/>
</g>
<defs>
<clipPath id="clip0_273_2804">
<rect width="16" height="16" fill="white" transform="translate(0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

8
designer-base/src/main/resources/com/fine/theme/icon/shadow/error.svg

@ -0,0 +1,8 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M15.5 8C15.5 11.8656 12.3656 15 8.5 15C4.63435 15 1.5 11.8656 1.5 8C1.5 4.13435 4.63435 1 8.5 1C12.3656 1 15.5 4.13435 15.5 8Z"
fill="#F1393C"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M11.3284 6.0201C11.5627 5.78578 11.5627 5.40588 11.3284 5.17157C11.0941 4.93725 10.7142 4.93725 10.4799 5.17157L8.5 7.15147L6.5201 5.17157C6.28579 4.93725 5.90589 4.93725 5.67157 5.17157C5.43726 5.40588 5.43726 5.78578 5.67157 6.0201L7.65147 7.99999L5.67157 9.97989C5.43726 10.2142 5.43726 10.5941 5.67157 10.8284C5.90589 11.0627 6.28579 11.0627 6.5201 10.8284L8.5 8.84852L10.4799 10.8284C10.7142 11.0627 11.0941 11.0627 11.3284 10.8284C11.5627 10.5941 11.5627 10.2142 11.3284 9.97989L9.34853 7.99999L11.3284 6.0201Z"
fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 927 B

13
designer-base/src/main/resources/com/fine/theme/icon/shadow/risk.svg

@ -0,0 +1,13 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="&#230;&#143;&#144;&#231;&#164;&#186;">
<path id="&#229;&#189;&#162;&#231;&#138;&#182;&#231;&#187;&#147;&#229;&#144;&#136;" fill-rule="evenodd"
clip-rule="evenodd"
d="M15 8C15 11.8656 11.8656 15 8 15C4.13435 15 1 11.8656 1 8C1 4.13435 4.13435 1 8 1C11.8656 1 15 4.13435 15 8Z"
fill="#F9AE31"/>
<path id="Path" fill-rule="evenodd" clip-rule="evenodd"
d="M7.43333 10.292C7.27777 10.4476 7.2 10.6365 7.2 10.8587C7.2 11.0809 7.27777 11.2698 7.43333 11.4254C7.58889 11.5809 7.77777 11.6587 8 11.6587C8.22222 11.6587 8.41111 11.5809 8.56666 11.4254C8.72222 11.2698 8.8 11.0809 8.8 10.8587C8.8 10.6365 8.72222 10.4476 8.56666 10.292C8.41111 10.1365 8.22222 10.0587 8 10.0587C7.77777 10.0587 7.58889 10.1365 7.43333 10.292Z"
fill="white"/>
<rect id="&#231;&#159;&#169;&#229;&#189;&#162;" x="7.3" y="4.22131" width="1.4" height="5" rx="0.7"
fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

5
designer-base/src/main/resources/com/fine/theme/icon/shadow/success.svg

@ -0,0 +1,5 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M8.5 15C12.3656 15 15.5 11.8656 15.5 8C15.5 4.13435 12.3656 1 8.5 1C4.63435 1 1.5 4.13435 1.5 8C1.5 11.8656 4.63435 15 8.5 15ZM4.69061 7.66137C4.93286 7.43527 5.31254 7.44836 5.53864 7.69061L7.43334 9.72065L11.6614 5.19061C11.8875 4.94836 12.2671 4.93527 12.5094 5.16137C12.7516 5.38747 12.7647 5.76714 12.5386 6.00939L7.87197 11.0094C7.63477 11.2635 7.2319 11.2635 6.9947 11.0094L4.66137 8.50939C4.43527 8.26714 4.44836 7.88747 4.69061 7.66137Z"
fill="#46B15D"/>
</svg>

After

Width:  |  Height:  |  Size: 640 B

10
designer-base/src/main/resources/com/fine/theme/icon/shadow/suggestion.svg

@ -0,0 +1,10 @@
<svg width="14" height="13" viewBox="0 0 14 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group 1210707234">
<path id="Rectangle 34627615"
d="M0 1C0 0.447715 0.447715 0 1 0H13C13.5523 0 14 0.447715 14 1V10C14 10.5523 13.5523 11 13 11H10.5H8.75L7.37629 12.57C7.17708 12.7976 6.82292 12.7976 6.62371 12.57L5.25 11H3.5H1C0.447715 11 0 10.5523 0 10V1Z"
fill="#46B15D"/>
<circle id="Ellipse 598" cx="3" cy="5.5" r="1" fill="white"/>
<circle id="Ellipse 599" cx="7" cy="5.5" r="1" fill="white"/>
<circle id="Ellipse 600" cx="11" cy="5.5" r="1" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 646 B

7
designer-base/src/main/resources/com/fine/theme/light/ui/fine_light.icon.json

@ -515,6 +515,11 @@
"auto_chart": {
"normal": "insert/auto_chart_normal.svg",
"disable": "insert/auto_chart_disabled.svg"
}
},
"shadow_detect": "shadow/detect.svg",
"shadow_success": "shadow/success.svg",
"shadow_error": "shadow/error.svg",
"shadow_risk": "shadow/risk.svg",
"shadow_suggestion": "shadow/suggestion.svg"
}
}

1
designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties

@ -1185,6 +1185,7 @@ West.border = $defaultBorderColor
#---- ExpandablePane ----
ExpandablePane.HeaderPane.borderInsets=0, 6, 0, 6
ExpandablePane.HeaderPane.hGap=0
ExpandablePane.HeaderPane.iconGap=4
ExpandablePane.vGap=5
HeaderPane.width=248
HeaderPane.height=$Component.defaultHeight

1
designer-base/src/test/java/com/fr/design/gui/storybook/components/ComboCheckBoxStoryBoard.java

@ -5,7 +5,6 @@ import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.storybook.StoryBoard;
import com.fr.stable.ArrayUtils;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.flex;

4
designer-base/src/test/java/com/fr/design/gui/storybook/components/ExpandablePaneStoryBoard.java

@ -1,5 +1,6 @@
package com.fr.design.gui.storybook.components;
import com.fine.theme.icon.LazyIcon;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
@ -8,7 +9,7 @@ import com.fr.design.gui.storybook.StoryBoard;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import static com.fine.swing.ui.layout.Layouts.*;
import static com.fine.swing.ui.layout.Layouts.cell;
/**
* 扩展面板
@ -22,6 +23,7 @@ public class ExpandablePaneStoryBoard extends StoryBoard {
super("扩展面板");
add(cell(new UIExpandablePane("扩展", createContentPane())));
add(cell(new UIExpandablePane("扩展2", createContentPane2())));
add(cell(new UIExpandablePane("带图标的扩展", new LazyIcon("logo"), createContentPane2())));
}

19
designer-chart/src/main/java/com/fr/design/chart/AutoChartTypePane.java

@ -1,6 +1,7 @@
package com.fr.design.chart;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.chart.chartdata.CallbackEvent;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.design.chart.auto.AutoTypeCalculate;
@ -18,7 +19,6 @@ import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.GeneralUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.chart.vanchart.VanChart;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
@ -34,24 +34,23 @@ import javax.swing.UIManager;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.SplitPaneUI;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CancellationException;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CancellationException;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* @author Bjorn

2
designer-chart/src/main/java/com/fr/van/chart/designer/type/AbstractVanChartTypePane.java

@ -1,9 +1,7 @@
package com.fr.van.chart.designer.type;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.BaseUtils;
import com.fr.base.chart.chartdata.TopDefinitionProvider;
import com.fr.base.svg.IconUtils;
import com.fr.chart.base.AttrFillStyle;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.chartattr.Legend;

4
designer-realize/src/main/java/com/fanruan/boot/init/DesignWorkContextComponent.java

@ -8,6 +8,7 @@ import com.fanruan.carina.annotions.Start;
import com.fanruan.carina.annotions.Stop;
import com.fanruan.carina.annotions.Supplemental;
import com.fanruan.plugin.autonomy.AutonomyClassManagerGroup;
import com.fanruan.repository.ConfigRepository;
import com.fanruan.repository.TemplateRepository;
import com.fanruan.workplace.conetxt.CompatiblePool;
import com.fanruan.workplace.http.HttpConstants;
@ -35,6 +36,7 @@ import com.fr.file.filetree.FileNodes;
import com.fr.file.filetree.LocalFileNodes;
import com.fr.general.build.BuildInfoOperator;
import com.fr.general.build.impl.BuildInfoOperatorImpl;
import com.fr.nx.analyze.shadow.workspace.repository.ShadowRepository;
import com.fr.report.UnLockedHandler;
import com.fr.security.encryption.storage.StorageEncryptors;
import com.fr.security.encryption.storage.StorageTransfer;
@ -62,7 +64,6 @@ import com.fr.workspace.pool.WorkRPCType;
import com.fr.workspace.resource.WorkResource;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import com.fr.workspace.server.repository.compatible.register.CompatibleRegister;
import com.fanruan.repository.ConfigRepository;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.map.MapRepository;
import com.fr.workspace.server.repository.plugin.PluginRepository;
@ -119,6 +120,7 @@ public class DesignWorkContextComponent {
RepositoryManager.getInstance().pureRegisterRepo4Start(ConfigRepository.getInstance());
RepositoryManager.getInstance().pureRegisterRepo4Start(PluginRepository.getInstance());
RepositoryManager.getInstance().pureRegisterRepo4Start(MapRepository.getInstance());
RepositoryManager.getInstance().pureRegisterRepo4Start(ShadowRepository.getInstance());
RepositoryManager.getInstance().initLocalRepository();
CompatibleRegister.registerCompatibleEnv();
for (WorkRPCRegister<?> workRPCRegister : ServiceContext.group(WorkspaceKey.class).getAll()) {

14
designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe;
import com.fanruan.product.ProductConstants;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.DynamicUnitList;
import com.fr.base.Parameter;
@ -50,6 +51,8 @@ import com.fr.design.gui.icontainer.UIModeControlContainer;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.cell.QuickEditorRegion;
import com.fr.design.mainframe.shadow.action.DetectErrorShowAction;
import com.fr.design.mainframe.shadow.action.TemplateHelperAction;
import com.fr.design.mainframe.template.info.JWorkBookProcessInfo;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
import com.fr.design.mainframe.theme.dialog.TemplateThemeUsingDialog;
@ -103,7 +106,6 @@ import com.fr.report.poly.PolyWorkSheet;
import com.fr.report.worksheet.WorkSheet;
import com.fr.stable.ArrayUtils;
import com.fr.stable.AssistUtils;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.module.Module;
@ -115,6 +117,7 @@ import com.fr.workspace.WorkContext;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileOutputStream;
@ -1229,6 +1232,15 @@ public class JWorkBook extends JTemplate<WorkBook, WorkBookUndoState> {
// return new UIButton[]{new ShareButton()};
}
@Override
public Component[] createShadowButton() {
TemplateHelperAction templateHelperAction = new TemplateHelperAction();
UIButton templateHelperUIButton = (UIButton) templateHelperAction.createToolBarComponent();
DetectErrorShowAction detectErrorShowAction = new DetectErrorShowAction();
UIButton errorComponents = (UIButton) detectErrorShowAction.createToolBarComponent();
return new Component[]{templateHelperUIButton, errorComponents};
}
@Override
public String route() {
return ViewRequestConstants.REPORT_VIEW_PATH;

2
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/DesensitizationCellPane.java

@ -38,8 +38,8 @@ 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;
import static com.fine.swing.ui.layout.Layouts.fix;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.theme.utils.FineUIStyle.PLAIN_BUTTON;
import static com.fine.theme.utils.FineUIStyle.TRANSPARENT_TEXT_FIELD;
import static com.fine.theme.utils.FineUIStyle.setStyle;

116
designer-realize/src/main/java/com/fr/design/mainframe/shadow/action/DetectErrorShowAction.java

@ -0,0 +1,116 @@
package com.fr.design.mainframe.shadow.action;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.extension.FileExtension;
import com.fr.design.actions.UpdateAction;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.detect.SCDefaultSCTemplateHelper;
import com.fr.design.mainframe.shadow.ui.detect.SCDefaultSCTemplateHelperDetect;
import com.fr.design.menu.MenuKeySet;
import com.fr.log.FineLoggerFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.SwingWorker;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER;
/**
* 检测错误action
*
* @author fly.li
* @since 10.0
* Created on 2021/8/14
*/
public class DetectErrorShowAction extends UpdateAction {
private static final MenuKeySet DETECT_ATTR = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'E';
}
@Override
public String getMenuName() {
return Toolkit.i18nText("Fine-Design_Template_Assistant_Detect_Error_Tip");
}
@Override
public KeyStroke getKeyStroke() {
return KeyStroke.getKeyStroke(KeyEvent.VK_T, DEFAULT_MODIFIER);
}
};
public DetectErrorShowAction() {
init();
}
@Override
public void actionPerformed(ActionEvent e) {
SCDefaultSCTemplateHelper.getInstance().startShow(false);
}
private void init() {
this.setMenuKeySet(DETECT_ATTR);
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setName(getMenuKeySet().getMenuKeySetName());
this.setAccelerator(getMenuKeySet().getKeyStroke());
}
@Override
public boolean isEnabled() {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String path = jt.getEditingFILE().getPath();
return FileExtension.CPT.matchExtension(path) || FileExtension.FRM.matchExtension(path);
}
@Override
public JComponent createToolBarComponent() {
UIButton transBtn = (UIButton) super.createToolBarComponent();
transBtn.set4ToolbarButton();
transBtn.setForeground(Color.RED);
transBtn.setToolTipText(Toolkit.i18nText("Fine-Design_Template_Assistant_Detect_Error_Tip"));
SwingWorker<Integer, Void> worker = new SwingWorker<Integer, Void>() {
@Override
protected Integer doInBackground() {
return SCDefaultSCTemplateHelperDetect.getInstance().errorCount(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate());
}
@Override
protected void done() {
int errorCount = 0;
try {
errorCount = get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
transBtn.setIcon(getIcon(errorCount));
if (errorCount > 0) {
transBtn.setText(String.valueOf(errorCount));
}
}
};
worker.execute();
return transBtn;
}
private Icon getIcon(int errorCount) {
Icon icon = null;
if (errorCount == 0) {
icon = new LazyIcon("shadow_success");
} else if (errorCount > 0) {
icon = new LazyIcon("shadow_error");
}
return icon;
}
}

82
designer-realize/src/main/java/com/fr/design/mainframe/shadow/action/TemplateHelperAction.java

@ -0,0 +1,82 @@
package com.fr.design.mainframe.shadow.action;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.extension.FileExtension;
import com.fr.design.actions.UpdateAction;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.detect.SCDefaultSCTemplateHelper;
import com.fr.design.menu.MenuKeySet;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER;
/**
* 模板助手检测action
*
* @author fly.li
* @since 10.0
* Created on 2021/8/5
*/
public class TemplateHelperAction extends UpdateAction {
private static final MenuKeySet DETECT_ATTR = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'D';
}
@Override
public String getMenuName() {
return Toolkit.i18nText("Fine-Design_Template_Assistant_Template_Detect_Helper");
}
@Override
public KeyStroke getKeyStroke() {
return KeyStroke.getKeyStroke(KeyEvent.VK_T, DEFAULT_MODIFIER);
}
};
public TemplateHelperAction() {
init();
}
private void init() {
this.setMenuKeySet(DETECT_ATTR);
this.setSmallIcon(new LazyIcon("shadow_detect"));
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setName(getMenuKeySet().getMenuKeySetName());
this.setAccelerator(getMenuKeySet().getKeyStroke());
}
@Override
public void actionPerformed(ActionEvent e) {
SCDefaultSCTemplateHelper.getInstance().startAndShow();
}
@Override
public boolean isEnabled() {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String path = jt.getEditingFILE().getPath();
// 不在当前工作目录下,不启用模板助手
if (!jt.getEditingFILE().isEnvFile()) {
return false;
}
return FileExtension.CPT.matchExtension(path) || FileExtension.FRM.matchExtension(path);
}
@Override
public JComponent createToolBarComponent() {
UIButton transBtn = (UIButton) super.createToolBarComponent();
transBtn.set4ToolbarButton();
transBtn.setToolTipText(Toolkit.i18nText("Fine-Design_Template_Assistant_Template_Detect_Helper"));
return transBtn;
}
}

19
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/SCJumpHandler.java

@ -0,0 +1,19 @@
package com.fr.design.mainframe.shadow.handler;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
/**
* @author fly.li
* @since 10.0
* Created on 2021/7/21
* 跳转界面处理接口
*/
public interface SCJumpHandler {
/**
* 根据传入的参数信息来具体的跳转进行处理为总的流程
*/
void handle(SCRecordJumper scRecordJumper, int sheetIndex);
}

71
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/SCJumpHandlerProvider.java

@ -0,0 +1,71 @@
package com.fr.design.mainframe.shadow.handler;
import com.fr.design.mainframe.shadow.handler.impl.DefaultSCJumpHandler;
import com.fr.design.mainframe.shadow.handler.impl.SCCellSCJumpHandler;
import com.fr.design.mainframe.shadow.handler.impl.SCDataSourceRecordHandler;
import com.fr.design.mainframe.shadow.handler.impl.SCGlobalParameterJumpHandler;
import com.fr.design.mainframe.shadow.handler.impl.SCNxCompileJumperHandler;
import com.fr.design.mainframe.shadow.handler.impl.SCWatermarkJumpHandler;
import com.fr.design.mainframe.shadow.handler.impl.SCWebLinkJumpHandler;
import com.fr.nx.analyze.shadow.metric.recorder.SCMetricRecorder;
import com.fr.nx.analyze.shadow.metric.recorder.impl.SCDesignerMetricRecorder;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCCellJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCGlobalParameterJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCNxCompileJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCTableDataJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCWatermarkJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCWebLinkJumper;
import java.util.Collections;
import java.util.HashMap;
/**
* <>跳转到设计器相应界面的接口</>
*
* @author fly.li
* @since 10.0
* Created on 2021/8/7
*/
public class SCJumpHandlerProvider {
private static HashMap<String, SCJumpHandler> handlers;
private static ThreadLocal<SCMetricRecorder> recorder = ThreadLocal.withInitial(SCDesignerMetricRecorder::createOnJumpRecorder);
static {
handlers = new HashMap<>();
handlers.put(SCCellJumper.class.getName(), new SCCellSCJumpHandler());
handlers.put(SCTableDataJumper.class.getName(), new SCDataSourceRecordHandler());
handlers.put(SCWebLinkJumper.class.getName(), new SCWebLinkJumpHandler());
handlers.put(SCNxCompileJumper.class.getName(), new SCNxCompileJumperHandler());
handlers.put(SCGlobalParameterJumper.class.getName(), new SCGlobalParameterJumpHandler());
handlers.put(SCWatermarkJumper.class.getName(), new SCWatermarkJumpHandler());
}
private SCJumpHandlerProvider() {
}
/**
* 添加handler
*
* @param key key
* @param handler handler
*/
public static void addHandler(String key, SCJumpHandler handler) {
handlers.put(key, handler);
}
/**
* 这里根据传入的信息不同调用不同的handler进行处理需要传入相关的信息参数
*/
public static void jumpToTarget(SCRecordJumper scRecordJumper, int sheetIndex) {
handlers.getOrDefault(scRecordJumper.getClass().getName(), new DefaultSCJumpHandler()).handle(scRecordJumper, sheetIndex);
// 记录跳转埋点
if (scRecordJumper.getMetricType() != null) {
recorder.get().record(Collections.singleton(scRecordJumper.getMetricType()));
}
}
}

19
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/DefaultSCJumpHandler.java

@ -0,0 +1,19 @@
package com.fr.design.mainframe.shadow.handler.impl;
import com.fr.design.mainframe.shadow.handler.SCJumpHandler;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
/**
* 跳转界面处理接口
*
* @author fly.li
* @since 10.0
* Created on 2021/7/21
*/
public class DefaultSCJumpHandler implements SCJumpHandler {
@Override
public void handle(SCRecordJumper scRecordJumper, int sheetIndex) {
}
}

172
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCCellSCJumpHandler.java

@ -0,0 +1,172 @@
package com.fr.design.mainframe.shadow.handler.impl;
import com.fr.base.BaseFormula;
import com.fr.design.cell.editor.CellEditor;
import com.fr.design.dscolumn.DSColumnPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.ReportComponent;
import com.fr.design.mainframe.ReportComponentCardPane;
import com.fr.design.mainframe.shadow.handler.SCJumpHandler;
import com.fr.design.mainframe.shadow.utils.DesignerPaneUtil;
import com.fr.grid.Grid;
import com.fr.grid.selection.CellSelection;
import com.fr.grid.selection.Selection;
import com.fr.invoke.Reflect;
import com.fr.main.impl.WorkBook;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCCellJumper;
import com.fr.nx.analyze.shadow.record.jumper.type.CellAttrType;
import com.fr.report.block.ElementCaseBlockImplement;
import com.fr.report.cell.CellElement;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.cell.cellattr.core.group.DSColumn;
import com.fr.report.elementcase.TemplateElementCase;
import com.fr.report.worksheet.WorkSheet;
import com.fr.stable.ColumnRow;
import java.awt.Component;
import java.awt.Window;
/**
* 单元格跳转handler
*
* @author fly.li
* @since 10.0
* Created on 2021/09/18
*/
public class SCCellSCJumpHandler implements SCJumpHandler {
@Override
public void handle(SCRecordJumper scRecordJumper, int sheetIndex) {
ColumnRow columnRow = ((SCCellJumper) scRecordJumper).getColumnRow();
ElementCasePane elementCasePane = getElementCasePane(columnRow, sheetIndex);
handle0(elementCasePane, ((SCCellJumper) scRecordJumper).getCellAttrType());
}
/**
* 先使用if else实现
*/
private void handle0(ElementCasePane elementCasePane, CellAttrType cellAttrType) {
//进行公式界面或者条件过滤面板的跳转
Grid grid = elementCasePane.getGrid();
switch (cellAttrType) {
case FORMULA:
startEditing(grid, BaseFormula.class);
break;
case DATA_COlUMN:
startEditing(grid, DSColumn.class);
break;
default:
}
}
private ElementCasePane getElementCasePane(ColumnRow columnRow, int sheetIndex) {
JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
WorkBook workBook = (WorkBook) currentEditingTemplate.getTarget();
WorkSheet workSheet = (WorkSheet) workBook.getTemplateReport(sheetIndex);
ReportComponentCardPane reportComponentCardPane = DesignerPaneUtil.getCurrentReportComponentCardPane();
changeCurrentSheet(reportComponentCardPane, workSheet);
ElementCasePane elementCasePane = getEditingElementCasePane(reportComponentCardPane);
ElementCaseBlockImplement block = workSheet.getBlock();
CellElement cellElement = block.getCellElement(columnRow.getColumn(), columnRow.getRow());
int columnSpan = cellElement.getColumnSpan();
int rowSpan = cellElement.getRowSpan();
elementCasePane.setSelection(new CellSelection(cellElement.getColumn(), cellElement.getRow(), columnSpan, rowSpan));
return elementCasePane;
}
private ElementCasePane getEditingElementCasePane(ReportComponentCardPane reportComponentCardPane) {
ReportComponent reportComponent = Reflect.on(reportComponentCardPane).get("editingComponet");
ElementCasePane editingElementCasePane = reportComponent.getEditingElementCasePane();
return editingElementCasePane;
}
private void changeCurrentSheet(ReportComponentCardPane reportComponentCardPane, WorkSheet workSheet) {
Reflect.on(reportComponentCardPane).call("showJWorkSheet", workSheet);
}
private void startEditing(Grid grid, Class type) {
gridAttributesSetting(grid, type);
Component editorComponent = grid.getEditorComponent();
if (editorComponent instanceof Window) {
//如果是数据列,需要设置默认tab为"过滤"
if (type == DSColumn.class) {
CellEditor cellEditor = grid.getCellEditor();
setDefaultTab(cellEditor);
}
showPaneOnTop((Window) editorComponent);
}
}
/**
* 标注一下复用的是Grid#startCellEditingAt_DEC()的代码
* (复用的原因是需要将数据列设置的默认选项卡设置为过滤tab以及在mac中需要将面板显示在最顶层)
*/
private void gridAttributesSetting(Grid grid, Class type) {
if (grid.isEditing()) {
grid.stopEditing();
}
if (!grid.isEditable()) {
return;
}
ElementCasePane reportPane = grid.getElementCasePane();
TemplateElementCase report = reportPane.getEditingElementCase();
Selection s = reportPane.getSelection();
int row = -1;
int column = -1;
if (s instanceof CellSelection) {
CellSelection selection = (CellSelection) s;
row = selection.getRow();
column = selection.getColumn();
}
if (row < 0 || column < 0) {
return;
}
grid.setEditingColumn(column);
grid.setEditingRow(row);
modifyGridAttr(grid, type, report, column, row);
}
private static void modifyGridAttr(Grid grid, Class type, TemplateElementCase report, int column, int row) {
TemplateCellElement editingCellElement = report.getTemplateCellElement(column, row);
if (editingCellElement == null) {
//为null返回,在fr11中有另外的处理,需要注意
return;
}
Reflect.on(grid).set("editingCellElement", editingCellElement);
CellEditor cellEditor = grid.getDefaultCellEditor(type);
if (cellEditor == null) {
return;
}
grid.setCellEditor(cellEditor);
//在这个地方将数据列设置面板放在了cellEditor的属性中,但是返回的只是一个dialog,后面要拿到面板,需要从cellEditor中拿
Component editorComponent = Reflect.on(grid).call("getCellEditingComp").get();
if (editorComponent == null) {
return;
}
Reflect.on(grid).set("editorComponent", editorComponent);
}
/**
* 设置默认选项卡为"过滤"
*/
private void setDefaultTab(CellEditor cellEditor) {
DSColumnPane dsColumnPane = Reflect.on(cellEditor).get("dsColumnPane");
//根据tab标题找到index,不能写死为1
UITabbedPane tabbedPane = Reflect.on(dsColumnPane).get("tabbedPane");
int index = tabbedPane.indexOfTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Filter"));
tabbedPane.setSelectedIndex(index);
}
/**
* 在最顶层显示面板
*/
private void showPaneOnTop(Window window) {
window.setAlwaysOnTop(true);
window.setVisible(true);
}
}

133
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCDataSourceRecordHandler.java

@ -0,0 +1,133 @@
package com.fr.design.mainframe.shadow.handler.impl;
import com.fr.base.TableData;
import com.fr.data.TableDataSource;
import com.fr.data.impl.TableDataSourceDependent;
import com.fr.design.DesignModelAdapter;
import com.fr.design.data.BasicTableDataTreePane;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTree;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.data.tabledata.StoreProcedureWorkerListener;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.mainframe.shadow.handler.SCJumpHandler;
import com.fr.general.ComparatorUtils;
import com.fr.general.NameObject;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCTableDataJumper;
import com.fr.stable.core.PropertyChangeAdapter;
import org.jetbrains.annotations.NotNull;
import org.jooq.tools.reflect.Reflect;
import javax.swing.SwingUtilities;
import java.util.HashMap;
import java.util.Map;
/**
* @author fly.li
* @since 10.0
* Created on 2021/8/7
* <>跳转到数据集界面</>
*/
public class SCDataSourceRecordHandler implements SCJumpHandler {
@Override
public void handle(SCRecordJumper scRecordJumper, int sheetIndex) {
String dsName = ((SCTableDataJumper) scRecordJumper).getDsName();
TemplateTableDataWrapper ds = findDS(dsName);
if (ds != null) {
TableDataTreePane tableDataTreePane = (TableDataTreePane) TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter());
showTableDataPane(ds.creatTableDataPane(), dsName, tableDataTreePane);
}
}
private TemplateTableDataWrapper findDS(String DSName) {
BasicTableDataTreePane instance = TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter());
TableDataTree dataTree = instance.getDataTree();
ExpandMutableTreeNode root = (ExpandMutableTreeNode) dataTree.getModel().getRoot();
int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
ExpandMutableTreeNode child = (ExpandMutableTreeNode) root.getChildAt(i);
NameObject userObject = (NameObject) child.getUserObject();
TemplateTableDataWrapper templateTableDataWrapper = (TemplateTableDataWrapper) userObject.getObject();
if (DSName.equals(templateTableDataWrapper.getTableDataName())) {
return templateTableDataWrapper;
}
}
return null;
}
/**
* 标识一下复用了TableDataTreePane#dgEdit方法目的是为了mac中数据集设置面板弹窗默认在最顶层
* 改行为新添加非复用代码dg.setAlwaysOnTop(true)
*/
private void showTableDataPane(final AbstractTableDataPane<?> tableDataPane, String originalName, TableDataTreePane tableDataTreePane) {
tableDataPane.addStoreProcedureWorkerListener(createStoreProcedureWorkerListener(tableDataTreePane));
final BasicPane.NamePane namePane = tableDataPane.asNamePane();
namePane.setObjectName(originalName);
DesignModelAdapter tc = Reflect.on(tableDataTreePane).get("tc");
Reflect.on(tableDataTreePane).set("allDSNames", DesignTableDataManager.getAllDSNames(tc.getBook()));
final BasicDialog dg = namePane.showLargeWindow(SwingUtilities.getWindowAncestor(tableDataTreePane), createActionAdapter(tableDataPane, originalName, tableDataTreePane, tc, namePane));
namePane.addPropertyChangeListener(new PropertyChangeAdapter() {
public void propertyChange() {
Reflect.on(tableDataTreePane).call("doPropertyChange", dg, namePane, originalName);
}
});
dg.setAlwaysOnTop(true);
dg.setVisible(true);
}
private static @NotNull DialogActionAdapter createActionAdapter(AbstractTableDataPane<?> tableDataPane, String originalName, TableDataTreePane tableDataTreePane, DesignModelAdapter tc, BasicPane.NamePane namePane) {
return new DialogActionAdapter() {
@Override
public void doOk() {
DesignTableDataManager.setThreadLocal(DesignTableDataManager.NO_PARAMETER);
tc.renameTableData(originalName, namePane.getObjectName(), false);
TableDataSource tds = tc.getBook();
TableData td = tableDataPane.updateBean();
if (td instanceof TableDataSourceDependent) {
((TableDataSourceDependent) td).setTableDataSource(tds);
}
String tdName = namePane.getObjectName();
tds.putTableData(tdName, td);
Map map = new HashMap();
if (!ComparatorUtils.equals(originalName, tdName)) {
map.put(originalName, tdName);
}
tableDataTreePane.fireDSChanged(map);
tc.fireTargetModified();
tc.tableDataParametersChanged(originalName, tdName, td);
TableDataTree dataTree = tableDataTreePane.getDataTree();
int[] rows = dataTree.getSelectionRows();
dataTree.refreshChildByName(tdName);
dataTree.setSelectionRows(rows);
}
};
}
private static @NotNull StoreProcedureWorkerListener createStoreProcedureWorkerListener(TableDataTreePane tableDataTreePane) {
return () -> {
TableDataTree dataTree = tableDataTreePane.getDataTree();
if (dataTree.getSelectionPath() == null) {
dataTree.refresh();
} else {
Object object = dataTree.getSelectionPath().getLastPathComponent();
int[] rows = dataTree.getSelectionRows();
dataTree.refreshChildByName(object.toString());
dataTree.setSelectionRows(rows);
}
};
}
}

84
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCGlobalParameterJumpHandler.java

@ -0,0 +1,84 @@
package com.fr.design.mainframe.shadow.handler.impl;
import com.fr.base.ParameterConfig;
import com.fr.config.ServerPreferenceConfig;
import com.fr.design.DesignModelAdapter;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.shadow.handler.SCJumpHandler;
import com.fr.design.parameter.ParameterManagerPane;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import com.fr.workspace.WorkContext;
import org.jetbrains.annotations.NotNull;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
/**
* 全局参数跳转handler
*
* @author fly.li
* @since 10.0
* Created on 2021/12/22
*/
public class SCGlobalParameterJumpHandler implements SCJumpHandler {
@Override
public void handle(SCRecordJumper scRecordJumper, int sheetIndex) {
DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
if (notJump()) {
FineJOptionPane.showMessageDialog(
designerFrame,
Toolkit.i18nText("Fine-Design_Template_Assistant_Jump_No_Auth"),
Toolkit.i18nText("Fine-Design_Basic_Error"),
JOptionPane.ERROR_MESSAGE,
UIManager.getIcon("OptionPane.errorIcon"));
return;
}
ParameterManagerPane parameterManagerPane = new ParameterManagerPane();
BasicDialog parameterManagerDialog = parameterManagerPane.showWindow(designerFrame);
//marks:读取服务器配置信息
parameterManagerPane.populate(ParameterConfig.getInstance().getGlobalParameters());
parameterManagerDialog.addDialogActionListener(createActionListener(parameterManagerPane, parameterManagerDialog));
parameterManagerDialog.setModal(true);
parameterManagerDialog.setAlwaysOnTop(true);
parameterManagerDialog.setVisible(true);
}
private static @NotNull DialogActionAdapter createActionListener(ParameterManagerPane parameterManagerPane, BasicDialog parameterManagerDialog) {
return new DialogActionAdapter() {
public void doOk() {
Configurations.modify(new WorkerFacade(ServerPreferenceConfig.class) {
@Override
public void run() {
parameterManagerPane.update();
}
}.addCallBack(new CallBackAdaptor() {
@Override
public void afterCommit() {
DesignModelAdapter<?, ?> model = DesignModelAdapter.getCurrentModelAdapter();
if (model != null) {
model.parameterChanged();
}
parameterManagerDialog.setDoOKSucceed(!parameterManagerPane.isContainsRename());
}
}));
}
};
}
/**
* 判断是否屏蔽全局参数配置界面
* 如果当前环境是远程环境并且登录用户为非管理员则不跳转其他情况都跳转
*/
private boolean notJump() {
return WorkContext.getCurrent() != null && !WorkContext.getCurrent().isLocal() && !WorkContext.getCurrent().isRoot();
}
}

29
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCNxCompileJumperHandler.java

@ -0,0 +1,29 @@
package com.fr.design.mainframe.shadow.handler.impl;
import com.fr.design.mainframe.shadow.handler.SCJumpHandler;
import com.fr.design.mainframe.shadow.ui.detect.SCDefaultSCTemplateHelper;
import com.fr.invoke.Reflect;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.stable.StringUtils;
import java.awt.event.ActionEvent;
/**
* @author Leo.Qin
* @since 10.0
* Created on 2021/10/8.
*
* <p>新引擎预编译的跳转处理器
*/
public class SCNxCompileJumperHandler implements SCJumpHandler {
@Override
public void handle(SCRecordJumper scRecordJumper, int sheetIndex) {
// 由于模块依赖问题,暂时先用反射了
Reflect.on("com.fr.plugin.designer.toolbar.CompileAction", this.getClass().getClassLoader())
.create()
.call("actionPerformed", new ActionEvent(this, ActionEvent.ACTION_FIRST, StringUtils.EMPTY));
// 关掉当前面板
SCDefaultSCTemplateHelper.getInstance().close();
}
}

54
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCWatermarkJumpHandler.java

@ -0,0 +1,54 @@
package com.fr.design.mainframe.shadow.handler.impl;
import com.fr.base.iofile.attr.WatermarkAttr;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.handler.SCJumpHandler;
import com.fr.design.report.WatermarkSettingPane;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.main.impl.WorkBook;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.report.core.ReportUtils;
/**
* 水印跳转handler
*
* @author fly.li
* @since 10.0
* Created on 2021/12/23
*/
public class SCWatermarkJumpHandler implements SCJumpHandler {
@Override
public void handle(SCRecordJumper scRecordJumper, int sheetIndex) {
JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
Object target = currentEditingTemplate.getTarget();
if (target instanceof WorkBook) {
WorkBook workBook = (WorkBook) target;
WatermarkAttr watermarkAttr = ReportUtils.getWatermarkAttrFromServerConfig();
WatermarkSettingPane watermarkPane = new WatermarkSettingPane();
watermarkPane.populate(watermarkAttr);
BasicDialog dialog = watermarkPane.showWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
public void doOk() {
workBook.addAttrMark(watermarkPane.update());
currentEditingTemplate.fireTargetModified();
SCWatermarkJumpHandler.this.recordFunction();
}
});
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
}
}
@Focus(
id = "com.fr.watermark",
text = "Fine-Design_Form_WaterMark",
source = Original.EMBED
)
private void recordFunction() {
}
}

28
designer-realize/src/main/java/com/fr/design/mainframe/shadow/handler/impl/SCWebLinkJumpHandler.java

@ -0,0 +1,28 @@
package com.fr.design.mainframe.shadow.handler.impl;
import com.fr.design.mainframe.shadow.handler.SCJumpHandler;
import com.fr.log.FineLoggerFactory;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCWebLinkJumper;
import java.awt.Desktop;
import java.net.URI;
/**
* @author Leo.Qin
* @since 10.0
* Created on 2021/9/29.
*
* <p>打开网页链接的跳转处理器
*/
public class SCWebLinkJumpHandler implements SCJumpHandler {
@Override
public void handle(SCRecordJumper scRecordJumper, int sheetIndex) {
SCWebLinkJumper j = (SCWebLinkJumper) scRecordJumper;
try {
Desktop.getDesktop().browse(new URI(j.getUrl()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error("open url failed: " + e.getMessage(), e);
}
}
}

13
designer-realize/src/main/java/com/fr/design/mainframe/shadow/listener/AbstractSCJumperListener.java

@ -0,0 +1,13 @@
package com.fr.design.mainframe.shadow.listener;
import java.awt.event.MouseAdapter;
/**
* 跳转Listener抽象类
*
* @author fly.li
* @since 10.0
* Created on 2021/11/12
*/
public class AbstractSCJumperListener extends MouseAdapter {
}

11
designer-realize/src/main/java/com/fr/design/mainframe/shadow/listener/SCDefaultJumpListener.java

@ -0,0 +1,11 @@
package com.fr.design.mainframe.shadow.listener;
/**
* 默认跳转Listener
*
* @author fly.li
* @since 10.0
* Created on 2021/09/23
*/
public class SCDefaultJumpListener extends AbstractSCJumperListener {
}

30
designer-realize/src/main/java/com/fr/design/mainframe/shadow/listener/SCJumperListener.java

@ -0,0 +1,30 @@
package com.fr.design.mainframe.shadow.listener;
import com.fr.design.mainframe.shadow.handler.SCJumpHandlerProvider;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import java.awt.event.MouseEvent;
/**
* 跳转Listener
*
* @author fly.li
* @since 10.0
* Created on 2021/09/23
*/
public class SCJumperListener extends AbstractSCJumperListener {
private SCRecordJumper scJumper;
private int sheetIndex;
public SCJumperListener(SCRecordJumper scJumper, int sheetIndex) {
this.scJumper = scJumper;
this.sheetIndex = sheetIndex;
}
@Override
public void mouseClicked(MouseEvent e) {
if (sheetIndex > -1) {
SCJumpHandlerProvider.jumpToTarget(scJumper, sheetIndex);
}
}
}

46
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/DetectFailedPane.java

@ -0,0 +1,46 @@
package com.fr.design.mainframe.shadow.ui;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import javax.swing.JPanel;
import java.awt.BorderLayout;
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.fix;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* 检测失败面板
*
* @author fly.li
* @since 10.0
* Created on 2021/08/23
*/
public class DetectFailedPane extends JPanel {
public DetectFailedPane() {
init();
}
private void init() {
this.setLayout(new BorderLayout());
UILabel image = new UILabel();
image.setPreferredSize(FineUIScale.createScaleDimension(110, 110));
image.setIcon(new LazyIcon("shadow_error", 110));
add(column(
flex(),
row(flex(), cell(image), flex()),
fix(4),
row(flex(), cell(new UILabel(Toolkit.i18nText("Fine-Design_Template_Assistant_Detect_Failed_Tip"), FineUIStyle.LABEL_DISABLED)), flex()),
flex()
).getComponent());
}
}

81
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/DetectNoErrorPane.java

@ -0,0 +1,81 @@
package com.fr.design.mainframe.shadow.ui;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.LocaleLinkProvider;
import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
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.fix;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* 没有检测出错误的提示界面
*
* @author fly.li
* @since 10.0
* Created on 2021/8/7
*/
public class DetectNoErrorPane extends JPanel {
/**
* 云中心模版检测助手链接在配置文件中对应的配置文件key
*/
private static final String PROPS_LINK_KEY = "Fine-Design_Template_Assistant__Help";
/**
* 云中心模版检测助手默认链接在配置文件中对应的配置文件key
*/
private static final String PROPS_LINK_KEY_DEFAULT = "Fine-Design_Template_Assistant__Help_Default";
public DetectNoErrorPane() {
init();
}
private void init() {
this.setLayout(new BorderLayout());
UILabel image = new UILabel();
image.setPreferredSize(FineUIScale.createScaleDimension(110, 110));
image.setIcon(new LazyIcon("shadow_success", 110));
UILabel secondLineLeft = new UILabel("<html><a href=''>" + Toolkit.i18nText("Fine-Design_Template_Assistant_No_Error_Result_Tipb") + "</a></html>");
secondLineLeft.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
try {
Desktop.getDesktop().browse(new URI(LocaleLinkProvider.getInstance().getLink(PROPS_LINK_KEY, PROPS_LINK_KEY_DEFAULT)));
} catch (IOException | URISyntaxException ex) {
FineLoggerFactory.getLogger().error("io exception or not find website", ex);
}
}
});
secondLineLeft.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
add(column(
flex(),
row(flex(), cell(image), flex()),
fix(4),
row(flex(), cell(new UILabel(Toolkit.i18nText("Fine-Design_Template_Assistant_No_Error_Result_Tipa"), FineUIStyle.LABEL_DISABLED)), flex()),
fix(10),
row(flex(), cell(secondLineLeft), cell(new UILabel(Toolkit.i18nText("Fine-Design_Template_Assistant_No_Error_Result_Tipc"), FineUIStyle.LABEL_DISABLED)), flex()),
flex()
).getComponent());
}
}

35
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/OptimizationProgressPane.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.shadow.ui;
import com.fr.design.i18n.Toolkit;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* @author fly.li
* @since 10.0
* Created on 2021/8/7
* <>优化进行中的画面</>
*/
public class OptimizationProgressPane extends JPanel {
public static final Icon DETECT_PROCESS_ICON = IOUtils.readIcon("/com/fr/nx/analyze/shadow/detecting.png");
public OptimizationProgressPane() {
init();
}
protected void init() {
JLabel label = new JLabel();
this.add(label);
label.setIcon(DETECT_PROCESS_ICON);
label.setText(Toolkit.i18nText("Fine-Design_Template_Assistant_Loading_Tip"));
label.setVerticalTextPosition(JLabel.BOTTOM);
label.setHorizontalTextPosition(JLabel.CENTER);
}
}

69
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/TemplateHelperShowPane.java

@ -0,0 +1,69 @@
package com.fr.design.mainframe.shadow.ui.component;
import com.fr.design.gui.frpane.FineTabbedPane;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.ui.component.table.AutoOptimizeDetectMultiTablePane;
import com.fr.design.mainframe.shadow.ui.component.table.DetectMultiTablePane;
import com.fr.design.mainframe.shadow.ui.data.DetectMutiTableData;
import com.fr.design.mainframe.shadow.ui.data.TemplateDetectResultData;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* 模版检测助手展示面板
*
* @author fly.li
* @since 10.0
* Created on 2021/09/15
*/
public class TemplateHelperShowPane extends JPanel {
public static final List<String> SORTED_TAB_STRS = new ArrayList<>();
static {
SORTED_TAB_STRS.add(Toolkit.i18nText("Fine-Design_Template_Assistant_Manual_Optimize"));
SORTED_TAB_STRS.add(Toolkit.i18nText("Fine-Design_Template_Assistant_Auto_Optimize"));
SORTED_TAB_STRS.add(Toolkit.i18nText("Fine-Design_Template_Assistant_SQL_Tuning_Tips_Pane_Title"));
SORTED_TAB_STRS.add(Toolkit.i18nText("Fine-Design_Template_Assistant_Function_Guide"));
}
private AutoOptimizeDetectMultiTablePane autoOptimizeDetectMultiTablePane;
public TemplateHelperShowPane(TemplateDetectResultData templateDetectResultData) {
init(templateDetectResultData);
}
private void init(TemplateDetectResultData templateDetectResultData) {
this.setLayout(new BorderLayout());
FineTabbedPane.TabPaneBuilder builder = FineTabbedPane.builder();
for (String tabStr : SORTED_TAB_STRS) {
//创建相应的面板
DetectMutiTableData detectMutiTableData = templateDetectResultData.getDetectMutiTableData(tabStr);
if (detectMutiTableData != null) {
DetectMultiTablePane detectMultiTablePane;
if (Objects.equals(Toolkit.i18nText("Fine-Design_Template_Assistant_Auto_Optimize"), tabStr)) {
autoOptimizeDetectMultiTablePane = new AutoOptimizeDetectMultiTablePane(detectMutiTableData);
detectMultiTablePane = autoOptimizeDetectMultiTablePane;
} else {
detectMultiTablePane = new DetectMultiTablePane(detectMutiTableData);
}
UIScrollPane uiScrollPane = new UIScrollPane(detectMultiTablePane);
uiScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
builder = builder.addTab(tabStr, uiScrollPane);
}
}
add(builder.withAdaptiveFit().build());
}
public AutoOptimizeDetectMultiTablePane getAutoOptimizeDetectMultiTablePane() {
return autoOptimizeDetectMultiTablePane;
}
}

105
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/AbstractSCRecordItemPane.java

@ -0,0 +1,105 @@
package com.fr.design.mainframe.shadow.ui.component.item;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.listener.AbstractSCJumperListener;
import com.fr.design.mainframe.shadow.ui.data.SheetIndexToName;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.stable.StringUtils;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* 设置一些统一的面板布局
*
* @author fly.li
* @since 10.0
* Created on 2021/09/16
*/
public abstract class AbstractSCRecordItemPane extends JPanel {
public AbstractSCRecordItemPane(SCRecordItem scRecordItem, Object extra) {
init(scRecordItem, extra);
}
/**
* 初始化
*/
public void init(SCRecordItem scRecordItem, Object extra) {
this.setLayout(new BorderLayout());
JLabel advicePositionLabel = createAdvicePositionLabel(scRecordItem, extra);
advicePositionLabel.setVerticalAlignment(JLabel.CENTER);
this.add(advicePositionLabel, BorderLayout.WEST);
this.add(advicePositionLabel);
UIButton jumperButton = createJumperButton(scRecordItem.getJumper(), extra);
if (jumperButton != null) {
add(row(
cell(advicePositionLabel),
flex(),
cell(jumperButton)
).getComponent());
} else {
add(row(
cell(advicePositionLabel),
flex()
).getComponent());
}
}
/**
* 创建建议等级的label
*/
public abstract JLabel createAdvicePositionLabel(SCRecordItem scRecordItem, Object extra);
/**
* 创建跳转按钮
*/
public UIButton createJumperButton(SCRecordJumper scRecordJumper, Object extra) {
if (!isJumper(scRecordJumper)) {
return null;
}
AbstractSCJumperListener scJumperListener = createSCJumperListener(scRecordJumper, extra);
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Template_Assistant_Jump"));
button.addMouseListener(scJumperListener);
return button;
}
/**
* 决定是否创建跳转按钮返回true则创建返回false不创建
*/
protected abstract boolean isJumper(SCRecordJumper scRecordJumper);
/**
* 创建跳转按钮的监听器
*/
public abstract AbstractSCJumperListener createSCJumperListener(SCRecordJumper scRecordJumper, Object SheetIndex);
/**
* 根据extra获取sheetName
*/
public String convertToSheetName(Object extra) {
int sheetIndex = extra instanceof Integer ? (Integer) extra : -1;
if (sheetIndex > -1 || sheetIndex < SheetIndexToName.getInstance().getSheetCount()) {
return sheetIndex > -1 ? SheetIndexToName.getInstance().getSheetName(sheetIndex) : StringUtils.EMPTY;
} else {
throw new SheetIndexNotFindException();
}
}
static class SheetIndexNotFindException extends RuntimeException {
@Override
public String getMessage() {
return "sheetIndex not find";
}
}
}

106
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/AbstractSCRecordItemPaneFactory.java

@ -0,0 +1,106 @@
package com.fr.design.mainframe.shadow.ui.component.item;
import com.fr.log.FineLoggerFactory;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCCellRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCColumnRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCDataSourceRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCMessageRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCRowRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCWidgetRecordItem;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* 检测item面板工厂
*
* @author fly.li
* @since 10.0
* Created on 2021/09/16
*/
public abstract class AbstractSCRecordItemPaneFactory {
private static Map<String, Function<SCRecordItemExtra, AbstractSCRecordItemPane>> map = new HashMap();
static {
map.put(SCCellRecordItem.class.getName(), AbstractSCRecordItemPaneFactory::createSCCellRecordItemPane);
map.put(SCRowRecordItem.class.getName(), AbstractSCRecordItemPaneFactory::createSCRowRecordItemPane);
map.put(SCDataSourceRecordItem.class.getName(), AbstractSCRecordItemPaneFactory::createSCDataSourceRecordItemPane);
map.put(SCColumnRecordItem.class.getName(), AbstractSCRecordItemPaneFactory::createSCColumnRecordItemPane);
map.put(SCWidgetRecordItem.class.getName(), AbstractSCRecordItemPaneFactory::createSCWidgetRecordItemPane);
map.put(SCMessageRecordItem.class.getName(), AbstractSCRecordItemPaneFactory::createSCMessageRecordItemPane);
}
/**
* 注册SCRecordItemPane的创建方法
*
* @param className SCRecordItem的类名
* @param function SCRecordItemPane的创建方法
*/
public static void register(String className, Function<SCRecordItemExtra, AbstractSCRecordItemPane> function) {
map.put(className, function);
}
/**
* 根据不同的SCRecordItem创建相应的面板
* 改变面板的创建方式之后每次创建一个新类型的面板都需要增加一个creator过于浪费(所有的creator类被删除了)
* 直接使用switch来创建也不会造成更多的维护困难这里感觉使用if也是一样
* 因为这里没有复杂的判断逻辑每个if只是判断类型相等而已if并不存在难以维护的问题
* (离散值适合switchswitch可能时间效率更好一点空间效率稍差)
* <>final String cell = SCRowRecordItem.class.getName().intern()不能作为case常量来处理</>;
* 其他的转化为hashCode(可能存在碰撞)和直接使用包全名包名可能会变化也不合适
* 因此最后使用map的方式用Function接口来创建面板
*/
public static AbstractSCRecordItemPane createSCRecordItemPane(SCRecordItem scRecordItem, Object extra) {
Function<SCRecordItemExtra, AbstractSCRecordItemPane> function = map.get(scRecordItem.getClass().getName());
if (function != null) {
return function.apply(new SCRecordItemExtra(scRecordItem, extra));
} else {
FineLoggerFactory.getLogger().error("Corresponding SCRecordItemPane Create Method not exist: {}", scRecordItem.getClass().getName());
throw new TypeException("Corresponding SCRecordItemPane Create Method not exist");
}
}
private static SCCellRecordItemPane createSCCellRecordItemPane(SCRecordItemExtra scRecordItemExtra) {
return new SCCellRecordItemPane((SCCellRecordItem) scRecordItemExtra.scRecordItem, scRecordItemExtra.extra);
}
private static SCRowRecordItemPane createSCRowRecordItemPane(SCRecordItemExtra scRecordItemExtra) {
return new SCRowRecordItemPane((SCRowRecordItem) scRecordItemExtra.scRecordItem, scRecordItemExtra.extra);
}
private static SCDataSourceRecordItemPane createSCDataSourceRecordItemPane(SCRecordItemExtra scRecordItemExtra) {
return new SCDataSourceRecordItemPane((SCDataSourceRecordItem) scRecordItemExtra.scRecordItem, scRecordItemExtra.extra);
}
private static SCColumnRecordItemPane createSCColumnRecordItemPane(SCRecordItemExtra scRecordItemExtra) {
return new SCColumnRecordItemPane((SCColumnRecordItem) scRecordItemExtra.scRecordItem, scRecordItemExtra.extra);
}
private static SCWidgetRecordItemPane createSCWidgetRecordItemPane(SCRecordItemExtra scRecordItemExtra) {
return new SCWidgetRecordItemPane((SCWidgetRecordItem) scRecordItemExtra.scRecordItem, scRecordItemExtra.extra);
}
private static SCMessageRecordItemPane createSCMessageRecordItemPane(SCRecordItemExtra scRecordItemExtra) {
return new SCMessageRecordItemPane((SCMessageRecordItem) scRecordItemExtra.scRecordItem, scRecordItemExtra.extra);
}
static class SCRecordItemExtra {
SCRecordItem scRecordItem;
Object extra;
SCRecordItemExtra(SCRecordItem scRecordItem, Object extra) {
this.scRecordItem = scRecordItem;
this.extra = extra;
}
}
private static class TypeException extends RuntimeException {
private TypeException(String message) {
super(message);
}
}
}

55
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCCellRecordItemPane.java

@ -0,0 +1,55 @@
package com.fr.design.mainframe.shadow.ui.component.item;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.listener.SCJumperListener;
import com.fr.main.impl.WorkBook;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCCellRecordItem;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.nx.analyze.shadow.record.jumper.impl.SCCellJumper;
import com.fr.nx.analyze.shadow.record.jumper.type.CellAttrType;
import com.fr.stable.ColumnRow;
import javax.swing.JLabel;
/**
* 单元格检测item
*
* @author fly.li
* @since 10.0
* Created on 2021/09/16
*/
public class SCCellRecordItemPane extends AbstractSCRecordItemPane {
public SCCellRecordItemPane(SCCellRecordItem scCellRecordItem, Object extraData) {
super(scCellRecordItem, extraData);
}
@Override
public JLabel createAdvicePositionLabel(SCRecordItem scRecordItem, Object extra) {
SCCellRecordItem scCellRecordItem = (SCCellRecordItem) scRecordItem;
ColumnRow columnRow = scCellRecordItem.getColumnRow();
String sheetName = convertToSheetName(extra);
JLabel advicePositionLabel = new JLabel(sheetName + "/" + columnRow.toString());
return advicePositionLabel;
}
@Override
protected boolean isJumper(SCRecordJumper scRecordJumper) {
CellAttrType cellAttrType = ((SCCellJumper) scRecordJumper).getCellAttrType();
return (cellAttrType == CellAttrType.FORMULA || cellAttrType == CellAttrType.DATA_COlUMN) && isWorkBook();
}
@Override
public SCJumperListener createSCJumperListener(SCRecordJumper scRecordJumper, Object extra) {
int sheetIndex = extra instanceof Integer ? (Integer) extra : -1;
SCJumperListener scJumperListener = new SCJumperListener(scRecordJumper, sheetIndex);
return scJumperListener;
}
private boolean isWorkBook() {
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return currentEditingTemplate.getTarget() instanceof WorkBook;
}
}

43
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCColumnRecordItemPane.java

@ -0,0 +1,43 @@
package com.fr.design.mainframe.shadow.ui.component.item;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.listener.AbstractSCJumperListener;
import com.fr.design.mainframe.shadow.listener.SCDefaultJumpListener;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCColumnRecordItem;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import javax.swing.JLabel;
/**
* 检测结果item pane
*
* @author fly.li
* @since 10.0
* Created on 2021/10/11
*/
public class SCColumnRecordItemPane extends AbstractSCRecordItemPane {
public SCColumnRecordItemPane(SCColumnRecordItem scColumnRecordItem, Object extra) {
super(scColumnRecordItem, extra);
}
@Override
public JLabel createAdvicePositionLabel(SCRecordItem scRecordItem, Object extra) {
SCColumnRecordItem scColumnRecordItem = (SCColumnRecordItem) scRecordItem;
int column = scColumnRecordItem.getColumn() + 1;
String sheetName = convertToSheetName(extra);
return new JLabel(sheetName + "/" + Toolkit.i18nText("Fine-Design_Template_Assistant_First") + column + Toolkit.i18nText("Fine-Design_Template_Assistant_Column"));
}
@Override
protected boolean isJumper(SCRecordJumper scRecordJumper) {
return false;
}
@Override
public AbstractSCJumperListener createSCJumperListener(SCRecordJumper scRecordJumper, Object SheetIndex) {
return new SCDefaultJumpListener();
}
}

43
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCDataSourceRecordItemPane.java

@ -0,0 +1,43 @@
package com.fr.design.mainframe.shadow.ui.component.item;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.listener.AbstractSCJumperListener;
import com.fr.design.mainframe.shadow.listener.SCJumperListener;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCDataSourceRecordItem;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import javax.swing.JLabel;
/**
* 数据源记录项面板
*
* @author fly.li
* @since 10.0
* Created on 2021/09/16
*/
public class SCDataSourceRecordItemPane extends AbstractSCRecordItemPane {
private final int NONE = 1;
public SCDataSourceRecordItemPane(SCDataSourceRecordItem scDataSourceRecordItem, Object object) {
super(scDataSourceRecordItem, object);
}
@Override
public JLabel createAdvicePositionLabel(SCRecordItem scRecordItem, Object extra) {
SCDataSourceRecordItem scDataSourceRecordItem = (SCDataSourceRecordItem) scRecordItem;
String dsName = scDataSourceRecordItem.getDsName();
JLabel advicePositionLabel = new JLabel(Toolkit.i18nText("Fine-Design_Template_Assistant_DS") + dsName);
return advicePositionLabel;
}
@Override
protected boolean isJumper(SCRecordJumper scRecordJumper) {
return true;
}
@Override
public AbstractSCJumperListener createSCJumperListener(SCRecordJumper scRecordJumper, Object SheetIndex) {
return new SCJumperListener(scRecordJumper, NONE);
}
}

57
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCMessageRecordItemPane.java

@ -0,0 +1,57 @@
package com.fr.design.mainframe.shadow.ui.component.item;
import com.fr.design.mainframe.shadow.listener.AbstractSCJumperListener;
import com.fr.design.mainframe.shadow.listener.SCJumperListener;
import com.fr.locale.InterProvider;
import com.fr.locale.InterProviderFactory;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCMessageRecordItem;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import com.fr.stable.StringUtils;
import javax.swing.JLabel;
import java.util.HashMap;
import java.util.Map;
/**
* @author Leo.Qin
* @since 10.0
* Created on 2021/9/29.
*
* <p>处理 SCMessageRecordItem 的面板
*/
public class SCMessageRecordItemPane extends AbstractSCRecordItemPane {
private static Map<String, String> map = new HashMap<>();
static {
InterProvider provider = InterProviderFactory.getProvider();
map.put(provider.getLocText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Driver_Recommend_Mysql"), provider.getLocText("Fine-Design_Template_Assistant_Click_Obtain_Driver"));
map.put(provider.getLocText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Driver_Recommend_Sqlserver"), provider.getLocText("Fine-Design_Template_Assistant_Click_Obtain_Driver"));
map.put(provider.getLocText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Use_Ds_Cache_Message"), provider.getLocText("Fine-Design_Template_Assistant_Click_Know"));
map.put(provider.getLocText("Fine-Design_Template_Assistant_Shadow_Record_Nx_Message"), provider.getLocText("Fine-Design_Template_Assistant_Open_New_Engine_Paging"));
}
public SCMessageRecordItemPane(SCMessageRecordItem item, Object extraData) {
super(item, extraData);
}
/**
*
*/
@Override
public JLabel createAdvicePositionLabel(SCRecordItem scRecordItem, Object extra) {
String message = ((SCMessageRecordItem) scRecordItem).getMessage();
JLabel advicePositionLabel = new JLabel(StringUtils.isEmpty(map.get(message)) ? message : map.get(message));
return advicePositionLabel;
}
@Override
protected boolean isJumper(SCRecordJumper scRecordJumper) {
return scRecordJumper != SCRecordJumper.NOOP;
}
@Override
public AbstractSCJumperListener createSCJumperListener(SCRecordJumper scRecordJumper, Object SheetIndex) {
return new SCJumperListener(scRecordJumper, 0);
}
}

42
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCRowRecordItemPane.java

@ -0,0 +1,42 @@
package com.fr.design.mainframe.shadow.ui.component.item;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.listener.AbstractSCJumperListener;
import com.fr.design.mainframe.shadow.listener.SCDefaultJumpListener;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCRowRecordItem;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import javax.swing.JLabel;
/**
* 行结果item面板
*
* @author fly.li
* @since 10.0
* Created on 2021/09/16
*/
public class SCRowRecordItemPane extends AbstractSCRecordItemPane {
public SCRowRecordItemPane(SCRowRecordItem scRowRecordItem, Object extraData) {
super(scRowRecordItem, extraData);
}
@Override
public JLabel createAdvicePositionLabel(SCRecordItem scRecordItem, Object extra) {
String sheetName = convertToSheetName(extra);
int row = ((SCRowRecordItem) scRecordItem).getRow() + 1;
JLabel advicePositionLabel = new JLabel(sheetName + "/" + Toolkit.i18nText("Fine-Design_Template_Assistant_First") + row + Toolkit.i18nText("Fine-Design_Template_Assistant_Line"));
return advicePositionLabel;
}
@Override
protected boolean isJumper(SCRecordJumper scRecordJumper) {
return false;
}
@Override
public AbstractSCJumperListener createSCJumperListener(SCRecordJumper scRecordJumper, Object SheetIndex) {
return new SCDefaultJumpListener();
}
}

40
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/item/SCWidgetRecordItemPane.java

@ -0,0 +1,40 @@
package com.fr.design.mainframe.shadow.ui.component.item;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.listener.AbstractSCJumperListener;
import com.fr.design.mainframe.shadow.listener.SCDefaultJumpListener;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCWidgetRecordItem;
import com.fr.nx.analyze.shadow.record.jumper.SCRecordJumper;
import javax.swing.JLabel;
/**
* 控件检测列表项面板
*
* @author fly.li
* @since 10.0
* Created on 2021/10/11
*/
public class SCWidgetRecordItemPane extends AbstractSCRecordItemPane {
public SCWidgetRecordItemPane(SCWidgetRecordItem scWidgetRecordItem, Object extra) {
super(scWidgetRecordItem, extra);
}
@Override
public JLabel createAdvicePositionLabel(SCRecordItem scRecordItem, Object extra) {
SCWidgetRecordItem scWidgetRecordItem = (SCWidgetRecordItem) scRecordItem;
String widgetName = scWidgetRecordItem.getWidgetName();
return new JLabel(Toolkit.i18nText("Fine-Design_Template_Assistant_Widget") + widgetName);
}
@Override
protected boolean isJumper(SCRecordJumper scRecordJumper) {
return false;
}
@Override
public AbstractSCJumperListener createSCJumperListener(SCRecordJumper scRecordJumper, Object SheetIndex) {
return new SCDefaultJumpListener();
}
}

57
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/table/AutoOptimizeDetectMultiTablePane.java

@ -0,0 +1,57 @@
package com.fr.design.mainframe.shadow.ui.component.table;
import com.fr.base.io.IOFile;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.data.DetectMutiTableData;
import com.fr.nx.analyze.shadow.attr.SCOptionAttrMark;
import java.awt.BorderLayout;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* 自动优化面板
*
* @author fly.li
* @since 10.0
* Created on 2021/11/18
*/
public class AutoOptimizeDetectMultiTablePane extends DetectMultiTablePane {
private UICheckBox skipAutoOptimizeSwitchCheckBox;
public AutoOptimizeDetectMultiTablePane(DetectMutiTableData detectMutiTableData) {
super(detectMutiTableData);
init();
}
private void init() {
addSkipAutoOptimizeSwitch();
}
private void addSkipAutoOptimizeSwitch() {
skipAutoOptimizeSwitchCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Template_Assistant_Not_Auto_Optimize"));
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
Object target = currentEditingTemplate.getTarget();
if (target instanceof IOFile) {
IOFile ioFile = (IOFile) target;
SCOptionAttrMark attrMark = ioFile.getAttrMark(SCOptionAttrMark.MARK);
skipAutoOptimizeSwitchCheckBox.setSelected(attrMark != null && attrMark.isSkipAutoTask());
}
this.add(row(
cell(skipAutoOptimizeSwitchCheckBox),
flex()
).getComponent(), BorderLayout.SOUTH);
}
public boolean isSkipAutoOptimize() {
return skipAutoOptimizeSwitchCheckBox.isSelected();
}
}

96
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/table/DetectMultiTablePane.java

@ -0,0 +1,96 @@
package com.fr.design.mainframe.shadow.ui.component.table;
import com.fine.theme.utils.FineLayoutBuilder;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.LocaleLinkProvider;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.ui.data.DetectMutiTableData;
import com.fr.design.mainframe.shadow.ui.data.DetectSingleTableData;
import com.fr.log.FineLoggerFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
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.flex;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* 检测结果面板
*
* @author fly.li
* @since 10.0
* Created on 2021/09/15
*/
public class DetectMultiTablePane extends JPanel {
/**
* 云中心模版检测助手链接在配置文件中对应的配置文件key
*/
private static final String PROPS_LINK_KEY = "Fine-Design_Template_Assistant__Help";
/**
* 云中心模版检测助手默认链接在配置文件中对应的配置文件key
*/
private static final String PROPS_LINK_KEY_DEFAULT = "Fine-Design_Template_Assistant__Help_Default";
public DetectMultiTablePane(DetectMutiTableData detectMutiTableData) {
init(detectMutiTableData);
}
private void init(DetectMutiTableData detectMutiTableData) {
addDetectSingleTablePanes(detectMutiTableData);
}
protected void addDetectSingleTablePanes(DetectMutiTableData detectMutiTableData) {
this.setLayout(new BorderLayout());
List<Component> components = new ArrayList<>();
for (String key : detectMutiTableData.keys()) {
DetectSingleTableData detectSingleTableData = detectMutiTableData.getDetectSingleTableData(key);
int scRecordItemsCount = detectSingleTableData.getSCRecordItemsCount();
if (scRecordItemsCount > 0) {
DetectSingleTablePane scRecordItemPane = new DetectSingleTablePane(detectSingleTableData);
components.add(scRecordItemPane);
}
}
add(
column(
row(flex(), cell(createHelperPane())),
cell(FineLayoutBuilder.createVerticalLayout(10, components.toArray(new Component[0])))
).getComponent()
);
}
private UILabel createHelperPane() {
UILabel helper = new UILabel("<html><a href=''>" + Toolkit.i18nText("Fine-Design_Template_Assistant_Helper_Doc") + "</a></html>");
helper.setCursor(new Cursor(Cursor.HAND_CURSOR));
helper.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
try {
Desktop.getDesktop().browse(new URI(LocaleLinkProvider.getInstance().getLink(PROPS_LINK_KEY, PROPS_LINK_KEY_DEFAULT)));
} catch (IOException | URISyntaxException ex) {
FineLoggerFactory.getLogger().error("io exception or not find website", ex);
}
}
});
return helper;
}
}

61
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/table/DetectSingleTablePane.java

@ -0,0 +1,61 @@
package com.fr.design.mainframe.shadow.ui.component.table;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIUtils;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.gui.ilable.MultilineLabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.ui.data.DetectSingleTableData;
import com.fr.nx.analyze.shadow.record.SCRecordLevel;
import javax.swing.Icon;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
/**
* 单个检测结果面板
*
* @author fly.li
* @since 10.0
* Created on 2021/09/16
*/
public class DetectSingleTablePane extends JPanel {
public DetectSingleTablePane(DetectSingleTableData detectSingleTableData) {
init(detectSingleTableData);
}
private void init(DetectSingleTableData detectSingleTableData) {
this.setLayout(new BorderLayout());
Icon icon = getIcon(detectSingleTableData.getLevel());
add(new UIExpandablePane(detectSingleTableData.getTitle(), icon,
column(
20,
cell(FineUIUtils.wrapComponentWithTitle(new MultilineLabel(detectSingleTableData.getProblemDescription()), Toolkit.i18nText("Fine-Design_Template_Assistant_Problem_Description"))),
cell(FineUIUtils.wrapComponentWithTitle(new MultilineLabel(detectSingleTableData.getAdvice()), Toolkit.i18nText("Fine-Design_Template_Assistant_Problem_Advice"))),
cell(FineUIUtils.wrapComponentWithTitle(new ProblemPositionPane(detectSingleTableData), Toolkit.i18nText("Fine-Design_Template_Assistant_Problem_Position")))
).getComponent()
));
}
private Icon getIcon(SCRecordLevel level) {
if (level == null) {
return new LazyIcon("shadow_error");
}
switch (level) {
case RISK:
return new LazyIcon("shadow_risk");
case SUGGESTION:
return new LazyIcon("shadow_suggestion");
default:
return new LazyIcon("shadow_error");
}
}
}

39
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/component/table/ProblemPositionPane.java

@ -0,0 +1,39 @@
package com.fr.design.mainframe.shadow.ui.component.table;
import com.fine.theme.utils.FineLayoutBuilder;
import com.fr.design.mainframe.shadow.ui.component.item.AbstractSCRecordItemPane;
import com.fr.design.mainframe.shadow.ui.component.item.AbstractSCRecordItemPaneFactory;
import com.fr.design.mainframe.shadow.ui.data.DetectSingleTableData;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @author fly.li
* @since 10.0
* Created on 2021/11/11
* 问题位置面板
*/
public class ProblemPositionPane extends JPanel {
public ProblemPositionPane(DetectSingleTableData detectSingleTableData) {
this.setLayout(new BorderLayout());
List<Component> components = new ArrayList<>();
for (int i = 0; i < detectSingleTableData.getSCRecordItemsCount() - 1; i++) {
AbstractSCRecordItemPane problemPositionPane = AbstractSCRecordItemPaneFactory.createSCRecordItemPane(detectSingleTableData.getSCRecordItem(i), detectSingleTableData.getExtraData(i));
components.add(problemPositionPane);
}
int lastIndex = detectSingleTableData.getSCRecordItemsCount() - 1;
AbstractSCRecordItemPane problemPositionPane = AbstractSCRecordItemPaneFactory.createSCRecordItemPane(detectSingleTableData.getSCRecordItem(lastIndex), detectSingleTableData.getExtraData(lastIndex));
components.add(problemPositionPane);
add(FineLayoutBuilder.createVerticalLayout(14, components.toArray(new Component[0])));
}
}

32
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/DetectMutiTableData.java

@ -0,0 +1,32 @@
package com.fr.design.mainframe.shadow.ui.data;
import java.util.Set;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/14
* <>对应是检测类型--自动类建议类优化类数据对象里面又包含对应的问题类型数据对象</>
*/
public interface DetectMutiTableData {
/**
* 添加单个检测类型这里的类型指的是修改建议自动优化sql自动优化建议等对应的某个问题类型冗余取数计算性能等的数据对象
*/
void putDetectSingleTableData(String key, DetectSingleTableData detectSingleTableData);
/**
* 是否包含某个问题类型
*/
boolean containsKey(String key);
DetectSingleTableData getDetectSingleTableData(String key);
/**
* 获取所有的问题类型
*/
Set<String> keys();
}

51
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/DetectSingleTableData.java

@ -0,0 +1,51 @@
package com.fr.design.mainframe.shadow.ui.data;
import com.fr.nx.analyze.shadow.record.SCRecordLevel;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import java.util.List;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/14
* <>每个检测类型的数据类里面包含检测类代表的每行数据最终如果想实现一个新的ui数据类也可以以SCRecordItem为准即可</>
*/
public interface DetectSingleTableData {
String getTitle();
String getAdvice();
String getProblemDescription();
SCRecordLevel getLevel();
/**
* 添加检测记录item
*/
void addSCRecordItem(SCRecordItem scRecordItem);
/**
* 添加检测记录item
*/
void addSCRecordItems(List<SCRecordItem> scRecordItems);
int getColumnCount();
int getSCRecordItemsCount();
SCRecordItem getSCRecordItem(int i);
Object getExtraData(int i);
/**
* 检查extra是否存在
*/
boolean checkExtraExist(Object object);
/**
* 构建问题描述
*/
void constructProblemDescription();
}

21
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/ProblemInformation.java

@ -0,0 +1,21 @@
package com.fr.design.mainframe.shadow.ui.data;
/**
* @author fly.li
* @since 10.0
* Created on 2021/11/16
* 每个检测任务对应的面板信息
*/
public interface ProblemInformation {
String getTitle();
String getAdvice();
/**
* 与记录相关因此需要相应的处理方法
*/
String getProblemDescription();
void setProblemDescription(String problemDescription);
}

71
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/ProblemInformationFactory.java

@ -0,0 +1,71 @@
package com.fr.design.mainframe.shadow.ui.data;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.ui.data.impl.DefaultProblemInformation;
import com.fr.nx.analyze.shadow.metric.type.impl.SCCalculationErrorMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCCalculationPerformanceMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCCellRelationMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCDataSourcePerformanceMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCFilterPerformanceMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCFormBackGroundImageOversizeMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCFormComponentTroppoMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCGlobalParameterMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCGlobalWatermarkMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCRecommendMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCRedundantCalculateMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCRedundantDataMetricType;
import com.fr.nx.analyze.shadow.metric.type.impl.SCWidgetMetricType;
import java.util.HashMap;
/**
* 异常信息工厂
*
* @author fly.li
* @since 10.0
* Created on 2021/11/16
*/
public class ProblemInformationFactory {
public static final String NONE = "00000";
private static HashMap<String, ProblemInformation> problemInformations = new HashMap<>();
static {
//这里添加一些信息相关的信息
String redundantCalculator = Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Calculator");
String filterPerformance = Toolkit.i18nText("Fine-Design_Template_Assistant_Filter_Performance");
String calculatePerformance = Toolkit.i18nText("Fine-Design_Template_Assistant_Calculate_Performance");
String globalSettingAbnormal = Toolkit.i18nText("Fine-Design_Template_Assistant_Global_Setting_Abnormal");
//静态检测
problemInformations.put(SCCalculationErrorMetricType.DIVISION_BY_ZERO.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Calculator_Error"), Toolkit.i18nText("Fine-Design_Template_Assistant_Calculator_Error_Dividion_Zero_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Calculator_Error_Dividion_Zero_Description")));
problemInformations.put(SCCellRelationMetricType.LONG_CHAIN.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Cell_Relation_Optimize_For_List_Expanding"), Toolkit.i18nText("Fine-Design_Template_Assistant_Cell_Relation_Optimize_For_List_Expanding_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Cell_Relation_Optimize_For_List_Expanding_Description")));
problemInformations.put(SCRedundantCalculateMetricType.DS_FILTER.value(), new DefaultProblemInformation(redundantCalculator, Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Condition_Filter_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Condition_Filter_Description")));
problemInformations.put(SCFilterPerformanceMetricType.FILTER_CONDITION.value(), new DefaultProblemInformation(filterPerformance, Toolkit.i18nText("Fine-Design_Template_Assistant_Filter_Performance_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Filter_Performance_Description")));
problemInformations.put(SCCalculationPerformanceMetricType.FUN_EXTEND.value(), new DefaultProblemInformation(calculatePerformance, Toolkit.i18nText("Fine-Design_Template_Assistant_Calculate_Performance_Fun_Extend_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Calculate_Performance_Fun_Extend_Description")));
problemInformations.put(SCRedundantCalculateMetricType.HIDE_ATTR_CR.value(), new DefaultProblemInformation(redundantCalculator, Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Calculator_Hide_Column_Row_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Calculator_Hide_Column_Row_Description")));
problemInformations.put(SCCalculationPerformanceMetricType.IF_REPEAT_CAL.value(), new DefaultProblemInformation(calculatePerformance, Toolkit.i18nText("Fine-Design_Template_Assistant_IF_Function_Calculate_Performance_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_IF_Function_Calculate_Performance_Description")));
problemInformations.put(SCCalculationPerformanceMetricType.LAYER_EXTEND.value(), new DefaultProblemInformation(calculatePerformance, Toolkit.i18nText("Fine-Design_Template_Assistant_Calculate_Performance_Layer_Coordinates_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Calculate_Performance_Layer_Coordinates_Description")));
problemInformations.put(SCRecommendMetricType.NX.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Record_Nx"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Record_Nx_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Record_Nx_Description")));
problemInformations.put(SCRedundantCalculateMetricType.CONDITION.value(), new DefaultProblemInformation(redundantCalculator, Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Calculator_Condition_Attr_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Calculator_Condition_Attr_Description")));
problemInformations.put(SCRedundantDataMetricType.DATA_FETCH.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Data_Fetch"), Toolkit.i18nText("Fine-Design_Template_Assistant_Redundant_Data_Fetch_Advice"), null));
problemInformations.put(SCWidgetMetricType.WIDGET_SQL.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Widget_Performance"), Toolkit.i18nText("Fine-Design_Template_Assistant_Widget_Performance_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Widget_Performance_Description")));
//动态检测
problemInformations.put(SCRecommendMetricType.CACHE.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Use_Ds_Cache"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Use_Ds_Cache_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Use_Ds_Cache_Description")));
problemInformations.put(SCDataSourcePerformanceMetricType.TOO_MANY.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Ds_Row_Too_Many"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Ds_Row_Too_Many_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Ds_Row_Too_Many_Description")));
problemInformations.put(SCRecommendMetricType.DRIVER.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Driver_Recommend"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Driver_Recommend_Advice"), null));
problemInformations.put(SCCalculationPerformanceMetricType.GROUP_TO_LIST.value(), new DefaultProblemInformation(calculatePerformance, Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Group_To_List_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Group_To_List_Description")));
problemInformations.put(SCCalculationPerformanceMetricType.GROUP_TO_LIST_AUTO.value(), new DefaultProblemInformation(calculatePerformance, Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Group_To_List_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Shadow_Runtime_Record_Group_To_List_Description")));
problemInformations.put(SCFormBackGroundImageOversizeMetricType.IMAGE_OVERSIZE.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_File_Oversize_Problem_Title"), Toolkit.i18nText("Fine-Design_Template_Assistant_File_Oversize_Problem_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_File_Oversize_Problem_Description")));
problemInformations.put(SCFormComponentTroppoMetricType.COMPONENT_TROPPO.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_Component_Troppo_Problem_Title"), Toolkit.i18nText("Fine-Design_Template_Assistant_Component_Troppo_Problem_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Component_Troppo_Problem_Description")));
problemInformations.put(SCFormComponentTroppoMetricType.EC_SIMPLIFICATION.value(), new DefaultProblemInformation(Toolkit.i18nText("Fine-Design_Template_Assistant_EC_Simplification_Problem_Title"), Toolkit.i18nText("Fine-Design_Template_Assistant_EC_Simplification_Problem_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_EC_Simplification_Problem_Description")));
problemInformations.put(SCGlobalParameterMetricType.PARA_SQL.value(), new DefaultProblemInformation(globalSettingAbnormal, Toolkit.i18nText("Fine-Design_Template_Assistant_Global_Parameter_Sql_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Global_Parameter_Sql_Description")));
problemInformations.put(SCGlobalWatermarkMetricType.WATERMARK_SQL.value(), new DefaultProblemInformation(globalSettingAbnormal, Toolkit.i18nText("Fine-Design_Template_Assistant_Global_Watermark_Sql_Advice"), Toolkit.i18nText("Fine-Design_Template_Assistant_Global_Watermark_Sql_Description")));
}
/**
* 获取问题信息
*/
public static ProblemInformation getProblemInformation(String id) {
return problemInformations.get(id);
}
}

48
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/SheetIndexToName.java

@ -0,0 +1,48 @@
package com.fr.design.mainframe.shadow.ui.data;
import java.util.ArrayList;
import java.util.List;
/**
* sheet索引转名字
*
* @author fly.li
* @since 10.0
* Created on 2021/09/17
*/
public class SheetIndexToName {
private final static SheetIndexToName SHEET_INDEX_TO_NAME = new SheetIndexToName();
private static List<String> sheetNames = new ArrayList<>();
public static SheetIndexToName getInstance() {
return SHEET_INDEX_TO_NAME;
}
public String getSheetName(int index) {
return sheetNames.get(index);
}
/**
* 添加sheet名字
*
* @param index sheet索引
* @param sheetName sheet名字
*/
public void addSheetName(int index, String sheetName) {
sheetNames.add(index, sheetName);
}
public int getSheetIndex(String sheetName) {
for (int index = 0; index < sheetNames.size(); index++) {
if (sheetNames.get(index).equals(sheetName)) {
return index;
}
}
return -1;
}
public int getSheetCount() {
return sheetNames.size();
}
}

40
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/TemplateDetectResultData.java

@ -0,0 +1,40 @@
package com.fr.design.mainframe.shadow.ui.data;
import java.util.Set;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/14
* <>展示面板的总数据类</>
*/
public interface TemplateDetectResultData {
/**
* 获取某个检测类型的数据
*
* @return DetectMutiTableData单个检测类型对应的数据对象
*/
DetectMutiTableData getDetectMutiTableData(String key);
/**
* 模板中是否检测出有问题的地方
*
* @return true代表检测出了错误false代表没有检测出错误
*/
boolean isNoError();
/**
* 是否包含某个检测类型的问题
*/
boolean containsKey(String key);
/**
* 添加某个检测类型的数据
*/
void putDetectMutiTableData(String key, DetectMutiTableData detectMutiTableData);
/**
* 获取所有检测类型的key
*/
Set<String> keys();
}

40
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/impl/DefaultDetectMutiTableData.java

@ -0,0 +1,40 @@
package com.fr.design.mainframe.shadow.ui.data.impl;
import com.fr.design.mainframe.shadow.ui.data.DetectMutiTableData;
import com.fr.design.mainframe.shadow.ui.data.DetectSingleTableData;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/14
* <>一般没有特别的结构都使用默认的就够用了区别比较大的是SCDetectSingleTableData中扩展也是以这个为基本扩展的主要是里面的数组结构需要改变</>
*/
public class DefaultDetectMutiTableData implements DetectMutiTableData {
private Map<String, DetectSingleTableData> detectSingleTableDatas = new HashMap<>();
@Override
public boolean containsKey(String key) {
return detectSingleTableDatas.containsKey(key);
}
@Override
public DetectSingleTableData getDetectSingleTableData(String key) {
return detectSingleTableDatas.get(key);
}
@Override
public void putDetectSingleTableData(String key, DetectSingleTableData detectSingleTableData) {
detectSingleTableDatas.put(key, detectSingleTableData);
}
@Override
public Set<String> keys() {
return detectSingleTableDatas.keySet();
}
}

149
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/impl/DefaultDetectSingleTableData.java

@ -0,0 +1,149 @@
package com.fr.design.mainframe.shadow.ui.data.impl;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.shadow.ui.data.DetectSingleTableData;
import com.fr.nx.analyze.shadow.record.SCRecordLevel;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCDataSourceRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCMessageRecordItem;
import java.util.ArrayList;
import java.util.List;
/**
* 每个检测类型的数据类
*
* @author fly.li
* @since 10.0
* Created on 2021/09/14
* <></>
*/
public class DefaultDetectSingleTableData implements DetectSingleTableData {
private String typeId;
private String title;
private String advice;
private String problemDescription;
private SCRecordLevel level;
//在某个地方放置相应的sheetName和sheetIndex的映射,这个一定会用的
private List<Integer> sheetIndexs = new ArrayList<>();
//每个scReordItem代表每行数据,根据行数据生成相应的ui界面
private List<SCRecordItem> scRecordItems = new ArrayList<>();
public DefaultDetectSingleTableData(String typeId) {
this.typeId = typeId;
}
public DefaultDetectSingleTableData(String typeId, String title, String advice, String problemDescription, SCRecordLevel level) {
this.typeId = typeId;
this.title = title;
this.advice = advice;
this.problemDescription = problemDescription;
this.level = level;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getAdvice() {
return advice;
}
@Override
public String getProblemDescription() {
return problemDescription;
}
@Override
public SCRecordLevel getLevel() {
return level;
}
@Override
public void addSCRecordItem(SCRecordItem scRecordItem) {
scRecordItems.add(scRecordItem);
}
@Override
public void addSCRecordItems(List<SCRecordItem> scRecordItems) {
this.scRecordItems.addAll(scRecordItems);
}
@Override
public int getColumnCount() {
return scRecordItems.size();
}
/**
* 添加sheetIndex
*/
public void addIndexs(int sheetIndex, int n) {
for (int i = 0; i < n; i++) {
sheetIndexs.add(sheetIndex);
}
}
@Override
public int getSCRecordItemsCount() {
return scRecordItems.size();
}
@Override
public SCRecordItem getSCRecordItem(int i) {
return scRecordItems.get(i);
}
@Override
public Object getExtraData(int index) {
if (checkExtraExist(index)) {
return sheetIndexs.get(index);
} else {
return null;
}
}
@Override
public boolean checkExtraExist(Object index) {
return (int) index < sheetIndexs.size();
}
/**
* 因为是按照某个类型分的类所以这里的SCRecordItem为同一个类型
*/
@Override
public void constructProblemDescription() {
StringBuilder stringBuilder = new StringBuilder();
//在这里构建
switch (typeId) {
case "01001":
for (SCRecordItem item :
scRecordItems) {
SCDataSourceRecordItem scDataSourceRecordItem = (SCDataSourceRecordItem) item;
String dsName = scDataSourceRecordItem.getDsName();
String message = scDataSourceRecordItem.getMessage();
stringBuilder.append(Toolkit.i18nText("Fine-Design_Template_Assistant_Problem_Description_Redundant_Data_Fetch_DS"))
.append(dsName)
.append(Toolkit.i18nText("Fine-Design_Template_Assistant_Problem_Description_Redundant_Data_Fetch_Redundant_Detect"))
.append(message)
.append(Toolkit.i18nText("Fine-Design_Template_Assistant_Problem_Description_Redundant_Data_Fetch_Actual_Used"))
.append('\n');
}
break;
//驱动检测的描述信息
case "30003":
for (SCRecordItem item :
scRecordItems) {
stringBuilder.append(((SCMessageRecordItem) item).getMessage())
.append('\n');
}
break;
default:
}
problemDescription = stringBuilder.toString();
}
}

58
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/impl/DefaultProblemInformation.java

@ -0,0 +1,58 @@
package com.fr.design.mainframe.shadow.ui.data.impl;
import com.fr.design.mainframe.shadow.ui.data.ProblemInformation;
/**
* 默认异常信息
*
* @author fly.li
* @since 10.0
* Created on 2021/11/16
*/
public class DefaultProblemInformation implements ProblemInformation {
/**
* 标题
*/
private String title;
/**
* 建议
*/
private String advice;
/**
* 问题描述
*/
private String problemDescription;
public DefaultProblemInformation(String title, String advice) {
this.title = title;
this.advice = advice;
}
public DefaultProblemInformation(String title, String advice, String problemDescription) {
this.title = title;
this.advice = advice;
this.problemDescription = problemDescription;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getAdvice() {
return advice;
}
@Override
public String getProblemDescription() {
return problemDescription;
}
@Override
public void setProblemDescription(String problemDescription) {
this.problemDescription = problemDescription;
}
}

50
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/data/impl/DefaultTemplateDetectResultData.java

@ -0,0 +1,50 @@
package com.fr.design.mainframe.shadow.ui.data.impl;
import com.fr.design.mainframe.shadow.ui.data.DetectMutiTableData;
import com.fr.design.mainframe.shadow.ui.data.TemplateDetectResultData;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 展示面板的总数据类实现
*
* @author fly.li
* @since 10.0
* Created on 2021/09/14
*/
public class DefaultTemplateDetectResultData implements TemplateDetectResultData {
//标签,用来对应显示的标签顺序,以此为“修改建议”、“自动优化”和“sql优化建议”
private int dataStatus;
private Map<String, DetectMutiTableData> detectMutiTableDatas = new HashMap<>();
@Override
public DetectMutiTableData getDetectMutiTableData(String key) {
return detectMutiTableDatas.get(key);
}
@Override
public void putDetectMutiTableData(String key, DetectMutiTableData detectMutiTableData) {
detectMutiTableDatas.put(key, detectMutiTableData);
}
public int getDataStatus() {
return dataStatus;
}
@Override
public boolean isNoError() {
return detectMutiTableDatas.size() == 0;
}
@Override
public boolean containsKey(String key) {
return detectMutiTableDatas.containsKey(key);
}
@Override
public Set<String> keys() {
return detectMutiTableDatas.keySet();
}
}

357
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/SCDefaultSCTemplateHelper.java

@ -0,0 +1,357 @@
package com.fr.design.mainframe.shadow.ui.detect;
import com.fr.base.io.IOFile;
import com.fr.base.vcs.DesignerMode;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.DetectFailedPane;
import com.fr.design.mainframe.shadow.ui.DetectNoErrorPane;
import com.fr.design.mainframe.shadow.ui.OptimizationProgressPane;
import com.fr.design.mainframe.shadow.ui.component.TemplateHelperShowPane;
import com.fr.design.mainframe.shadow.ui.component.table.AutoOptimizeDetectMultiTablePane;
import com.fr.design.mainframe.shadow.ui.data.TemplateDetectResultData;
import com.fr.invoke.Reflect;
import com.fr.log.FineLoggerFactory;
import com.fr.nx.analyze.shadow.attr.SCOptionAttrMark;
import com.fr.nx.analyze.shadow.metric.SCMetricHelper;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.SwingWorker;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.ExecutionException;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/15
* <>交互的需求需要在检测过程开始前先显示检测中的界面在检测完成后显示结果界面,检测前和检测后页面在同一个面板中决定了检测SCTemplateHelperDetect和展示(内部类ShowPane)不可能分开因此创建一个类来实现完成这两部分</>
*/
public class SCDefaultSCTemplateHelper implements SCTemplateHelper {
private static final SCDefaultSCTemplateHelper INSTANCE = new SCDefaultSCTemplateHelper();
private boolean skipAutoOptimize;
private ShowPane showPane;
private SCDefaultSCTemplateHelper() {
showPane = new ShowPane();
}
public static SCDefaultSCTemplateHelper getInstance() {
return INSTANCE;
}
/**
* 点击主动检测图标的流程
*/
public void startAndShow() {
//每次开始之前都清空一下组件,否则不同层级的组件可能会相互影响
showPane.clearComponent();
JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
skipAutoOptimize = isSkipAutoOptimize(currentEditingTemplate);
if (!confirmSaveFile(currentEditingTemplate)) {
return;
}
SCTemplateHelperDetect scTemplateHelperDetect = SCDefaultSCTemplateHelperDetect.getInstance();
SwingWorker<TemplateDetectResultData, Integer> resultDealWith = new SwingWorker<TemplateDetectResultData, Integer>() {
@Override
protected TemplateDetectResultData doInBackground() {
//做检测
return scTemplateHelperDetect.detect();
}
@Override
protected void done() {
//检测完成后,切换界面显示真正的面板
TemplateDetectResultData templateDetectResultData = null;
try {
templateDetectResultData = get();
} catch (InterruptedException | ExecutionException e) {
FineLoggerFactory.getLogger().error("pane repaint error", e);
}
//检测结果出来后,显示结果面板,并且刷新错误显示工具栏
showPane.showResultPane(scTemplateHelperDetect.getDetectStatus(), templateDetectResultData);
DesignerContext.getDesignerFrame().resetToolkitByPlus(currentEditingTemplate);
}
};
resultDealWith.execute();
showPane.startShow();
}
/**
* 保存检测和点击错误图标显示检测结果流程
*
* @param isSaveDetect 其是用来区分保存显示和点击错误图标显示的该参数目前没有用保存检测目前被屏蔽
*/
public void startShow(boolean isSaveDetect) {
showPane.clearComponent();
skipAutoOptimize = isSkipAutoOptimize(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate());
SCTemplateHelperDetect scTemplateHelperDetect = SCDefaultSCTemplateHelperDetect.getInstance();
SwingWorker<TemplateDetectResultData, Integer> resultDealWith = new SwingWorker<TemplateDetectResultData, Integer>() {
@Override
protected TemplateDetectResultData doInBackground() {
//做检测
return scTemplateHelperDetect.detect();
}
@Override
protected void done() {
TemplateDetectResultData templateDetectResultData = null;
try {
templateDetectResultData = get();
} catch (InterruptedException | ExecutionException e) {
FineLoggerFactory.getLogger().error("pane repaint error", e);
}
//检测结果出来后,显示结果面板
if (isSaveDetect) {
//保存检测应该加一个刷新错误数字的操作,记录一下
SCDefaultSCTemplateHelper.this.showPane.showResultPaneInSave(scTemplateHelperDetect.getDetectStatus(), templateDetectResultData);
} else {
SCDefaultSCTemplateHelper.this.showPane.showResultPane(scTemplateHelperDetect.getDetectStatus(), templateDetectResultData);
}
}
};
resultDealWith.execute();
}
/**
* 关闭检测界面
*/
public void close() {
showPane.hideDialog();
}
/**
* 判断检测状态从而显示不同的面板
*/
private Status judgeCondition(boolean detectStatus, TemplateDetectResultData templateDetectResultData) {
//检测状态为SUCCESS的情况下检测结果也可能为null(还没找出来原因,日志显示并发取消异常)
if (templateDetectResultData == null) {
return Status.FAILURE;
}
if (!detectStatus) {
return Status.FAILURE;
} else if (templateDetectResultData.isNoError()) {
return Status.CORRECT;
} else {
return Status.ERROR;
}
}
/**
* 检测过程中如果文件未保存需要提示保存文件
* 如果点击不保存返回false(不进行检测并且不显示检测界面)保存返回true(进行检测并且显示检测界面)
*/
private boolean confirmSaveFile(JTemplate currentEditingTemplate) {
boolean confirmSave = true;
if (!currentEditingTemplate.isALLSaved() && !DesignerMode.isVcsMode()) {
currentEditingTemplate.stopEditing();
confirmSave = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + currentEditingTemplate.getEditingFILE() + "\" ?", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Confirm"), 1, 3) == 0;
if (confirmSave) {
/*
* 最近的保存流程时间是2021.4.15该流程也没有复用之前的检测流程即使使用反射也是使用新的流程
* 如果合并到fr11,可以直接使用saveDirectly方法
* */
currentEditingTemplate.saveTemplate();
currentEditingTemplate.requestFocus();
try {
// 这个类老jar里没有,兼容一下
// 看里下 saveTemplate 里面的逻辑好像只是记录埋点之类的信息,如果调不到就不管了
Reflect.on("com.fr.design.share.SharableManager").call("saveTemplate", currentEditingTemplate);
} catch (Exception e) {
// ignore
}
//在主动检测时,遇到未保存且是首次保存时,会触发首次保存的展示结果流程,主动检测后面的展示流程应该略过,这里记录一下(现在是屏蔽的)
}
}
return confirmSave;
}
private boolean isSkipAutoOptimize(JTemplate currentEditingTemplate) {
SCOptionAttrMark scOptionAttrMark = getSCOptionAttrMark(currentEditingTemplate);
if (scOptionAttrMark != null && scOptionAttrMark.isSkipAutoTask()) {
return true;
} else {
return false;
}
}
private SCOptionAttrMark getSCOptionAttrMark(JTemplate currentEditingTemplate) {
IOFile ioFile = getIOFile(currentEditingTemplate);
if (ioFile != null) {
return ioFile.getAttrMark(SCOptionAttrMark.MARK);
} else {
return null;
}
}
private IOFile getIOFile(JTemplate currentEditingTemplate) {
Object target = currentEditingTemplate.getTarget();
if (target instanceof IOFile) {
return (IOFile) target;
}
return null;
}
private enum Status {
/**
* 检测失败状态
*/
FAILURE,
/**
* 没有需要优化的状态
*/
CORRECT,
/**
* 包含手动优化项
*/
ERROR
}
/**
* 该面板是显示界面入口类
*/
private class ShowPane extends BasicPane {
// private ReportComponentCardPane reportComponentCardPane;
private final int WIDTH = 660;
private final int HEIGHT = 600;
/**
* JLayeredPane用于不同界面之间的切换
* 只能使用绝对布局的方式导致不同计算机之间显示存在差距
* 后面使用自定义代码的方式实现界面的切换尝试一下先记录一下
*/
JLayeredPane layeredPane;
private UIDialog dialog;
private Rectangle rectangle = new Rectangle(0, 0, 640, 556);
public ShowPane() {
init();
}
/**
* 初始化面板并显示面板
*/
private void init() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
dialog = showWindow(DesignerContext.getDesignerFrame(), false);
Rectangle frameBounds = DesignerContext.getDesignerFrame().getBounds();
dialog.setBounds((int) (frameBounds.getWidth() / 2) - WIDTH / 2, (int) frameBounds.height / 2 - HEIGHT / 2, WIDTH, HEIGHT);
layeredPane = new JLayeredPane();
layeredPane.setBounds(rectangle);
this.add(layeredPane);
dialog.setTitle(Toolkit.i18nText("Fine-Design_Template_Assistant_Result_Pane_Title"));
dialog.setModal(false);
//在退出结果面板后再刷新一下主面板
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (isChangeWithAutoOptimizeSwitch()) {
currentEditingTemplate.fireTargetModified();
SCOptionAttrMark scOptionAttrMark = getSCOptionAttrMark(currentEditingTemplate);
if (scOptionAttrMark == null) {
scOptionAttrMark = new SCOptionAttrMark();
IOFile ioFile = getIOFile(currentEditingTemplate);
ioFile.addAttrMark(scOptionAttrMark);
}
//保存自动优化规则开启状态并记录一下开启自动优化规则的埋点
scOptionAttrMark.setSkipAutoTask(!skipAutoOptimize);
SCMetricHelper.submitF6013(currentEditingTemplate.getEditingFILE().getPath(), !skipAutoOptimize ? 0 : 1);
}
}
});
}
private void showPane(JComponent jComponent) {
layeredPane.add(jComponent, JLayeredPane.DEFAULT_LAYER);
jComponent.setBounds(rectangle);
layeredPane.moveToFront(jComponent);
//这里需要重新showDialog,不然会出现排版错误
showDialog();
}
private void showResultPane(boolean detectStatus, TemplateDetectResultData templateDetectResultData) {
Status status = judgeCondition(detectStatus, templateDetectResultData);
//在这里决定创建哪个对象并显示结果
switch (status) {
case CORRECT:
DetectNoErrorPane detectNoErrorPane = new DetectNoErrorPane();
showPane(detectNoErrorPane);
break;
case ERROR:
TemplateHelperShowPane templateHelperShowPane = new TemplateHelperShowPane(templateDetectResultData);
showPane(templateHelperShowPane);
break;
default:
DetectFailedPane detectFailedPane = new DetectFailedPane();
showPane(detectFailedPane);
}
}
private void showResultPaneInSave(boolean detectStatus, TemplateDetectResultData templateDetectResultData) {
Status status = judgeCondition(detectStatus, templateDetectResultData);
if (status.equals(Status.ERROR)) {
TemplateHelperShowPane templateHelperShowPane = new TemplateHelperShowPane(templateDetectResultData);
showPane(templateHelperShowPane);
}
}
private void clearComponent() {
layeredPane.removeAll();
}
private void showDialog() {
dialog.setVisible(true);
}
private void hideDialog() {
dialog.setVisible(false);
}
private void startShow() {
//在需要时候才会创建面板对象并且放进layeredPane中
OptimizationProgressPane optimizationProgressPane = new OptimizationProgressPane();
optimizationProgressPane.setBounds(rectangle);
layeredPane.add(optimizationProgressPane, JLayeredPane.DEFAULT_LAYER);
layeredPane.moveToFront(optimizationProgressPane);
showDialog();
}
public void setDialog(UIDialog dialog) {
this.dialog = dialog;
}
@Override
protected String title4PopupWindow() {
return null;
}
private boolean isChangeWithAutoOptimizeSwitch() {
Component[] components = layeredPane.getComponents();
for (Component component : components) {
if (component instanceof TemplateHelperShowPane) {
AutoOptimizeDetectMultiTablePane autoOptimizeDetectMultiTablePane = ((TemplateHelperShowPane) component).getAutoOptimizeDetectMultiTablePane();
if (autoOptimizeDetectMultiTablePane != null && skipAutoOptimize ^ autoOptimizeDetectMultiTablePane.isSkipAutoOptimize()) {
return true;
}
}
}
return false;
}
}
}

115
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/SCDefaultSCTemplateHelperDetect.java

@ -0,0 +1,115 @@
package com.fr.design.mainframe.shadow.ui.detect;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.data.SheetIndexToName;
import com.fr.design.mainframe.shadow.ui.data.TemplateDetectResultData;
import com.fr.design.mainframe.shadow.ui.data.impl.DefaultTemplateDetectResultData;
import com.fr.design.mainframe.shadow.ui.detect.adapter.SCDetectAdapter;
import com.fr.design.mainframe.shadow.ui.detect.adapter.impl.SCDefaultSCDetectAdapter;
import com.fr.design.mainframe.shadow.ui.detect.filter.impl.SCWatermarkFilter;
import com.fr.form.main.Form;
import com.fr.form.ui.ElementCaseEditorProvider;
import com.fr.main.AbstractFineBook;
import com.fr.nx.analyze.shadow.manager.SCManagerFactory;
import com.fr.nx.analyze.shadow.utils.TemplatePathUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/16
* <></>
*/
public class SCDefaultSCTemplateHelperDetect implements SCTemplateHelperDetect {
private static final List<SCDetectAdapter> SC_DETECT_ADAPTERS = new ArrayList<>();
private static SCDefaultSCTemplateHelperDetect instance = new SCDefaultSCTemplateHelperDetect(SC_DETECT_ADAPTERS);
static {
SC_DETECT_ADAPTERS.add(new SCDefaultSCDetectAdapter(new SCWatermarkFilter()));
}
/**
* 所有检测流程需要实现的适配器
*/
private List<SCDetectAdapter> scDetectAdapters = new ArrayList<>();
private boolean detectStatus;
private SCDefaultSCTemplateHelperDetect(List<SCDetectAdapter> scDetectAdapters) {
this.scDetectAdapters = scDetectAdapters;
}
/**
* 整个设计器执行期间单个类执行注册一次因此该注册方法最好在类加载时候执行
*/
public static void register(SCDetectAdapter scDetectAdapter) {
SC_DETECT_ADAPTERS.add(scDetectAdapter);
}
public static SCTemplateHelperDetect getInstance() {
return instance;
}
@Override
public TemplateDetectResultData detect() {
TemplateDetectResultData templateDetectResultData = new DefaultTemplateDetectResultData();
JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
dataPrepareBeforeDetect(currentEditingTemplate);
int status = 1;
for (SCDetectAdapter scDetectAdapter : scDetectAdapters) {
status &= scDetectAdapter.detectAndAddResult2Data(templateDetectResultData, currentEditingTemplate);
}
detectStatus = status == SCDetectAdapter.SUCCESS;
return templateDetectResultData;
}
@Override
public int errorCount(JTemplate jTemplate) {
// 模板是否保存在当前工作目录
if (!jTemplate.getEditingFILE().isEnvFile()) {
return -1;
}
if (isFirstSave(jTemplate)) {
return -1;
}
int errorCount = 0;
for (SCDetectAdapter scDetectAdapter :
scDetectAdapters) {
errorCount += scDetectAdapter.errorCount(jTemplate);
}
return errorCount;
}
private void dataPrepareBeforeDetect(JTemplate jTemplate) {
Object target = jTemplate.getTarget();
SheetIndexToName sheetIndexToName = SheetIndexToName.getInstance();
if (target instanceof AbstractFineBook) {
AbstractFineBook abstractFineBook = (AbstractFineBook) target;
for (int index = 0; index < abstractFineBook.getReportCount(); index++) {
sheetIndexToName.addSheetName(index, abstractFineBook.getReportName(index));
}
}
//如果是form的话需要,准备一下控件名称和控件索引的对应关系
if (target instanceof Form) {
Form form = (Form) target;
ElementCaseEditorProvider[] elementCases = form.getElementCases();
for (int index = 0; index < elementCases.length; index++) {
sheetIndexToName.addSheetName(index, elementCases[index].getWidgetName());
}
}
}
@Override
public boolean isFirstSave(JTemplate jTemplate) {
//初次保存的判断也放在这里,暂时先不管sql优化建议是否是初次保存
return !SCManagerFactory.sharedManager().hasHistoryShadowTemplate(TemplatePathUtils.trimPrefix(jTemplate.getPath()));
}
@Override
public boolean getDetectStatus() {
return detectStatus;
}
}

11
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/SCTemplateHelper.java

@ -0,0 +1,11 @@
package com.fr.design.mainframe.shadow.ui.detect;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/15
* <>感觉没有必要定义一个接口以防万一还是定义一个接口真正的实现在DefaultTemplateHelper中</>
*/
public interface SCTemplateHelper {
}

39
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/SCTemplateHelperDetect.java

@ -0,0 +1,39 @@
package com.fr.design.mainframe.shadow.ui.detect;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.data.TemplateDetectResultData;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/16
* <>检测流程接口</>
*/
public interface SCTemplateHelperDetect {
/**
* 检测流程入口
*
* @return TemplateHelperShowData代表所有检测流程检测出的结果转换成指定接口的形式
*/
TemplateDetectResultData detect();
/**
* 检测流程最终的状态
*
* @return booleantrue代表成功false代表失败只有所有流程都检测成功才会返回true
*/
boolean getDetectStatus();
/**
* 是否是第一次保存检测
*/
boolean isFirstSave(JTemplate jTemplate);
/**
* 检测出的所有错误问题数
*
* @return int 检测出的所有问题数
*/
int errorCount(JTemplate jTemplate);
}

33
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/adapter/SCDetectAdapter.java

@ -0,0 +1,33 @@
package com.fr.design.mainframe.shadow.ui.detect.adapter;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.data.TemplateDetectResultData;
/**
* @author fly.li
* @since 10.0
* Created on 2021/09/14
* <>检测流程的适配器接口</>
*/
public interface SCDetectAdapter {
int FAILURE = 0;
int SUCCESS = 1;
/**
* 检测并将结果添加到templateHelperShowData中需要转换成固定的格式
*
* @param templateDetectResultData, 检测出的结果转换成固定格式放在添加到TemplateHelperShowData中
* @param jTemplate, 当前模板
* @return, int, 当前检测流程检测状态返回0代表检测失败返回1代表检测成功
*/
int detectAndAddResult2Data(TemplateDetectResultData templateDetectResultData, JTemplate jTemplate);
/**
* 返回检测出的问题数面板中的显示错误数字
*
* @param jTemplate, 当前模板
* @return, int, 当前检测流程检测出来的错误问题数
*/
int errorCount(JTemplate jTemplate);
}

248
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/adapter/impl/SCDefaultSCDetectAdapter.java

@ -0,0 +1,248 @@
package com.fr.design.mainframe.shadow.ui.detect.adapter.impl;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.data.DetectMutiTableData;
import com.fr.design.mainframe.shadow.ui.data.DetectSingleTableData;
import com.fr.design.mainframe.shadow.ui.data.ProblemInformation;
import com.fr.design.mainframe.shadow.ui.data.ProblemInformationFactory;
import com.fr.design.mainframe.shadow.ui.data.TemplateDetectResultData;
import com.fr.design.mainframe.shadow.ui.data.impl.DefaultDetectMutiTableData;
import com.fr.design.mainframe.shadow.ui.data.impl.DefaultDetectSingleTableData;
import com.fr.design.mainframe.shadow.ui.detect.adapter.SCDetectAdapter;
import com.fr.design.mainframe.shadow.ui.detect.filter.SCRecordFilter;
import com.fr.form.main.Form;
import com.fr.form.ui.ElementCaseEditorProvider;
import com.fr.log.FineLoggerFactory;
import com.fr.main.impl.WorkBook;
import com.fr.nx.analyze.shadow.entity.result.SCResult;
import com.fr.nx.analyze.shadow.entity.result.SCResultStatus;
import com.fr.nx.analyze.shadow.manager.SCManager;
import com.fr.nx.analyze.shadow.manager.SCManagerFactory;
import com.fr.nx.analyze.shadow.metric.recorder.impl.SCDesignerMetricRecorder;
import com.fr.nx.analyze.shadow.record.SCRecord;
import com.fr.nx.analyze.shadow.record.SCRecordType;
import com.fr.nx.analyze.shadow.record.impl.SCRecordImpl;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.runtime.SCRuntimeFactory;
import com.fr.nx.analyze.shadow.template.SCTemplateHolder;
import com.fr.nx.analyze.shadow.utils.TemplatePathUtils;
import com.fr.stable.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 对ScManager进行包装,SCManage对修改建议自动优化两类进行检测
*
* @author fly.li
* @since 10.0
* Created on 2021/09/14
*/
public class SCDefaultSCDetectAdapter implements SCDetectAdapter {
private SCResultStatus status = SCResultStatus.FAILURE;
private SCRecordFilter filter;
public SCDefaultSCDetectAdapter() {
}
public SCDefaultSCDetectAdapter(SCRecordFilter filter) {
this.filter = filter;
}
@Override
public int detectAndAddResult2Data(TemplateDetectResultData templateDetectResultData, JTemplate jTemplate) {
//动态检测没有检测信息(失败还是成功),以静态检测为准
List<SCRecord> optimizeRecords = detectAndFilter0(jTemplate);
if (!optimizeRecords.isEmpty()) {
for (SCRecord scRecord :
optimizeRecords) {
SCRecordType type = scRecord.getType();
String typeStr = StringUtils.EMPTY;
switch (type) {
case INFO:
typeStr = Toolkit.i18nText("Fine-Design_Template_Assistant_Manual_Optimize");
break;
case AUTO:
typeStr = Toolkit.i18nText("Fine-Design_Template_Assistant_Auto_Optimize");
break;
case RECOMMEND:
typeStr = Toolkit.i18nText("Fine-Design_Template_Assistant_Function_Guide");
break;
default:
FineLoggerFactory.getLogger().error("unknown type");
}
fillSCTemplateHelperShowData(scRecord, templateDetectResultData, jTemplate, typeStr);
}
afterFillSCTemplateHelperShowData(templateDetectResultData);
}
return status.equals(SCResultStatus.SUCCEED) ? SUCCESS : FAILURE;
}
private void afterFillSCTemplateHelperShowData(TemplateDetectResultData templateDetectResultData) {
// 在这里完成未完成的填充,比如有些描述信息不是固定的,在这里需要生成并进行填充,多sheet的描述信息必须在按照id分完类之后进行描述。
for (String keyMu :
templateDetectResultData.keys()) {
DetectMutiTableData detectMutiTableData = templateDetectResultData.getDetectMutiTableData(keyMu);
for (String keySin :
detectMutiTableData.keys()) {
DetectSingleTableData detectSingleTableData = detectMutiTableData.getDetectSingleTableData(keySin);
if (StringUtils.isEmpty(detectSingleTableData.getProblemDescription())) {
detectSingleTableData.constructProblemDescription();
}
}
}
}
@Override
public int errorCount(JTemplate jTemplate) {
int count = 0;
List<SCRecord> scRecords = detectAndFilter0(jTemplate);
if (scRecords != null && scRecords.size() > 0) {
for (SCRecord scRecord : scRecords) {
if (!scRecord.getType().equals(SCRecordType.AUTO)) {
count += scRecord.getItems().size();
}
}
}
return count;
}
private List<SCRecord> detectAndFilter0(JTemplate jTemplate) {
List<SCRecord> records = detect0(jTemplate);
return filter0(records);
}
private List<SCRecord> detect0(JTemplate jTemplate) {
SCResult staticSCResult = staticDetect0(jTemplate);
List<SCRecord> records = runTimeDetect0(jTemplate);
if (staticSCResult != null) {
List<SCRecord> staticOptimizeRecords = staticSCResult.getOptimizeRecords();
records.addAll(staticOptimizeRecords);
}
return records;
}
private SCResult staticDetect0(JTemplate jTemplate) {
SCManager scManager = SCManagerFactory.sharedManager();
SCResult scResult = null;
try {
SCTemplateHolder tplHolder = SCTemplateHolder.parse(jTemplate.getTarget());
if (tplHolder != null) {
scResult = scManager.acquireShadowTemplate(
TemplatePathUtils.trimPrefix(jTemplate.getPath()),
tplHolder,
SCDesignerMetricRecorder.createManualOperateRecorder()
).get();
}
if (scResult != null) {
status = scResult.getStatus();
}
} catch (InterruptedException | ExecutionException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return scResult;
}
private List<SCRecord> runTimeDetect0(JTemplate jTemplate) {
List<SCRecord> records = new ArrayList<>();
records.addAll(SCRuntimeFactory.sharedManager().getOptimizeRecords(TemplatePathUtils.trimPrefix(jTemplate.getPath())));
records.addAll(SCRuntimeFactory.sharedManager().getGlobalOptimizeRecords());
return records;
}
private List<SCRecord> filter0(List<SCRecord> records) {
List<SCRecord> remainingRecords = new ArrayList<>();
for (SCRecord record : records) {
SCRecord scRecord = filterAndGetSCRecord(record);
if (!scRecord.getItems().isEmpty()) {
remainingRecords.add(scRecord);
}
}
return remainingRecords;
}
private void fillSCTemplateHelperShowData(SCRecord scRecord, TemplateDetectResultData templateDetectResultData, JTemplate jTemplate, String type) {
if (StringUtils.isEmpty(type)) {
return;
}
if (!templateDetectResultData.containsKey(type)) {
templateDetectResultData.putDetectMutiTableData(type, new DefaultDetectMutiTableData());
}
DetectMutiTableData detectMutiTableData = templateDetectResultData.getDetectMutiTableData(type);
String id = scRecord.getId();
if (StringUtils.isEmpty(id)) {
//可能某个检测任务忘记设置了id
id = ProblemInformationFactory.NONE;
}
if (!detectMutiTableData.containsKey(id)) {
ProblemInformation problemInformation = ProblemInformationFactory.getProblemInformation(scRecord.getId());
if (problemInformation == null) {
//可能相应检测任务没有设置相应的问题描述、建议、优化类型等
detectMutiTableData.putDetectSingleTableData(id, new DefaultDetectSingleTableData(id));
} else {
detectMutiTableData.putDetectSingleTableData(id, new DefaultDetectSingleTableData(id, problemInformation.getTitle(), problemInformation.getAdvice(), problemInformation.getProblemDescription(), scRecord.getLevel()));
}
}
DetectSingleTableData detectSingleTableData = detectMutiTableData.getDetectSingleTableData(scRecord.getId());
String sheetName = scRecord.getSheetName();
List<SCRecordItem> items = scRecord.getItems();
detectSingleTableData.addSCRecordItems(items);
if (!StringUtils.isEmpty(sheetName)) {
int sheetIndex = getSheetIndex(jTemplate, sheetName);
//item的索引对应的是sheetIndex,每次查找item的时候都可以找到对应的sheetIndex.
((DefaultDetectSingleTableData) detectSingleTableData).addIndexs(sheetIndex, items.size());
}
}
private int getSheetIndex(JTemplate jTemplate, String sheetName) {
Object target = jTemplate.getTarget();
if (target instanceof WorkBook) {
WorkBook workBook = (WorkBook) target;
for (int i = 0; i < workBook.getReportCount(); i++) {
if (sheetName.equals(workBook.getReportName(i))) {
return i;
}
}
}
//兼容一下Form
if (target instanceof Form) {
Form form = (Form) target;
ElementCaseEditorProvider[] elementCases = form.getElementCases();
for (int i = 0; i < elementCases.length; i++) {
if (sheetName.equals(elementCases[i].getWidgetName())) {
return i;
}
}
}
return -1;
}
private SCRecord filterAndGetSCRecord(SCRecord record) {
if (record instanceof SCRecordImpl) {
SCRecordImpl scRecord = null;
try {
scRecord = (SCRecordImpl) record.clone();
} catch (CloneNotSupportedException e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
if (scRecord == null) {
return record;
}
//因为items是不可修改列表,因此这里删除元素,需要转换一下list的类型
List<SCRecordItem> items = scRecord.getItems();
List<SCRecordItem> remainingItems = new ArrayList<>(items);
scRecord.setItems(remainingItems);
if (filter != null) {
filter.filter(remainingItems);
}
return scRecord;
}
return record;
}
}

18
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/filter/SCRecordFilter.java

@ -0,0 +1,18 @@
package com.fr.design.mainframe.shadow.ui.detect.filter;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import java.util.List;
/**
* @author fly.li
* @since 10.0
* Created on 2022/01/06
* <>对最终检测到的结果进行过滤</>
*/
public interface SCRecordFilter {
/**
* 对已经检测到的数据进行过滤
*/
void filter(List<SCRecordItem> items);
}

50
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/detect/filter/impl/SCWatermarkFilter.java

@ -0,0 +1,50 @@
package com.fr.design.mainframe.shadow.ui.detect.filter.impl;
import com.fr.base.iofile.attr.WatermarkAttr;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.shadow.ui.detect.filter.SCRecordFilter;
import com.fr.main.impl.WorkBook;
import com.fr.nx.analyze.shadow.record.item.SCRecordItem;
import com.fr.nx.analyze.shadow.record.item.impl.SCMessageRecordItem;
import java.util.List;
/**
* @author fly.li
* @since 10.0
* Created on 2022/01/06
* <>水印设置为当前模板单独设置的时候需要将检测到的全局水印结果过滤掉</>
*/
public class SCWatermarkFilter implements SCRecordFilter {
@Override
public void filter(List<SCRecordItem> items) {
JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
Object object = currentEditingTemplate.getTarget();
//这里items不能进行修改,并且
SCRecordItem scRecordItem = null;
if (object instanceof WorkBook && isWaterMarkValid((WorkBook) object)) {
for (SCRecordItem item : items) {
if (isMeetFilterCondition(item)) {
scRecordItem = item;
}
}
}
if (scRecordItem != null) {
items.remove(scRecordItem);
}
}
private boolean isMeetFilterCondition(SCRecordItem item) {
if (item instanceof SCMessageRecordItem) {
//暂时只能用message来判断是否是要过滤的item
return ((SCMessageRecordItem) item).getMessage().equals(Toolkit.i18nText("Fine-Design_Template_Assistant_Global_Watermark"));
}
return false;
}
private boolean isWaterMarkValid(WorkBook workBook) {
return workBook != null && workBook.getAttrMark("WatermarkAttr") != null && ((WatermarkAttr) workBook.getAttrMark("WatermarkAttr")).isValid();
}
}

60
designer-realize/src/main/java/com/fr/design/mainframe/shadow/ui/icon/CountIcon.java

@ -0,0 +1,60 @@
package com.fr.design.mainframe.shadow.ui.icon;
import com.fr.general.FRFont;
import javax.swing.ImageIcon;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
/**
* 可以显示不同数字的图标
*
* @author rinoux
* @since 10.0
* Created on 2021/10/22
*/
public class CountIcon extends ImageIcon {
private final static String FONT_NAME = "Microsoft YaHei";
private final static int FONT_SIZE = 8;
private final static String MAX = "99+";
private final static int Y_OFFSET = 13;
private final int count;
public CountIcon(Image backgroundImage, int count) {
super(backgroundImage);
this.count = count;
}
@Override
public synchronized final void paintIcon(Component c, Graphics g, int x, int y) {
super.paintIcon(c, g, x, y);
if (count > 0) {
g.setFont(FRFont.getInstance(FONT_NAME, Font.BOLD, FONT_SIZE));
g.setColor(Color.WHITE);
//根据这个字体不同位数的数字,摸索了一下位置
String text = String.valueOf(count);
int xOffset;
switch (text.length()) {
case 0:
case 1:
xOffset = 9;
break;
case 2:
xOffset = 6;
break;
case 3:
default:
text = MAX;
xOffset = 3;
break;
}
g.drawString(text, xOffset, Y_OFFSET);
}
}
}

33
designer-realize/src/main/java/com/fr/design/mainframe/shadow/utils/DesignerPaneUtil.java

@ -0,0 +1,33 @@
package com.fr.design.mainframe.shadow.utils;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.ReportComponentCardPane;
import com.fr.invoke.Reflect;
import javax.swing.JComponent;
/**
* @author fly.li
* @since 10.0
* Created on 2021/8/5
* 获取设计器界面的工具类
*/
public class DesignerPaneUtil {
/**
* 获取当前编辑的模板的ReportComponentCardPane
*/
public static ReportComponentCardPane getReportComponentCardPane(JTemplate jTemplate) {
JComponent currentReportComponentPane = jTemplate.getCurrentReportComponentPane();
return Reflect.on(currentReportComponentPane).get("centerCardPane");
}
/**
* 获取当前编辑的模板的ReportComponentCardPane
*/
public static ReportComponentCardPane getCurrentReportComponentCardPane() {
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return getReportComponentCardPane(currentEditingTemplate);
}
}

90
designer-realize/src/test/java/com/fr/design/shadow/SCDesignerMetricRecorderTest.java

@ -0,0 +1,90 @@
package com.fr.design.shadow;
import com.fr.design.DesignerEnvManager;
import com.fr.nx.analyze.shadow.metric.SCMetric;
import com.fr.nx.analyze.shadow.metric.recorder.impl.SCDesignerMetricRecorder;
import com.fr.nx.analyze.shadow.metric.utils.DesignerFileWriter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.getCurrentArguments;
import static org.easymock.EasyMock.mock;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Created by loy on 2021/8/25.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({DesignerEnvManager.class, DesignerFileWriter.class})
public class SCDesignerMetricRecorderTest {
@Before
public void setUp() throws Exception {
DesignerEnvManager manager = mock(DesignerEnvManager.class);
expect(manager.getUUID()).andReturn("1234-5678-aaaa-bbbb").anyTimes();
replay(manager);
PowerMock.mockStatic(DesignerEnvManager.class);
expect(DesignerEnvManager.getEnvManager()).andReturn(manager).anyTimes();
PowerMock.replay(DesignerEnvManager.class);
}
@Test
public void recordManualOperate() {
List<Object> args = new ArrayList<>();
PowerMock.mockStatic(DesignerFileWriter.class);
DesignerFileWriter.appendLine(anyString(), anyString(), anyString());
expectLastCall().andAnswer(() -> {
args.addAll(Arrays.asList(getCurrentArguments()));
return null;
}).once();
PowerMock.replay(DesignerFileWriter.class);
SCDesignerMetricRecorder
.createManualOperateRecorder()
.record(Collections.singletonList(new SCMetric("01", "001", 1)));
PowerMock.verify(DesignerFileWriter.class);
assertEquals(3, args.size());
assertTrue(((String) args.get(0)).startsWith("F0010"));
assertTrue(((String) args.get(1)).startsWith("designerAssistant"));
}
@Test
public void recordOnSave() {
List<Object> args = new ArrayList<>();
PowerMock.mockStatic(DesignerFileWriter.class);
DesignerFileWriter.appendLine(anyString(), anyString(), anyString());
expectLastCall().andAnswer(() -> {
args.addAll(Arrays.asList(getCurrentArguments()));
return null;
}).once();
PowerMock.replay(DesignerFileWriter.class);
SCDesignerMetricRecorder
.createOnSaveRecorder()
.record(Collections.singletonList(new SCMetric("02", "001", 2)));
PowerMock.verify(DesignerFileWriter.class);
assertEquals(3, args.size());
assertTrue(((String) args.get(0)).startsWith("F0011"));
assertTrue(((String) args.get(1)).startsWith("designerAssistant"));
}
}
Loading…
Cancel
Save