Browse Source

Merge pull request #12315 in DESIGN/design from release/11.0 to final/11.0

* commit 'd9d57be83fac4224c6046a83c70b9a063833bbbb': (56 commits)
  REPORT-97591 排序按钮设置颜色后,新增排序规则保存并关闭模板,再次打开排序按钮颜色丢失
  REPORT-97591 排序按钮设置颜色后,新增排序规则保存并关闭模板,再次打开排序按钮颜色丢失
  REPORT-97591 排序按钮设置颜色后,新增排序规则保存并关闭模板,再次打开排序按钮颜色丢失
  REPORT-99320 插件管理整体优化-设计器内单个插件更新的提示没有显示哪个插件更新,和平台提示文本不一致
  REPORT-99332 设计器文本输入框文本被自动移除的问题 rt, 把 trim 取消掉
  REPORT-97972 回退一下自己代码库的改动
  REPORT-97972 回退一下自己代码库的改动
  REPORT-97972 【FR国际化】文字显示不全
  REPORT-99073 插件管理整体优化-设计器内,批量禁用、启用插件没有效果
  REPORT-98879 修复jxbrowser7在windows下路径问题
  Revert "REPORT-80651 模板版本管理重构一期补交"
  Revert "REPORT-91839 模板版本管理二期"
  Revert "REPORT-91839 模板版本管理二期 修复规范问题"
  Revert "REPORT-91839 模板版本管理二期 完善一下判断逻辑,增加自动保存标签设置"
  Revert "REPORT-91839 模板版本管理二期 优化判断新老模式的逻辑,事件响应改为Config准备后进行"
  Revert "REPORT-91839 模板版本管理二期 补充按钮交互,消除冗余代码"
  Revert "REPORT-91839 模板版本管理二期 多删了一部分"
  Revert "REPORT-91839 模板版本管理二期 修复bug"
  REPORT-94637 单元测试修复
  fix: fvs适配jxbrowser7.26兼容问题 #REPORT-98648
  ...
new-design
superman 1 year ago
parent
commit
05ca05892f
  1. 10
      build.gradle
  2. 8
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  3. 17
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  4. 20
      designer-base/src/main/java/com/fr/design/actions/help/FineUIAction.java
  5. 3
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java
  6. 19
      designer-base/src/main/java/com/fr/design/dcm/UniversalDatabasePane.java
  7. 22
      designer-base/src/main/java/com/fr/design/dcm/UniversalDcmBridge.java
  8. 184
      designer-base/src/main/java/com/fr/design/extra/PluginBatchModifyDetailPane.java
  9. 106
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  10. 127
      designer-base/src/main/java/com/fr/design/extra/exe/callback/AbstractBatchModifyStatusCallback.java
  11. 43
      designer-base/src/main/java/com/fr/design/extra/exe/callback/BatchModifyStatusCallback.java
  12. 77
      designer-base/src/main/java/com/fr/design/extra/exe/callback/BatchUpdateOnlineCallback.java
  13. 14
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  14. 59
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabUtils.java
  15. 2
      designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java
  16. 6
      designer-base/src/main/java/com/fr/design/fun/impl/AbstractDefaultValueAdjustProvider.java
  17. 40
      designer-base/src/main/java/com/fr/design/jxbrowser/BrowserExecutor.java
  18. 140
      designer-base/src/main/java/com/fr/design/jxbrowser/JxEngine.java
  19. 555
      designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java
  20. 113
      designer-base/src/main/java/com/fr/design/jxbrowser/MimeType.java
  21. 177
      designer-base/src/main/java/com/fr/design/jxbrowser/NxInterceptRequestCallback.java
  22. 20
      designer-base/src/main/java/com/fr/design/jxbrowser/PropertyBuild.java
  23. 60
      designer-base/src/main/java/com/fr/design/login/DesignerLoginBridge.java
  24. 20
      designer-base/src/main/java/com/fr/design/login/DesignerLoginPane.java
  25. 17
      designer-base/src/main/java/com/fr/design/login/config/DesignerLoginConfigManager.java
  26. 68
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideBridge.java
  27. 3
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java
  28. 20
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuidePane.java
  29. 12
      designer-base/src/main/java/com/fr/design/os/impl/PMDialogAction.java
  30. 16
      designer-base/src/main/java/com/fr/design/ui/ModernUIConstants.java
  31. 24
      designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java
  32. 33
      designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java
  33. 35
      designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java
  34. 362
      designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java
  35. 86
      designer-base/src/main/java/com/fr/design/ui/compatible/NxComplexInterceptRequestCallback.java
  36. 148
      designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java
  37. 42
      designer-base/src/main/java/com/fr/design/update/push/DesignerPushUpdateDialog.java
  38. 10
      designer-base/src/main/java/com/fr/design/update/push/DesignerUpdateInfo.java
  39. 28
      designer-base/src/main/java/com/fr/design/upm/UpmBridge.java
  40. 26
      designer-base/src/main/java/com/fr/design/upm/UpmBridgeV7.java
  41. 4
      designer-base/src/main/java/com/fr/design/upm/UpmFinder.java
  42. 30
      designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java
  43. 20
      designer-base/src/test/java/com/fr/design/actions/help/TutorialActionTest.java
  44. 12
      designer-base/src/test/java/com/fr/design/base/clipboard/DesignerClipboardTest.java
  45. 17
      designer-base/src/test/java/com/fr/design/data/DesignTableDataManagerTest.java
  46. 20
      designer-base/src/test/java/com/fr/design/data/datapane/TableDataPaneListPaneTest.java
  47. 6
      designer-base/src/test/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtilsTest.java
  48. 289
      designer-base/src/test/java/com/fr/design/file/MultiTemplateTabPaneTest.java
  49. 4
      designer-base/src/test/java/com/fr/design/formula/FormulaPaneTest.java
  50. 12
      designer-base/src/test/java/com/fr/design/formula/FunctionConstantsTest.java
  51. 17
      designer-base/src/test/java/com/fr/design/gui/icombocheckbox/UICheckListPopupTest.java
  52. 72
      designer-base/src/test/java/com/fr/design/jxbrowser/JxUIPaneTest.java
  53. 21
      designer-base/src/test/java/com/fr/design/jxbrowser/MimeTypeTest.java
  54. 128
      designer-base/src/test/java/com/fr/design/mainfarme/toolbar/ToolBarMenuDockTest.java
  55. 19
      designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java
  56. 2
      designer-base/src/test/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfoTest.java
  57. 3
      designer-base/src/test/java/com/fr/design/ui/FineUIDemo.java
  58. 10
      designer-base/src/test/java/com/fr/design/ui/report/TemplateWebSettingDemo.java
  59. 21
      designer-base/src/test/java/com/fr/file/FILEChooserPaneTest.java
  60. 4
      designer-chart/src/main/java/com/fr/van/chart/box/VanChartBoxRichTextDetailedFieldListPane.java
  61. 4
      designer-chart/src/main/java/com/fr/van/chart/box/VanChartBoxRichTextResultFieldListPane.java
  62. 6
      designer-chart/src/main/java/com/fr/van/chart/box/VanChartBoxTooltipContentPane.java
  63. 6
      designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartTooltipContentPane.java
  64. 6
      designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartFieldListPane.java
  65. 2
      designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichEditorModel.java
  66. 97
      designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichEditorPane.java
  67. 6
      designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichTextPane.java
  68. 6
      designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/TooltipContentPaneWithOutSeries.java
  69. 4
      designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/VanChartFieldListPaneWithOutSeries.java
  70. 6
      designer-chart/src/main/java/com/fr/van/chart/funnel/designer/style/VanChartFunnelLabelContentPane.java
  71. 4
      designer-chart/src/main/java/com/fr/van/chart/funnel/designer/style/VanChartFunnelRichTextFieldListPane.java
  72. 6
      designer-chart/src/main/java/com/fr/van/chart/funnel/designer/style/VanChartFunnelTooltipContentPane.java
  73. 4
      designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/tooltip/VanChartGanttRichTextFieldListPane.java
  74. 6
      designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/tooltip/VanChartGanttTooltipContentPane.java
  75. 4
      designer-chart/src/main/java/com/fr/van/chart/map/designer/style/VanChartMapRichTextFieldListPane.java
  76. 6
      designer-chart/src/main/java/com/fr/van/chart/map/designer/style/label/VanChartMapLabelContentPane.java
  77. 6
      designer-chart/src/main/java/com/fr/van/chart/map/designer/style/tooltip/VanChartMapTooltipContentPane.java
  78. 4
      designer-chart/src/main/java/com/fr/van/chart/map/line/VanChartLineMapRichTextFieldListPane.java
  79. 6
      designer-chart/src/main/java/com/fr/van/chart/map/line/VanChartLineMapTooltipContentPane.java
  80. 6
      designer-chart/src/main/java/com/fr/van/chart/multilayer/style/VanChartMultiPieLabelContentPane.java
  81. 4
      designer-chart/src/main/java/com/fr/van/chart/multilayer/style/VanChartMultiPieRichTextFieldListPane.java
  82. 6
      designer-chart/src/main/java/com/fr/van/chart/multilayer/style/VanChartMultiPieTooltipContentPane.java
  83. 6
      designer-chart/src/main/java/com/fr/van/chart/pie/style/VanChartPieCategoryLabelContentPane.java
  84. 4
      designer-chart/src/main/java/com/fr/van/chart/pie/style/VanChartPieCategoryRichTextFieldListPane.java
  85. 6
      designer-chart/src/main/java/com/fr/van/chart/pie/style/VanChartPieValueLabelContentPane.java
  86. 4
      designer-chart/src/main/java/com/fr/van/chart/pie/style/VanChartPieValueRichTextFieldListPane.java
  87. 4
      designer-chart/src/main/java/com/fr/van/chart/scatter/VanChartScatterRichTextFieldListPane.java
  88. 6
      designer-chart/src/main/java/com/fr/van/chart/scatter/VanChartScatterTooltipContentPane.java
  89. 4
      designer-chart/src/main/java/com/fr/van/chart/structure/desinger/style/VanChartStructureRichTextFieldListPane.java
  90. 6
      designer-chart/src/main/java/com/fr/van/chart/structure/desinger/style/VanChartStructureTooltipContentPane.java
  91. 4
      designer-chart/src/main/java/com/fr/van/chart/wordcloud/designer/style/VanChartWordCloudRichTextFieldListPane.java
  92. 6
      designer-chart/src/main/java/com/fr/van/chart/wordcloud/designer/style/VanChartWordCloudTooltipContentPane.java
  93. 4
      designer-chart/src/main/resources/com/fr/design/editor/rich_editor.html
  94. 35
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopPane.java
  95. 18
      designer-form/src/test/java/com/fr/design/mainframe/template/info/ComponentCreateOperateTest.java
  96. 4
      designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java
  97. 6
      designer-realize/src/main/java/com/fr/quickeditor/CellQuickEditor.java
  98. 6
      designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellStringQuickEditor.java
  99. 18
      designer-realize/src/test/java/com.fr/design/mainframe/alphafine/cell/model/ModelTest.java
  100. 17
      designer-realize/src/test/java/com.fr/design/mainframe/alphafine/search/manager/impl/FileSearchManagerTest.java
  101. Some files were not shown because too many files have changed in this diff Show More

10
build.gradle

@ -14,6 +14,7 @@ ext {
outputPath = "build"
ignoreTestFailureSetting = true
languageLevelSetting = 1.8
jxBrowserVersion = '7.26'
}
applyGlobalConfigPathIfExist()
@ -66,8 +67,8 @@ allprojects {
implementation 'com.fr.cbb:fine-universal-skeleton:' + cbbVersion
implementation 'com.install4j:install4j-runtime:8.0.4'
implementation 'com.fr.third:jxbrowser:6.23'
implementation 'com.fr.third:jxbrowser-v7:7.22'
implementation 'com.fr.third:jxbrowser-swing-v7:7.22'
implementation "com.fr.third:jxbrowser-v7:${jxBrowserVersion}"
implementation "com.fr.third:jxbrowser-swing-v7:${jxBrowserVersion}"
implementation 'com.fr.third.server:servlet-api:3.0'
implementation 'org.swingexplorer:swexpl:2.0.1'
implementation 'org.swingexplorer:swag:1.0'
@ -89,18 +90,19 @@ allprojects {
testImplementation 'org.easymock:easymock:3.5.1'
testImplementation 'org.powermock:powermock-module-junit4:1.7.1'
testImplementation 'org.powermock:powermock-api-easymock:1.7.1'
testImplementation 'org.powermock:powermock-api-mockito2:1.7.4'
testImplementation 'junit:junit:4.12'
}
if (OperatingSystem.current().isMacOsX()) {
dependencies {
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation 'com.fr.third:jxbrowser-mac-v7:7.22'
implementation "com.fr.third:jxbrowser-mac-v7:${jxBrowserVersion}"
}
} else if (OperatingSystem.current().isWindows()) {
dependencies {
implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation 'com.fr.third:jxbrowser-win64-v7:7.22'
implementation "com.fr.third:jxbrowser-win64-v7:${jxBrowserVersion}"
}
}
}

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

@ -1021,6 +1021,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
designerLoginConfigManager.setUseOldVersionLogin(useOldVersionLogin);
}
public boolean isUseNewPluginFirst() {
return designerLoginConfigManager.isUseNewPluginFirst();
}
public void setUseNewPluginFirst(boolean useNewPluginFirst) {
designerLoginConfigManager.setUseNewPluginFirst(useNewPluginFirst);
}
/**
* 内置服务器是否使用时启动
*

17
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -811,8 +811,7 @@ public class PreferencePane extends BasicPane {
this.portEditor.setValue(new Integer(designerEnvManager.getEmbedServerPort()));
if (useOptimizedUPMCheckbox != null) {
useOptimizedUPMCheckbox.setSelected(ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter());
useOptimizedUPMCheckbox.setSelected(checkOptimizedUPMUse());
}
if (useNewVersionLoginCheckbox != null) {
@ -856,6 +855,15 @@ public class PreferencePane extends BasicPane {
this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled());
}
private boolean checkOptimizedUPMUse() {
//如果是没手动配置过则默认开启
//isUseNewPluginFirst如果为true说明没手动配置过,直接开启
//走到这里说明checkBox不为空,机型肯定符合
return DesignerEnvManager.getEnvManager().isUseNewPluginFirst()
|| ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter();
}
private int chooseCase(int sign) {
switch (sign) {
case 0:
@ -913,7 +921,10 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setJoinProductImprove(this.joinProductImproveCheckBox.isSelected());
designerEnvManager.setEmbedServerLazyStartup(this.embedServerLazyStartupCheckBox.isSelected());
designerEnvManager.setImageCompress(this.imageCompressPanelCheckBox.isSelected());
designerEnvManager.setUseOptimizedUPM4Adapter(this.useOptimizedUPMCheckbox != null && this.useOptimizedUPMCheckbox.isSelected());
boolean optimizedUPMFlag = this.useOptimizedUPMCheckbox != null && this.useOptimizedUPMCheckbox.isSelected();
designerEnvManager.setUseOptimizedUPM4Adapter(optimizedUPMFlag);
//只有取消掉使用新插件管理器这个选项才需要把useNewPluginFirst置false(意味着用户手动配置了,如果勾选着的话,这个useNewPluginFirst为true就行了)
designerEnvManager.setUseNewPluginFirst(optimizedUPMFlag);
designerEnvManager.setCloudAnalyticsDelay(this.cloudAnalyticsDelayCheckBox.isSelected());
VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager();
vcsConfigManager.setSaveInterval(this.saveIntervalEditor.getValue());

20
designer-base/src/main/java/com/fr/design/actions/help/FineUIAction.java

@ -3,14 +3,15 @@ package com.fr.design.actions.help;
import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.ui.ModernUIPane;
import com.fr.locale.InterProviderFactory;
import com.fr.web.struct.AssembleComponent;
import com.fr.web.struct.Atom;
import com.fr.web.struct.browser.RequestClient;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.impl.FineUI;
import com.teamdev.jxbrowser.js.JsAccessible;
import java.awt.event.ActionEvent;
@ -27,14 +28,8 @@ public class FineUIAction extends UpdateAction {
@Override
public void actionPerformed(final ActionEvent e) {
ModernUIPane<?> pane = new ModernUIPane.Builder<>()
// .prepare(new ScriptContextAdapter() {
// @Override
// public void onScriptContextCreated(ScriptContextEvent event) {
// JSValue pool = event.getBrowser().executeJavaScriptAndReturnValue("window.Pool");
// pool.asObject().setProperty("i18n", new I18n());
// }
// })
JxUIPane<?> pane = new JxUIPane.Builder<>()
.bindNamespace("i18n", new I18n())
.withComponent(new AssembleComponent() {
@Override
@ -44,20 +39,21 @@ public class FineUIAction extends UpdateAction {
@Override
public Atom[] refer() {
return new Atom[] {FineUI.KEY};
return new Atom[]{FineUI.KEY};
}
})
.build();
BasicDialog dialog = pane.showLargeWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
BasicDialog dialog = pane.showLargeWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
// Do nothing
}
});
dialog.setVisible(true);
dialog.setVisible(true);
}
@JsAccessible
public static class I18n {
public String i18nText(String key) {

3
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java

@ -59,7 +59,8 @@ public class ProcedureDataPane extends AbstractTableDataPane<StoreProcedure> imp
"com.microsoft.sqlserver.jdbc.SQLServerDriver",
"com.ibm.db2.jcc.DB2Driver",
"com.mysql.jdbc.Driver",
"org.gjt.mm.mysql.Driver"
"org.gjt.mm.mysql.Driver",
"dm.jdbc.driver.DmDriver"
}; // 需要隐藏面板的数据库的驱动
private static final String PREVIEW_BUTTON = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview");
private ConnectionTableProcedurePane connectionTableProcedurePane;

19
designer-base/src/main/java/com/fr/design/dcm/UniversalDatabasePane.java

@ -1,12 +1,9 @@
package com.fr.design.dcm;
import com.fr.design.dialog.BasicPane;
import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import com.fr.design.jxbrowser.JxUIPane;
import java.awt.*;
import java.awt.BorderLayout;
/**
* @author richie
@ -15,8 +12,6 @@ import java.awt.*;
*/
public class UniversalDatabasePane extends BasicPane {
private ModernUIPane<Object> modernUIPane;
@Override
protected String title4PopupWindow() {
return "Database";
@ -24,15 +19,9 @@ public class UniversalDatabasePane extends BasicPane {
public UniversalDatabasePane() {
setLayout(new BorderLayout());
modernUIPane = new ModernUIPane.Builder<>()
JxUIPane<Object> modernUIPane = new JxUIPane.Builder<>()
.withComponent(UniversalDatabaseComponent.KEY)
.prepare(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window");
window.asObject().setProperty("DcmHelper", UniversalDcmBridge.getBridge(event.getBrowser()));
}
})
.bindWindow("DcmHelper", UniversalDcmBridge::getBridge)
.build();
add(modernUIPane, BorderLayout.CENTER);
}

22
designer-base/src/main/java/com/fr/design/dcm/UniversalDcmBridge.java

@ -2,8 +2,8 @@ package com.fr.design.dcm;
import com.fr.decision.webservice.bean.BaseBean;
import com.fr.design.bridge.exec.JSBridge;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.js.JsAccessible;
import com.teamdev.jxbrowser.js.JsObject;
/**
* @author richie
@ -11,20 +11,28 @@ import com.teamdev.jxbrowser.chromium.JSObject;
* Created by richie on 2019-05-17
* 桥接Java和JavaScript的类
*/
@JsAccessible
public class UniversalDcmBridge {
public static UniversalDcmBridge getBridge(Browser browser) {
return new UniversalDcmBridge(browser);
/**
* 获取 js-java bridge
*
* @param window 全局环境
* @return bridge
*/
public static UniversalDcmBridge getBridge(JsObject window) {
return new UniversalDcmBridge(window);
}
private JSObject window;
private JsObject window;
private UniversalDcmBridge(Browser browser) {
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
private UniversalDcmBridge(JsObject window) {
this.window = window;
}
/**
* 获取所有的数据连接
*
* @return 数据连接集合
*/
@JSBridge

184
designer-base/src/main/java/com/fr/design/extra/PluginBatchModifyDetailPane.java

@ -0,0 +1,184 @@
package com.fr.design.extra;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* 插件批量处理弹窗面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/5/19
*/
public class PluginBatchModifyDetailPane {
private UILabel message = new UILabel();
private UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK"));
private UILabel uiLabel = new UILabel();
private UILabel directUiLabel = new UILabel();
private UILabel detailLabel = new UILabel();
private JPanel upPane;
private JPanel midPane;
private JPanel downPane;
private JPanel hiddenPanel;
private JTextArea jta;
private JDialog dialog;
/**
* 弹窗面板默认大小
*/
public static final Dimension DEFAULT = new Dimension(380, 150);
/**
* 弹窗面板展开大小
*/
public static final Dimension DEFAULT_PRO = new Dimension(380, 270);
public PluginBatchModifyDetailPane(Dialog parent) {
init(parent);
}
private void init(Dialog parent) {
message.setBorder(BorderFactory.createEmptyBorder(8, 5, 0, 0));
dialog = new JDialog(parent, Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager"), true);
dialog.setSize(DEFAULT);
JPanel jp = new JPanel();
initUpPane();
initDownPane();
initMidPane();
initHiddenPanel();
initListener();
jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS));
jp.add(upPane);
jp.add(midPane);
jp.add(hiddenPanel);
jp.add(downPane);
hiddenPanel.setVisible(false);
dialog.add(jp);
dialog.setResizable(false);
dialog.setLocationRelativeTo(SwingUtilities.getWindowAncestor(parent));
}
private void initDownPane() {
downPane = new JPanel();
downPane.setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 9));
downPane.add(cancelButton);
}
private void initUpPane() {
upPane = new JPanel();
uiLabel = new UILabel(UIManager.getIcon("OptionPane.errorIcon"));
upPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
upPane.add(uiLabel);
upPane.add(message);
}
private void initMidPane() {
midPane = new JPanel();
midPane.add(directUiLabel);
midPane.add(detailLabel);
midPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
detailLabel.setForeground(Color.BLUE);
detailLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
}
private void initHiddenPanel() {
hiddenPanel = new JPanel();
hiddenPanel.setLayout(new BorderLayout(2, 0));
hiddenPanel.add(new JPanel(), BorderLayout.WEST);
hiddenPanel.add(new JPanel(), BorderLayout.EAST);
JPanel borderPanel = new JPanel();
borderPanel.setLayout(new BorderLayout());
jta = new JTextArea();
JScrollPane jsp = new JScrollPane(jta);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jta.setEditable(false);
borderPanel.add(jsp, BorderLayout.CENTER);
hiddenPanel.add(borderPanel);
}
/**
* 补充更详细的报错信息
*
* @param message 信息
*/
public void updateDetailArea(String message) {
jta.append(message + "\n");
}
private void initListener() {
detailLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (hiddenPanel.isVisible()) {
hiddenPanel.setVisible(false);
dialog.setSize(DEFAULT);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
} else {
dialog.setSize(DEFAULT_PRO);
hiddenPanel.setVisible(true);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail"));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down"));
}
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hiddenPanel.removeAll();
dialog.dispose();
}
});
}
/**
* 更新标题
* @param title 标题
*/
public void updateTitle(String title) {
dialog.setTitle(title);
}
/**
* 更新展示信息
*
* @param failedCount 处理失败个数
* @param successCount 处理成功个数
*/
public void updateMessage(int failedCount, int successCount) {
message.setText(Toolkit.i18nText("Fine-Design_Basic_Plugin_Batch_Modify_Info", failedCount, successCount));
}
/**
* 显示面板
*/
public void show() {
dialog.setVisible(true);
}
}

