Browse Source
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=1191537310fbp/feature
Leo.Qin-覃宇攀
5 days ago
73 changed files with 3691 additions and 27 deletions
@ -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); |
||||
} |
||||
}; |
||||
} |
||||
} |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 927 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 640 B |
After Width: | Height: | Size: 646 B |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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); |
||||
|
||||
|
||||
} |
@ -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())); |
||||
} |
||||
} |
||||
} |
@ -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) { |
||||
|
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
|
||||
}; |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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() { |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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 { |
||||
} |
@ -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 { |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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()); |
||||
} |
||||
} |
@ -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()); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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"; |
||||
} |
||||
} |
||||
} |
@ -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并不存在难以维护的问题 |
||||
* (离散值适合switch,switch可能时间效率更好一点,空间效率稍差) |
||||
* <>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); |
||||
} |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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"); |
||||
} |
||||
} |
||||
|
||||
} |
@ -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]))); |
||||
|
||||
} |
||||
|
||||
} |
@ -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(); |
||||
|
||||
|
||||
} |
@ -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(); |
||||
} |
@ -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); |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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(); |
||||
} |
@ -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(); |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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 { |
||||
|
||||
} |
@ -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 boolean,true代表成功,false代表失败,只有所有流程都检测成功才会返回true |
||||
*/ |
||||
boolean getDetectStatus(); |
||||
|
||||
/** |
||||
* 是否是第一次保存检测 |
||||
*/ |
||||
boolean isFirstSave(JTemplate jTemplate); |
||||
|
||||
/** |
||||
* 检测出的所有错误问题数 |
||||
* |
||||
* @return int 检测出的所有问题数 |
||||
*/ |
||||
int errorCount(JTemplate jTemplate); |
||||
|
||||
} |
@ -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); |
||||
|
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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); |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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…
Reference in new issue