106
designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java

@ -3,6 +3,8 @@ package com.fr.design.extra;
import com.fr.design.DesignerEnvManager;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.exe.callback.BatchModifyStatusCallback;
import com.fr.design.extra.exe.callback.BatchUpdateOnlineCallback;
import com.fr.design.extra.exe.callback.InstallFromDiskCallback;
import com.fr.design.extra.exe.callback.InstallOnlineCallback;
import com.fr.design.extra.exe.callback.ModifyStatusCallback;
@ -28,11 +30,13 @@ import com.fr.plugin.view.PluginView;
import com.fr.plugin.xml.PluginElementName;
import com.fr.plugin.xml.PluginXmlElement;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.JSArray;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.io.File;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;
@ -65,12 +69,14 @@ public class PluginOperateUtils {
public static void updatePluginOnline(List<PluginMarker> pluginMarkerList, JSCallback jsCallback) {
for (int i = 0; i < pluginMarkerList.size(); i++) {
updatePluginOnline(pluginMarkerList.get(i), jsCallback);
int size = pluginMarkerList.size();
BatchUpdateOnlineCallback batchUpdateOnlineCallback = size <= 1 ? BatchUpdateOnlineCallback.NONE : new BatchUpdateOnlineCallback(jsCallback, size);
for (int i = 0; i < size; i++) {
updatePluginOnline(pluginMarkerList.get(i), jsCallback, batchUpdateOnlineCallback);
}
}
public static void updatePluginOnline(PluginMarker pluginMarker, JSCallback jsCallback) {
private static void updatePluginOnline(PluginMarker pluginMarker, JSCallback jsCallback, BatchUpdateOnlineCallback batchUpdateOnlineCallback) {
try {
JSONObject latestPluginInfo = PluginUtils.getLatestPluginInfo(pluginMarker.getPluginID());
String latestPluginVersion = latestPluginInfo.getString("version");
@ -79,11 +85,25 @@ public class PluginOperateUtils {
//当前已经安装的相同ID插件marker
PluginMarker currentMarker = PluginMarkerAdapter.create(PluginUtils.getInstalledPluginMarkerByID(pluginMarker.getPluginID()), pluginName);
PluginTask pluginTask = PluginTask.updateTask(currentMarker, toPluginMarker);
PluginControllerHelper.updateOnline(currentMarker, toPluginMarker, new UpdateOnlineCallback(pluginTask, jsCallback), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
if (!batchUpdateOnlineCallback.equals(BatchUpdateOnlineCallback.NONE)) {
batchUpdateOnlineCallback.createInnerPreTaskCallback(pluginTask, jsCallback);
PluginControllerHelper.updateOnline(currentMarker, toPluginMarker, batchUpdateOnlineCallback.getInnerPreTaskCallback(), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
} else {
PluginControllerHelper.updateOnline(currentMarker, toPluginMarker, new UpdateOnlineCallback(pluginTask, jsCallback), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 更新插件
*
* @param pluginMarker 插件marker
* @param jsCallback 回调
*/
public static void updatePluginOnline(PluginMarker pluginMarker, JSCallback jsCallback) {
updatePluginOnline(pluginMarker, jsCallback, BatchUpdateOnlineCallback.NONE);
}
@ -92,6 +112,40 @@ public class PluginOperateUtils {
}
private static void dealWithPluginActive(PluginMarker pluginMarker, BatchModifyStatusCallback modifyStatusCallback) {
PluginContext plugin = PluginManager.getContext(pluginMarker);
boolean running = plugin.isRunning();
modifyStatusCallback.updateActiveStatus(running);
changePluginActive(running, pluginMarker, modifyStatusCallback, plugin);
}
private static void changePluginActive(boolean isRunning, PluginMarker pluginMarker, PluginTaskCallback modifyStatusCallback, PluginContext plugin) {
if (isRunning) {
PluginXmlElement forbidReminder = plugin.getXml().getElement(PluginElementName.ForbidReminder);
if (forbidReminder != null && forbidReminder.getContent() != null) {
// 禁用前提示
int rv = FineJOptionPane.showConfirmDialog(
null,
forbidReminder.getContent(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
PluginManager.getController().forbidPersistently(pluginMarker, modifyStatusCallback);
}
} else {
// 正常禁用
PluginManager.getController().forbidPersistently(pluginMarker, modifyStatusCallback);
}
} else {
PluginManager.getController().enablePersistently(pluginMarker, modifyStatusCallback);
}
}
public static void setPluginActive(String pluginInfo, JSCallback jsCallback) {
SwingUtilities.invokeLater(new Runnable() {
@ -101,26 +155,27 @@ public class PluginOperateUtils {
PluginContext plugin = PluginManager.getContext(pluginMarker);
boolean isRunning = plugin.isRunning();
PluginTaskCallback modifyStatusCallback = new ModifyStatusCallback(isRunning, jsCallback);
if (isRunning) {
PluginXmlElement forbidReminder = plugin.getXml().getElement(PluginElementName.ForbidReminder);
if (forbidReminder != null && forbidReminder.getContent() != null) {
// 禁用前提示
int rv = FineJOptionPane.showConfirmDialog(
null,
forbidReminder.getContent(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
PluginManager.getController().forbidPersistently(pluginMarker, modifyStatusCallback);
}
} else {
// 正常禁用
PluginManager.getController().forbidPersistently(pluginMarker, modifyStatusCallback);
}
} else {
PluginManager.getController().enablePersistently(pluginMarker, modifyStatusCallback);
changePluginActive(isRunning, pluginMarker, modifyStatusCallback, plugin);
}
});
}
/**
* 批量启用或禁用插件
*
* @param pluginIDs 要处理的插件信息
* @param jsCallback 回调函数
*/
public static void setPluginActive(List<String> pluginIDs, JSCallback jsCallback) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int len = pluginIDs.size();
BatchModifyStatusCallback modifyStatusCallback = new BatchModifyStatusCallback(jsCallback, len);
for (String pluginInfo : pluginIDs) {
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
dealWithPluginActive(pluginMarker, modifyStatusCallback);
}
}
});
@ -255,8 +310,7 @@ public class PluginOperateUtils {
private static String getPluginName(PluginContext pluginContext, PluginMarker pluginMarker) {
if (pluginContext != null) {
return pluginContext.getName();
}
else if (pluginMarker instanceof PluginMarkerAdapter) {
} else if (pluginMarker instanceof PluginMarkerAdapter) {
return ((PluginMarkerAdapter) pluginMarker).getPluginName();
}
return pluginMarker == null ? StringUtils.EMPTY : pluginMarker.getPluginID();

127
designer-base/src/main/java/com/fr/design/extra/exe/callback/AbstractBatchModifyStatusCallback.java

@ -0,0 +1,127 @@
package com.fr.design.extra.exe.callback;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.PluginBatchModifyDetailPane;
import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.i18n.Toolkit;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.manage.control.PluginTask;
import com.fr.plugin.manage.control.PluginTaskResult;
import com.fr.plugin.manage.control.ProgressCallback;
import com.fr.stable.StringUtils;
import javax.swing.JOptionPane;
import java.util.HashMap;
import java.util.Map;
/**
* 带进度条的批量处理的callback
* <li> content与title是处理完成后弹出的面板的内容与标题子类需要在done之前设定好对应的信息
* <li> 进度条是以 当前完成任务数/总任务数 来计算的
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/6/6
*/
public abstract class AbstractBatchModifyStatusCallback implements ProgressCallback {
protected JSCallback jsCallback;
protected Map<String, String> resultMap = new HashMap<>();
protected String content = StringUtils.EMPTY;
protected String title = StringUtils.EMPTY;
public int pluginCount = 0;
public int allPluginCount = 0;
public int successCount = 0;
public int failedCount = 0;
public static final int HUNDRED_PERCENT = 100;
public static final String PERCENT = "%";
public static final String DEFAULT = "default";
public AbstractBatchModifyStatusCallback() {
}
public AbstractBatchModifyStatusCallback(JSCallback jsCallback, int size) {
this.jsCallback = jsCallback;
this.allPluginCount = size;
}
@Override
public void done(PluginTaskResult result) {
String pluginInfo = PluginOperateUtils.getSuccessInfo(result);
if (result.isSuccess()) {
successCount++;
String modifyMessage = updateMessage(pluginInfo);
FineLoggerFactory.getLogger().info(modifyMessage);
} else {
failedCount++;
resultMap.put(getPluginName(result), pluginInfo);
}
updateProgressAndCheckCompletion();
}
/**
* 获取插件名
*
* @param result 任务结果
* @return 插件名
*/
public String getPluginName(PluginTaskResult result) {
PluginTask pluginTask = result.getCurrentTask();
if (pluginTask != null) {
PluginMarker pluginMarker = pluginTask.getToMarker();
if (pluginMarker != null) {
return pluginMarker.getPluginID();
}
}
return DEFAULT;
}
/**
* 更新当前Map状态,进度条,如果全部都更新完了就回调
*/
public void updateProgressAndCheckCompletion() {
pluginCount++;
updateProgress(StringUtils.EMPTY, (double) pluginCount / allPluginCount);
if (pluginCount == allPluginCount) {
jsCallback.execute("success");
showMessageDialog();
}
}
/**
* 展示信息面板
*/
public void showMessageDialog() {
if (failedCount == 0) {
FineJOptionPane.showMessageDialog(DesignerPluginContext.getPluginDialog(),
content,
title,
JOptionPane.INFORMATION_MESSAGE);
} else {
PluginBatchModifyDetailPane detailPane = new PluginBatchModifyDetailPane(DesignerPluginContext.getPluginDialog());
for (String key : resultMap.keySet()) {
detailPane.updateDetailArea(resultMap.get(key));
}
detailPane.updateMessage(failedCount, successCount);
detailPane.updateTitle(title);
detailPane.show();
}
}
@Override
public void updateProgress(String description, double progress) {
jsCallback.execute(progress * HUNDRED_PERCENT + PERCENT);
}
/**
* 更新处理成功返回的日志信息
*
* @return 返回的日志信息
*/
abstract public String updateMessage(String pluginInfo);
}

43
designer-base/src/main/java/com/fr/design/extra/exe/callback/BatchModifyStatusCallback.java

@ -0,0 +1,43 @@
package com.fr.design.extra.exe.callback;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.i18n.Toolkit;
/**
* 批量启用/禁用插件的Callback
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/5/18
*/
public class BatchModifyStatusCallback extends AbstractBatchModifyStatusCallback {
private boolean active;
private boolean operatorFlag = false;
public BatchModifyStatusCallback(JSCallback jsCallback, int size) {
super(jsCallback, size);
}
@Override
public String updateMessage(String pluginInfo) {
return active ? pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Been_Disabled_Duplicate") : pluginInfo + Toolkit.i18nText("Fine-Design_Plugin_Has_Been_Actived_Duplicate");
}
/**
* 更新启用/禁用信息
*
* @param active
*/
public void updateActiveStatus(boolean active) {
if (!operatorFlag) {
this.active = active;
this.operatorFlag = true;
this.title = active ? Toolkit.i18nText("Fine-Design_Basic_Plugin_Stop") : Toolkit.i18nText("Fine-Design_Basic_Plugin_Start");
this.content = active ? Toolkit.i18nText("Fine-Design_Basic_Plugin_Batch_Modify_Stop_Success") : Toolkit.i18nText("Fine-Design_Basic_Plugin_Batch_Modify_Start_Success");
}
}
}

77
designer-base/src/main/java/com/fr/design/extra/exe/callback/BatchUpdateOnlineCallback.java

@ -0,0 +1,77 @@
package com.fr.design.extra.exe.callback;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.manage.control.PluginTask;
import com.fr.plugin.manage.control.PluginTaskResult;
/**
* 批量更新的callback
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/6/6
*/
public class BatchUpdateOnlineCallback extends AbstractBatchModifyStatusCallback{
public static final BatchUpdateOnlineCallback NONE = new BatchUpdateOnlineCallback();
/**
* 可自动处理前置任务的callback用来处理实际更新逻辑
*/
private InnerUpdateCallback innerPreTaskCallback;
public BatchUpdateOnlineCallback() {
}
public BatchUpdateOnlineCallback(JSCallback jsCallback, int size) {
super(jsCallback, size);
this.title = Toolkit.i18nText("Fine-Design_Basic_Plugin_Update");
this.content = Toolkit.i18nText("Fine-Design_Basic_Plugin_Update_Success");
}
/**
* 更新任务
*
* @param pluginTask 任务
* @param jsCallback callback
*/
public void createInnerPreTaskCallback(PluginTask pluginTask, JSCallback jsCallback) {
innerPreTaskCallback = new InnerUpdateCallback(pluginTask, jsCallback);
}
public InnerUpdateCallback getInnerPreTaskCallback() {
return innerPreTaskCallback;
}
@Override
public String updateMessage(String pluginInfo) {
return pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Update_Success");
}
/**
* 可自动处理前置任务的callback用来处理实际更新逻辑
*/
public class InnerUpdateCallback extends UpdateOnlineCallback {
public InnerUpdateCallback(PluginTask pluginTask, JSCallback jsCallback) {
super(pluginTask, jsCallback);
}
@Override
public void updateProgress(String description, double aProgress) {
//不进行处理
}
@Override
public void allDone(PluginTaskResult result) {
BatchUpdateOnlineCallback.this.done(result);
}
}
}

14
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java

@ -1108,18 +1108,8 @@ public class MultiTemplateTabPane extends JComponent {
* @return
*/
public int calNextShowJTemplateIndex(int currentIndex) {
//先看是否有可以展示的模板
for (int i = currentIndex; i >= 0; i--) {
if (showJTemplateTab(openedTemplate.get(i))) {
return i;
}
}
for (int i = currentIndex; i >= 0; i--) {
if (!showJTemplateTab(openedTemplate.get(i))) {
return i;
}
}
return -1;
JTemplate jTemplate= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return MultiTemplateTabUtils.calShowTemplateIndex(currentIndex, openedTemplate, jTemplate.getTemplateTabOperatorType());
}

59
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabUtils.java

@ -0,0 +1,59 @@
package com.fr.design.file;
import com.fr.design.mainframe.JTemplate;
import com.fr.general.ComparatorUtils;
import java.util.List;
import java.util.function.Predicate;
public class MultiTemplateTabUtils {
/**
* 计算离currentIndex最近的相同模式的模板index值优先左边
*
* @param currentIndex 当前index
* @param openedTemplate 模板list
* @param type 当前显示模式
* @return
*/
public static int calShowTemplateIndex(int currentIndex, List<JTemplate<?, ?>> openedTemplate, String type) {
if (currentIndex < 0 || currentIndex > openedTemplate.size() - 1) {
return -1;
}
int result = getShowJTemplateTab(currentIndex, openedTemplate, template -> showJTemplateTab(type, template));
if (result != -1) return result;
return getShowJTemplateTab(currentIndex, openedTemplate, template -> !showJTemplateTab(type, template));
}
/**
* 先从左找再从右找离得最近的满足条件的模板
*
* @param currentIndex 当前index
* @param openedTemplate 模板list
* @param predicate
* @return
*/
private static int getShowJTemplateTab(int currentIndex, List<JTemplate<?, ?>> openedTemplate, Predicate<JTemplate<?, ?>> predicate) {
for (int i = currentIndex; i >= 0; i--) {
if (predicate.test(openedTemplate.get(i))) {
return i;
}
}
for (int i = currentIndex + 1; i < openedTemplate.size(); i++) {
if (predicate.test(openedTemplate.get(i))) {
return i;
}
}
return -1;
}
/**
* 是否显示模板
*
* @param type 模板类型
* @param jTemplate 模板
* @return
*/
private static boolean showJTemplateTab(String type, JTemplate<?, ?> jTemplate) {
return ComparatorUtils.equals(type, jTemplate.getTemplateTabOperatorType());
}
}

2
designer-base/src/main/java/com/fr/design/fun/DefaultValueAdjustProvider.java

@ -14,7 +14,7 @@ import java.awt.Font;
*/
public interface DefaultValueAdjustProvider extends Selectable {
String MARK_STRING = "DefaultValueAdjustProvider";
int CURRENT_LEVEL = 1;
int CURRENT_LEVEL = 2;
/**
* 调整单元格对象默认值

6
designer-base/src/main/java/com/fr/design/fun/impl/AbstractDefaultValueAdjustProvider.java

@ -9,9 +9,13 @@ import com.fr.stable.fun.mark.API;
@API(level = DefaultValueAdjustProvider.CURRENT_LEVEL)
public abstract class AbstractDefaultValueAdjustProvider extends AbstractProvider implements DefaultValueAdjustProvider {
//1.16及之前发布版本插件里面没有实现currentAPILevel方法,运行时候会走到主jar,拿到-2。
//1.16.1及之后发布版本插件实现currentAPILevel方法,编译插件的时候,会把DefaultValueAdjustProvider.CURRENT_LEVEL的值编译给插件,比如1.16.1会拿到2。
private static final int OLD_CURRENT_LEVEL = -2;
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
return OLD_CURRENT_LEVEL;
}
public String mark4Provider() {

40
designer-base/src/main/java/com/fr/design/jxbrowser/BrowserExecutor.java

@ -0,0 +1,40 @@
package com.fr.design.jxbrowser;
import com.fr.design.bridge.exec.JSExecutor;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
/**
* 用于 jxbrowser 执行后的回调执行器
* 适配7.15之后
*
* @author vito
* @since 11.0
* Created on 2023/6/8
*/
public class BrowserExecutor implements JSExecutor {
/**
* 创建一个回调执行器
*
* @param window js环境的window对象
* @param callback 回调
* @return 执行器
*/
public static BrowserExecutor create(JsObject window, JsFunction callback) {
return new BrowserExecutor(window, callback);
}
private final JsObject window;
private final JsFunction callback;
private BrowserExecutor(JsObject window, JsFunction callback) {
this.window = window;
this.callback = callback;
}
@Override
public void executor(String newValue) {
callback.invoke(window, newValue);
}
}

140
designer-base/src/main/java/com/fr/design/jxbrowser/JxEngine.java

@ -0,0 +1,140 @@
package com.fr.design.jxbrowser;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ui.ModernUIConstants;
import com.fr.log.FineLoggerFactory;
import com.fr.value.ClearableLazyValue;
import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.engine.event.EngineCrashed;
import com.teamdev.jxbrowser.net.Network;
import com.teamdev.jxbrowser.net.Scheme;
import com.teamdev.jxbrowser.net.callback.VerifyCertificateCallback;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.Map;
/**
* 可重复启动的 Jxbrowser 引擎
* 手动创建的引擎应当自己负责管理声明周期 {@link #newInstance()}
* 单例的引擎由系统管理生命周期使用后仅需清理browser和map等数据
* {@link #getEngine()} {@link #getPublicEngineInstance()}
*
* @author vito
* @since 11.0
* Created on 2023/6/8
*/
public class JxEngine {
private static final JxEngine INSTANCE = new JxEngine();
private AssembleComponent component;
private Map<String, String> parameterMap = Collections.emptyMap();
private final ClearableLazyValue<Engine> ENGINE = ClearableLazyValue.create(() -> {
EngineOptions.Builder builder = EngineOptions
.newBuilder(RenderingMode.HARDWARE_ACCELERATED)
.addSwitch("--disable-google-traffic")
.addScheme(Scheme.of(ModernUIConstants.EMB_TAG),
new NxInterceptRequestCallback(this::getComponent, this::getParameterMap));
Engine engine = Engine.newInstance(builder.build());
engine.on(EngineCrashed.class, (event) -> {
FineLoggerFactory.getLogger().error("jxBrowser engine crashed with exitCode: {}", event.exitCode());
event.engine().close();
});
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
// 调试模式下,禁止HTTPS证书验证,使得可以正常访问商城测试服务器等
Network network = engine.network();
network.set(VerifyCertificateCallback.class, params -> VerifyCertificateCallback.Response.valid());
}
return engine;
});
public Map<String, String> getParameterMap() {
return Collections.unmodifiableMap(parameterMap);
}
public void setMap(Map<String, String> parameterMap) {
if (parameterMap == null) {
return;
}
this.parameterMap = parameterMap;
}
/**
* 清理map
*/
public void clearMap() {
this.parameterMap = Collections.emptyMap();
}
public AssembleComponent getComponent() {
return component;
}
public void setComponent(AssembleComponent component) {
this.component = component;
}
/**
* 清理component
*/
public void clearComponent() {
this.component = null;
}
/**
* 获取单例引擎包装能够更新渲染
* 从单例获取的引擎不用负责关闭
* 应用系统管理声明周期
*
* @return jxbrowser 引擎包装类
*/
public static JxEngine getInstance() {
return INSTANCE;
}
/**
* 获取公共引擎公共引擎使用后不用关闭引擎但需要自己管理 browser
* 应用系统管理引擎生命周期
*
* @return 引擎
*/
@NotNull
public Engine getEngine() {
return ENGINE.getValue();
}
/**
* 关闭引擎
*/
public void close() {
ENGINE.getValue().close();
ENGINE.drop();
}
/**
* 获取公共引擎公共引擎使用后不用关闭引擎但需要自己管理 browser
* 应用系统管理引擎生命周期
*
* @return 引擎
*/
public static Engine getPublicEngineInstance() {
return getInstance().ENGINE.getValue();
}
/**
* 创建一个新的引擎创建引擎使用后需负责关闭引擎
* 但可以独立使用 map component
*
* @return 引擎
*/
public static JxEngine newInstance() {
return new JxEngine();
}
}

555
designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java

@ -0,0 +1,555 @@
package com.fr.design.jxbrowser;
import com.fr.design.DesignerEnvManager;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIConstants;
import com.fr.design.ui.ModernUIPane;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
import com.fr.stable.os.OperatingSystem;
import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener;
import com.teamdev.jxbrowser.event.Observer;
import com.teamdev.jxbrowser.frame.Frame;
import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.view.swing.BrowserView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import static com.fr.design.ui.ModernUIConstants.COMPONENT_TAG;
import static com.fr.design.ui.ModernUIConstants.DEFAULT_EXPRESSION;
import static com.fr.design.ui.ModernUIConstants.DEFAULT_NAMESPACE;
import static com.fr.design.ui.ModernUIConstants.DEFAULT_VARIABLE;
import static com.fr.design.ui.ModernUIConstants.DOT;
import static com.fr.design.ui.ModernUIConstants.EMB_TAG;
import static com.fr.design.ui.ModernUIConstants.SCHEME_HEADER;
import static com.fr.design.ui.ModernUIConstants.WINDOW;
/**
* 基于v7 jxbrowser 实现
* 用于加载 html5 的Swing容器可以在设计选项设置中打开调试窗口
* 示例可查看com.fr.design.ui.JxUIPaneTest
*
* @author vito
* @since 11.0
* Created on 2023-06-12
*/
public class JxUIPane<T> extends ModernUIPane<T> {
/**
* 冒号
*/
public static final String COLON = ":";
private static final String COLON_ESCAPE = "\\:";
private Browser browser;
private String namespace = "Pool";
private String variable = "data";
private String expression = "update()";
private JxUIPane() {
super();
}
private void initialize() {
setLayout(new BorderLayout());
if (browser != null) {
return;
}
initDebugIfNeeded();
// 使用公共引擎创建浏览器
browser = JxEngine.getPublicEngineInstance().newBrowser();
add(BrowserView.newInstance(browser), BorderLayout.CENTER);
}
/**
* 按需初始化debug界面UI
*/
private void initDebugIfNeeded() {
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
UIToolbar toolbar = new UIToolbar();
add(toolbar, BorderLayout.NORTH);
UIButton openDebugButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Open_Debug_Window"));
openDebugButton.addActionListener(e -> browser.devTools().show());
toolbar.add(openDebugButton);
UIButton reloadButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Reload"));
reloadButton.addActionListener(e -> browser.navigation().reloadIgnoringCache());
toolbar.add(reloadButton);
UIButton closeButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Close_Window"));
closeButton.addActionListener(e -> SwingUtilities.getWindowAncestor(JxUIPane.this).setVisible(false));
toolbar.add(closeButton);
}
}
/**
* 在初始化时进行注入JS的方法只被build调用
*
* @param injectJsCallback 回调
*/
private void initInjectJs(InjectJsCallback injectJsCallback) {
browser.set(InjectJsCallback.class, params -> {
// 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的
params.frame().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace));
return injectJsCallback.on(params);
});
}
/**
* 设置 InjectJsCallback
* 这个方法解决重复InjectJsCallback被覆盖的问题
* 用于本类内部方法使用{@link #populate(Object)}
*
* @param injectJsCallback 回调
*/
private void setInjectJsCallback(InjectJsCallback injectJsCallback) {
Optional<InjectJsCallback> callback = browser.get(InjectJsCallback.class);
if (callback.isPresent()) {
browser.set(InjectJsCallback.class, params -> {
callback.get().on(params);
return injectJsCallback.on(params);
});
} else {
browser.set(InjectJsCallback.class, injectJsCallback);
}
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
*/
@Override
public void redirect(String url) {
browser.navigation().loadUrl(encodeWindowsPath(url));
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
* @param map 初始化参数
*/
@Override
public void redirect(String url, Map<String, String> map) {
setMap(map);
browser.navigation().loadUrl(encodeWindowsPath(url));
}
private void setMap(Map<String, String> map) {
JxEngine.getInstance().setMap(map);
}
private void setComponent(AssembleComponent component) {
JxEngine.getInstance().setComponent(component);
}
@Override
protected String title4PopupWindow() {
return "ModernUI7";
}
@Override
public void populate(final T t) {
setInjectJsCallback(params -> {
executeJsObject(params.frame(), WINDOW + DOT + namespace)
.ifPresent(ns -> ns.putProperty(variable, t));
return InjectJsCallback.Response.proceed();
});
}
@Override
@Nullable
public T update() {
if (browser.mainFrame().isPresent()) {
return browser.mainFrame().get().executeJavaScript("window." + namespace + "." + expression);
}
return null;
}
/**
* 关闭浏览器
*/
public void disposeBrowser() {
if (browser != null) {
browser.close();
browser = null;
JxEngine.getInstance().clearMap();
JxEngine.getInstance().clearComponent();
}
}
/**
* 清理浏览器缓存
*/
public void clearCache() {
if (browser != null) {
browser.engine().httpCache().clear();
}
}
/**
* 执行一段js
*
* @param javaScript 待执行的js脚本
*/
public void executeJavaScript(String javaScript) {
if (browser != null) {
browser.mainFrame().ifPresent(frame -> {
frame.executeJavaScript(javaScript);
});
}
}
/**
* 获取js对象
* 注意类内部使用用于简化编码提供 Optional 包装
*
* @param frame 页面frame对象
* @param name 变量命名
* @return js对象
*/
private static Optional<JsObject> executeJsObject(Frame frame, String name) {
return Optional.ofNullable(frame.executeJavaScript(name));
}
/**
* 由于自定义scheme目前走的是url因此路径会被自动转化比如windows路径下对冒号问题
* C:\\abc 变成 /C/abc这里对冒号进行编码转义
*/
private static String encodeWindowsPath(String path) {
if (OperatingSystem.isWindows() && path.startsWith(EMB_TAG + SCHEME_HEADER)) {
String s = path.split(EMB_TAG + SCHEME_HEADER)[1];
return EMB_TAG + SCHEME_HEADER + s.replace(COLON, COLON_ESCAPE);
}
return path;
}
/**
* JxUIPane 的建造者
*
* @param <T> 参数
*/
public static class Builder<T> extends ModernUIPane.Builder<T> {
private String namespace;
private String variable;
private String expression;
private InjectJsCallback callback;
private Pair<Class, Observer> listenerPair;
private final Map<String, Object> namespacePropertyMap;
private final Map<String, Object> propertyMap;
private final Map<String, PropertyBuild> buildPropertyMap;
private Object variableProperty;
private Map<String, String> parameterMap;
private AssembleComponent component;
private String url;
private String html;
public Builder() {
this.namespace = DEFAULT_NAMESPACE;
this.variable = DEFAULT_VARIABLE;
this.expression = DEFAULT_EXPRESSION;
this.callback = null;
this.listenerPair = null;
this.namespacePropertyMap = new HashMap<>();
this.propertyMap = new HashMap<>();
this.buildPropertyMap = new HashMap<>();
this.variableProperty = null;
this.parameterMap = null;
this.component = null;
this.url = StringUtils.EMPTY;
this.html = StringUtils.EMPTY;
}
/**
* 注入一个回调回调的js会在初始化进行执行
*
* @param callback 回调
* @return builder
*/
public Builder<T> prepare(InjectJsCallback callback) {
this.callback = callback;
return this;
}
@Override
public Builder<T> prepareForV6(ScriptContextListener contextListener) {
return this;
}
@Override
public Builder<T> prepareForV6(LoadListener loadListener) {
return this;
}
@Override
public JxUIPane.Builder<T> prepareForV7(InjectJsCallback callback) {
prepare(callback);
return this;
}
@Override
public JxUIPane.Builder<T> prepareForV7(Class event, Observer listener) {
listenerPair = new Pair<>(event, listener);
return this;
}
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
public JxUIPane.Builder<T> withEMB(final String path) {
this.url = EMB_TAG + SCHEME_HEADER + path;
return this;
}
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
public JxUIPane.Builder<T> withEMB(final String path, Map<String, String> map) {
this.parameterMap = map;
this.url = EMB_TAG + SCHEME_HEADER + path;
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
public JxUIPane.Builder<T> withURL(final String url) {
this.url = url;
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
public JxUIPane.Builder<T> withURL(final String url, Map<String, String> map) {
this.parameterMap = map;
this.url = url;
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
public JxUIPane.Builder<T> withComponent(AssembleComponent component) {
return withComponent(component, null);
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
public JxUIPane.Builder<T> withComponent(AssembleComponent component, Map<String, String> map) {
this.parameterMap = map;
this.component = component;
this.url = COMPONENT_TAG;
return this;
}
/**
* 加载html文本内容
*
* @param html 要加载html文本内容
*/
public JxUIPane.Builder<T> withHTML(String html) {
this.html = html;
return this;
}
/**
* 设置该前端页面做数据交换所使用的对象
* 相当于
* const namespace = "Pool";
* 调用
* window[namespace];
* 默认下结构如
* window.Pool
*
* @param namespace 对象名
*/
public JxUIPane.Builder<T> namespace(String namespace) {
this.namespace = namespace;
return this;
}
/**
* java端往js端传数据时使用的变量名字
* 默认值为 data
* 相当于
* const variable = "data";
* 调用
* window[namespace][variable];
* 默认下结构如
* window.Pool.data
*
* @param name 变量的名字
*/
public JxUIPane.Builder<T> variable(String name) {
this.variable = name;
return this;
}
/**
* js端往java端传数据时执行的函数表达式
*
* @param expression 函数表达式
*/
public JxUIPane.Builder<T> expression(String expression) {
this.expression = expression;
return this;
}
/**
* 注入一个java对象到js中绑定在全局变量window的指定变量variable
* variable 可由 {@link #namespace(String)} 设置默认值为 data
* 这个方法仅在在加载的网页上执行 JavaScript 之前注入
* 相当于
* window[namespace][property] = javaObject
* 默认下
* window.Pool[property] = javaObject
*
* @param obj java对象
* @return 链式对象
*/
public JxUIPane.Builder<T> bindNamespace(String property, @Nullable Object obj) {
this.namespacePropertyMap.put(property, obj);
return this;
}
/**
* 注入一个java对象到js中绑定在全局变量window的指定变量variable
* variable 可由 {@link #variable(String)} 设置默认值为 data
* 这个方法仅在在加载的网页上执行 JavaScript 之前注入
* 相当于
* window[namespace][variable] = javaObject
* 默认下
* window.Pool.data = javaObject
*
* @param obj java对象
* @return 链式对象
*/
public JxUIPane.Builder<T> bindVariable(@NotNull Object obj) {
this.variableProperty = obj;
return this;
}
/**
* 注入一个java对象到js中,绑定在全局变量 window的
* property指定的变量这个方法仅在在加载的网页上执
* JavaScript 之前注入
* 相当于
* window[property] = javaObject
*
* @param property 属性
* @param obj java对象
* @return 链式对象
* @see #bindWindow(String, PropertyBuild)
*/
public JxUIPane.Builder<T> bindWindow(String property, @Nullable Object obj) {
this.propertyMap.put(property, obj);
return this;
}
/**
* 注入一个java对象到js中绑定在全局变量 window的property指定的变量
* PropertyBuild用于动态生成绑定属性个方法仅在在加载的网页上执行
* JavaScript 之前注入
* 相当于
* window[property] = javaObject
*
* @param property 属性构建器
* @param obj java对象
* @return 链式对象
* @see #bindWindow(String, Object)
*/
public JxUIPane.Builder<T> bindWindow(String property, PropertyBuild obj) {
buildPropertyMap.put(property, obj);
return this;
}
/**
* 构建
*/
public JxUIPane<T> build() {
JxUIPane<T> pane = new JxUIPane<>();
pane.namespace = namespace;
pane.variable = variable;
pane.expression = expression;
pane.setMap(parameterMap);
pane.setComponent(component);
pane.initialize();
injectJs(pane);
if (!Objects.isNull(listenerPair)) {
pane.browser.navigation().on(listenerPair.getFirst(), listenerPair.getSecond());
}
if (StringUtils.isNotEmpty(this.url)) {
pane.browser.navigation().loadUrl(encodeWindowsPath(this.url));
} else if (StringUtils.isNotEmpty(this.html)) {
pane.browser.mainFrame().ifPresent(f -> f.loadHtml(html));
}
return pane;
}
/**
* 由于 InjectJsCallback 的回调机制在初始化期间只有
* InjectJsCallback putProperty 才能生效
* 因此嵌套回调分别做默认初始化putProperty外置初始化
*/
private void injectJs(JxUIPane<T> pane) {
pane.initInjectJs(params -> {
Frame frame = params.frame();
if (!propertyMap.isEmpty()) {
propertyMap.forEach((key, value) ->
executeJsObject(frame, WINDOW)
.ifPresent(window -> window.putProperty(key, value)));
}
if (!buildPropertyMap.isEmpty()) {
buildPropertyMap.forEach((key, value) ->
executeJsObject(frame, WINDOW)
.ifPresent(window -> window.putProperty(key, value.build(window))));
}
if (!namespacePropertyMap.isEmpty()) {
namespacePropertyMap.forEach((key, value) ->
executeJsObject(frame, WINDOW + DOT + namespace)
.ifPresent(pool -> pool.putProperty(key, value)));
}
if (variableProperty != null) {
executeJsObject(frame, WINDOW + DOT + namespace)
.ifPresent(pool -> pool.putProperty(variable, variableProperty));
}
if (callback != null) {
return callback.on(params);
}
return InjectJsCallback.Response.proceed();
});
}
}
}

113
designer-base/src/main/java/com/fr/design/jxbrowser/MimeType.java

@ -0,0 +1,113 @@
package com.fr.design.jxbrowser;
import com.fr.stable.StringUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Optional;
/**
* jxbrowser 使用的一些媒体类型
*
* @author vito
* @since 11.0
* Created on 2023/6/13
*/
public enum MimeType {
/**
* html 格式
*/
HTML(".html", "text/html"),
/**
* CSS 格式
*/
CSS(".css", "text/css"),
/**
* js 格式
*/
JS(".js", "text/css"),
/**
* svg 格式
*/
SVG(".svg", "text/javascript"),
/**
* png 格式
*/
PNG(".png", "image/png"),
/**
* jpg 格式
*/
JPG(".jpg", "image/jpeg"),
/**
* jpeg 格式
*/
JPEG(".jpeg", "image/jpeg"),
/**
* gif 格式
*/
GIF(".gif", "image/gif"),
/**
* woff 字体格式
*/
WOFF(".woff", "font/woff"),
/**
* ttf 字体格式
*/
TTF(".ttf", "truetype"),
/**
* MS 嵌入式开放字体
*/
EOT(".eot", "embedded-opentype");
private final String suffix;
private final String mimeType;
MimeType(String suffix, String mimeType) {
this.suffix = suffix;
this.mimeType = mimeType;
}
public String getMimeType() {
return mimeType;
}
/**
* 获取指定路径对应的 mimetype优先匹配常量中的类型
* 如果没有尝试使用 Files.probeContentType 检测
* 如果没有默认返回 text/html
*
* @param url url路径
* @return MimeType
*/
public static String parseMimeType(String url) {
if (StringUtils.isBlank(url)) {
return HTML.mimeType;
}
String finalPath = url.split("\\?")[0];
Optional<MimeType> mimeType = Arrays.stream(values())
.filter(type -> finalPath.endsWith(type.suffix))
.findFirst();
if (mimeType.isPresent()) {
return mimeType.get().mimeType;
} else {
return getFileMimeType(finalPath);
}
}
private static String getFileMimeType(String finalPath) {
Path file = new File(finalPath).toPath();
try {
String s = Files.probeContentType(file);
return StringUtils.isEmpty(s) ? HTML.mimeType : s;
} catch (IOException e) {
return HTML.mimeType;
}
}
}

177
designer-base/src/main/java/com/fr/design/jxbrowser/NxInterceptRequestCallback.java

@ -0,0 +1,177 @@
package com.fr.design.jxbrowser;
import com.fr.base.TemplateUtils;
import com.fr.design.ui.ModernRequestClient;
import com.fr.design.ui.ModernUIConstants;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.web.struct.AssembleComponent;
import com.fr.web.struct.AtomBuilder;
import com.fr.web.struct.PathGroup;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.category.StylePath;
import com.teamdev.jxbrowser.net.HttpHeader;
import com.teamdev.jxbrowser.net.HttpStatus;
import com.teamdev.jxbrowser.net.UrlRequest;
import com.teamdev.jxbrowser.net.UrlRequestJob;
import com.teamdev.jxbrowser.net.callback.InterceptUrlRequestCallback;
import org.jetbrains.annotations.NotNull;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import static com.fr.design.ui.ModernUIConstants.COMPONENT_TAG;
/**
* jxbrowser7 自定义 scheme 处理回调
*
* @author vito
* @since 11.0
* Created on 2023/6/8
*/
public class NxInterceptRequestCallback implements InterceptUrlRequestCallback {
private static final String COLON_DECODE_ESCAPE = "/:";
private static final String SCHEME_SPLIT = ":/";
private Supplier<AssembleComponent> component;
private Supplier<Map<String, String>> renderParameterBuild;
public NxInterceptRequestCallback(Supplier<Map<String, String>> renderParameterBuild) {
this.renderParameterBuild = renderParameterBuild;
}
public NxInterceptRequestCallback(Supplier<AssembleComponent> component,
Supplier<Map<String, String>> renderParameterBuild) {
this.component = component;
this.renderParameterBuild = renderParameterBuild;
}
/**
* 主要包括 atom emb协议的文件链接处理
* 去掉file文件协议的支持因此jxbrowser 7之后不支持覆盖内置协议详细见
* {@link com.teamdev.jxbrowser.net.internal.NonInterceptableScheme}
*
* @param params 参数
* @return 响应
*/
@Override
public Response on(Params params) {
UrlRequest urlRequest = params.urlRequest();
String path = urlRequest.url().replace(COLON_DECODE_ESCAPE, JxUIPane.COLON);
Optional<UrlRequestJob> urlRequestJobOptional;
if (path.startsWith(COMPONENT_TAG)) {
String text = htmlText(renderParameterBuild.get());
urlRequestJobOptional = generateBasicUrlRequestJob(params,
"text/html", text.getBytes(StandardCharsets.UTF_8));
} else {
urlRequestJobOptional = generateFileProtocolUrlRequestJob(params, path);
}
return urlRequestJobOptional
.map(Response::intercept)
.orElseGet(Response::proceed);
}
protected Optional<UrlRequestJob> generateFileProtocolUrlRequestJob(Params params, String path) {
try {
InputStream inputStream = getResourceStream(path);
String mimeType = MimeType.parseMimeType(path);
byte[] bytes;
if (isHtml(mimeType)) {
String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8);
text = TemplateUtils.renderParameter4Tpl(text, renderParameterBuild.get());
bytes = text.getBytes(StandardCharsets.UTF_8);
} else {
bytes = IOUtils.inputStream2Bytes(inputStream);
}
return generateBasicUrlRequestJob(params, mimeType, bytes);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return Optional.empty();
}
/**
* 获取资源文件流
*
* @param path 文件路径
* @return 输入流
* @throws Exception IO异常
*/
private InputStream getResourceStream(String path) throws Exception {
int index = path.indexOf("=");
if (index > 0) {
path = path.substring(index + 1);
} else {
// jxbrowser 7之后,协议会自动补齐双斜杠//
int i = path.indexOf(SCHEME_SPLIT);
path = path.substring(i + SCHEME_SPLIT.length());
// 通过自定义协议之后的url会自动encode一些中文字符,这里做一个decode,否则会导致路径访问失败
path = URLDecoder.decode(path, StandardCharsets.UTF_8.name());
}
return IOUtils.readResource(path);
}
private boolean isHtml(String mimeType) {
return MimeType.HTML.getMimeType().equals(mimeType);
}
private Optional<UrlRequestJob> generateBasicUrlRequestJob(Params params, String mimeType, byte[] bytes) {
if (StringUtils.isEmpty(mimeType)) {
return Optional.empty();
}
UrlRequestJob.Options options = UrlRequestJob.Options
.newBuilder(HttpStatus.OK)
.addHttpHeader(HttpHeader.of("Content-Type", mimeType))
.build();
UrlRequestJob urlRequestJob = params.newUrlRequestJob(options);
urlRequestJob.write(bytes);
urlRequestJob.complete();
return Optional.of(urlRequestJob);
}
private String htmlText(Map<String, String> map) {
return component.get() == null ?
StringUtils.EMPTY :
parseComponent(component.get(), map);
}
@NotNull
private static String parseComponent(AssembleComponent component, Map<String, String> map) {
PathGroup pathGroup = AtomBuilder.create().buildAssembleFilePath(ModernRequestClient.KEY, component);
StylePath[] stylePaths = pathGroup.toStylePathGroup();
StringBuilder styleText = new StringBuilder();
for (StylePath path : stylePaths) {
if (StringUtils.isNotBlank(path.toFilePath())) {
styleText.append("<link rel=\"stylesheet\" href=\"emb://");
styleText.append(path.toFilePath());
styleText.append("\"/>");
}
}
String result = ModernUIConstants.HTML_TPL.replaceAll("##style##", styleText.toString());
ScriptPath[] scriptPaths = pathGroup.toScriptPathGroup();
StringBuilder scriptText = new StringBuilder();
for (ScriptPath path : scriptPaths) {
if (StringUtils.isNotBlank(path.toFilePath())) {
scriptText.append("<script src=\"emb://");
scriptText.append(path.toFilePath());
scriptText.append("\"></script>");
}
}
result = result.replaceAll("##script##", scriptText.toString());
if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
result = result.replaceAll("\\$\\{" + key + "}", value);
}
}
return result;
}
}

20
designer-base/src/main/java/com/fr/design/jxbrowser/PropertyBuild.java

@ -0,0 +1,20 @@
package com.fr.design.jxbrowser;
import com.teamdev.jxbrowser.js.JsObject;
/**
* 属性构建器
*
* @author vito
* @since 11.0
* Created on 2023/6/8
*/
public interface PropertyBuild {
/**
* 构建属性
*
* @param window js环境的window对象
* @return 待注入java对象
*/
Object build(JsObject window);
}

60
designer-base/src/main/java/com/fr/design/login/DesignerLoginBridge.java

@ -7,9 +7,9 @@ import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.LocaleLinkProvider;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jxbrowser.BrowserExecutor;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.login.executor.DesignerLoginBrowserExecutor;
import com.fr.design.login.executor.DesignerLoginExecutor;
import com.fr.design.login.executor.DesignerSendCaptchaExecutor;
import com.fr.design.login.executor.DesignerSmsLoginExecutor;
@ -21,25 +21,26 @@ import com.fr.general.CloudCenter;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.log.FineLoggerFactory;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.js.JsAccessible;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.util.Map;
import java.util.Set;
/**
* 设计器登录通行证js-java桥
*
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
@JsAccessible
public class DesignerLoginBridge {
/**
@ -52,20 +53,26 @@ public class DesignerLoginBridge {
*/
private static final String PROPS_LINK_KEY_DEFAULT = "Fine-Design-CloudCenter_Market_Template_Default";
private Map<String, String> params;
private final Map<String, String> params;
public static DesignerLoginBridge getBridge(Browser browser, Map<String, String> params) {
return new DesignerLoginBridge(browser, params);
/**
* 获取 js-java bridge
*
* @param window 全局环境
* @return bridge
*/
public static DesignerLoginBridge getBridge(JsObject window, Map<String, String> params) {
return new DesignerLoginBridge(window, params);
}
private JSObject window;
private final JsObject window;
private DesignerLoginBridge(Browser browser, Map<String, String> params) {
private DesignerLoginBridge(JsObject window, Map<String, String> params) {
this.params = params;
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
this.window = window;
Set<Map.Entry<String, String>> entries = params.entrySet();
for (Map.Entry<String, String> entry : entries) {
this.window.setProperty(entry.getKey(), entry.getValue());
this.window.putProperty(entry.getKey(), entry.getValue());
}
}
@ -183,9 +190,9 @@ public class DesignerLoginBridge {
* @param callback 回调函数
*/
@JSBridge
public void normalLogin(String username, String password, final JSFunction callback) {
public void normalLogin(String username, String password, final JsFunction callback) {
DesignerLoginTaskWorker<Void> worker = new DesignerLoginTaskWorker<>(
new JSCallback(DesignerLoginBrowserExecutor.create(window, callback)),
new JSCallback(BrowserExecutor.create(window, callback)),
new DesignerLoginExecutor(username, password));
worker.execute();
}
@ -198,9 +205,9 @@ public class DesignerLoginBridge {
* @param callback 回调函数
*/
@JSBridge
public void sendCaptcha(String regionCode, String phone, final JSFunction callback) {
public void sendCaptcha(String regionCode, String phone, final JsFunction callback) {
DesignerLoginTaskWorker<Void> worker = new DesignerLoginTaskWorker<>(
new JSCallback(DesignerLoginBrowserExecutor.create(window, callback)),
new JSCallback(BrowserExecutor.create(window, callback)),
new DesignerSendCaptchaExecutor(regionCode, phone));
worker.execute();
}
@ -214,9 +221,9 @@ public class DesignerLoginBridge {
* @param callback 回调函数
*/
@JSBridge
public void smsLogin(String regionCode, String phone, String code, final JSFunction callback) {
public void smsLogin(String regionCode, String phone, String code, final JsFunction callback) {
DesignerLoginTaskWorker<Void> worker = new DesignerLoginTaskWorker<>(
new JSCallback(DesignerLoginBrowserExecutor.create(window, callback)),
new JSCallback(BrowserExecutor.create(window, callback)),
new DesignerSmsLoginExecutor(regionCode, phone, code));
worker.execute();
}
@ -231,9 +238,9 @@ public class DesignerLoginBridge {
* @param callback 回调函数
*/
@JSBridge
public void smsRegister(String regionCode, String phone, String password, String regToken, final JSFunction callback) {
public void smsRegister(String regionCode, String phone, String password, String regToken, final JsFunction callback) {
DesignerLoginTaskWorker<Void> worker = new DesignerLoginTaskWorker<>(
new JSCallback(DesignerLoginBrowserExecutor.create(window, callback)),
new JSCallback(BrowserExecutor.create(window, callback)),
new DesignerSmsRegisterExecutor(regionCode, phone, password, regToken));
worker.execute();
}
@ -275,13 +282,10 @@ public class DesignerLoginBridge {
private JPanel getHyperlinkPane(String title, String hyperlinkText, String hyperlink) {
ActionLabel actionLabel = new ActionLabel(hyperlinkText);
actionLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().browse(new URI(hyperlink));
} catch (Exception ignore) {
}
actionLabel.addActionListener(e -> {
try {
Desktop.getDesktop().browse(new URI(hyperlink));
} catch (Exception ignore) {
}
});
JPanel panel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();

20
designer-base/src/main/java/com/fr/design/login/DesignerLoginPane.java

@ -2,21 +2,23 @@ package com.fr.design.login;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.BasicPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import java.awt.BorderLayout;
import java.util.Map;
/**
* 设计器登录通行证面板
*
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerLoginPane extends BasicPane {
private static final String DESIGNER_LOGIN_HELPER = "DesignerLoginHelper";
@Override
protected String title4PopupWindow() {
return "DESIGNER_LOGIN";
@ -27,14 +29,8 @@ public class DesignerLoginPane extends BasicPane {
params.put("lastLoginType", String.valueOf(DesignerEnvManager.getEnvManager().getLastLoginType().getType()));
params.put("lastLoginAccount", DesignerEnvManager.getEnvManager().getLastLoginAccount());
setLayout(new BorderLayout());
ModernUIPane<Object> modernUIPane = new ModernUIPane.Builder<>()
.prepare(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window");
window.asObject().setProperty("DesignerLoginHelper", DesignerLoginBridge.getBridge(event.getBrowser(), params));
}
})
JxUIPane<Object> modernUIPane = new JxUIPane.Builder<>()
.bindWindow(DESIGNER_LOGIN_HELPER, window -> DesignerLoginBridge.getBridge(window, params))
.withEMB(DesignerLoginHelper.getMainResourcePath(), DesignerLoginUtils.renderMap())
.build();
add(modernUIPane, BorderLayout.CENTER);

17
designer-base/src/main/java/com/fr/design/login/config/DesignerLoginConfigManager.java

@ -75,6 +75,13 @@ public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
*/
private boolean useOldVersionLogin = false;
/**
* 是否手动配置过新插件管理
* <li>11.0.18版本开始全部认为没有手动配置过,符合机型的都默认开启新插件管理,如果需要关闭需要再次手动配置</li>
* <li>如果手动配置过则置为false</li>
*/
private boolean useNewPluginFirst = true;
private DesignerLoginConfigManager() {
}
@ -103,6 +110,7 @@ public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
this.setLoginRemindBeforeJumpBBS(reader.getAttrAsBoolean("loginRemindBeforeJumpBBS", true));
this.setPluginRemindOnFirstLaunch(reader.getAttrAsBoolean("pluginRemindOnFirstLaunch", true));
this.setUseOldVersionLogin(reader.getAttrAsBoolean("useOldVersionLogin", false));
this.setUseNewPluginFirst(reader.getAttrAsBoolean("useNewPluginFirst", true));
}
}
@ -123,6 +131,7 @@ public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
writer.attr("loginRemindBeforeJumpBBS", loginRemindBeforeJumpBBS);
writer.attr("pluginRemindOnFirstLaunch", pluginRemindOnFirstLaunch);
writer.attr("useOldVersionLogin", useOldVersionLogin);
writer.attr("useNewPluginFirst", useNewPluginFirst);
writer.end();
}
@ -237,4 +246,12 @@ public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
public void setUseOldVersionLogin(boolean useOldVersionLogin) {
this.useOldVersionLogin = useOldVersionLogin;
}
public boolean isUseNewPluginFirst() {
return useNewPluginFirst;
}
public void setUseNewPluginFirst(boolean useNewPluginFirst) {
this.useNewPluginFirst = useNewPluginFirst;
}
}

68
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideBridge.java

@ -6,26 +6,31 @@ import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.login.DesignerLoginHelper;
import com.fr.design.login.DesignerLoginSource;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.js.JsAccessible;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
/**
* 设计器登录指南面板的js-java桥
*
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
@JsAccessible
public class DesignerGuideBridge {
public static DesignerGuideBridge getBridge(Browser browser) {
return new DesignerGuideBridge(browser);
/**
* 获取 js-java bridge
*
* @return bridge
*/
public static DesignerGuideBridge getBridge() {
return new DesignerGuideBridge();
}
private JSObject window;
private DesignerGuideBridge(Browser browser) {
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
private DesignerGuideBridge() {
}
@JSBridge
@ -40,31 +45,28 @@ public class DesignerGuideBridge {
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.GUIDE);
checkDoNotRemind(doNotRemind);
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String[] options = new String[]{
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Quit"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Return_Login")
};
int rv = FineJOptionPane.showConfirmDialog(
DesignerGuideHelper.getDialog(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Quit_Tip"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[1]
);
if (rv == JOptionPane.YES_OPTION) {
DesignerGuideHelper.closeWindow();
checkDoNotRemind(doNotRemind);
} else if (rv == JOptionPane.NO_OPTION) {
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.GUIDE);
DesignerGuideHelper.closeWindow();
checkDoNotRemind(doNotRemind);
}
SwingUtilities.invokeLater(() -> {
String[] options = new String[]{
Toolkit.i18nText("Fine-Designer_Login_Quit"),
Toolkit.i18nText("Fine-Designer_Login_Return_Login")
};
int rv = FineJOptionPane.showConfirmDialog(
DesignerGuideHelper.getDialog(),
Toolkit.i18nText("Fine-Designer_Login_Quit_Tip"),
Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[1]
);
if (rv == JOptionPane.YES_OPTION) {
DesignerGuideHelper.closeWindow();
checkDoNotRemind(doNotRemind);
} else if (rv == JOptionPane.NO_OPTION) {
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.GUIDE);
DesignerGuideHelper.closeWindow();
checkDoNotRemind(doNotRemind);
}
});
}

3
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java

@ -10,9 +10,12 @@ import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.update.push.DesignerPushUpdateManager;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.swing.WindowConstants;
/**
* 设计器登录指南帮助类
*
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21

20
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuidePane.java

@ -1,20 +1,22 @@
package com.fr.design.login.guide;
import com.fr.design.dialog.BasicPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.login.guide.utils.DesignerGuideUtils;
import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import java.awt.BorderLayout;
/**
* 设计器登录帆软通行证的指南面板
*
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerGuidePane extends BasicPane {
private static final String DESIGNER_GUIDE_HELPER = "DesignerGuideHelper";
@Override
protected String title4PopupWindow() {
return "DESIGNER_GUIDE";
@ -22,14 +24,8 @@ public class DesignerGuidePane extends BasicPane {
public DesignerGuidePane() {
setLayout(new BorderLayout());
ModernUIPane<Object> modernUIPane = new ModernUIPane.Builder<>()
.prepare(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window");
window.asObject().setProperty("DesignerGuideHelper", DesignerGuideBridge.getBridge(event.getBrowser()));
}
})
JxUIPane<Object> modernUIPane = new JxUIPane.Builder<>()
.bindWindow(DESIGNER_GUIDE_HELPER, w -> DesignerGuideBridge.getBridge())
.withEMB(DesignerGuideHelper.getMainResourcePath(), DesignerGuideUtils.renderMap())
.build();
add(modernUIPane, BorderLayout.CENTER);

12
designer-base/src/main/java/com/fr/design/os/impl/PMDialogAction.java

@ -24,12 +24,18 @@ public class PMDialogAction implements OSBasedAction {
DesignUtils.visitEnvServerByParameters( PLUGIN_MANAGER_ROUTE,null,null);
return;
}
if (ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter()) {
if (checkUPMSupport()) {
UpmFinder.showUPMDialog();
} else {
WebViewDlgHelper.createPluginDialog();
}
}
private boolean checkUPMSupport() {
return ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter()
//默认开启
|| DesignerEnvManager.getEnvManager().isUseNewPluginFirst();
}
}

16
designer-base/src/main/java/com/fr/design/ui/ModernUIConstants.java

@ -3,12 +3,28 @@ package com.fr.design.ui;
import com.fr.general.IOUtils;
/**
* 新式面板常量
*
* @author richie
* @version 10.0
* Created by richie on 2019-03-05
*/
public class ModernUIConstants {
public static final String WINDOW = "window";
public static final String DOT = ".";
public static final String EMB_TAG = "emb";
/**
* 从emb:dynamic 改为 emb://dynamic
* 7之后协议会自动在":"后加上斜杠导致识别错误
*/
public static final String COMPONENT_TAG = "emb://dynamic";
public static final String SCHEME_HEADER = "://";
public static final String DEFAULT_NAMESPACE = "Pool";
public static final String DEFAULT_VARIABLE = "data";
public static final String DEFAULT_EXPRESSION = "update()";
public static final String SCRIPT_INIT_NAME_SPACE = IOUtils.readResourceAsString("/com/fr/design/ui/InitNameSpace.js");
public static final String HTML_TPL = IOUtils.readResourceAsString("/com/fr/design/ui/tpl.html");

24
designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java

@ -34,7 +34,10 @@ import java.util.Map;
* @version 10.0
* Created by richie on 2019-03-04
* 用于加载html5的Swing容器可以在设计选项设置中打开调试窗口示例可查看com.fr.design.ui.ModernUIPaneTest
* @see {@link com.fr.design.jxbrowser.JxUIPane}
* @deprecated 主要用于jxbrowser6将在下个版本删除
*/
@Deprecated
public class ModernUIPane<T> extends BasicPane {
private Browser browser;
@ -119,6 +122,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
*/
public void redirect(String url) {
@ -127,6 +131,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
* @param map 初始化参数
*/
@ -161,7 +166,7 @@ public class ModernUIPane<T> extends BasicPane {
public void disposeBrowser() {
if(browser != null) {
if (browser != null) {
browser.dispose();
browser = null;
}
@ -191,6 +196,12 @@ public class ModernUIPane<T> extends BasicPane {
return null;
}
/**
* ModernUIPane 建造者
*
* @param <T>
*/
public static class Builder<T> implements BuilderDiff<T> {
private ModernUIPane<T> pane;
@ -219,6 +230,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
public Builder<T> withEMB(final String path) {
@ -229,6 +241,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
public Builder<T> withEMB(final String path, Map<String, String> map) {
@ -239,6 +252,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
public Builder<T> withURL(final String url) {
@ -249,6 +263,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
public Builder<T> withURL(final String url, Map<String, String> map) {
@ -259,6 +274,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 加载Atom组件
*
* @param component Atom组件
*/
public Builder<T> withComponent(AssembleComponent component) {
@ -269,6 +285,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 加载Atom组件
*
* @param component Atom组件
*/
public Builder<T> withComponent(AssembleComponent component, Map<String, String> map) {
@ -277,9 +294,9 @@ public class ModernUIPane<T> extends BasicPane {
return this;
}
/**
* 加载html文本内容
*
* @param html 要加载html文本内容
*/
public Builder<T> withHTML(String html) {
@ -290,6 +307,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* 设置该前端页面做数据交换所使用的对象
*
* @param namespace 对象名
*/
public Builder<T> namespace(String namespace) {
@ -299,6 +317,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* java端往js端传数据时使用的变量名字
*
* @param name 变量的名字
*/
public Builder<T> variable(String name) {
@ -308,6 +327,7 @@ public class ModernUIPane<T> extends BasicPane {
/**
* js端往java端传数据时执行的函数表达式
*
* @param expression 函数表达式
*/
public Builder<T> expression(String expression) {

33
designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java

@ -1,5 +1,6 @@
package com.fr.design.ui.compatible;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
@ -10,17 +11,45 @@ import com.teamdev.jxbrowser.event.Observer;
* 封装jxbrwoser v6/v7的构建方式的差异
*
* @author hades
* @version 10.0
* Created by hades on 2021/6/13
* @see {@link JxUIPane}
* @since 10.0
* Created on 2021/6/13
* @deprecated 6在下个版本弃用
*/
@Deprecated
public interface BuilderDiff<T> {
/**
* v6准备工作
*
* @param contextListener 上下文监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV6(ScriptContextListener contextListener);
/**
* v6准备工作
*
* @param loadListener 加载监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV6(LoadListener loadListener);
/**
* v7准备工作
*
* @param callback 注入js回调器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV7(InjectJsCallback callback);
/**
* v7准备工作
*
* @param event 事件
* @param listener 监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV7(Class event, Observer listener);
}

35
designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java

@ -1,36 +1,45 @@
package com.fr.design.ui.compatible;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.ui.ModernUIPane;
import com.fr.stable.os.OperatingSystem;
/**
* 根据版本选择构造器
*
* @author hades
* @version 10.0
* Created by hades on 2021/6/13
* @see {@link JxUIPane}
* @since 10.0
* Created on 2021/6/13
* @deprecated 6在下个版本弃用
*/
public class ModernUIPaneFactory {
/**
* 获取一个 JxBrowser pane 的构造器
*
* @param <T> 参数
* @return 构造器
*/
public static <T> ModernUIPane.Builder<T> modernUIPaneBuilder() {
if (isV7()) {
return new NewModernUIPane.Builder<>();
return new JxUIPane.Builder<>();
} else {
return new ModernUIPane.Builder<>();
}
}
/**
* 判断 JxBrowser 版本是否在7或之上
*
* @return 是否7或之上
*/
public static boolean isV7() {
// 7.15的class不存在时 走老版本
boolean hasJxBrowserV7_15 = true;
boolean jxBrowserV7 = true;
try {
Class.forName("com.teamdev.jxbrowser.net.Scheme");
} catch (ClassNotFoundException e) {
hasJxBrowserV7_15 = false;
jxBrowserV7 = false;
}
return OperatingSystem.isWindows() && hasJxBrowserV7_15;
return jxBrowserV7;
}
}

362
designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java

@ -1,362 +0,0 @@
package com.fr.design.ui.compatible;
import com.fr.design.DesignerEnvManager;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIConstants;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.event.Observer;
import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.net.Network;
import com.teamdev.jxbrowser.net.Scheme;
import com.teamdev.jxbrowser.net.callback.VerifyCertificateCallback;
import com.teamdev.jxbrowser.view.swing.BrowserView;
import org.jetbrains.annotations.Nullable;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Map;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
/**
* 基于v7 jxbrowser实现
*
* @author richie
* @version 10.0
* Created by richie on 2019-03-04
* 用于加载html5的Swing容器可以在设计选项设置中打开调试窗口示例可查看com.fr.design.ui.ModernUIPaneTest
*/
public class NewModernUIPane<T> extends ModernUIPane<T> {
private Browser browser;
private String namespace = "Pool";
private String variable = "data";
private String expression = "update()";
private Scheme scheme;
private NxInterceptRequestCallback requestCallback;
private NewModernUIPane() {
super();
initialize();
}
private void initialize() {
setLayout(new BorderLayout());
if (browser == null) {
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
UIToolbar toolbar = new UIToolbar();
add(toolbar, BorderLayout.NORTH);
UIButton openDebugButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Open_Debug_Window"));
toolbar.add(openDebugButton);
UIButton reloadButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Reload"));
toolbar.add(reloadButton);
UIButton closeButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Close_Window"));
toolbar.add(closeButton);
openDebugButton.addActionListener(e -> showDebuggerDialog());
reloadButton.addActionListener(e -> browser.navigation().reloadIgnoringCache());
closeButton.addActionListener(e -> SwingUtilities.getWindowAncestor(
NewModernUIPane.this).setVisible(false));
initializeBrowser();
add(BrowserView.newInstance(browser), BorderLayout.CENTER);
} else {
initializeBrowser();
add(BrowserView.newInstance(browser), BorderLayout.CENTER);
}
}
}
private void showDebuggerDialog() {
JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this));
Browser debugger = browser.engine().newBrowser();
BrowserView debuggerView = BrowserView.newInstance(debugger);
dialog.add(debuggerView, BorderLayout.CENTER);
dialog.setSize(new Dimension(800, 400));
GUICoreUtils.centerWindow(dialog);
dialog.setVisible(true);
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
browser.devTools().remoteDebuggingUrl().ifPresent(url -> {
debugger.navigation().loadUrl(url);
});
}
private void initializeBrowser() {
EngineOptions.Builder builder;
if (scheme != null && requestCallback != null) {
builder = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").addScheme(scheme, requestCallback);
} else {
builder = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic");
}
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
builder.remoteDebuggingPort(9222);
}
Engine engine = Engine.newInstance(builder.build());
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
// 调试模式下,禁止HTTPS证书验证,使得可以正常访问商城测试服务器等
Network network = engine.network();
network.set(VerifyCertificateCallback.class, new VerifyCertificateCallback() {
@Nullable
@Override
public Response on(Params params) {
return VerifyCertificateCallback.Response.valid();
}
});
}
browser = engine.newBrowser();
// 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的
browser.set(InjectJsCallback.class, params -> {
params.frame().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace));
return InjectJsCallback.Response.proceed();
});
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
*/
@Override
public void redirect(String url) {
browser.navigation().loadUrl(url);
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
* @param map 初始化参数
*/
@Override
public void redirect(String url, Map<String, String> map) {
if (requestCallback != null) {
requestCallback.setMap(map);
}
browser.navigation().loadUrl(url);
}
@Override
protected String title4PopupWindow() {
return "Modern";
}
@Override
public void populate(final T t) {
browser.set(InjectJsCallback.class, params -> {
JsObject ns = params.frame().executeJavaScript("window." + namespace);
if (ns != null) {
ns.putProperty(variable, t);
}
return InjectJsCallback.Response.proceed();
});
}
@Override
public T update() {
if (browser.mainFrame().isPresent()) {
return browser.mainFrame().get().executeJavaScript("window." + namespace + "." + expression);
}
return null;
}
public void disposeBrowser() {
if (browser != null) {
browser.engine().close();
browser = null;
}
}
public void clearCache() {
if (browser != null) {
browser.engine().httpCache().clear();
}
}
public void executeJavaScript(String javaScript) {
if (browser != null) {
browser.mainFrame().ifPresent(frame -> {
frame.executeJavaScript(javaScript);
});
}
}
public static class Builder<T> extends ModernUIPane.Builder<T> {
private NewModernUIPane<T> pane = new NewModernUIPane<>();
public Builder() {
super((ModernUIPane<T>)null);
}
public NewModernUIPane.Builder<T> prepare(InjectJsCallback callback) {
pane.browser.set(InjectJsCallback.class, callback);
return this;
}
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
@Override
public NewModernUIPane.Builder<T> withEMB(final String path) {
pane.scheme = Scheme.of("emb");
pane.requestCallback = new NxComplexInterceptRequestCallback(null);
pane.browser.navigation().loadUrl("emb:" + path);
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
@Override
public NewModernUIPane.Builder<T> withURL(final String url) {
pane.scheme = Scheme.of("file");
pane.requestCallback = new NxComplexInterceptRequestCallback(null);
pane.browser.navigation().loadUrl(url);
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
@Override
public NewModernUIPane.Builder<T> withURL(final String url, Map<String, String> map) {
pane.scheme = Scheme.of("file");
pane.requestCallback = new NxInterceptRequestCallback(map);
pane.browser.navigation().loadUrl(url);
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
@Override
public NewModernUIPane.Builder<T> withComponent(AssembleComponent component) {
pane.scheme = Scheme.of("emb");
pane.requestCallback = new NxComplexInterceptRequestCallback(component);
pane.browser.navigation().loadUrl("emb:dynamic");
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
@Override
public NewModernUIPane.Builder<T> withComponent(AssembleComponent component, Map<String, String> map) {
pane.scheme = Scheme.of("emb");
pane.requestCallback = new NxComplexInterceptRequestCallback(component, map);
pane.browser.navigation().loadUrl("emb:dynamic");
return this;
}
/**
* 加载html文本内容
*
* @param html 要加载html文本内容
*/
@Override
public NewModernUIPane.Builder<T> withHTML(String html) {
pane.scheme = Scheme.of("html");
pane.requestCallback = new NxInterceptRequestCallback();
pane.browser.mainFrame().ifPresent(frame -> {
frame.loadHtml(html);
});
return this;
}
/**
* 设置该前端页面做数据交换所使用的对象
*
* @param namespace 对象名
*/
@Override
public NewModernUIPane.Builder<T> namespace(String namespace) {
pane.namespace = namespace;
return this;
}
/**
* java端往js端传数据时使用的变量名字
*
* @param name 变量的名字
*/
@Override
public NewModernUIPane.Builder<T> variable(String name) {
pane.variable = name;
return this;
}
/**
* js端往java端传数据时执行的函数表达式
*
* @param expression 函数表达式
*/
@Override
public NewModernUIPane.Builder<T> expression(String expression) {
pane.expression = expression;
return this;
}
@Override
public NewModernUIPane.Builder<T> prepareForV6(ScriptContextListener contextListener) {
// do nothing
return this;
}
@Override
public NewModernUIPane.Builder<T> prepareForV6(LoadListener loadListener) {
// do nothing
return this;
}
@Override
public NewModernUIPane.Builder<T> prepareForV7(InjectJsCallback callback) {
return prepare(callback);
}
@Override
public ModernUIPane.Builder<T> prepareForV7(Class event, Observer listener) {
pane.browser.navigation().on(event, listener);
return this;
}
@Override
public NewModernUIPane<T> build() {
return pane;
}
}
}

86
designer-base/src/main/java/com/fr/design/ui/compatible/NxComplexInterceptRequestCallback.java

@ -1,86 +0,0 @@
package com.fr.design.ui.compatible;
import com.fr.design.ui.ModernRequestClient;
import com.fr.design.ui.ModernUIConstants;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
import com.fr.web.struct.AssembleComponent;
import com.fr.web.struct.AtomBuilder;
import com.fr.web.struct.PathGroup;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.category.StylePath;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* @author richie
* @version 10.0
* Created by richie on 2020/3/25
*/
public class NxComplexInterceptRequestCallback extends NxInterceptRequestCallback {
private AssembleComponent component;
public NxComplexInterceptRequestCallback(AssembleComponent component) {
this.component = component;
}
public NxComplexInterceptRequestCallback(AssembleComponent component, Map<String, String> map) {
super(map);
this.component = component;
}
@Override
protected Response next(Params params, String path) {
if (path.startsWith("emb:dynamic")) {
String text = htmlText(map);
return Response.intercept(generateBasicUrlRequestJob(params, "text/html", text.getBytes(StandardCharsets.UTF_8)));
} else {
int index = path.indexOf("=");
if (index > 0) {
path = path.substring(index + 1);
} else {
path = path.substring(4);
}
InputStream inputStream = IOUtils.readResource(path);
if (inputStream == null) {
return Response.proceed();
}
return Response.intercept(generateBasicUrlRequestJob(params, getMimeType(path), IOUtils.inputStream2Bytes(inputStream)));
}
}
private String htmlText(Map<String, String> map) {
PathGroup pathGroup = AtomBuilder.create().buildAssembleFilePath(ModernRequestClient.KEY, component);
StylePath[] stylePaths = pathGroup.toStylePathGroup();
StringBuilder styleText = new StringBuilder();
for (StylePath path : stylePaths) {
if (StringUtils.isNotBlank(path.toFilePath())) {
styleText.append("<link rel=\"stylesheet\" href=\"emb:");
styleText.append(path.toFilePath());
styleText.append("\"/>");
}
}
String result = ModernUIConstants.HTML_TPL.replaceAll("##style##", styleText.toString());
ScriptPath[] scriptPaths = pathGroup.toScriptPathGroup();
StringBuilder scriptText = new StringBuilder();
for (ScriptPath path : scriptPaths) {
if (StringUtils.isNotBlank(path.toFilePath())) {
scriptText.append("<script src=\"emb:");
scriptText.append(path.toFilePath());
scriptText.append("\"></script>");
}
}
result = result.replaceAll("##script##", scriptText.toString());
if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
result = result.replaceAll("\\$\\{" + key + "}", value);
}
}
return result;
}
}

148
designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java

@ -1,148 +0,0 @@
package com.fr.design.ui.compatible;
import com.fr.base.TemplateUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.codec.net.URLCodec;
import com.teamdev.jxbrowser.net.HttpHeader;
import com.teamdev.jxbrowser.net.HttpStatus;
import com.teamdev.jxbrowser.net.UrlRequest;
import com.teamdev.jxbrowser.net.UrlRequestJob;
import com.teamdev.jxbrowser.net.callback.InterceptUrlRequestCallback;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
/**
* @author richie
* @version 10.0
* Created by richie on 2020/3/25
*/
public class NxInterceptRequestCallback implements InterceptUrlRequestCallback {
Map<String, String> map;
public NxInterceptRequestCallback() {
}
public NxInterceptRequestCallback(Map<String, String> map) {
this.map = map;
}
@Override
public Response on(Params params) {
UrlRequest urlRequest = params.urlRequest();
String path = urlRequest.url();
if (path.startsWith("file:")) {
Optional<UrlRequestJob> optional = generateFileProtocolUrlRequestJob(params, path);
if (optional.isPresent()) {
return Response.intercept(optional.get());
}
} else {
return next(params, path);
}
return Response.proceed();
}
Response next(Params params, String path) {
return Response.proceed();
}
private Optional<UrlRequestJob> generateFileProtocolUrlRequestJob(Params params, String path) {
try {
String url = new URLCodec().decode(path);
String filePath = TemplateUtils.renderParameter4Tpl(url, map);
File file = new File(URI.create(filePath).getPath());
InputStream inputStream = IOUtils.readResource(file.getAbsolutePath());
String mimeType = getMimeType(path);
byte[] bytes;
if (isPlainText(mimeType)) {
String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8);
text = TemplateUtils.renderParameter4Tpl(text, map);
bytes = text.getBytes(StandardCharsets.UTF_8);
} else {
bytes = IOUtils.inputStream2Bytes(inputStream);
}
return Optional.of(generateBasicUrlRequestJob(params, mimeType, bytes));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return Optional.empty();
}
private boolean isPlainText(String mimeType) {
return ArrayUtils.contains(new String[]{"text/html", "text/javascript", "text/css"}, mimeType);
}
UrlRequestJob generateBasicUrlRequestJob(Params params, String mimeType, byte[] bytes) {
UrlRequestJob.Options options = UrlRequestJob.Options
.newBuilder(HttpStatus.OK)
.addHttpHeader(HttpHeader.of("Content-Type", mimeType))
.build();
UrlRequestJob urlRequestJob = params.newUrlRequestJob(options);
urlRequestJob.write(bytes);
urlRequestJob.complete();
return urlRequestJob;
}
String getMimeType(String path) {
// 去除 xxx?xxx 后面部分
int index = path.indexOf("?");
if (index != -1) {
path = path.substring(0, path.indexOf("?"));
}
if (StringUtils.isBlank(path)) {
return "text/html";
}
if (path.endsWith(".html")) {
return "text/html";
}
if (path.endsWith(".css")) {
return "text/css";
}
if (path.endsWith(".js")) {
return "text/javascript";
}
if (path.endsWith(".svg")) {
return "image/svg+xml";
}
if (path.endsWith(".png")) {
return "image/png";
}
if (path.endsWith(".jpeg")) {
return "image/jpeg";
}
if (path.endsWith(".gif")) {
return "image/gif";
}
if (path.endsWith(".woff")) {
return "font/woff";
}
if (path.endsWith(".ttf")) {
return "truetype";
}
if (path.endsWith(".eot")) {
return "embedded-opentype";
}
Path file = new File(path).toPath();
try {
return Files.probeContentType(file);
} catch (IOException e) {
return "text/html";
}
}
public void setMap(Map<String, String> map) {
this.map = map;
}
}

42
designer-base/src/main/java/com/fr/design/update/push/DesignerPushUpdateDialog.java

@ -1,7 +1,7 @@
package com.fr.design.update.push;
import com.fr.design.dialog.UIDialog;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.utils.BrowseUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.intelli.record.FocusPoint;
@ -14,20 +14,24 @@ import com.fr.web.struct.browser.RequestClient;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.category.StylePath;
import com.fr.web.struct.impl.FineUI;
import com.teamdev.jxbrowser.js.JsAccessible;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
/**
* Created by plough on 2019/4/10.
* 设计器推送更新对话框
*
* @author plough
* @since 10.0
* Created on 2019/4/10.
*/
class DesignerPushUpdateDialog extends UIDialog {
public class DesignerPushUpdateDialog extends UIDialog {
public static final Dimension DEFAULT = new Dimension(640, 360);
private ModernUIPane<Model> jsPane;
private JxUIPane<Model> jsPane;
private DesignerPushUpdateDialog(Frame parent) {
super(parent);
@ -35,23 +39,23 @@ class DesignerPushUpdateDialog extends UIDialog {
initComponents();
}
static void createAndShow(final Frame parent, final DesignerUpdateInfo updateInfo) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
DesignerPushUpdateDialog dialog = new DesignerPushUpdateDialog(parent);
dialog.populate(updateInfo);
dialog.showDialog();
}
});
/**
* 创建并展示窗口
*
* @param parent 父窗体
* @param updateInfo 要展示的更新数据
*/
public static void createAndShow(final Frame parent, final DesignerUpdateInfo updateInfo) {
DesignerPushUpdateDialog dialog = new DesignerPushUpdateDialog(parent);
dialog.populate(updateInfo);
dialog.showDialog();
}
private void initComponents() {
JPanel contentPane = (JPanel) getContentPane();
contentPane.setLayout(new BorderLayout());
jsPane = new ModernUIPane.Builder<Model>()
jsPane = new JxUIPane.Builder<Model>()
.withComponent(new AssembleComponent() {
@Override
public ScriptPath script(RequestClient req) {
@ -67,7 +71,7 @@ class DesignerPushUpdateDialog extends UIDialog {
public Atom[] refer() {
return new Atom[]{FineUI.KEY};
}
}).namespace("Pool").build();
}).build();
contentPane.add(jsPane);
}
@ -101,6 +105,7 @@ class DesignerPushUpdateDialog extends UIDialog {
setVisible(true);
}
@JsAccessible
public class Model {
private String version;
private String content;
@ -163,6 +168,7 @@ class DesignerPushUpdateDialog extends UIDialog {
exit();
}
@JsAccessible
public String i18nText(String key) {
return com.fr.design.i18n.Toolkit.i18nText(key);
}
@ -180,9 +186,11 @@ class DesignerPushUpdateDialog extends UIDialog {
private enum OperateType {
CLOSE_WINDOW(0), UPDATE(1), REMIND_NEXT_TIME(2), SKIP(3);
private int index;
OperateType(int index) {
this.index = index;
}
private String toText() {
return String.valueOf(this.index);
}

10
designer-base/src/main/java/com/fr/design/update/push/DesignerUpdateInfo.java

@ -12,9 +12,13 @@ import com.fr.stable.StringUtils;
import java.security.InvalidParameterException;
/**
* Created by plough on 2019/4/8.
* 设计器更新信息bean
*
* @author plough
* @since 10.0
* Created on 2019/4/8.
*/
class DesignerUpdateInfo {
public class DesignerUpdateInfo {
private static final String KEY_VERSION = "version";
private static final String KEY_CONTENT = "content";
private static final String KEY_BACKGROUND_URL = "background";
@ -32,7 +36,7 @@ class DesignerUpdateInfo {
private final String backgroundUrl; // 推送背景图片 url
private final String moreInfoUrl; // 更多新特性
DesignerUpdateInfo(String currentVersion, String latestVersion, String lastIgnoredVersion, JSONObject pushData) {
public DesignerUpdateInfo(String currentVersion, String latestVersion, String lastIgnoredVersion, JSONObject pushData) {
this.currentVersion = currentVersion;
this.latestVersion = latestVersion;
this.latestFullVersion = initLatestFullVersion();

28
designer-base/src/main/java/com/fr/design/upm/UpmBridge.java

@ -40,12 +40,13 @@ import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSArray;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.chromium.JSValue;
import java.awt.Desktop;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.Desktop;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
@ -59,7 +60,9 @@ import java.util.concurrent.RunnableFuture;
* @version 10.0
* Created by richie on 2019-04-12
* 桥接Java和JavaScript的类
* @deprecated 用于jxbrowser6下版本删除
*/
@Deprecated
public class UpmBridge {
public static UpmBridge getBridge(Browser browser) {
@ -78,6 +81,7 @@ public class UpmBridge {
/**
* 更新插件管理中心资源文件这个方法仅仅是为了语义上的作用更新
*
* @param callback 安装完成后的回调函数
*/
@JSBridge
@ -96,6 +100,7 @@ public class UpmBridge {
/**
* 下载并安装插件管理中心的资源文件
*
* @param callback 安装完成后的回调函数
*/
@JSBridge
@ -126,6 +131,7 @@ public class UpmBridge {
/**
* 获取upm的版本信息
*
* @return 版本信息
*/
@JSBridge
@ -291,6 +297,23 @@ public class UpmBridge {
PluginOperateUtils.setPluginActive(pluginID, jsCallback);
}
/**
* 批量修改选中的插件的活跃状态
*
* @param pluginIDs 要处理的插件ID
* @param callback 回调函数
*/
@JSBridge
public void setAllPluginActive(JSArray pluginIDs, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
List<String> list = new ArrayList<>();
int len = pluginIDs.length();
for (int i = 0; i < len; i++) {
list.add(pluginIDs.get(i).asString().getValue());
}
PluginOperateUtils.setPluginActive(list, jsCallback);
}
/**
* 选择文件对话框
*
@ -315,7 +338,7 @@ public class UpmBridge {
@Override
public String call() {
FileChooserProvider fileChooserProvider = FileChooserFactory.createFileChooser(
FileChooserArgs.newBuilder().
FileChooserArgs.newBuilder().
setFileSelectionMode(FileSelectionMode.FILE).
setFilter(des, filter).build());
int result = fileChooserProvider.showDialog(UpmFinder.getDialog());
@ -468,6 +491,7 @@ public class UpmBridge {
/**
* 使用系统浏览器打开网页
*
* @param url 要打开的网页
*/
@JSBridge

26
designer-base/src/main/java/com/fr/design/upm/NewUpmBridge.java → designer-base/src/main/java/com/fr/design/upm/UpmBridgeV7.java

@ -28,7 +28,7 @@ import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.js.JsAccessible;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.js.internal.JsArrayImpl;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
@ -45,15 +45,16 @@ import java.util.concurrent.RunnableFuture;
* Created by richie on 2019-04-12
* 桥接Java和JavaScript的类
*/
public class NewUpmBridge extends UpmBridge {
@JsAccessible
public class UpmBridgeV7 extends UpmBridge {
public static NewUpmBridge getBridge(JsObject jsObject) {
return new NewUpmBridge(jsObject);
public static UpmBridgeV7 getBridge(JsObject jsObject) {
return new UpmBridgeV7(jsObject);
}
private JsObject jsObject;
private NewUpmBridge(JsObject jsObject) {
private UpmBridgeV7(JsObject jsObject) {
this.jsObject = jsObject;
}
@ -264,6 +265,21 @@ public class NewUpmBridge extends UpmBridge {
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
}
/**
* 批量修改选中的插件的活跃状态
*
* @param pluginIDs 要处理的插件ID
* @param callback 回调函数
*/
@JSBridge
@JsAccessible
public void setAllPluginActive(JsObject pluginIDs, final JsFunction callback) {
JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback));
List array = ((JsArrayImpl) pluginIDs).toList();
PluginOperateUtils.setPluginActive(array, jsCallback);
}
/**
* 从插件服务器上安装插件
*

4
designer-base/src/main/java/com/fr/design/upm/UpmFinder.java

@ -8,6 +8,7 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.ui.ModernUIConstants;
import com.fr.design.update.ui.dialog.UpdateMainDialog;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
@ -57,7 +58,8 @@ public class UpmFinder {
}
public static String getMainResourcePath() {
return "file:///" + StableUtils.pathJoin(installHome, MAIN_RESOURCE_PATH);
return ModernUIConstants.EMB_TAG + ModernUIConstants.SCHEME_HEADER
+ StableUtils.pathJoin(installHome, MAIN_RESOURCE_PATH);
}
public static UIDialog getDialog() {

30
designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java

@ -1,19 +1,13 @@
package com.fr.design.upm;
import com.fr.design.dialog.BasicPane;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.ui.compatible.ModernUIPaneFactory;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.upm.event.DownloadEvent;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import com.teamdev.jxbrowser.js.JsObject;
import java.awt.*;
import java.awt.BorderLayout;
/**
* @author richie
@ -23,7 +17,9 @@ import java.awt.*;
*/
public class UpmShowPane extends BasicPane {
private ModernUIPane<Object> modernUIPane;
public static final String PLUGIN_HELPER = "PluginHelper";
private final JxUIPane<Object> jxUIPane;
@Override
protected String title4PopupWindow() {
@ -32,28 +28,22 @@ public class UpmShowPane extends BasicPane {
UpmShowPane() {
setLayout(new BorderLayout());
modernUIPane = new ModernUIPane.Builder<>()
.prepare(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window");
window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser()));
}
})
jxUIPane = new JxUIPane.Builder<>()
.bindWindow(PLUGIN_HELPER, UpmBridgeV7::getBridge)
.withURL(UpmFinder.getMainResourcePath(), UpmUtils.renderMap())
.build();
EventDispatcher.listen(DownloadEvent.UPDATE, new Listener<String>() {
@Override
public void on(Event event, String param) {
modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap());
jxUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap());
}
});
EventDispatcher.listen(DownloadEvent.UPDATE, new Listener<String>() {
@Override
public void on(Event event, String param) {
modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap());
jxUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap());
}
});
add(modernUIPane, BorderLayout.CENTER);
add(jxUIPane, BorderLayout.CENTER);
}
}

20
designer-base/src/test/java/com/fr/design/actions/help/TutorialActionTest.java

@ -1,14 +1,34 @@
package com.fr.design.actions.help;
import com.fr.base.svg.SystemScaleUtils;
import com.fr.design.i18n.Toolkit;
import com.fr.general.GeneralContext;
import com.fr.stable.ProductConstants;
import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.Locale;
import java.util.UUID;
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*","javax.net.ssl.*"})
@PrepareForTest({Toolkit.class, SystemScaleUtils.class})
public class TutorialActionTest extends TestCase {
public void setUp() {
PowerMock.mockStatic(Toolkit.class);
EasyMock.expect(Toolkit.i18nText(EasyMock.anyString())).andReturn("test").anyTimes();
PowerMock.mockStatic(SystemScaleUtils.class);
EasyMock.expect(SystemScaleUtils.sysScale()).andReturn(1F).anyTimes();
EasyMock.expect(SystemScaleUtils.isJreHiDPIEnabled()).andReturn(false).anyTimes();
PowerMock.replayAll();
}
public void testCreateKey() {
TutorialAction action = new TutorialAction();
GeneralContext.setLocale(Locale.US);

12
designer-base/src/test/java/com/fr/design/base/clipboard/DesignerClipboardTest.java

@ -1,5 +1,6 @@
package com.fr.design.base.clipboard;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.fun.ClipboardHandlerProvider;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.dnd.ArrayListTransferable;
@ -41,11 +42,20 @@ public class DesignerClipboardTest {
.andReturn(providers)
.anyTimes();
EasyMock.replay(formClassManager);
ExtraDesignClassManager designClassManager = EasyMock.mock(ExtraDesignClassManager.class);
EasyMock.expect(designClassManager.getArray(ClipboardHandlerProvider.XML_TAG))
.andReturn(providers)
.anyTimes();
EasyMock.replay(designClassManager);
PowerMock.mockStatic(PluginModule.class);
EasyMock.expect(PluginModule.getAgent(PluginModule.ExtraForm))
.andReturn(formClassManager)
.anyTimes();
EasyMock.expect(PluginModule.getAgent(PluginModule.ExtraDesign))
.andReturn(designClassManager)
.anyTimes();
PowerMock.replayAll();
}
@ -72,4 +82,4 @@ public class DesignerClipboardTest {
Assert.assertEquals(transferData.get(0), transferData2.get(0));
}
}
}

17
designer-base/src/test/java/com/fr/design/data/DesignTableDataManagerTest.java

@ -141,18 +141,15 @@ public class DesignTableDataManagerTest {
}
@Test
public void testAddDsColumnNames() {
DesignTableDataManager.addDsColumnNames("ds1", new String[]{"a", "b", "c"});
Map<TableDataSource, Map<String, String[]>> map = Reflect.on(DesignTableDataManager.class).field(
"columnCache").get();
Assert.assertEquals(new String[]{"a", "b", "c"}, map.get(null).get("ds1"));
}
@Test
public void testGetDsColumnNames() {
Assert.assertTrue(ArrayUtils.isEmpty(DesignTableDataManager.getDsColumnNames("ds1")));
public void testOperateDsColumnNames() {
String[] columnNames = new String[]{"a", "b", "c"};
Assert.assertTrue(ArrayUtils.isEmpty(DesignTableDataManager.getDsColumnNames("ds1")));
// 测试Add
DesignTableDataManager.addDsColumnNames("ds1", new String[]{"a", "b", "c"});
// 测试Get
Assert.assertEquals(columnNames, DesignTableDataManager.getDsColumnNames("ds1"));
// 测试Remove
DesignTableDataManager.removeSelectedColumnNames("ds1");
Assert.assertTrue(ArrayUtils.isEmpty(DesignTableDataManager.getDsColumnNames("ds1")));
}
}

20
designer-base/src/test/java/com/fr/design/data/datapane/TableDataPaneListPaneTest.java

@ -1,6 +1,14 @@
package com.fr.design.data.datapane;
import com.fr.design.i18n.Toolkit;
import org.easymock.EasyMock;
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.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.Map;
@ -11,8 +19,18 @@ import static org.junit.Assert.*;
* @version 10.0
* Created by Yyming on 2020/9/29
*/
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.swing.*"})
@PrepareForTest(Toolkit.class)
public class TableDataPaneListPaneTest {
@Before
public void setUp() {
PowerMock.mockStatic(Toolkit.class);
EasyMock.expect(Toolkit.i18nText(EasyMock.anyString())).andReturn("test").anyTimes();
PowerMock.replayAll();
}
@Test
public void rename() {
TableDataPaneListPane listPane = new TableDataPaneListPane();
@ -23,4 +41,4 @@ public class TableDataPaneListPaneTest {
listPane.rename("333","111");
assertEquals(0, dsNameChangedMap.size());
}
}
}

6
designer-base/src/test/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtilsTest.java

@ -62,6 +62,7 @@ public class TableDataFollowingPasteUtilsTest extends TestCase {
PowerMock.mockStatic(DesignTableDataManager.class);
EasyMock.expect(DesignTableDataManager.getEditingTableDataSource()).andReturn(tableDataSource).anyTimes();
EasyMock.expect(DesignTableDataManager.getEditingDataSet(tableDataSource)).andReturn(list).anyTimes();
EasyMock.expect(DesignTableDataManager.getAllDataSetIncludingProcedure(templateDataMap)).andReturn(templateDataMap).anyTimes();
PowerMock.replayAll();
}
@ -107,6 +108,7 @@ public class TableDataFollowingPasteUtilsTest extends TestCase {
set.add("ds3");
MockWidget widget1 = EasyMock.mock(MockWidget.class);
EasyMock.expect(widget1.getUsedTableDataSets()).andReturn(set).anyTimes();
EasyMock.expect(widget1.getChartCollections()).andReturn(new ArrayList<>()).anyTimes();
EasyMock.replay(widget1);
DataBinding dataBinding = new DataBinding("ds4", "");
@ -114,6 +116,7 @@ public class TableDataFollowingPasteUtilsTest extends TestCase {
widgetValue2.setValue(dataBinding);
AbstractDataControl widget2 = EasyMock.mock(AbstractDataControl.class);
EasyMock.expect(widget2.getWidgetValue()).andReturn(widgetValue2).anyTimes();
EasyMock.expect(widget2.getChartCollections()).andReturn(new ArrayList<>()).anyTimes();
EasyMock.replay(widget2);
DataTableConfig dataTableConfig = EasyMock.mock(DataTableConfig.class);
@ -122,6 +125,7 @@ public class TableDataFollowingPasteUtilsTest extends TestCase {
widgetValue3.setValue(dataTableConfig);
AbstractDataControl widget3 = EasyMock.mock(AbstractDataControl.class);
EasyMock.expect(widget3.getWidgetValue()).andReturn(widgetValue3).anyTimes();
EasyMock.expect(widget3.getChartCollections()).andReturn(new ArrayList<>()).anyTimes();
EasyMock.replay(dataTableConfig, widget3);
Widget[] widgets = new Widget[3];
@ -198,4 +202,4 @@ public class TableDataFollowingPasteUtilsTest extends TestCase {
return new String[0];
}
}
}
}

289
designer-base/src/test/java/com/fr/design/file/MultiTemplateTabPaneTest.java

@ -0,0 +1,289 @@
package com.fr.design.file;
import com.fr.design.DesignModelAdapter;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.designer.TargetComponent;
import com.fr.design.gui.frpane.HyperlinkGroupPane;
import com.fr.design.gui.frpane.HyperlinkGroupPaneActionProvider;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.mainframe.AuthorityEditPane;
import com.fr.design.mainframe.BaseUndoState;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef;
import com.fr.plugin.injectable.PluginModule;
import junit.framework.TestCase;
import org.junit.Assert;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.List;
public class MultiTemplateTabPaneTest extends TestCase {
@Override
protected void setUp() throws Exception {
PluginModule.registerAgent(PluginModule.ExtraDesign, new ExtraDesignClassManager());
}
/**
* 当前显示模式A传入index左边(含当前)或右边有模式A的模板返回最近的模式A模板index优先左边
*/
public void test_index_left_has_same_mode_temp() {
//当前显示模式A,传入index左边(含当前)有模式A的模板,返回左边最近的模式A模板index
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
openedTemplateList.add(new A_Mode());
Assert.assertEquals(0, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(new A_Mode());
Assert.assertEquals(1, MultiTemplateTabUtils.calShowTemplateIndex(1, openedTemplateList, "A_Mode"));
openedTemplateList.add(new B_Mode());
Assert.assertEquals(1, MultiTemplateTabUtils.calShowTemplateIndex(1, openedTemplateList, "A_Mode"));
}
public void test_index_left_has_not_but_right_has_same_mode_temp() {
//当前显示模式A,传入index左边没有但是右边有模式A的模板,返回右边最近的模式A模板index
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
openedTemplateList.add(new B_Mode());
openedTemplateList.add(new A_Mode());
Assert.assertEquals(1, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(1, new B_Mode());
openedTemplateList.add(new A_Mode());
Assert.assertEquals(2, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(new A_Mode());
Assert.assertEquals(2, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
}
/**
* 当前显示模式A没有模式A的模板左边(含当前)或者右边有其他模式的模板返回最近的其他模式模式模板index优先左边
*/
public void test_no_same_mode_temp_but_index_left_has_other_mode_temp() {
//当前显示模式A,没有模式A的模板,左边(含当前)有其他模式模板,返回左边最近的其他模式模板index
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
openedTemplateList.add(new B_Mode());
Assert.assertEquals(0, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(new B_Mode());
Assert.assertEquals(1, MultiTemplateTabUtils.calShowTemplateIndex(1, openedTemplateList, "A_Mode"));
}
public void test_has_no_temp() {
//当前显示模式A,没有模式A的模板,也没有其他模式的模板,返回-1
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
Assert.assertEquals(-1, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
}
public void test_if_index_less_than_zero_or_more_than_open_temp_size() {
//index<0 或者超出openTemplateList.size时,返回-1
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
Assert.assertEquals(-1, MultiTemplateTabUtils.calShowTemplateIndex(-1, openedTemplateList, "A_Mode"));
Assert.assertEquals(-1, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(new A_Mode());
Assert.assertEquals(-1, MultiTemplateTabUtils.calShowTemplateIndex(1, openedTemplateList, "A_Mode"));
}
private class A_Mode extends AbstractTestMode {
public String getTemplateTabOperatorType() {
return "A_Mode";
}
}
private class B_Mode extends AbstractTestMode {
public String getTemplateTabOperatorType() {
return "B_Mode";
}
}
private abstract class AbstractTestMode extends JTemplate {
public AbstractTestMode() {
}
@Override
public void copy() {
}
@Override
public boolean paste() {
return false;
}
@Override
public boolean cut() {
return false;
}
@Override
public AuthorityEditPane createAuthorityEditPane() {
return null;
}
@Override
public JPanel getEastUpPane() {
return null;
}
@Override
public JPanel getEastDownPane() {
return null;
}
@Override
public ToolBarDef[] toolbars4Target() {
return new ToolBarDef[0];
}
@Override
public JPanel[] toolbarPanes4Form() {
return new JPanel[0];
}
@Override
public JComponent[] toolBarButton4Form() {
return new JComponent[0];
}
@Override
public JComponent toolBar4Authority() {
return null;
}
@Override
public int getToolBarHeight() {
return 0;
}
@Override
public void refreshEastPropertiesPane() {
}
@Override
public TargetComponent getCurrentElementCasePane() {
return null;
}
@Override
public JComponent getCurrentReportComponentPane() {
return null;
}
@Override
public TemplateProcessInfo getProcessInfo() {
return null;
}
@Override
public void setJTemplateResolution(int resolution) {
}
@Override
public int getJTemplateResolution() {
return 0;
}
@Override
protected JComponent createCenterPane() {
return null;
}
@Override
public void removeTemplateSelection() {
}
@Override
public void refreshContainer() {
}
@Override
public void removeParameterPaneSelection() {
}
@Override
public void setScale(int resolution) {
}
@Override
public int getScale() {
return 0;
}
@Override
public int selfAdaptUpdate() {
return 0;
}
@Override
protected DesignModelAdapter createDesignModel() {
return null;
}
@Override
public UIMenuItem[] createMenuItem4Preview() {
return new UIMenuItem[0];
}
@Override
protected BaseUndoState<?> createUndoState() {
return null;
}
@Override
public String suffix() {
return null;
}
@Override
public ShortCut[] shortcut4TemplateMenu() {
return new ShortCut[0];
}
@Override
public ShortCut[] shortCuts4Authority() {
return new ShortCut[0];
}
@Override
public boolean isJWorkBook() {
return false;
}
@Override
public HyperlinkGroupPane getHyperLinkPane(HyperlinkGroupPaneActionProvider hyperlinkGroupPaneActionProvider) {
return null;
}
@Override
public HyperlinkGroupPane getHyperLinkPaneNoPop(HyperlinkGroupPaneActionProvider hyperlinkGroupPaneActionProvider) {
return null;
}
@Override
public void setAuthorityMode(boolean isUpMode) {
}
@Override
public Icon getIcon() {
return null;
}
@Override
public String route() {
return null;
}
@Override
protected void applyUndoState(BaseUndoState baseUndoState) {
}
}
}

4
designer-base/src/test/java/com/fr/design/formula/FormulaPaneTest.java

@ -16,8 +16,8 @@ public class FormulaPaneTest extends TestCase {
@Test
public void testSimilarComparator() {
String[] strs = new String[] {"ScriptEval", "SPLIT", "SUMPRECISE"};
String[] result = new String[] {"SPLIT", "ScriptEval", "SUMPRECISE"};
String[] strs = new String[]{"ScriptEval", "SPLIT", "SUMPRECISE"};
String[] result = new String[]{"SPLIT", "SUMPRECISE", "ScriptEval"};
Arrays.sort(strs, new FormulaPane.SimilarComparator("sp"));
Assert.assertArrayEquals(result, strs);
}

12
designer-base/src/test/java/com/fr/design/formula/FunctionConstantsTest.java

@ -1,12 +1,16 @@
package com.fr.design.formula;
import com.fr.design.i18n.Toolkit;
import com.fr.general.GeneralUtils;
import com.fr.invoke.Reflect;
import com.fr.log.FineLoggerFactory;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.easymock.PowerMock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@ -19,9 +23,15 @@ import static org.junit.Assert.fail;
* Created by plough on 2018/12/7.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest(GeneralUtils.class)
@PrepareForTest({GeneralUtils.class, Toolkit.class})
public class FunctionConstantsTest {
@Before
public void setUp() {
PowerMockito.mockStatic(Toolkit.class);
PowerMockito.when(Toolkit.i18nText(Mockito.anyString())).thenReturn("test");
}
@Test
public void testNewInstanceFail() throws Exception {
try {

17
designer-base/src/test/java/com/fr/design/gui/icombocheckbox/UICheckListPopupTest.java

@ -1,8 +1,16 @@
package com.fr.design.gui.icombocheckbox;
import com.fr.design.i18n.Toolkit;
import junit.framework.TestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
@ -14,8 +22,17 @@ import java.util.TreeMap;
* @version 10.0
* Created by hades on 2020/4/3
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest(Toolkit.class)
@PowerMockIgnore("javax.swing.*")
public class UICheckListPopupTest extends TestCase {
@Before
public void setUp() {
PowerMockito.mockStatic(Toolkit.class);
PowerMockito.when(Toolkit.i18nText(Mockito.anyString())).thenReturn("test");
}
@Test
public void testGetSelectedValues() {
Object[] values = new Object[]{"a", "b", "c"};

72
designer-base/src/test/java/com/fr/design/jxbrowser/JxUIPaneTest.java

@ -0,0 +1,72 @@
package com.fr.design.jxbrowser;
import com.fr.design.DesignerEnvManager;
import com.teamdev.jxbrowser.js.JsAccessible;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
public class JxUIPaneTest {
public static void main(String... args) {
final JFrame frame = new JFrame();
frame.setSize(1200, 800);
JPanel contentPane = (JPanel) frame.getContentPane();
// 是否需要开启调试窗口
DesignerEnvManager.getEnvManager().setOpenDebug(true);
final JxUIPane<Model> pane = new JxUIPane.Builder<Model>()
.withEMB("/com/fr/design/ui/demo.html").namespace("Pool").build();
contentPane.add(pane, BorderLayout.CENTER);
Model model = new Model();
model.setAge(20);
model.setName("Pick");
pane.populate(model);
JPanel panel = new JPanel(new FlowLayout());
contentPane.add(panel, BorderLayout.SOUTH);
JButton button = new JButton("点击我可以看到Swing的弹框,输出填写的信息");
panel.add(button);
button.addActionListener(e -> {
Model returnValue = pane.update();
if (returnValue != null) {
JOptionPane.showMessageDialog(frame, String.format("姓名为:%s,年龄为:%d", returnValue.getName(), returnValue.getAge()));
}
});
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
@JsAccessible
public static class Model {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void print(String message) {
System.out.println(message);
}
}
}

21
designer-base/src/test/java/com/fr/design/jxbrowser/MimeTypeTest.java

@ -0,0 +1,21 @@
package com.fr.design.jxbrowser;
import org.junit.Assert;
import org.junit.Test;
/**
* @author vito
* @since 11.0
* Created on 2023/6/13
*/
public class MimeTypeTest {
@Test
public void getMimeType() {
Assert.assertEquals("text/html", MimeType.parseMimeType("http://a.html"));
Assert.assertEquals("text/html", MimeType.parseMimeType("http://a.html?a=ji"));
Assert.assertEquals("text/html", MimeType.parseMimeType("http://a.xml?a=ji"));
Assert.assertEquals("image/jpeg", MimeType.parseMimeType("http://a.jpg?a=ji"));
Assert.assertEquals("image/jpeg", MimeType.parseMimeType("http://a.jpeg?a=ji"));
}
}

128
designer-base/src/test/java/com/fr/design/mainfarme/toolbar/ToolBarMenuDockTest.java

@ -1,30 +1,35 @@
package com.fr.design.mainfarme.toolbar;
import java.util.HashMap;
import java.util.Locale;
import com.fr.base.svg.SystemScaleUtils;
import com.fr.design.DesignerEnvManager;
import com.fr.design.actions.community.TechSupportAction;
import com.fr.design.actions.community.VideoAction;
import com.fr.design.actions.help.AboutAction;
import com.fr.design.actions.help.FineUIAction;
import com.fr.design.actions.help.TutorialAction;
import com.fr.design.actions.help.WebDemoAction;
import com.fr.design.actions.help.alphafine.AlphaFineAction;
import com.fr.design.actions.help.alphafine.AlphaFineConfigManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.platform.ServicePlatformAction;
import com.fr.design.mainframe.toolbar.ToolBarMenuDock;
import com.fr.design.menu.SeparatorDef;
import com.fr.design.menu.ShortCut;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.update.actions.SoftwareUpdateAction;
import com.fr.env.detect.ui.EnvDetectorAction;
import com.fr.general.GeneralContext;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import org.easymock.EasyMock;
import org.easymock.Mock;
import org.junit.Assert;
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.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
@ -42,66 +47,99 @@ import org.powermock.reflect.Whitebox;
Locale.class,
WorkContext.class,
DesignerEnvManager.class,
Toolkit.class,
SystemScaleUtils.class,
AlphaFineConfigManager.class})
@PowerMockIgnore({"javax.management.*"})
public class ToolBarMenuDockTest {
@Mock
VideoAction videoAction;
@Mock
TutorialAction tutorialAction;
@Mock
WebDemoAction webDemoAction;
@Mock
SoftwareUpdateAction softwareUpdateAction;
@Mock
AlphaFineAction alphaFineAction;
@Mock
FineUIAction fineUIAction;
@Mock
AboutAction aboutAction;
@Before
public void testCreateHelpShortCutsBefore() {
try {
PowerMock.expectNew(VideoAction.class).andReturn(videoAction).anyTimes();
PowerMock.expectNew(TutorialAction.class).andReturn(tutorialAction).anyTimes();
PowerMock.expectNew(WebDemoAction.class).andReturn(webDemoAction).anyTimes();
PowerMock.expectNew(SoftwareUpdateAction.class).andReturn(softwareUpdateAction).anyTimes();
PowerMock.expectNew(AlphaFineAction.class).andReturn(alphaFineAction).anyTimes();
PowerMock.expectNew(FineUIAction.class).andReturn(fineUIAction).anyTimes();
PowerMock.expectNew(AboutAction.class).andReturn(aboutAction).anyTimes();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
PowerMock.mockStatic(Toolkit.class);
EasyMock.expect(Toolkit.i18nText(EasyMock.anyString())).andReturn("test").anyTimes();
PowerMock.mockStatic(SystemScaleUtils.class);
EasyMock.expect(SystemScaleUtils.sysScale()).andReturn(1F).anyTimes();
EasyMock.expect(SystemScaleUtils.isJreHiDPIEnabled()).andReturn(false).anyTimes();
PowerMock.replay();
}
@Test
public void testCreateHelpShortCuts() {
public void testCreateHelpShortCutsWithLocaleChina() {
// 处理判断条件
GeneralContext context = EasyMock.createMock(GeneralContext.class);
PowerMock.mockStatic(GeneralContext.class);
EasyMock.expect(GeneralContext.getLocale()).andReturn(Locale.CHINA).once();
EasyMock.expect(GeneralContext.getLocale()).andReturn(Locale.US).once();
EasyMock.expect(GeneralContext.getLocale()).andReturn(Locale.CHINA).anyTimes();
Workspace workspace = EasyMock.createMock(Workspace.class);
PowerMock.mockStatic(WorkContext.class);
EasyMock.expect(WorkContext.getCurrent()).andReturn(workspace).anyTimes();
EasyMock.expect(workspace.isLocal()).andReturn(false).once();
EasyMock.expect(workspace.isLocal()).andReturn(true).once();
EasyMock.expect(workspace.isLocal()).andReturn(true).anyTimes();
DesignerEnvManager envManager = EasyMock.createMock(DesignerEnvManager.class);
PowerMock.mockStatic(DesignerEnvManager.class);
EasyMock.expect(DesignerEnvManager.getEnvManager()).andReturn(envManager).anyTimes();
EasyMock.expect(envManager.isOpenDebug()).andReturn(true).anyTimes();
AlphaFineConfigManager configManager = EasyMock.createMock(AlphaFineConfigManager.class);
PowerMock.mockStatic(AlphaFineConfigManager.class);
EasyMock.expect(AlphaFineConfigManager.getInstance()).andReturn(configManager).anyTimes();
EasyMock.expect(configManager.isALPHALicAvailable()).andReturn(true).anyTimes();
EasyMock.expect(configManager.getActionSearchTextCache()).andReturn(new HashMap<>()).anyTimes();
EasyMock.expect(configManager.getCacheBuildNO()).andReturn("").anyTimes();
SupportOSImpl osImpl = EasyMock.createMock(SupportOSImpl.class);
Whitebox.setInternalState(SupportOSImpl.class, "FINEUI", osImpl);
EasyMock.expect(osImpl.support()).andReturn(false).anyTimes();
EasyMock.replay(context, workspace, envManager, configManager, osImpl);
PowerMock.replayAll();
ToolBarMenuDock menuDock = new ToolBarMenuDock() {
@Override
public ShortCut[] createNewFileShortCuts() {
return new ShortCut[0];
}
};
ShortCut[] shortCuts = new ShortCut[] {
new WebDemoAction(),
new SoftwareUpdateAction(),
new AlphaFineAction(),
new EnvDetectorAction(),
new ServicePlatformAction(),
SeparatorDef.DEFAULT,
new AboutAction()};
Assert.assertEquals(menuDock.createHelpShortCuts(), shortCuts);
}
@Test
public void testCreateHelpShortCutsWithLocaleUS() {
// 处理判断条件
GeneralContext context = EasyMock.createMock(GeneralContext.class);
PowerMock.mockStatic(GeneralContext.class);
EasyMock.expect(GeneralContext.getLocale()).andReturn(Locale.US).anyTimes();
EasyMock.expect(envManager.isOpenDebug()).andReturn(false).once();
EasyMock.expect(envManager.isOpenDebug()).andReturn(true).once();
Workspace workspace = EasyMock.createMock(Workspace.class);
PowerMock.mockStatic(WorkContext.class);
EasyMock.expect(WorkContext.getCurrent()).andReturn(workspace).anyTimes();
EasyMock.expect(workspace.isLocal()).andReturn(false).anyTimes();
DesignerEnvManager envManager = EasyMock.createMock(DesignerEnvManager.class);
PowerMock.mockStatic(DesignerEnvManager.class);
EasyMock.expect(DesignerEnvManager.getEnvManager()).andReturn(envManager).anyTimes();
EasyMock.expect(envManager.isOpenDebug()).andReturn(false).anyTimes();
AlphaFineConfigManager configManager = EasyMock.createMock(AlphaFineConfigManager.class);
PowerMock.mockStatic(AlphaFineConfigManager.class);
EasyMock.expect(AlphaFineConfigManager.isALPHALicAvailable()).andReturn(false).once();
EasyMock.expect(AlphaFineConfigManager.isALPHALicAvailable()).andReturn(true).once();
EasyMock.expect(configManager.isALPHALicAvailable()).andReturn(false).anyTimes();
EasyMock.expect(configManager.getActionSearchTextCache()).andReturn(new HashMap<>()).anyTimes();
EasyMock.expect(configManager.getCacheBuildNO()).andReturn("").anyTimes();
EasyMock.expect(AlphaFineConfigManager.getInstance()).andReturn(configManager).anyTimes();
SupportOSImpl osImpl = EasyMock.createMock(SupportOSImpl.class);
Whitebox.setInternalState(SupportOSImpl.class, "FINEUI", osImpl);
@ -118,12 +156,14 @@ public class ToolBarMenuDockTest {
}
};
ShortCut[] shortCuts1 = new ShortCut[] {SeparatorDef.DEFAULT, aboutAction};
ShortCut[] shortCuts2 = new ShortCut[] {videoAction, tutorialAction, webDemoAction,
softwareUpdateAction, alphaFineAction, SeparatorDef.DEFAULT, aboutAction};
Assert.assertEquals(menuDock.createHelpShortCuts(), shortCuts1);
Assert.assertEquals(menuDock.createHelpShortCuts(), shortCuts2);
ShortCut[] shortCuts = new ShortCut[] {
new VideoAction(),
new TutorialAction(),
new TechSupportAction(),
new EnvDetectorAction(),
SeparatorDef.DEFAULT,
new AboutAction()};
Assert.assertEquals(menuDock.createHelpShortCuts(), shortCuts);
}
}

19
designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java

@ -1,7 +1,16 @@
package com.fr.design.mainframe.loghandler;
import com.fr.design.i18n.Toolkit;
import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.junit.Assert;
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.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.junit.Assert.*;
@ -10,8 +19,18 @@ import static org.junit.Assert.*;
* @version 10.0
* Created by vito on 2022/1/25
*/
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.swing.*"})
@PrepareForTest(Toolkit.class)
public class DesignerLogHandlerTest {
@Before
public void setUp() {
PowerMock.mockStatic(Toolkit.class);
EasyMock.expect(Toolkit.i18nText(EasyMock.anyString())).andReturn("test").anyTimes();
PowerMock.replayAll();
}
@Test
public void findTplLink() {
Assert.assertArrayEquals(

2
designer-base/src/test/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfoTest.java

@ -37,7 +37,7 @@ public class ComponentReuseNotificationInfoTest {
writer.flush();
writer.close();
Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<ComponentReuseNotificationInfo xmlVersion=\"20170720\" releaseVersion=\"\" clickedWidgetLib=\"false\" hasCompleteEmbedFilter=\"false\" firstDrag=\"true\" widgetLibHasRefreshed=\"false\" firstDragEndTime=\"0\" historyCreatedReuses=\"[]\"/>\n", sw.toString());
"<ComponentReuseNotificationInfo xmlVersion=\"20211223\" releaseVersion=\"\" clickedWidgetLib=\"false\" completeEmbedFilter=\"false\" completeFirstShowComponentLib=\"false\" firstDrag=\"true\" widgetLibHasRefreshed=\"false\" firstDragEndTime=\"0\" historyCreatedReuses=\"[]\"/>\n", sw.toString());
}
}

3
designer-base/src/test/java/com/fr/design/ui/FineUIDemo.java

@ -1,6 +1,7 @@
package com.fr.design.ui;
import com.fr.design.DesignerEnvManager;
import com.fr.design.jxbrowser.JxUIPane;
import javax.swing.*;
import java.awt.*;
@ -19,7 +20,7 @@ public class FineUIDemo {
// 是否需要开启调试窗口
DesignerEnvManager.getEnvManager().setOpenDebug(true);
final ModernUIPane<ModernUIPaneTest.Model> pane = new ModernUIPane.Builder<ModernUIPaneTest.Model>()
final JxUIPane<ModernUIPaneTest.Model> pane = new JxUIPane.Builder<ModernUIPaneTest.Model>()
.withComponent(StartComponent.KEY).build();
contentPane.add(pane, BorderLayout.CENTER);
frame.setVisible(true);

10
designer-base/src/test/java/com/fr/design/ui/report/TemplateWebSettingDemo.java

@ -1,11 +1,13 @@
package com.fr.design.ui.report;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.ui.ModernUIPaneTest;
import javax.swing.*;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
/**
* Created by windy on 2019/3/26.
@ -19,7 +21,7 @@ public class TemplateWebSettingDemo {
// 是否需要开启调试窗口
DesignerEnvManager.getEnvManager().setOpenDebug(true);
final ModernUIPane<ModernUIPaneTest.Model> pane = new ModernUIPane.Builder<ModernUIPaneTest.Model>()
final JxUIPane<ModernUIPaneTest.Model> pane = new JxUIPane.Builder<ModernUIPaneTest.Model>()
.withComponent(TemplateWebSettingComponent.KEY).build();
contentPane.add(pane, BorderLayout.CENTER);
frame.setVisible(true);

21
designer-base/src/test/java/com/fr/file/FILEChooserPaneTest.java

@ -1,20 +1,33 @@
package com.fr.file;
import com.fr.base.extension.FileExtension;
import com.fr.design.i18n.Toolkit;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.invoke.Reflect;
import com.fr.stable.StringUtils;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by kerry on 2019-10-15
*/
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.swing.*"})
@PrepareForTest({Toolkit.class, FileNodeFILE.class})
public class FILEChooserPaneTest {
@Test
public void testAddChooseFileFilter() {
FILEChooserPane chooserPane = Reflect.on(FILEChooserPane.class).field("INSTANCE").get();
PowerMock.mockStatic(Toolkit.class);
EasyMock.expect(Toolkit.i18nText(EasyMock.anyString())).andReturn("test").anyTimes();
PowerMock.replayAll();
FILEChooserPane chooserPane = EasyMock.mock(FILEChooserPane.class);
Reflect.on(chooserPane).set("suffix", ".cpt");
String result1 = Reflect.on(chooserPane).call("calProperFileName", "WorkBook1.cpt", null).get();
Assert.assertEquals("WorkBook1.cpt", result1);
@ -25,11 +38,11 @@ public class FILEChooserPaneTest {
ChooseFileFilter chooseFileFilter2 = new ChooseFileFilter(FileExtension.CPTX, StringUtils.EMPTY);
String result3 = Reflect.on(chooserPane).call("calProperFileName", "WorkBook1.cpt", chooseFileFilter2).get();
Assert.assertEquals("WorkBook1.cpt.cptx", result3);
Assert.assertEquals("WorkBook1.cptx", result3);
ChooseFileFilter chooseFileFilter3 = new ChooseFileFilter(FileExtension.CPT, StringUtils.EMPTY);
String result4 = Reflect.on(chooserPane).call("calProperFileName", "WorkBook1.cptx", chooseFileFilter3).get();
Assert.assertEquals("WorkBook1.cptx.cpt", result4);
Assert.assertEquals("WorkBook1.cpt", result4);
ChooseFileFilter chooseFileFilter5 = new ChooseFileFilter(FileExtension.CPTX, StringUtils.EMPTY);
String result5 = Reflect.on(chooserPane).call("calProperFileName", "WorkBook1.cptx", chooseFileFilter5).get();

4
designer-chart/src/main/java/com/fr/van/chart/box/VanChartBoxRichTextDetailedFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.box;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipCategoryFormat;
import com.fr.plugin.chart.base.format.AttrTooltipDataMaxFormat;
@ -33,7 +33,7 @@ public class VanChartBoxRichTextDetailedFieldListPane extends VanChartFieldListP
private VanChartFieldButton richTextMin;
private VanChartFieldButton richTextOutlier;
public VanChartBoxRichTextDetailedFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartBoxRichTextDetailedFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

4
designer-chart/src/main/java/com/fr/van/chart/box/VanChartBoxRichTextResultFieldListPane.java

@ -1,6 +1,6 @@
package com.fr.van.chart.box;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.van.chart.designer.component.richText.VanChartFieldAttrPane;
import com.fr.van.chart.designer.component.richText.VanChartFieldButton;
import com.fr.van.chart.designer.component.richText.VanChartRichEditorModel;
@ -11,7 +11,7 @@ import java.util.List;
public class VanChartBoxRichTextResultFieldListPane extends VanChartBoxRichTextDetailedFieldListPane {
public VanChartBoxRichTextResultFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartBoxRichTextResultFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/box/VanChartBoxTooltipContentPane.java

@ -2,9 +2,9 @@ package com.fr.van.chart.box;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.ui.ModernUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipCategoryFormat;
import com.fr.plugin.chart.base.format.AttrTooltipDataMaxFormat;
@ -103,11 +103,11 @@ public class VanChartBoxTooltipContentPane extends VanChartTooltipContentPane {
return commonPanel;
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
if (detailed) {
return new VanChartBoxRichTextDetailedFieldListPane(fieldAttrPane, richEditor);
}

6
designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartTooltipContentPane.java

@ -7,11 +7,11 @@ import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPane;
import com.fr.design.ui.ModernUIPane;
import com.fr.general.ComparatorUtils;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.AttrTooltipRichText;
@ -390,7 +390,7 @@ public class VanChartTooltipContentPane extends BasicBeanPane<AttrTooltipContent
private void fireRichEditor() {
AttrTooltipRichText richText = this.richTextTooltipContent.getRichTextAttr();
refreshTableFieldParams(richText.getParams());
ModernUIPane<VanChartRichEditorModel> richEditorPane = VanChartRichEditorPane.createRichEditorPane(richText);
JxUIPane<VanChartRichEditorModel> richEditorPane = VanChartRichEditorPane.createRichEditorPane(richText);
VanChartRichTextPane richTextPane = this.createRichTextPane(richEditorPane);
BasicDialog richTextDialog = new VanChartRichTextDialog(DesignerContext.getDesignerFrame(), richTextPane);
@ -431,7 +431,7 @@ public class VanChartTooltipContentPane extends BasicBeanPane<AttrTooltipContent
}
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartFieldListPane.java

@ -4,7 +4,7 @@ import com.fr.data.util.function.AbstractDataFunction;
import com.fr.data.util.function.DataFunction;
import com.fr.design.event.UIObserverListener;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.chart.base.AttrTooltipContent;
@ -43,14 +43,14 @@ public class VanChartFieldListPane extends JPanel {
private VanChartFieldButton percentButton;
private VanChartFieldAttrPane fieldAttrPane;
private ModernUIPane<VanChartRichEditorModel> richEditorPane;
private JxUIPane<VanChartRichEditorModel> richEditorPane;
private List<String> tableFieldNameList;
private List<VanChartFieldButton> tableFieldButtonList = new ArrayList<>();
private TableFieldCollection tableFieldCollection = new TableFieldCollection();
private VanChartFieldListener fieldListener;
public VanChartFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
List<String> richEditorFieldNames = VanChartRichEditorPane.getFieldNames();

2
designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichEditorModel.java

@ -2,7 +2,9 @@ package com.fr.van.chart.designer.component.richText;
import com.fr.plugin.chart.type.TextAlign;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.js.JsAccessible;
@JsAccessible
public class VanChartRichEditorModel {
private String content = StringUtils.EMPTY;

97
designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichEditorPane.java

@ -11,7 +11,7 @@ import com.fr.data.impl.NameTableData;
import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignerEnvManager;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.plugin.chart.base.AttrTooltipRichText;
@ -21,11 +21,9 @@ import com.fr.plugin.chart.type.TextAlign;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.lang3.SystemUtils;
import com.fr.van.chart.designer.PlotFactory;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserType;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.frame.Frame;
import com.teamdev.jxbrowser.js.JsObject;
import java.util.ArrayList;
import java.util.Arrays;
@ -45,8 +43,8 @@ public class VanChartRichEditorPane {
private static final String REFRESH = "refresh()";
private static final String ADD_FIELD = "addField()";
private static ModernUIPane<VanChartRichEditorModel> richEditorPane;
private static Browser browser;
private static JxUIPane<VanChartRichEditorModel> richEditorPane;
private static Frame frame;
private static List<String> fieldNames;
private static final boolean USE_LIGHT_WEIGHT = SystemUtils.IS_OS_WINDOWS_10;
@ -123,12 +121,24 @@ public class VanChartRichEditorPane {
fieldNames.addAll(Arrays.asList(columnNames));
}
public static ModernUIPane<VanChartRichEditorModel> createRichEditorPane(AttrTooltipRichText richEditor) {
/**
* 创建富文本编辑器
*
* @param richEditor 属性
* @return 富文本编辑器
*/
public static JxUIPane<VanChartRichEditorModel> createRichEditorPane(AttrTooltipRichText richEditor) {
VanChartRichEditorModel model = getRichEditorModel(richEditor);
return createRichEditorPane(model);
}
public static ModernUIPane<VanChartRichEditorModel> createRichEditorPane(VanChartRichEditorModel model) {
/**
* 创建富文本编辑器
*
* @param model 模型
* @return 富文本编辑器
*/
public static JxUIPane<VanChartRichEditorModel> createRichEditorPane(VanChartRichEditorModel model) {
if (richEditorPane == null) {
richEditorPane = initPane(model);
} else {
@ -139,50 +149,57 @@ public class VanChartRichEditorPane {
}
public static void richEditorRefresh(VanChartRichEditorModel model) {
if (richEditorPane != null && browser != null) {
refresh(browser, model);
if (richEditorPane != null && frame != null) {
refresh(frame, model);
}
}
public static void richEditorAddField(VanChartRichEditorModel model) {
if (richEditorPane != null && browser != null) {
addField(browser, model);
if (richEditorPane != null && frame != null) {
addField(frame, model);
}
}
public static ModernUIPane<VanChartRichEditorModel> initPane(VanChartRichEditorModel model) {
BrowserType type = USE_LIGHT_WEIGHT ? BrowserType.LIGHTWEIGHT : BrowserType.HEAVYWEIGHT;
return new ModernUIPane.Builder<VanChartRichEditorModel>(type)
.prepare(new ScriptContextAdapter() {
public void onScriptContextCreated(ScriptContextEvent event) {
browser = event.getBrowser();
browser.getCacheStorage().clearCache();
browser.executeJavaScript(IOUtils.readResourceAsString("/com/fr/web/ui/fineui.min.js"));
browser.executeJavaScript(IOUtils.readResourceAsString("/com/fr/design/editor/script/i18n.js"));
browser.executeJavaScript(generateTransformI18nJS());
browser.executeJavaScript(IOUtils.readResourceAsString("/com/fr/web/ui/materials.min.js"));
JSValue ns = browser.executeJavaScriptAndReturnValue("window." + NAME_SPACE);
ns.asObject().setProperty(VARIABLE, model);
/**
* 初始化富文本编辑器
*
* @param model 模型
* @return pane
*/
public static JxUIPane<VanChartRichEditorModel> initPane(VanChartRichEditorModel model) {
return new JxUIPane.Builder<VanChartRichEditorModel>()
.prepare(params -> {
frame = params.frame();
frame.browser().engine().httpCache().clear();
frame.executeJavaScript(IOUtils.readResourceAsString("/com/fr/web/ui/fineui.min.js"));
frame.executeJavaScript(IOUtils.readResourceAsString("/com/fr/design/editor/script/i18n.js"));
frame.executeJavaScript(generateTransformI18nJS());
frame.executeJavaScript(IOUtils.readResourceAsString("/com/fr/web/ui/materials.min.js"));
JsObject ns = frame.executeJavaScript("window." + NAME_SPACE);
if (ns != null) {
ns.putProperty(VARIABLE, model);
}
return InjectJsCallback.Response.proceed();
})
.withEMB(RICH_EDITOR_HTML)
.namespace(NAME_SPACE).build();
}
public static void refresh(Browser browser, VanChartRichEditorModel model) {
stateChange(browser, model, REFRESH);
private static void refresh(Frame frame, VanChartRichEditorModel model) {
stateChange(frame, model, REFRESH);
}
public static void addField(Browser browser, VanChartRichEditorModel model) {
stateChange(browser, model, ADD_FIELD);
private static void addField(Frame frame, VanChartRichEditorModel model) {
stateChange(frame, model, ADD_FIELD);
}
public static void stateChange(Browser browser, VanChartRichEditorModel model, String trigger) {
JSValue ns = browser.executeJavaScriptAndReturnValue("window." + NAME_SPACE);
ns.asObject().setProperty(VARIABLE, model);
browser.executeJavaScript("window." + NAME_SPACE + "." + trigger);
private static void stateChange(Frame frame, VanChartRichEditorModel model, String trigger) {
JsObject ns = frame.executeJavaScript("window." + NAME_SPACE);
if (ns != null) {
ns.putProperty(VARIABLE, model);
frame.executeJavaScript("window." + NAME_SPACE + "." + trigger);
}
}
public static VanChartRichEditorModel getRichEditorModel(AttrTooltipRichText richText) {
@ -231,9 +248,7 @@ public class VanChartRichEditorPane {
}
public static void checkDispose() {
if (USE_LIGHT_WEIGHT) {
browser.dispose();
richEditorPane = null;
}
frame.browser().close();
richEditorPane = null;
}
}

6
designer-chart/src/main/java/com/fr/van/chart/designer/component/richText/VanChartRichTextPane.java

@ -2,8 +2,8 @@ package com.fr.van.chart.designer.component.richText;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.ui.ModernUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.stable.StringUtils;
@ -25,7 +25,7 @@ public class VanChartRichTextPane extends BasicBeanPane<AttrTooltipContent> {
private VanChartFieldListPane fieldListPane;
private VanChartFieldAttrPane fieldAttrPane;
public VanChartRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditor) {
public VanChartRichTextPane(JxUIPane<VanChartRichEditorModel> richEditor) {
fieldAttrPane = new VanChartFieldAttrPane();
fieldListPane = createFieldListPane(fieldAttrPane, richEditor);
@ -63,7 +63,7 @@ public class VanChartRichTextPane extends BasicBeanPane<AttrTooltipContent> {
return fieldPane;
}
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartFieldListPane(fieldAttrPane, richEditor);
}

6
designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/TooltipContentPaneWithOutSeries.java

@ -1,7 +1,7 @@
package com.fr.van.chart.designer.component.tooltip;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipCategoryFormat;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
@ -63,11 +63,11 @@ public class TooltipContentPaneWithOutSeries extends VanChartTooltipContentPane
};
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartFieldListPaneWithOutSeries(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/designer/component/tooltip/VanChartFieldListPaneWithOutSeries.java

@ -1,7 +1,7 @@
package com.fr.van.chart.designer.component.tooltip;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipTargetValueFormat;
import com.fr.plugin.chart.base.format.AttrTooltipValueFormat;
@ -20,7 +20,7 @@ public class VanChartFieldListPaneWithOutSeries extends VanChartFieldListPane {
private VanChartFieldButton targetValueButton;
public VanChartFieldListPaneWithOutSeries(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartFieldListPaneWithOutSeries(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/funnel/designer/style/VanChartFunnelLabelContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.funnel.designer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
import com.fr.plugin.chart.base.format.AttrTooltipNameFormat;
@ -49,11 +49,11 @@ public class VanChartFunnelLabelContentPane extends VanChartLabelContentPane {
setPercentFormatPane(new FunnelPercentFormatPaneWithCheckBox(parent, showOnPane));
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartFunnelRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/funnel/designer/style/VanChartFunnelRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.funnel.designer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.format.AttrTooltipCategoryFormat;
import com.fr.plugin.chart.base.format.AttrTooltipNameFormat;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
@ -18,7 +18,7 @@ import java.util.List;
public class VanChartFunnelRichTextFieldListPane extends VanChartFieldListPane {
public VanChartFunnelRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartFunnelRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/funnel/designer/style/VanChartFunnelTooltipContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.funnel.designer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
import com.fr.plugin.chart.base.format.AttrTooltipNameFormat;
@ -48,11 +48,11 @@ public class VanChartFunnelTooltipContentPane extends VanChartTooltipContentPane
setPercentFormatPane(new FunnelPercentFormatPaneWithCheckBox(parent, showOnPane));
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartFunnelRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/tooltip/VanChartGanttRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.gantt.designer.style.tooltip;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipDurationFormat;
import com.fr.plugin.chart.base.format.AttrTooltipEndTimeFormat;
@ -28,7 +28,7 @@ public class VanChartGanttRichTextFieldListPane extends VanChartFieldListPane {
private VanChartFieldButton richTextDurationFormatPane;
private VanChartFieldButton richTextProgressFormatPane;
public VanChartGanttRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartGanttRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/tooltip/VanChartGanttTooltipContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.gantt.designer.style.tooltip;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipDurationFormat;
import com.fr.plugin.chart.base.format.AttrTooltipEndTimeFormat;
@ -66,11 +66,11 @@ public class VanChartGanttTooltipContentPane extends VanChartTooltipContentPane
};
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartGanttRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/map/designer/style/VanChartMapRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.map.designer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.format.AttrTooltipAreaNameFormat;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
import com.fr.plugin.chart.base.format.AttrTooltipSeriesFormat;
@ -14,7 +14,7 @@ import com.fr.van.chart.designer.component.richText.VanChartRichEditorModel;
public class VanChartMapRichTextFieldListPane extends VanChartFieldListPane {
public VanChartMapRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartMapRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/map/designer/style/label/VanChartMapLabelContentPane.java

@ -3,8 +3,8 @@ package com.fr.van.chart.map.designer.style.label;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.layout.TableLayout;
import com.fr.design.ui.ModernUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipAreaNameFormat;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
@ -50,11 +50,11 @@ public class VanChartMapLabelContentPane extends VanChartLabelContentPane {
setPercentFormatPane(new PercentFormatPaneWithCheckBox(parent, showOnPane));
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartMapRichTextFieldListPane(fieldAttrPane, richEditor);
}

6
designer-chart/src/main/java/com/fr/van/chart/map/designer/style/tooltip/VanChartMapTooltipContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.map.designer.style.tooltip;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipAreaNameFormat;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
@ -39,11 +39,11 @@ public class VanChartMapTooltipContentPane extends VanChartTooltipContentPane {
setPercentFormatPane(new PercentFormatPaneWithCheckBox(parent, showOnPane));
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartMapRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/map/line/VanChartLineMapRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.map.line;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
import com.fr.plugin.chart.base.format.AttrTooltipSeriesFormat;
import com.fr.plugin.chart.base.format.AttrTooltipStartAndEndNameFormat;
@ -14,7 +14,7 @@ import com.fr.van.chart.designer.component.richText.VanChartRichEditorModel;
public class VanChartLineMapRichTextFieldListPane extends VanChartFieldListPane {
public VanChartLineMapRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartLineMapRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/map/line/VanChartLineMapTooltipContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.map.line;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
@ -36,11 +36,11 @@ public class VanChartLineMapTooltipContentPane extends VanChartTooltipContentPan
setPercentFormatPane(new PercentFormatPaneWithCheckBox(parent, showOnPane));
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartLineMapRichTextFieldListPane(fieldAttrPane, richEditor);
}

6
designer-chart/src/main/java/com/fr/van/chart/multilayer/style/VanChartMultiPieLabelContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.multilayer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
@ -36,10 +36,10 @@ public class VanChartMultiPieLabelContentPane extends VanChartLabelContentPane {
setPercentFormatPane(new PercentFormatPaneWithCheckBox(parent, showOnPane));
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartMultiPieRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/multilayer/style/VanChartMultiPieRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.multilayer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
import com.fr.plugin.chart.base.format.AttrTooltipSeriesFormat;
import com.fr.plugin.chart.base.format.AttrTooltipValueFormat;
@ -14,7 +14,7 @@ import com.fr.van.chart.designer.component.richText.VanChartRichEditorModel;
public class VanChartMultiPieRichTextFieldListPane extends VanChartFieldListPane {
public VanChartMultiPieRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartMultiPieRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/multilayer/style/VanChartMultiPieTooltipContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.multilayer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
@ -35,10 +35,10 @@ public class VanChartMultiPieTooltipContentPane extends VanChartTooltipContentPa
setPercentFormatPane(new PercentFormatPaneWithCheckBox(parent, showOnPane));
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartMultiPieRichTextFieldListPane(fieldAttrPane, richEditor);
}

6
designer-chart/src/main/java/com/fr/van/chart/pie/style/VanChartPieCategoryLabelContentPane.java

@ -1,8 +1,8 @@
package com.fr.van.chart.pie.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPaneWithAuto;
import com.fr.design.ui.ModernUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipCategoryFormat;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
@ -45,11 +45,11 @@ public class VanChartPieCategoryLabelContentPane extends VanChartLabelContentPan
summaryValueFormatPane = new SummaryValueFormatPaneWithCheckBox(parent, showOnPane);
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartPieCategoryRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/pie/style/VanChartPieCategoryRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.pie.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipSummaryValueFormat;
import com.fr.plugin.chart.pie.attr.PieCategoryLabelContent;
@ -19,7 +19,7 @@ public class VanChartPieCategoryRichTextFieldListPane extends VanChartFieldListP
private VanChartFieldButton summaryValueButton;
public VanChartPieCategoryRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartPieCategoryRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/pie/style/VanChartPieValueLabelContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.pie.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
@ -43,11 +43,11 @@ public class VanChartPieValueLabelContentPane extends VanChartLabelContentPane {
setPercentFormatPane(new PercentFormatPaneWithCheckBox(parent, showOnPane));
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartPieValueRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/pie/style/VanChartPieValueRichTextFieldListPane.java

@ -1,6 +1,6 @@
package com.fr.van.chart.pie.style;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.van.chart.designer.component.richText.VanChartFieldAttrPane;
import com.fr.van.chart.designer.component.richText.VanChartFieldButton;
import com.fr.van.chart.designer.component.richText.VanChartFieldListPane;
@ -12,7 +12,7 @@ import java.util.List;
public class VanChartPieValueRichTextFieldListPane extends VanChartFieldListPane {
public VanChartPieValueRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartPieValueRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

4
designer-chart/src/main/java/com/fr/van/chart/scatter/VanChartScatterRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.scatter;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipSizeFormat;
import com.fr.plugin.chart.base.format.AttrTooltipXFormat;
@ -23,7 +23,7 @@ public class VanChartScatterRichTextFieldListPane extends VanChartFieldListPane
private VanChartFieldButton richTextYFormatPane;
private VanChartFieldButton richTextSizeFormatPane;
public VanChartScatterRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartScatterRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/scatter/VanChartScatterTooltipContentPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.scatter;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
import com.fr.plugin.chart.base.format.AttrTooltipSeriesFormat;
@ -60,11 +60,11 @@ public class VanChartScatterTooltipContentPane extends VanChartTooltipContentPa
sizeFormatPane = new ValueFormatPaneWithCheckBox(parent, showOnPane);
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartScatterRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/structure/desinger/style/VanChartStructureRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.structure.desinger.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
import com.fr.plugin.chart.base.format.AttrTooltipSeriesFormat;
import com.fr.plugin.chart.base.format.AttrTooltipValueFormat;
@ -18,7 +18,7 @@ import java.util.List;
public class VanChartStructureRichTextFieldListPane extends VanChartFieldListPane {
public VanChartStructureRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartStructureRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/structure/desinger/style/VanChartStructureTooltipContentPane.java

@ -2,7 +2,7 @@ package com.fr.van.chart.structure.desinger.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
import com.fr.plugin.chart.base.format.AttrTooltipSeriesFormat;
@ -62,11 +62,11 @@ public class VanChartStructureTooltipContentPane extends VanChartTooltipContentP
setPercentFormatPane(percentFormatPane);
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartStructureRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/java/com/fr/van/chart/wordcloud/designer/style/VanChartWordCloudRichTextFieldListPane.java

@ -1,7 +1,7 @@
package com.fr.van.chart.wordcloud.designer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.format.AttrTooltipCategoryFormat;
import com.fr.plugin.chart.base.format.AttrTooltipNameFormat;
import com.fr.plugin.chart.base.format.AttrTooltipPercentFormat;
@ -14,7 +14,7 @@ import com.fr.van.chart.designer.component.richText.VanChartRichEditorModel;
public class VanChartWordCloudRichTextFieldListPane extends VanChartFieldListPane {
public VanChartWordCloudRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditorPane) {
public VanChartWordCloudRichTextFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditorPane) {
super(fieldAttrPane, richEditorPane);
}

6
designer-chart/src/main/java/com/fr/van/chart/wordcloud/designer/style/VanChartWordCloudTooltipContentPane.java

@ -2,7 +2,7 @@ package com.fr.van.chart.wordcloud.designer.style;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.plugin.chart.base.AttrTooltipContent;
import com.fr.plugin.chart.base.format.AttrTooltipCategoryFormat;
import com.fr.plugin.chart.base.format.AttrTooltipFormat;
@ -58,10 +58,10 @@ public class VanChartWordCloudTooltipContentPane extends VanChartTooltipContentP
setPercentFormatPane(percentFormatPane);
}
protected VanChartRichTextPane createRichTextPane(ModernUIPane<VanChartRichEditorModel> richEditorPane) {
protected VanChartRichTextPane createRichTextPane(JxUIPane<VanChartRichEditorModel> richEditorPane) {
return new VanChartRichTextPane(richEditorPane) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, ModernUIPane<VanChartRichEditorModel> richEditor) {
protected VanChartFieldListPane createFieldListPane(VanChartFieldAttrPane fieldAttrPane, JxUIPane<VanChartRichEditorModel> richEditor) {
return new VanChartWordCloudRichTextFieldListPane(fieldAttrPane, richEditor);
}

4
designer-chart/src/main/resources/com/fr/design/editor/rich_editor.html

@ -3,8 +3,8 @@
<head>
<meta charset="utf-8"/>
<title></title>
<link rel="stylesheet" type="text/css" href="emb:/com/fr/web/ui/fineui.min.css"/>
<link rel="stylesheet" type="text/css" href="emb:/com/fr/web/ui/materials.min.css"/>
<link rel="stylesheet" type="text/css" href="emb://com/fr/web/ui/fineui.min.css"/>
<link rel="stylesheet" type="text/css" href="emb://com/fr/web/ui/materials.min.css"/>
</head>
<body>
<script src="script/enums.js"></script>

35
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopPane.java

@ -1,19 +1,12 @@
package com.fr.design.mainframe.share.ui.online.mini;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.mainframe.share.ui.online.mini.bridge.ComposedNativeBridges;
import com.fr.design.mainframe.share.util.OnlineShopUtils;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.ui.compatible.ModernUIPaneFactory;
import com.fr.design.upm.event.CertificateEvent;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import com.teamdev.jxbrowser.js.JsObject;
import org.jetbrains.annotations.Nullable;
import javax.swing.JPanel;
import java.awt.BorderLayout;
@ -24,34 +17,16 @@ import java.awt.BorderLayout;
* Created by Starryi on 2021/12/20
*/
public class MiniComponentShopPane extends JPanel {
private final ModernUIPane<Object> modernUIPane;
private static final String SHOP_HELPER = "ShopHelper";
private final JxUIPane<Object> modernUIPane;
private final Listener<String> loginListener;
private final Listener<String> logoutListener;
public MiniComponentShopPane() {
setLayout(new BorderLayout());
modernUIPane = ModernUIPaneFactory.modernUIPaneBuilder()
modernUIPane = new JxUIPane.Builder<>()
.withURL(OnlineShopUtils.getWebMiniShopPath())
.prepareForV6(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
super.onScriptContextCreated(event);
JSObject window = event.getBrowser().executeJavaScriptAndReturnValue("window").asObject();
window.setProperty("ShopHelper", new ComposedNativeBridges(window));
}
})
.prepareForV7(new InjectJsCallback() {
@Nullable
@Override
public Response on(Params params) {
// 7.x
JsObject window = params.frame().executeJavaScript("window");
if (window != null) {
window.putProperty("ShopHelper", new ComposedNativeBridges(window));
}
return InjectJsCallback.Response.proceed();
}
})
.bindWindow(SHOP_HELPER, ComposedNativeBridges::new)
.build();
add(modernUIPane, BorderLayout.CENTER);

18
designer-form/src/test/java/com/fr/design/mainframe/template/info/ComponentCreateOperateTest.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe.template.info;
import com.fr.design.i18n.Toolkit;
import com.fr.form.ui.CardAddButton;
import com.fr.form.ui.CardSwitchButton;
import com.fr.form.ui.ChartEditor;
@ -16,16 +17,33 @@ import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout;
import com.fr.form.ui.widget.CRBoundsWidget;
import com.fr.general.ComparatorUtils;
import com.fr.json.JSONObject;
import org.easymock.EasyMock;
import org.junit.Assert;
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.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.awt.Rectangle;
/**
* Created by kerry on 2020-05-08
*/
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.swing.*"})
@PrepareForTest(Toolkit.class)
public class ComponentCreateOperateTest {
@Before
public void setUp() {
PowerMock.mockStatic(Toolkit.class);
EasyMock.expect(Toolkit.i18nText(EasyMock.anyString())).andReturn("test").anyTimes();
PowerMock.replayAll();
}
@Test
public void testConstructor() {
ElementCaseEditor caseEditor = new ElementCaseEditor();

4
designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java

@ -222,14 +222,18 @@ public class HeaderSortRulePane extends JPanel {
for (SortHeader.SortItem sortItem : sortItems) {
SortRule sortRule = sortItem.getSortRule();
BufferedImage bufferedImage = sortItem.getBufferedImage();
FineColor fineColor = sortItem.getFineColor();
if (sortRule == SortRule.ASC) {
ascIconButton.refreshIconLabel(bufferedImage);
ascIconButton.refreshIconLabelColor(fineColor);
ascUICheckBox.setSelected(true);
} else if (sortRule == SortRule.DES) {
desIconButton.refreshIconLabel(bufferedImage);
desIconButton.refreshIconLabelColor(fineColor);
desUICheckBox.setSelected(true);
} else if (sortRule == SortRule.NO_SORT) {
nosortIconButton.refreshIconLabel(bufferedImage);
nosortIconButton.refreshIconLabelColor(fineColor);
nosortUICheckBox.setSelected(true);
}
}

6
designer-realize/src/main/java/com/fr/quickeditor/CellQuickEditor.java

@ -446,12 +446,14 @@ public abstract class CellQuickEditor extends QuickEditor<ElementCasePane> {
Style oldStyle = cellElement == null ? Style.DEFAULT_STYLE : cellElement.getStyle();
Style style = formatPane.update(oldStyle);
for (TemplateCellElement cellElement : allCellElements) {
Format elementFormat = cellElement.getStyle().getFormat();
Style cellElementStyle = cellElement.getStyle();
Format elementFormat = cellElementStyle.getFormat();
Format paneFormat = style.getFormat();
if (!Objects.equals(paneFormat, elementFormat)) {
// 点击单元格,但未设置格式时,不将单元格设置为编辑状态,防止将所选的每个单元格都设置为编辑状态
editingElementCase.addCellElement(cellElement);
cellElement.setStyle(style);
Style newStyle = cellElementStyle.deriveFormat(paneFormat);
cellElement.setStyle(newStyle);
updateStyle = true;
}
}

6
designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellStringQuickEditor.java

@ -37,17 +37,17 @@ public class CellStringQuickEditor extends CellQuickEditor {
private DocumentListener documentListener = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
changeReportPaneCell(stringTextArea.getText().trim());
changeReportPaneCell(stringTextArea.getText());
}
@Override
public void removeUpdate(DocumentEvent e) {
changeReportPaneCell(stringTextArea.getText().trim());
changeReportPaneCell(stringTextArea.getText());
}
@Override
public void changedUpdate(DocumentEvent e) {
changeReportPaneCell(stringTextArea.getText().trim());
changeReportPaneCell(stringTextArea.getText());
}
};

18
designer-realize/src/test/java/com.fr/design/mainframe/alphafine/cell/model/ModelTest.java

@ -1,13 +1,31 @@
package com.fr.design.mainframe.alphafine.cell.model;
import com.fr.design.actions.help.alphafine.AlphaFineCloudConstants;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.alphafine.CellType;
import com.fr.json.JSONException;
import com.fr.json.JSONObject;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Toolkit.class)
@PowerMockIgnore("javax.swing.*")
public class ModelTest {
@Before
public void setUp() {
PowerMockito.mockStatic(Toolkit.class);
PowerMockito.when(Toolkit.i18nText(Mockito.anyString())).thenReturn("test");
}
@Test
public void documentModelTest() {
DocumentModel documentModel = new DocumentModel("name", "content", 1);

17
designer-realize/src/test/java/com.fr/design/mainframe/alphafine/search/manager/impl/FileSearchManagerTest.java

@ -1,7 +1,5 @@
package com.fr.design.mainframe.alphafine.search.manager.impl;
import com.fr.base.FRContext;
import com.fr.base.extension.FileExtension;
import com.fr.design.DesignerEnvManager;
import com.fr.design.actions.help.alphafine.AlphaFineConfigManager;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
@ -9,9 +7,6 @@ import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel;
import com.fr.design.mainframe.alphafine.model.SearchResult;
import com.fr.file.filetree.FileNode;
import com.fr.invoke.Reflect;
import com.fr.stable.project.ProjectConstants;
import com.fr.web.core.SessionPoolManager;
import com.fr.web.utils.WebUtils;
import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -23,7 +18,7 @@ import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
/**
* @author Yyming
@ -43,8 +38,8 @@ public class FileSearchManagerTest {
FileNode fileNode2 = EasyMock.createMock(FileNode.class);
EasyMock.expect(fileNode1.getName()).andReturn("workbook").anyTimes();
EasyMock.expect(fileNode2.getName()).andReturn("work book").anyTimes();
EasyMock.expect(fileNode1.getEnvPath()).andReturn("").anyTimes();
EasyMock.expect(fileNode2.getEnvPath()).andReturn("").anyTimes();
EasyMock.expect(fileNode1.getEnvPath()).andReturn("t1").anyTimes();
EasyMock.expect(fileNode2.getEnvPath()).andReturn("t2").anyTimes();
EasyMock.replay(fileNode1,fileNode2);
FileNode[] fileNodes = { fileNode1, fileNode2 };
Reflect.on(instance).set("fileNodes",fileNodes);
@ -65,8 +60,10 @@ public class FileSearchManagerTest {
PowerMock.mockStatic(AlphaFineHelper.class);
AlphaFineHelper.getFilterResult();
PowerMock.expectLastCall().andReturn(list).anyTimes();
AlphaFineHelper.findFolderName("");
PowerMock.expectLastCall().andReturn("").anyTimes();
AlphaFineHelper.findFolderName("t1");
PowerMock.expectLastCall().andReturn("t1").anyTimes();
AlphaFineHelper.findFolderName("t2");
PowerMock.expectLastCall().andReturn("t2").anyTimes();
AlphaFineHelper.checkCancel();
PowerMock.expectLastCall().andVoid().anyTimes();
PowerMock.replay(AlphaFineHelper.class);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save