Browse Source

Merge pull request #15999 in DESIGN/design from fbp/release to fbp/master

* commit '4438f218032680c87104e3312869d7af14b9cf1a': (74 commits)
  REPORT-141155 FR12埋点-远程设计切换埋点appid字段没有记录
  REPORT-145453 【fr-fbp】ssh和ssl的数据连接,去获取密钥等文件时,路径深的时候选择后路径有问题
  REPORT-144999 fix: 适配新的日志接口 & 删除多余逻辑
  fix: REPORT-145393 数据中心,日期弹窗主题色是绿色的
  REPORT-145295 fix:修复模板树移动显示空白
  REPORT-145301 fix:优化web属性几个面板中涉及到的滚动效果
  Revert "REPORT-145379 远程设计调试工具适配gzip"
  REPORT-145379 远程设计调试工具适配gzip
  REPORT-145372 修复设计器双击模板tab栏后台NPE的问题
  Revert "REPORT-145338 修复远程切换大量exist操作的问题"
  fix: REPORT-145330 公式显示为英文了
  REPORT-145338 修复远程切换大量exist操作的问题
  修改文件注释
  换个换行符
  增加单元格组图标
  fix: REPORT-145192 权限申请审批、数据中心-数据目录两个页面存在国际化问题
  无jira 代码质量
  REPORT-144981 fix:预览按钮禁用状态调整
  REPORT-145133 fix:重名校验交互变更
  REPORT-145122 feat:树组件选中状态问题修复
  ...
fbp/master
superman 4 months ago
parent
commit
d92a28cbcc
  1. 14
      designer-base/src/main/java/com/fine/theme/light/ui/FineTableHeaderUI.java
  2. 99
      designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java
  3. 7
      designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
  4. 2
      designer-base/src/main/java/com/fr/design/EnvSwitcherSubmitTask.java
  5. 3
      designer-base/src/main/java/com/fr/design/ExtraDesignClassManager.java
  6. 4
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  7. 2
      designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java
  8. 21
      designer-base/src/main/java/com/fr/design/carton/CartonUtils.java
  9. 68
      designer-base/src/main/java/com/fr/design/carton/DispatchInfo.java
  10. 193
      designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java
  11. 8
      designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java
  12. 33
      designer-base/src/main/java/com/fr/design/carton/latency/AbstractUIDispatchHandler.java
  13. 104
      designer-base/src/main/java/com/fr/design/carton/latency/UIDispatchManager.java
  14. 7
      designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java
  15. 33
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  16. 33
      designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java
  17. 15
      designer-base/src/main/java/com/fr/design/data/datapane/GlobalTableDataComboBox.java
  18. 2
      designer-base/src/main/java/com/fr/design/data/datapane/GlobalTreeTableDataDictPane.java
  19. 302
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java
  20. 7
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java
  21. 3
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java
  22. 15
      designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java
  23. 11
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java
  24. 19
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java
  25. 36
      designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java
  26. 264
      designer-base/src/main/java/com/fr/design/data/datapane/connect/JNDIDefPane.java
  27. 9
      designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java
  28. 5
      designer-base/src/main/java/com/fr/design/data/datapane/preview/ConnectionInfoBeanHelper.java
  29. 11
      designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java
  30. 6
      designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DCTableDataPane.java
  31. 16
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  32. 3
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java
  33. 5
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java
  34. 30
      designer-base/src/main/java/com/fr/design/debug/edt/StrictEDTException.java
  35. 130
      designer-base/src/main/java/com/fr/design/debug/edt/StrictEdtListeners.java
  36. 135
      designer-base/src/main/java/com/fr/design/debug/edt/StrictEdtManager.java
  37. 2
      designer-base/src/main/java/com/fr/design/debug/remote/HeaderRenderer.java
  38. 14
      designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkAction.java
  39. 2
      designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkHelper.java
  40. 8
      designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkTablePane.java
  41. 2
      designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkTableRowSorter.java
  42. 4
      designer-base/src/main/java/com/fr/design/debug/remote/SizeColorCellRenderer.java
  43. 4
      designer-base/src/main/java/com/fr/design/debug/remote/TimeColorCellRenderer.java
  44. 48
      designer-base/src/main/java/com/fr/design/debug/ui/LatencyInfo.java
  45. 17
      designer-base/src/main/java/com/fr/design/debug/ui/LatencyMonitorEvent.java
  46. 56
      designer-base/src/main/java/com/fr/design/debug/ui/UIInspectorHolder.java
  47. 46
      designer-base/src/main/java/com/fr/design/debug/ui/UILatencyInfoHandler.java
  48. 124
      designer-base/src/main/java/com/fr/design/debug/ui/UILatencyWorker.java
  49. 40
      designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorAction.java
  50. 44
      designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorHelper.java
  51. 285
      designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorPane.java
  52. 6
      designer-base/src/main/java/com/fr/design/dialog/BasicScrollPane.java
  53. 85
      designer-base/src/main/java/com/fr/design/editor/editor/ColumnRowGroupEditor.java
  54. 3
      designer-base/src/main/java/com/fr/design/editor/editor/ColumnSelectedEditor.java
  55. 3
      designer-base/src/main/java/com/fr/design/env/HttpWorkspaceConnector.java
  56. 8
      designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java
  57. 23
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  58. 1
      designer-base/src/main/java/com/fr/design/gui/frpane/UICorrelationPane.java
  59. 21
      designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/RefreshableJTree.java
  60. 56
      designer-base/src/main/java/com/fr/design/i18n/DesignExtendLanguageConfig.java
  61. 10
      designer-base/src/main/java/com/fr/design/jxbrowser/JxEngine.java
  62. 6
      designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java
  63. 3
      designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java
  64. 33
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  65. 6
      designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java
  66. 6
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  67. 20
      designer-base/src/main/java/com/fr/design/mainframe/toolbar/DebugModeMenuDef.java
  68. 2
      designer-base/src/main/java/com/fr/design/mainframe/widget/editors/DataBindingEditor.java
  69. 2
      designer-base/src/main/java/com/fr/design/mainframe/widget/editors/DataTableEditor.java
  70. 4
      designer-base/src/main/java/com/fr/design/metric/AbstractDesignerMetric.java
  71. 3
      designer-base/src/main/java/com/fr/design/present/dict/TableDataDictPane.java
  72. 158
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java
  73. 19
      designer-base/src/main/java/com/fr/design/utils/DesignUtils.java
  74. 22
      designer-base/src/main/java/com/fr/design/write/submit/DBManipulationPane.java
  75. 27
      designer-base/src/main/java/com/fr/env/EnvPrepare.java
  76. 2
      designer-base/src/main/java/com/fr/env/RemoteEnvPane.java
  77. 28
      designer-base/src/main/java/com/fr/env/RemoteWorkspaceURL.java
  78. 23
      designer-base/src/main/java/com/fr/file/FILEChooserPane.java
  79. 7
      designer-base/src/main/java/com/fr/start/server/DesignEmbedHelper.java
  80. 156
      designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java
  81. 4
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_function.svg
  82. 4
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_function_disable.svg
  83. 4
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_function_white.svg
  84. 11
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_plugin.svg
  85. 11
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_plugin_disable.svg
  86. 11
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_plugin_white.svg
  87. 3
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_template.svg
  88. 3
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_template_disable.svg
  89. 3
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_template_white.svg
  90. 16
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/internet_error.svg
  91. 13
      designer-base/src/main/resources/com/fine/theme/icon/editor/cell_group_popup.svg
  92. 13
      designer-base/src/main/resources/com/fine/theme/icon/editor/cell_group_popup_disable.svg
  93. 26
      designer-base/src/main/resources/com/fine/theme/light/ui/fine_light.icon.json
  94. BIN
      designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/business_model_card_direct.png
  95. 24
      designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/business_model_card_direct.svg
  96. BIN
      designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/business_model_card_spider.png
  97. 23
      designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/business_model_card_spider.svg
  98. BIN
      designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/dimension_card_direct.png
  99. 24
      designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/dimension_card_direct.svg
  100. BIN
      designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/dimension_card_spider.png
  101. Some files were not shown because too many files have changed in this diff Show More

14
designer-base/src/main/java/com/fine/theme/light/ui/FineTableHeaderUI.java

@ -124,14 +124,24 @@ public class FineTableHeaderUI extends FlatTableHeaderUI {
* @param column
*/
private void setToolTipText(JTable table, Object value, int column) {
String tipText = value == null ? StringUtils.BLANK : String.valueOf(value);
String tipText = value == null ? StringUtils.BLANK : getTooltipValue(value);
FontMetrics fm = this.getFontMetrics(this.getFont());
int textWidth = fm.stringWidth(String.valueOf(value));
int textWidth = fm.stringWidth(tipText);
if (textWidth > table.getColumnModel().getColumn(column).getWidth()) {
setToolTipText(tipText);
} else {
setToolTipText(null);
}
}
/**
* 提取实际显示值
*
* @param value
* @return 转换后的显示值
*/
public String getTooltipValue(Object value) {
return String.valueOf(value);
}
}
}

99
designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java

@ -6,6 +6,8 @@ import com.fr.design.border.FineBorderFactory;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.stable.os.OperatingSystem;
@ -16,6 +18,7 @@ import javax.swing.JLayer;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.JTextArea;
import javax.swing.JScrollBar;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
@ -503,4 +506,100 @@ public class FineUIUtils {
public static JTextArea createAutoWrapTipLabel(String text) {
return LabelUtils.createAutoWrapLabel(text, FineUIUtils.getUIColor("Label.tipColor", "inactiveCaption"));
}
/**
* 基于设计器父面板计算当前面板尺寸
* @param width 宽度比例
* @param height 高度比例
*
* @return 面板尺寸
*/
public static Dimension calPaneDimensionByContext(double width, double height) {
DesignerFrame parent = DesignerContext.getDesignerFrame();
return new Dimension((int) (parent.getWidth() * width),(int) (parent.getHeight() * height));
}
/**
* 处理子面板的滚动事件
* 根据滚动情况判断是否需要将事件传递给父面板或者由子面板自行处理滚动
*
* @param childScrollBar 子面板的滚动条
* @param parentScrollBar 父面板的滚动条
* @param scrollAmount 滚动增量通常是鼠标滚轮的滚动值
*/
public static void handleChildScrollEvent(JScrollBar childScrollBar, JScrollBar parentScrollBar, int scrollAmount) {
// 如果子面板的滚动条为空,返回
if (childScrollBar == null) {
return;
}
// 如果子面板没有显示滚动条,直接将滚动事件传递给父面板
if (!childScrollBar.isVisible()) {
propagateScrollToParent(parentScrollBar, scrollAmount);
return;
}
// 获取子面板当前的滚动值、最小值、最大值和可见区域的高度
int currentScrollValue = childScrollBar.getValue();
int minScrollValue = childScrollBar.getMinimum();
int maxScrollValue = childScrollBar.getMaximum();
int visibleAreaHeight = childScrollBar.getVisibleAmount();
// 如果滚动到顶部或到底部,将事件传递给父面板
if (isScrolledToTop(currentScrollValue, minScrollValue, scrollAmount)
|| isScrolledToBottom(currentScrollValue, maxScrollValue, visibleAreaHeight, scrollAmount)) {
propagateScrollToParent(parentScrollBar, scrollAmount);
} else {
// 否则由子面板自己处理滚动更新滚动值
childScrollBar.setValue(currentScrollValue + calculateScrollIncrement(childScrollBar, scrollAmount));
}
}
/**
* 判断是否滚动到顶部
*
* @param currentScrollValue 当前滚动条的位置
* @param minScrollValue 滚动条的最小值
* @param scrollAmount 滚动增量
* @return 如果滚动到顶部返回 true否则返回 false
*/
private static boolean isScrolledToTop(int currentScrollValue, int minScrollValue, int scrollAmount) {
return scrollAmount < 0 && currentScrollValue == minScrollValue;
}
/**
* 判断是否滚动到底部
*
* @param currentScrollValue 当前滚动条的位置
* @param maxScrollValue 滚动条的最大值
* @param visibleAreaHeight 可见区域的高度
* @param scrollAmount 滚动增量
* @return 如果滚动到底部返回 true否则返回 false
*/
private static boolean isScrolledToBottom(int currentScrollValue, int maxScrollValue, int visibleAreaHeight, int scrollAmount) {
return scrollAmount > 0 && currentScrollValue == maxScrollValue - visibleAreaHeight;
}
/**
* 将滚动事件传递给父面板处理父面板的滚动
*
* @param parentScrollBar 父面板的滚动条
* @param scrollAmount 滚动增量
*/
private static void propagateScrollToParent(JScrollBar parentScrollBar, int scrollAmount) {
if (parentScrollBar != null) {
// 根据滚动增量计算并更新父面板滚动条的位置
int scrollIncrement = calculateScrollIncrement(parentScrollBar, scrollAmount);
parentScrollBar.setValue(parentScrollBar.getValue() + scrollIncrement);
}
}
/**
* 计算滚动增量基于滚动条的单位增量和滚动的数量UIScrollPane中设置的30
*
* @param scrollBar 滚动条
* @param scrollAmount 滚动增量
* @return 计算出的增量值
*/
private static int calculateScrollIncrement(JScrollBar scrollBar, int scrollAmount) {
// 获取滚动条的单位增量,并计算实际的滚动增量
return scrollAmount * scrollBar.getUnitIncrement(1);
}
}

7
designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java

@ -22,6 +22,7 @@ import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.manager.clip.TemplateTreeClipboard;
import com.fr.design.notification.NotificationCenter;
import com.fr.design.plugin.remind.PluginErrorDesignReminder;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.DesignUtils;
import com.fr.design.versioncheck.VersionCheckUtils;
import com.fr.env.EnvListPane;
@ -515,7 +516,7 @@ public class EnvChangeEntrance {
final EnvListPane envListPane = new EnvListPane();
final BasicDialog envListDialog = envListPane.showWindow(DesignerContext.getDesignerFrame());
dialog = envListDialog;
envListPane.populateEnvManager(envName);
UIUtil.invokeLaterIfNeeded(() -> envListPane.populateEnvManager(envName));
envListDialog.addDialogActionListener(new DialogActionAdapter() {
@Override
@ -552,7 +553,7 @@ public class EnvChangeEntrance {
eventPipe.fire(new CarryMessageEvent(ReportState.STOP.getValue()));
}
final EnvListPane envListPane = new EnvListPane();
envListPane.populateEnvManager(DesignerEnvManager.getEnvManager().getCurEnvName());
UIUtil.invokeLaterIfNeeded(() -> envListPane.populateEnvManager(DesignerEnvManager.getEnvManager().getCurEnvName()));
BasicDialog envListDialog = envListPane.showWindow(SwingUtilities.getWindowAncestor(DesignerContext.getDesignerFrame()));
dialog = envListDialog;
envListDialog.addDialogActionListener(new DialogActionAdapter() {
@ -582,7 +583,7 @@ public class EnvChangeEntrance {
envListDialog.setVisible(true);
}
/**
/**
* 切换环境后 刷新远程目录需要忘记密码的情况
*/
private void updateNotRememberPwdEnv() {

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

@ -162,7 +162,7 @@ public class EnvSwitcherSubmitTask extends AbstractDesignerMetric {
/**
* 循环处理 JSON, 并降序排序
*
* @param moduleUsed 模块用时 {@link com.fr.module.engine.FineModule}
* @param moduleUsed 模块用时
* @param entries 降序排序的树集合
*/
private void sortBySelfUsed(JSONObject moduleUsed, TreeSet<Entry> entries) {

3
designer-base/src/main/java/com/fr/design/ExtraDesignClassManager.java

@ -4,6 +4,7 @@
package com.fr.design;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.BaseUtils;
import com.fr.common.annotations.Open;
import com.fr.design.data.datapane.TableDataNameObjectCreator;
@ -143,7 +144,7 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement
WidgetOption createT(ToolbarItemProvider provider) {
return WidgetOptionFactory.createByWidgetClass(
provider.nameForWidget(),
IOUtils.readIcon(provider.iconPathForWidget()),
new LazyIcon(provider.iconPathForWidget()),
provider.classForWidget()
);
}

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

@ -43,6 +43,7 @@ import com.fr.design.mainframe.vcs.ui.UIPositiveIntEditor;
import com.fr.design.mainframe.vcs.ui.VcsMovePanel;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.unit.UnitConvertUtil;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.ComparatorUtils;
@ -50,7 +51,6 @@ import com.fr.general.FRFont;
import com.fr.general.Inter;
import com.fr.general.log.Log4jConfig;
import com.fr.io.attr.ImageExportAttr;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.report.ReportConfigManager;
import com.fr.stable.Constants;
@ -774,7 +774,7 @@ public class PreferencePane extends BasicPane {
}
private UIDictionaryComboBox<Locale> createLanguageComboBox() {
Map<Locale, String> map = InterProviderFactory.getProvider().getSupportLocaleMap();
Map<Locale, String> map = DesignUtils.getAvailableLanguages();
int size = map.size();
Locale[] keys = new Locale[size];
String[] values = new String[size];

2
designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java

@ -186,7 +186,7 @@ public class RenameAction extends UpdateAction {
warnLabel.setPreferredSize(FineUIScale.scale(new Dimension(300, 50)));
warnLabel.setHorizontalAlignment(SwingConstants.LEFT);
warnLabel.setVerticalAlignment(SwingConstants.TOP);
warnLabel.setForeground(Color.RED);
FineUIStyle.setStyle(warnLabel, FineUIStyle.LABEL_WARNING_TIP);
warnLabel.setVisible(false);
JPanel midPanel = new JPanel(new BorderLayout());

21
designer-base/src/main/java/com/fr/design/carton/CartonUtils.java

@ -1,5 +1,6 @@
package com.fr.design.carton;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StableUtils;
@ -15,9 +16,11 @@ import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.text.SimpleDateFormat;
import static com.fr.design.carton.CartonConstants.DATE_FORMAT;
import static com.fr.design.carton.CartonConstants.EASY_CHECKER_FILE_NAME;
import static com.fr.design.carton.CartonConstants.JOURNAL_FILE_PATH;
import static com.fr.design.carton.CartonConstants.TIMER_CHECKER_FILE_NAME;
import static com.fr.design.carton.CartonConstants.UNREASONABLE_DISPATCH_DURATION_MS;
/**
* 设计器卡顿业务工具类
@ -125,6 +128,24 @@ public class CartonUtils {
}
}
/**
* 记录event事件信息
* @param info event事件信息
*/
public static void recordDispatchInfo(DispatchInfo info) {
long cost = info.timeSoFar();
JSONObject jsonObject = new JSONObject();
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), DATE_FORMAT.format(System.currentTimeMillis()));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "eventQueue_" + info.getEventSeq());
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Start_Time"), DATE_FORMAT.format(info.getStartDispatchTimeMillis()));
if (cost > UNREASONABLE_DISPATCH_DURATION_MS) {
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), cost + "ms");
} else {
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), info.totalTime() + "ms");
}
outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.EASY_CHECK_FLAG);
}
/**
* 用于判断是不是特定的堆栈
*/

68
designer-base/src/main/java/com/fr/design/carton/DispatchInfo.java

@ -0,0 +1,68 @@
package com.fr.design.carton;
/**
* SwingEvent事件包装类
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/05
*/
public class DispatchInfo {
/**
* 当前线程
*/
private final Thread eventDispatchThread = Thread.currentThread();
/**
* 上次触发时间
*/
private long lastDispatchTimeMillis = System.currentTimeMillis();
/**
* 开始时间
*/
private final long startDispatchTimeMillis = System.currentTimeMillis();
/**
* 事件唯一编号
*/
private final long eventSeq;
public DispatchInfo() {
eventSeq = EventDispatchThreadHangMonitor.incrementAndGetSeq();
}
public Thread getEventDispatchThread() {
return eventDispatchThread;
}
public long getLastDispatchTimeMillis() {
return lastDispatchTimeMillis;
}
public long getStartDispatchTimeMillis() {
return startDispatchTimeMillis;
}
public void setLastDispatchTimeMillis(long lastDispatchTimeMillis) {
this.lastDispatchTimeMillis = lastDispatchTimeMillis;
}
public long getEventSeq() {
return eventSeq;
}
/**
* event事件已运行时间
*/
public long timeSoFar() {
return (System.currentTimeMillis() - lastDispatchTimeMillis);
}
/**
* event事件总运行时间
*/
public long totalTime() {
return (System.currentTimeMillis() - startDispatchTimeMillis);
}
}

193
designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java

@ -1,16 +1,8 @@
package com.fr.design.carton;
import com.fanruan.product.ProductConstantsBase;
import com.fr.concurrent.FineExecutors;
import com.fr.design.carton.latency.DesignerLatencyMetric;
import com.fr.design.ui.util.UIUtil;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.SwingUtilities;
import java.awt.EventQueue;
@ -18,15 +10,10 @@ import java.awt.Toolkit;
import java.awt.AWTEvent;
import java.awt.event.WindowEvent;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static com.fr.design.carton.CartonConstants.CHECK_INTERVAL_MS;
import static com.fr.design.carton.CartonConstants.DATE_FORMAT;
import static com.fr.design.carton.CartonConstants.LATENCY_SAMPLING_FREQUENCY;
import static com.fr.design.carton.CartonConstants.UNREASONABLE_DISPATCH_DURATION_MS;
/**
* 参考自git swinghelper
@ -39,14 +26,11 @@ import static com.fr.design.carton.CartonConstants.UNREASONABLE_DISPATCH_DURATIO
public final class EventDispatchThreadHangMonitor extends EventQueue {
public static final EventDispatchThreadHangMonitor INSTANCE = new EventDispatchThreadHangMonitor();
/**
* 一个timer
*/
private Timer timer;
/**
* 事件唯一编码用于方便日志的查看
*/
private static long hangCount = 0;
private static long eventSequence = 0;
/**
* 类似于一个开关当该值为默认的false启动时定时任务在窗口开启前都不会对执行的事件进行检查
*/
@ -54,7 +38,7 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
/**
* 该链表为主要的实现定时任务的容器在重写的dispatchEvent中由pre方法将DispatchInfo加入到链表由post方法remove
*/
private final LinkedList<DispatchInfo> dispatches = new LinkedList<DispatchInfo>();
private final LinkedList<DispatchInfo> dispatches = new LinkedList<>();
/**
* 一个变量用于控制easy监测模式的开关
*/
@ -72,7 +56,6 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
/**
* 一个变量用于记录Timer的开关
*/
public boolean isTimerWitch() {
return timerWitch;
}
@ -83,96 +66,20 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
private boolean timerWitch = false;
private synchronized static long getHangCount() {
return hangCount++;
}
/**
* event事件的包装类
* 获取Swing事件唯一编号
*
* @return 事件编号
*/
public static class DispatchInfo {
// 上一次被打印的堆栈ou
private StackTraceElement[] lastReportedStack;
//获取执行该事件的线程
private final Thread eventDispatchThread = Thread.currentThread();
//在队列中等待执行的事件最后未执行的时间,当有一个事件执行完后就遍历dispatches给该值赋当前时间
private long lastDispatchTimeMillis = System.currentTimeMillis();
//事件开始的时间
private final long startDispatchTimeMillis = System.currentTimeMillis();
//事件编号
private final long hangNumber;
//构造函数,给当前对象赋一个递增的唯一编号
public DispatchInfo() {
hangNumber = getHangCount();
}
//定时调度任务检测的入口,如果执行时间大于设定的值就进入examineHang()方法
public void checkForHang() {
if (timeSoFar() > UNREASONABLE_DISPATCH_DURATION_MS) {
examineHang();
}
}
//超时堆栈的具体处理
private void examineHang() {
//获取执行线程的当前堆栈
StackTraceElement[] currentStack = eventDispatchThread.getStackTrace();
if (CartonUtils.isWaitingForNextEvent(currentStack)) {
return;
}
//某个事件执行时间很长,定时处理时可能会连续打很多个堆栈,对同一个事件的相同堆栈只打一次
if (lastReportedStack != null && CartonUtils.stacksEqual(lastReportedStack, currentStack)) {
return;
}
String stackTrace = CartonUtils.stackTraceToString(currentStack);
lastReportedStack = currentStack;
JSONObject jsonObject = new JSONObject();
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), DATE_FORMAT.format(System.currentTimeMillis()));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "eventQueue_" + hangNumber);
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Duration_Task_Execute"), timeSoFar() + "ms");
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Stack_Info"), stackTrace);
CartonUtils.outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.TIMER_CHECK_FLAG);
CartonUtils.checkForDeadlock();
}
//记录连续运行了多长时间
public long timeSoFar() {
return (System.currentTimeMillis() - lastDispatchTimeMillis);
}
//记录一个事件从被分发到结束的总运行时间
public long totalTime() {
return (System.currentTimeMillis() - startDispatchTimeMillis);
}
//事件处理完后的时间判断
public void dispose() {
if (timeSoFar() > UNREASONABLE_DISPATCH_DURATION_MS) {
exportCartonLog(true);
} else if (lastReportedStack != null) {
exportCartonLog(false);
}
}
public synchronized static long incrementAndGetSeq() {
return eventSequence++;
}
/**
*
* @param flag 判断一下输出日志时要输出哪个时间
*/
private void exportCartonLog(boolean flag) {
JSONObject jsonObject = new JSONObject();
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), DATE_FORMAT.format(System.currentTimeMillis()));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "eventQueue_" + hangNumber);
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Start_Time"), DATE_FORMAT.format(startDispatchTimeMillis));
if (flag) {
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), timeSoFar() + "ms");
} else {
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), totalTime() + "ms");
}
CartonUtils.outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.EASY_CHECK_FLAG);
}
public LinkedList<DispatchInfo> getDispatches() {
return dispatches;
}
private EventDispatchThreadHangMonitor() {
}
/**
@ -183,17 +90,9 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
*/
public void startFilterModalWindow() {
scheduledExecutorService = FineExecutors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//不用干事,切个片就可以
}
});
}
}, 0, 500, TimeUnit.MILLISECONDS);
scheduledExecutorService.scheduleAtFixedRate(() -> SwingUtilities.invokeLater(() -> {
// 切片即可
}), 0, 500, TimeUnit.MILLISECONDS);
}
public void stopFilterModalWindow() {
@ -201,54 +100,11 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
scheduledExecutorService.shutdown();
}
}
/**
* Sets up a timer to check for hangs frequently.
* 初始化一个Timer
*/
public void initTimer() {
final long initialDelayMs = 0;
final boolean daemon = true;
timer = new Timer("EventDispatchThreadHangMonitor", daemon);
timer.schedule(new HangChecker(), initialDelayMs, CHECK_INTERVAL_MS);
}
/**
* /消除Timer
*/
public void stopTimer() {
if (timer != null) {
timer.cancel();
}
}
/**
* /定时执行的任务
*/
public class HangChecker extends TimerTask {
@Override
public void run() {
synchronized (dispatches) {
//如果链表为空或者窗口还没启开,定时检测就不进行
if (dispatches.isEmpty() || !haveShownSomeComponent) {
return;
}
dispatches.getLast().checkForHang();
}
}
}
/**
* 将swing中默认的EventQueue换成自己的
*/
public static void initMonitoring() {
UIUtil.invokeLaterIfNeeded(() -> Toolkit.getDefaultToolkit().getSystemEventQueue().push(INSTANCE));
}
/**
* Overrides EventQueue.dispatchEvent to call our pre and post hooks either
* side of the system's event dispatch code.
* 重写
*/
@Override
protected void dispatchEvent(AWTEvent event) {
if (!useCustomEventQueue()) {
@ -267,16 +123,23 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
}
}
/**
* EDT监控器是否已就绪
*
* @return EDT监控器初始化完成
*/
public boolean ready() {
return !dispatches.isEmpty() && haveShownSomeComponent;
}
private boolean useCustomEventQueue() {
// 开启性能监控或开启卡顿工具箱,则走自定义的EventQueue
return SwitchForSwingChecker.isLatencyMonitoring() ||
isEasyWitch() || isTimerWitch();
return SwitchForSwingChecker.isLatencyMonitoring() || isEasyWitch() || isTimerWitch();
}
private boolean needSampling() {
// UI性能采样逻辑:开启采样并且符合采样频次
return SwitchForSwingChecker.isLatencyMonitoring()
&& (hangCount % LATENCY_SAMPLING_FREQUENCY == 0);
return SwitchForSwingChecker.isLatencyMonitoring() && (eventSequence % LATENCY_SAMPLING_FREQUENCY == 0);
}
/**
@ -298,13 +161,13 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
DesignerLatencyMetric.getInstance().record(justFinishedDispatch.timeSoFar());
}
if (isEasyWitch()) {
justFinishedDispatch.dispose();
CartonUtils.recordDispatchInfo(justFinishedDispatch);
}
//嵌套最深的事件执行完毕后刷新链表中其他事件的lastDispatchTimeMillis
Thread currentEventDispatchThread = Thread.currentThread();
for (DispatchInfo dispatchInfo : dispatches) {
if (dispatchInfo.eventDispatchThread == currentEventDispatchThread) {
dispatchInfo.lastDispatchTimeMillis = System.currentTimeMillis();
if (dispatchInfo.getEventDispatchThread() == currentEventDispatchThread) {
dispatchInfo.setLastDispatchTimeMillis(System.currentTimeMillis());
}
}
}

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

@ -1,7 +1,7 @@
package com.fr.design.carton;
import com.fanruan.product.ProductConstantsBase;
import com.fr.design.carton.latency.UIDispatchManager;
import com.fr.design.i18n.Toolkit;
import com.fr.general.GeneralUtils;
import com.fr.json.JSON;
@ -82,7 +82,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
public static void startTimerChecker() {
if (!checkerTimerSwitch) {
EventDispatchThreadHangMonitor.INSTANCE.initTimer();
UIDispatchManager.getInstance().startScheduler();
CartonThreadExecutorPool.getTimerThreadExecutorPool().initTimer();
EventDispatchThreadHangMonitor.INSTANCE.setTimerWitch(true);
checkerTimerSwitch = true;
@ -94,7 +94,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
public static void stopTimerChecker() {
if (checkerTimerSwitch) {
EventDispatchThreadHangMonitor.INSTANCE.stopTimer();
UIDispatchManager.getInstance().stopSchedulerIfNecessary();
CartonThreadExecutorPool.getTimerThreadExecutorPool().stopTimer();
EventDispatchThreadHangMonitor.INSTANCE.setTimerWitch(false);
checkerTimerSwitch = false;
@ -286,7 +286,7 @@ public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
CartonThreadExecutorPool.getTimerThreadExecutorPool().setEasyWitch(true);
}
if (checkerTimerSwitch) {
EventDispatchThreadHangMonitor.INSTANCE.initTimer();
UIDispatchManager.getInstance().startScheduler();
CartonThreadExecutorPool.getTimerThreadExecutorPool().initTimer();
EventDispatchThreadHangMonitor.INSTANCE.setTimerWitch(true);
}

33
designer-base/src/main/java/com/fr/design/carton/latency/AbstractUIDispatchHandler.java

@ -0,0 +1,33 @@
package com.fr.design.carton.latency;
import com.fr.design.carton.DispatchInfo;
/**
* 设计器UI事件切面处理器
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/07
*/
public abstract class AbstractUIDispatchHandler {
/**
* 是否需要处理
*/
protected abstract boolean accept(DispatchInfo info);
/**
* 实际处理
*/
protected abstract void doHandle(DispatchInfo info);
/**
* 处理UI切面
*/
public void handle(DispatchInfo info) {
if (accept(info)) {
doHandle(info);
}
}
}

104
designer-base/src/main/java/com/fr/design/carton/latency/UIDispatchManager.java

@ -0,0 +1,104 @@
package com.fr.design.carton.latency;
import com.fr.design.carton.DispatchInfo;
import com.fr.design.carton.EventDispatchThreadHangMonitor;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static com.fr.design.carton.CartonConstants.CHECK_INTERVAL_MS;
/**
* 设计器UI事件切面处理器
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/05
*/
public class UIDispatchManager {
private ScheduledExecutorService scheduler;
private final List<AbstractUIDispatchHandler> handlerList = new ArrayList<>();
private final static class InstanceHolder {
static final UIDispatchManager INSTANCE = new UIDispatchManager();
}
/**
* 单例
*/
public static UIDispatchManager getInstance() {
return UIDispatchManager.InstanceHolder.INSTANCE;
}
/**
* 注册处理器
* @param handler 处理器
*/
public void registerHandler(AbstractUIDispatchHandler handler) {
handlerList.add(handler);
}
/**
* 注销处理器
* @param handler 处理器
*/
public void unregisterHandler(AbstractUIDispatchHandler handler) {
handlerList.remove(handler);
}
/**
* 开启定时UI事件监听任务
*/
public void startScheduler() {
if (scheduler != null && !scheduler.isShutdown()) {
return;
}
scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
Thread thread = new Thread(r, "DesignerLatencyChecker");
thread.setDaemon(true);
return thread;
});
scheduler.scheduleAtFixedRate(new DispatchChecker(), 0, CHECK_INTERVAL_MS, TimeUnit.MILLISECONDS);
}
/**
* 尝试停止定时UI事件监听任务但如果存在处理器则不停止
*/
public void stopSchedulerIfNecessary() {
if (!handlerList.isEmpty()) {
return;
}
if (scheduler != null && !scheduler.isShutdown()) {
scheduler.shutdownNow();
}
}
/**
* UI事件切面检查器
*/
public class DispatchChecker implements Runnable {
@Override
public void run() {
LinkedList<DispatchInfo> dispatches = EventDispatchThreadHangMonitor.INSTANCE.getDispatches();
synchronized (dispatches) {
if (EventDispatchThreadHangMonitor.INSTANCE.ready()) {
handle(dispatches.getLast());
}
}
}
}
/**
* 处理UI事件
* @param dispatchInfo ui事件信息
*/
public void handle(DispatchInfo dispatchInfo) {
handlerList.forEach(handler -> handler.handle(dispatchInfo));
}
}

7
designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java

@ -38,6 +38,7 @@ import com.fr.general.NameObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import javax.swing.AbstractButton;
import javax.swing.Action;
@ -471,11 +472,11 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
// 获取无权限连接名称集合
Collection<String> noAuthConnections = TableDataAuthHelper.getNoAuthConnections();
// 获取有权限的连接名称集合
Collection<String> authConnections = ConnectionRepository.getInstance().getConnNames();
// 获取当前数据集对应的数据连接名称
String connectionName = TableDataAuthHelper.getConnectionNameByDBTableData((DBTableData) wrapper.getTableData());
return !noAuthConnections.contains(connectionName);
return authConnections.contains(connectionName);
}
@Override

33
designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java

@ -121,6 +121,9 @@ public abstract class DesignTableDataManager {
//增强for循环用的iterator实现的, 如果中间哪个listener修改或删除了(如ChartEditPane.dsChangeListener),
// 由于dsListeners是arraylist, 此时会ConcurrentModifyException
ChangeEvent e = null;
if (dsListeners.get(i) == null) {
continue;
}
dsListeners.get(i).stateChanged(e);
}
}
@ -197,17 +200,27 @@ public abstract class DesignTableDataManager {
* @param l ChangeListener监听器
*/
public static void addDsChangeListener(ChangeListener l) {
getDsListenersForCurrentTemplate().add(l);
}
/**
* 移除模板数据集改变 监听事件.
*
* @param l ChangeListener监听器
*/
public static void removeDsChangeListener(ChangeListener l) {
getDsListenersForCurrentTemplate().remove(l);
}
/**
* 获取当前模板的监听器列表.
*
* @return 模板对应的监听器列表如果列表不存在则新建.
*/
private static List<ChangeListener> getDsListenersForCurrentTemplate() {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String key = StringUtils.EMPTY;
if (JTemplate.isValid(template)) {
key = template.getPath();
}
List<ChangeListener> dsListeners = dsListenersMap.get(key);
if (dsListeners == null) {
dsListeners = new ArrayList<ChangeListener>();
dsListenersMap.put(key, dsListeners);
}
dsListeners.add(l);
String key = JTemplate.isValid(template) ? template.getPath() : StringUtils.EMPTY;
return dsListenersMap.computeIfAbsent(key, k -> new ArrayList<>());
}
/**

33
designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java

@ -1,9 +1,7 @@
package com.fr.design.data.datapane;
import com.fanruan.config.impl.data.ConnectionConfigProviderFactory;
import com.fr.base.TableData;
import com.fr.data.core.DataCoreUtils;
import com.fr.data.core.db.DBUtils;
import com.fr.data.core.db.TableProcedure;
import com.fr.data.core.db.dialect.Dialect;
import com.fr.data.core.db.dialect.DialectFactory;
@ -39,14 +37,9 @@ import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingWorker;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.PopupMenuEvent;
@ -56,21 +49,14 @@ import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CancellationException;
/**
@ -339,20 +325,7 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
}
private List<String> getHasAuthConnections() {
List<String> authConnections = new ArrayList<>();
Set<String> allConnections = new HashSet<>(ConnectionRepository.getInstance().getConnNames());
// 待实现
Collection<String> noAuthConnections = RemoteAuthorityRepository.getInstance().getNoAuthConnections();
if (noAuthConnections == null) {
return authConnections;
}
for (String name : allConnections) {
if (!noAuthConnections.contains(name)) {
authConnections.add(name);
}
}
return authConnections;
return ConnectionRepository.getInstance().getConnNames();
}
/**

15
designer-base/src/main/java/com/fr/design/data/datapane/GlobalTableDataComboBox.java

@ -12,9 +12,24 @@ import com.fr.data.TableDataSource;
*/
public class GlobalTableDataComboBox extends TableDataComboBox {
/**
* 兼容插件调用
* @param source 数据源
* @param treeName 树数据集名称
*/
public GlobalTableDataComboBox(TableDataSource source, String treeName) {
super(source, treeName);
}
/**
* 初始化GlobalTableDataComboBox
* @param treeName 树数据集名称
*/
public GlobalTableDataComboBox(String treeName) {
super(treeName);
}
@Override
protected void setResMap(TableDataSource source){
resMap = DesignTableDataManager.getGlobalDataSet();

2
designer-base/src/main/java/com/fr/design/data/datapane/GlobalTreeTableDataDictPane.java

@ -16,6 +16,6 @@ public class GlobalTreeTableDataDictPane extends TreeTableDataDictPane {
}
protected void setTableDataNameComboBox(String string) {
tableDataNameComboBox = new GlobalTableDataComboBox(DesignTableDataManager.getEditingTableDataSource(),string);
tableDataNameComboBox = new GlobalTableDataComboBox(string);
}
}

302
designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java

@ -1,15 +1,16 @@
package com.fr.design.data.datapane;
import com.fr.design.constants.UIConstants;
import com.fr.design.ui.util.UIUtil;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@ -33,136 +34,217 @@ public class TableDataComboBox extends UIComboBox implements Prepare4DataSourceC
protected java.util.Map<String, TableDataWrapper> resMap;
private java.util.Map<String, TableDataWrapper> dsMap;
private static final long serialVersionUID = 1L;
private boolean refresModel = false;
private String treeName; //树数据集本身的名字
private ChangeListener changeListener;
private boolean refreshModel = false;
private String treeName = StringUtils.EMPTY; //树数据集本身的名字
private ChangeListener changeListener;
public TableDataComboBox(TableDataSource source){
this(source,StringUtils.EMPTY);
/**
* 兼容插件调用
*
* @param source 插件中传入的数据源
*/
public TableDataComboBox(TableDataSource source) {
this();
}
public TableDataComboBox(TableDataSource source, String treeName) {
super();
/**
* 兼容插件调用
*
* @param source 插件中传入的数据源
* @param treeName 树数据集名称
*/
public TableDataComboBox(TableDataSource source, String treeName) {
this(treeName);
}
/**
* 根据树名称创建TableDataComboBox
*
* @param treeName 树数据集名称
*/
public TableDataComboBox(String treeName) {
this();
// 传入树数据集名称
this.treeName = treeName;
this.setRenderer(new UIComboBoxRenderer() {
private static final long serialVersionUID = 1L;
private boolean labelVisible = true;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel renderer = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof TableDataWrapper) {
labelVisible = true;
TableDataWrapper tableDataWrapper = (TableDataWrapper)value;
renderer.setIcon(tableDataWrapper.getIcon());
renderer.setText(tableDataWrapper.getTableDataName());
renderer.setToolTipText(tableDataWrapper.getTableDataName());
} else {
labelVisible = false;
renderer.setIcon(null);
renderer.setText(StringUtils.EMPTY);
}
return renderer;
}
@Override
public Dimension getPreferredSize() {
return labelVisible ? super.getPreferredSize() : new Dimension(super.getPreferredSize().width, 0);
}
});
refresh(source);
registerDSChangeListener();
}
}
/**
* 初始化TableDataComboBox
*/
public TableDataComboBox() {
super();
setListCellRenderer();
addComboBoxListener();
}
/**
* 设置渲染器
*/
private void setListCellRenderer() {
this.setRenderer(new UIComboBoxRenderer() {
private static final long serialVersionUID = 1L;
private boolean labelVisible = true;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel renderer = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof TableDataWrapper) {
labelVisible = true;
TableDataWrapper tableDataWrapper = (TableDataWrapper) value;
renderer.setIcon(tableDataWrapper.getIcon());
renderer.setText(tableDataWrapper.getTableDataName());
renderer.setToolTipText(tableDataWrapper.getTableDataName());
} else {
labelVisible = false;
renderer.setIcon(null);
renderer.setText(StringUtils.EMPTY);
}
return renderer;
}
@Override
public Dimension getPreferredSize() {
return labelVisible ? super.getPreferredSize() : new Dimension(super.getPreferredSize().width, 0);
}
});
}
/**
* 在comboBox可见时添加数据集响应事件与refresh操作
*/
private void addComboBoxListener() {
this.addAncestorListener(new AncestorListener() {
@Override
public void ancestorAdded(AncestorEvent event) {
registerDSChangeListener();
UIUtil.invokeLaterIfNeeded(() -> refresh(DesignTableDataManager.getEditingTableDataSource()));
}
@Override
public void ancestorRemoved(AncestorEvent event) {
DesignTableDataManager.removeDsChangeListener(changeListener);
}
@Override
public void ancestorMoved(AncestorEvent event) {
}
});
}
/**
* refresh ComboBox
* @param source
*
* @param source 数据源
*/
public void refresh(TableDataSource source) {
TableDataWrapper dataWrapper = getSelectedItem();
refresModel = true;
setResMap(source);
public void refresh(TableDataSource source) {
refreshModel = true;
setResMap(source);
setDsMap();
DefaultComboBoxModel model = new DefaultComboBoxModel();
this.setModel(model);
model.addElement(UIConstants.PENDING);
// 遍历添加所有数据项到模型
Iterator<Entry<String, TableDataWrapper>> entryIt = dsMap.entrySet().iterator();
while (entryIt.hasNext()) {
TableDataWrapper tableDataWrapper = entryIt.next().getValue();
if (!ComparatorUtils.equals(tableDataWrapper.getTableDataName(), treeName)) {
model.addElement(tableDataWrapper);
}
}
// 获取当前选中的数据项
TableDataWrapper dataWrapper = getSelectedItem();
// 更新下拉模型
refreshComboBoxModel();
//处理已选中的数据项
updateSelectedItem(dataWrapper);
refreshModel = false;
}
protected void setResMap(TableDataSource source) {
this.resMap = DesignTableDataManager.getAllEditingDataSet(source);
}
private void setDsMap() {
dsMap = DesignTableDataManager.getAllDataSetIncludingProcedure(resMap);
}
private void refreshComboBoxModel() {
//创建ComboBox模型并设置
DefaultComboBoxModel model = new DefaultComboBoxModel();
this.setModel(model);
model.addElement(UIConstants.PENDING);
// 遍历添加所有数据项到模型,树数据集comboBox下拉模型中排除掉本身
dsMap.values().stream()
.filter(tableDataWrapper -> tableDataWrapper != null && !ComparatorUtils.equals(tableDataWrapper.getTableDataName(), treeName))
.forEach(model::addElement);
}
private void updateSelectedItem(TableDataWrapper dataWrapper) {
if (dataWrapper != null) {
if (DesignTableDataManager.isDsNameChanged(dataWrapper.getTableDataName())) {
this.setSelectedTableDataByName(DesignTableDataManager.getChangedDsNameByOldDsName(dataWrapper.getTableDataName()));
this.setSelectedTableData(DesignTableDataManager.getChangedDsNameByOldDsName(dataWrapper.getTableDataName()));
} else {
this.getModel().setSelectedItem(dataWrapper);
}
}
refresModel = false;
}
}
protected void setResMap(TableDataSource source) {
this.resMap = DesignTableDataManager.getAllEditingDataSet(source);
/**
* 向resMap中添加TableData信息
*
* @param name 数据集名字
* @param templateTableDataWrapper 数据集
*/
public void putTableDataIntoMap(String name, TemplateTableDataWrapper templateTableDataWrapper) {
if (dsMap.containsKey(name)) {
return;
}
this.addItem(templateTableDataWrapper);
dsMap.put(name, templateTableDataWrapper);
}
private void setDsMap() {
dsMap = DesignTableDataManager.getAllDataSetIncludingProcedure(resMap);
public void setSelectedTableDataByName(String name) {
setResMap(DesignTableDataManager.getEditingTableDataSource());
setDsMap();
// 数据集名称修改后控件传入的还是旧名称
if (DesignTableDataManager.isDsNameChanged(name)) {
name = DesignTableDataManager.getChangedDsNameByOldDsName(name);
}
setSelectedTableData(name);
}
private void setSelectedTableData(String name) {
TableDataWrapper tableDataWrapper = dsMap.get(name) == null ? dsMap.get(name + "_P_CURSOR") : dsMap.get(name);
this.getModel().setSelectedItem(tableDataWrapper);
}
@Override
public TableDataWrapper getSelectedItem() {
if (dataModel.getSelectedItem() instanceof TableDataWrapper) {
return (TableDataWrapper) dataModel.getSelectedItem();
}
return null;
}
/**
* 向resMap中添加TableData信息
* @param name 数据集名字
* @param templateTableDataWrappe 数据集
* august:addElement方法竟然会fireItemStateChanged蛋疼
* @param e the event of interest
*
*/
public void putTableDataIntoMap(String name, TemplateTableDataWrapper templateTableDataWrappe) {
if (dsMap.containsKey(name)) {
return;
}
this.addItem(templateTableDataWrappe);
dsMap.put(name, templateTableDataWrappe);
}
public void setSelectedTableDataByName(String name) {
TableDataWrapper tableDataWrappe = dsMap.get(name) == null? dsMap.get(name + "_P_CURSOR") : dsMap.get(name);
this.getModel().setSelectedItem(tableDataWrappe);
}
@Override
public TableDataWrapper getSelectedItem() {
if (dataModel.getSelectedItem() instanceof TableDataWrapper) {
return (TableDataWrapper)dataModel.getSelectedItem();
}
return null;
}
//august:addElement方法竟然会fireItemStateChanged,蛋疼
@Override
protected void fireItemStateChanged(ItemEvent e) {
if (!refresModel) {
super.fireItemStateChanged(e);
}
}
/**
*注册listener,相应数据集改变
*/
@Override
public void registerDSChangeListener() {
changeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
TableDataComboBox.this.refresh(DesignTableDataManager.getEditingTableDataSource());
}
};
DesignTableDataManager.addDsChangeListener(changeListener);
}
public void registerGlobalDSChangeListener() {
DesignTableDataManager.addGlobalDsChangeListener(changeListener);
}
@Override
protected void fireItemStateChanged(ItemEvent e) {
if (!refreshModel) {
super.fireItemStateChanged(e);
}
}
/**
* 注册listener,相应数据集改变
*/
@Override
public void registerDSChangeListener() {
changeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
TableDataComboBox.this.refresh(DesignTableDataManager.getEditingTableDataSource());
}
};
DesignTableDataManager.addDsChangeListener(changeListener);
}
/**
* 兼容插件调用
*/
public void registerGlobalDSChangeListener() {
DesignTableDataManager.addGlobalDsChangeListener(changeListener);
}
}

7
designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java

@ -71,6 +71,7 @@ import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
@ -1056,11 +1057,11 @@ public class TableDataTreePane extends BasicTableDataTreePane {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
// 获取无权限连接名称集合
Collection<String> noAuthConnections = TableDataAuthHelper.getNoAuthConnections();
// 获取有权限的连接名称集合
Collection<String> authConnections = ConnectionRepository.getInstance().getConnNames();
// 获取当前数据集对应的数据连接名称
String connectionName = TableDataAuthHelper.getConnectionNameByDBTableData((DBTableData) wrapper.getTableData());
return !noAuthConnections.contains(connectionName);
return authConnections.contains(connectionName);
}
@Override

3
designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java

@ -180,8 +180,7 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
}
protected void setTableDataNameComboBox(String treeName) {
tableDataNameComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource(), treeName);
tableDataNameComboBox = new TableDataComboBox(treeName);
}
private void tdChange(boolean isChangeDS) {

15
designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java

@ -6,11 +6,6 @@ import com.fr.data.impl.DBTableData;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.connection.DBConnectAuth;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import java.util.Collection;
import java.util.Collections;
/**
* 数据连接权限相关的工具类
@ -28,16 +23,6 @@ public class TableDataAuthHelper {
return !WorkContext.getCurrent().isLocal() && tableData instanceof DBTableData;
}
/**
* 获取无权限数据连接集合
* 远程下需要调用RPC为耗时操作谨慎使用
* @return
*/
public static Collection<String> getNoAuthConnections() {
// 获取无权限连接集合
Collection<String> noAuthConnections = RemoteAuthorityRepository.getInstance().getNoAuthConnections();
return noAuthConnections == null ? Collections.emptyList() : noAuthConnections;
}
/**
* 通过数据集获取其数据连接的名称

11
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java

@ -13,7 +13,6 @@ import com.fr.design.gui.ibutton.UILockButton;
import com.fr.report.LockItem;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
@ -22,7 +21,6 @@ import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -80,19 +78,10 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
* 刷新ComboBox.items
*/
protected Iterator<String> items() {
Collection<String> noAuthConnections = RemoteAuthorityRepository.getInstance().getNoAuthConnections();
nameList = new ArrayList<>();
if (noAuthConnections == null) {
return nameList.iterator();
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.getCurrentConnectionMap();
for (Map.Entry<String, Connection> connectionEntry : connectionMap.entrySet()) {
String conName = connectionEntry.getKey();
if (noAuthConnections.contains(conName)) {
continue;
}
filterConnection(connectionEntry.getValue(), conName, nameList);
}
return nameList.iterator();

19
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java

@ -5,7 +5,6 @@ import com.fine.theme.utils.FineUIScale;
import com.fr.config.remote.RemoteConfigEvent;
import com.fr.data.impl.Connection;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.JNDIDatabaseConnection;
import com.fr.decision.webservice.bean.datasource.ConnectionInfoBean;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.data.MapCompareUtils;
@ -36,8 +35,9 @@ import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -172,17 +172,8 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
"JDBC", new LazyIcon("dataLink"),
JDBCDatabaseConnection.class, DatabaseConnectionPane.JDBC.class
);
NameObjectCreator jndi = new NameObjectCreator(
"JNDI", new LazyIcon("dataLink"),
JNDIDatabaseConnection.class, DatabaseConnectionPane.JNDI.class
);
NameableCreator[] creators;
if (WorkplaceConstants.isLimitDatabaseType()) {
// 不支持JNDI,屏蔽接口
creators = new NameableCreator[]{jdbc};
} else {
creators = new NameableCreator[]{jdbc, jndi};
}
creators = new NameableCreator[]{jdbc};
Set<ConnectionProvider> pluginCreators = ExtraDesignClassManager.getInstance().getArray(ConnectionProvider.XML_TAG);
for (ConnectionProvider provider : pluginCreators) {
NameObjectCreator creator = new NameObjectCreator(
@ -292,7 +283,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
* @return
*/
private boolean isEmbedConnection(Connection connection) {
return connection instanceof JDBCDatabaseConnection || connection instanceof JNDIDatabaseConnection;
return connection instanceof JDBCDatabaseConnection;
}
});
/// 先不管

36
designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java

@ -11,15 +11,14 @@ import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.data.driver.util.JarFileParseUtil;
import com.fr.data.impl.Connection;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.JNDIDatabaseConnection;
import com.fr.data.security.ssl.impl.NormalSsl;
import com.fr.data.solution.ExceptionSolutionSelector;
import com.fr.data.solution.entity.DriverPage;
import com.fr.data.solution.processor.ClassNotFoundExceptionSolutionProcessor;
import com.fr.data.solution.processor.SolutionProcessor;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icontainer.UIScrollPane;
@ -34,8 +33,8 @@ import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.engine.exception.DriverUnExistException;
import org.jetbrains.annotations.NotNull;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import org.jetbrains.annotations.NotNull;
import javax.swing.JDialog;
import javax.swing.JLabel;
@ -69,8 +68,8 @@ import java.util.concurrent.ExecutionException;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.fix;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.theme.utils.FineUIUtils.wrapComponentWithTitle;
/**
@ -411,35 +410,6 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
}
}
public static class JNDI extends DatabaseConnectionPane<JNDIDatabaseConnection> {
private static JNDIDefPane jndiDefPane = new JNDIDefPane();
@Override
protected JPanel mainPanel() {
return jndiDefPane;
}
@Override
protected boolean isFineBI() {
return false;
}
@Override
protected void populateSubDatabaseConnectionBean(JNDIDatabaseConnection ob) {
jndiDefPane.populate(ob);
}
@Override
protected JNDIDatabaseConnection updateSubDatabaseConnectionBean() {
return jndiDefPane.update();
}
@Override
protected String title4PopupWindow() {
return "JNDI";
}
}
private class TestConnectionWorker extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {

264
designer-base/src/main/java/com/fr/design/data/datapane/connect/JNDIDefPane.java

@ -1,264 +0,0 @@
package com.fr.design.data.datapane.connect;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import javax.swing.JDialog;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.gui.ilable.UILabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import com.fr.data.impl.JNDIDatabaseConnection;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.FRExplainLabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.dialog.BasicPane;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.theme.utils.FineUIUtils.wrapComponentWithTitle;
public class JNDIDefPane extends JPanel {
private static Map<String, String> jndiMap = new HashMap<String, String>();
static {
jndiMap.put("weblogic.jndi.WLInitialContextFactory", "t3://localhost:7001");
jndiMap.put("com.ibm.websphere.naming.WsnInitialContextFactory", "iiop://localhost:2809");
jndiMap.put("org.jboss.naming.HttpNamingContextFactory", "http://jboss_server_address:8080/invoker/JNDIFactory");
jndiMap.put("org.jnp.interfaces.NamingContextFactory", "localhost:1099");
jndiMap.put("com.caucho.burlap.BurlapContextFactory", "http://localhost:8080/hello/burlap");
}
private UITextField jndiNameTextField;
private UIComboBox JNDIFactoryComboBox;
private ContextTextField PROVIDER_URL_TF = new ContextTextField(Context.PROVIDER_URL);
private ContextTextField SECURITY_PRINCIPAL_TF = new ContextTextField(Context.SECURITY_PRINCIPAL);
private ContextTextField SECURITY_CREDENTIALS_TF = new ContextTextField(Context.SECURITY_CREDENTIALS);
private ContextTextField OBJECT_FACTORIES_TF = new ContextTextField(Context.OBJECT_FACTORIES);
private ContextTextField STATE_FACTORIES_TF = new ContextTextField(Context.STATE_FACTORIES);
private ContextTextField URL_PKG_PREFIXES_TF = new ContextTextField(Context.URL_PKG_PREFIXES);
private ContextTextField DNS_URL_TF = new ContextTextField(Context.DNS_URL);
private ContextTextField AUTHORITATIVE_TF = new ContextTextField(Context.AUTHORITATIVE);
private ContextTextField BATCHSIZE_TF = new ContextTextField(Context.BATCHSIZE);
private ContextTextField REFERRAL_TF = new ContextTextField(Context.REFERRAL);
private ContextTextField SECURITY_PROTOCOL_TF = new ContextTextField(Context.SECURITY_PROTOCOL);
private ContextTextField SECURITY_AUTHENTICATION_TF = new ContextTextField(Context.SECURITY_AUTHENTICATION);
private ContextTextField LANGUAGE_TF = new ContextTextField(Context.LANGUAGE);
private ContextTextField APPLET_TF = new ContextTextField(Context.APPLET);
private JDialog otherAttrDialog;
public JNDIDefPane() {
this.setLayout(new BorderLayout());
jndiNameTextField = new UITextField(20);
JNDIFactoryComboBox = new UIComboBox(new String[] { "", "weblogic.jndi.WLInitialContextFactory", "com.ibm.websphere.naming.WsnInitialContextFactory",
"org.jboss.naming.HttpNamingContextFactory", "org.jnp.interfaces.NamingContextFactory", "com.caucho.burlap.BurlapContextFactory", });
JNDIFactoryComboBox.setEditable(true);
JNDIFactoryComboBox.addActionListener(jndiListener);
JNDIFactoryComboBox.setPreferredSize(new Dimension(FineUIScale.scale(30), JNDIFactoryComboBox.getPreferredSize().height + FineUIScale.scale(2)));
// 上下文
JPanel contextPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
contextPane.add(column(LayoutConstants.VERTICAL_GAP,
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("INITIAL_CONTEXT_FACTORY")).weight(0.35), cell(JNDIFactoryComboBox).weight(0.65)),
row(LayoutConstants.HORIZONTAL_GAP,cell(new UILabel("PROVIDER_URL")).weight(0.35), cell(PROVIDER_URL_TF).weight(0.65)),
row(LayoutConstants.HORIZONTAL_GAP,cell(new UILabel("SECURITY_PRINCIPAL")).weight(0.35), cell(SECURITY_PRINCIPAL_TF).weight(0.65)),
row(LayoutConstants.HORIZONTAL_GAP,cell(new UILabel("SECURITY_CREDENTIALS")).weight(0.35), cell(SECURITY_CREDENTIALS_TF).weight(0.65))
).getComponent());
//其他属性
JPanel otherAttributePanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
ActionLabel actionLabel = new ActionLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Other_Attributes"));
actionLabel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//其他属性弹窗
JDialog wDialog = createJDialog();
wDialog.setVisible(true);
}
});
otherAttributePanel.add(actionLabel, BorderLayout.EAST);
//注意描述
JPanel jndiDesPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
jndiDesPanel.add(new JScrollPane(new FRExplainLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_JNDI_DES"))), BorderLayout.WEST);
//JNDI面板
JPanel centerPanel = column(LayoutConstants.VERTICAL_GAP,
row(cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_JNDI_Name"))).weight(0.15), cell(jndiNameTextField).weight(0.85)),
row(cell(getTopAlignLabelPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Context"))).weight(0.15), cell(contextPane).weight(0.85)),
cell(otherAttributePanel),
cell(jndiDesPanel)
).getComponent();
this.add(wrapComponentWithTitle(centerPanel,"JNDI"));
}
private JPanel getTopAlignLabelPane(String labelText) {
return column(LayoutConstants.VERTICAL_GAP, cell(new UILabel(labelText)))
.with(it -> it.setBorder(new ScaledEmptyBorder(2,0,0,0))).getComponent();
}
public void populate(JNDIDatabaseConnection jndiDatabase) {
if (jndiDatabase == null) {
jndiDatabase = new JNDIDatabaseConnection();
}
// Properties.
Map<String, String> contextHashtable = jndiDatabase.getContextHashtable();
Object INITIAL_CONTEXT_FACTORY = contextHashtable.get(Context.INITIAL_CONTEXT_FACTORY);
this.JNDIFactoryComboBox.setSelectedItem(INITIAL_CONTEXT_FACTORY == null ? "" : INITIAL_CONTEXT_FACTORY);
this.jndiNameTextField.setText(jndiDatabase.getJNDIName() == null ? "" : jndiDatabase.getJNDIName());
populateContextAttributes(contextHashtable, this.PROVIDER_URL_TF, Context.PROVIDER_URL);
populateContextAttributes(contextHashtable, this.SECURITY_PRINCIPAL_TF, Context.SECURITY_PRINCIPAL);
populateContextAttributes(contextHashtable, this.SECURITY_CREDENTIALS_TF, Context.SECURITY_CREDENTIALS);
populateContextAttributes(contextHashtable, this.OBJECT_FACTORIES_TF, Context.OBJECT_FACTORIES);
populateContextAttributes(contextHashtable, this.STATE_FACTORIES_TF, Context.STATE_FACTORIES);
populateContextAttributes(contextHashtable, this.URL_PKG_PREFIXES_TF, Context.URL_PKG_PREFIXES);
populateContextAttributes(contextHashtable, this.DNS_URL_TF, Context.DNS_URL);
populateContextAttributes(contextHashtable, this.AUTHORITATIVE_TF, Context.AUTHORITATIVE);
populateContextAttributes(contextHashtable, this.BATCHSIZE_TF, Context.BATCHSIZE);
populateContextAttributes(contextHashtable, this.REFERRAL_TF, Context.REFERRAL);
populateContextAttributes(contextHashtable, this.SECURITY_PROTOCOL_TF, Context.SECURITY_PROTOCOL);
populateContextAttributes(contextHashtable, this.SECURITY_AUTHENTICATION_TF, Context.SECURITY_AUTHENTICATION);
populateContextAttributes(contextHashtable, this.LANGUAGE_TF, Context.LANGUAGE);
populateContextAttributes(contextHashtable, this.APPLET_TF, Context.APPLET);
}
private void populateContextAttributes(Map<String, String> properties, UITextField textField, String contextAttr) {
String PROVIDER_URL = properties.get(contextAttr);
if (PROVIDER_URL != null) {
textField.setText(PROVIDER_URL);
}
}
public JNDIDatabaseConnection update() {
JNDIDatabaseConnection jndiDatabase = new JNDIDatabaseConnection();
jndiDatabase.setJNDIName(this.jndiNameTextField.getText());
Map<String, String> contextHashtable = jndiDatabase.getContextHashtable();
String factoryString = (String)this.JNDIFactoryComboBox.getEditor().getItem();
if (factoryString != null && factoryString.trim().length() > 0) {
contextHashtable.put(Context.INITIAL_CONTEXT_FACTORY, factoryString);
}
updateContextAttributes(contextHashtable, this.PROVIDER_URL_TF, Context.PROVIDER_URL);
updateContextAttributes(contextHashtable, this.SECURITY_PRINCIPAL_TF, Context.SECURITY_PRINCIPAL);
updateContextAttributes(contextHashtable, this.SECURITY_CREDENTIALS_TF, Context.SECURITY_CREDENTIALS);
updateContextAttributes(contextHashtable, this.OBJECT_FACTORIES_TF, Context.OBJECT_FACTORIES);
updateContextAttributes(contextHashtable, this.STATE_FACTORIES_TF, Context.STATE_FACTORIES);
updateContextAttributes(contextHashtable, this.URL_PKG_PREFIXES_TF, Context.URL_PKG_PREFIXES);
updateContextAttributes(contextHashtable, this.DNS_URL_TF, Context.DNS_URL);
updateContextAttributes(contextHashtable, this.AUTHORITATIVE_TF, Context.AUTHORITATIVE);
updateContextAttributes(contextHashtable, this.BATCHSIZE_TF, Context.BATCHSIZE);
updateContextAttributes(contextHashtable, this.REFERRAL_TF, Context.REFERRAL);
updateContextAttributes(contextHashtable, this.SECURITY_PROTOCOL_TF, Context.SECURITY_PROTOCOL);
updateContextAttributes(contextHashtable, this.SECURITY_AUTHENTICATION_TF, Context.SECURITY_AUTHENTICATION);
updateContextAttributes(contextHashtable, this.LANGUAGE_TF, Context.LANGUAGE);
updateContextAttributes(contextHashtable, this.APPLET_TF, Context.APPLET);
return jndiDatabase;
}
private void updateContextAttributes(Map<String, String> contextHashtable, UITextField textField, String contextAttr) {
String tValue = textField.getText();
if (tValue != null && tValue.trim().length() > 0) {
contextHashtable.put(contextAttr, tValue);
}
}
ActionListener jndiListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object o = JNDIFactoryComboBox.getSelectedItem();
if (o == null || ComparatorUtils.equals(o, StringUtils.EMPTY)) {
PROVIDER_URL_TF.setText("");
return;
}
PROVIDER_URL_TF.setText(jndiMap.get(o));
}
};
private JDialog createJDialog() {
if (this.otherAttrDialog == null) {
this.otherAttrDialog = new OtherAttrPane().showWindow(SwingUtilities.getWindowAncestor(JNDIDefPane.this));
}
return this.otherAttrDialog;
}
class OtherAttrPane extends BasicPane {
public OtherAttrPane() {
// JPanel northFlowPane
JPanel northFlowPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
northFlowPane.setBorder(new ScaledEmptyBorder(10,10,10,10));
// ContextPane
northFlowPane.add(column(LayoutConstants.VERTICAL_GAP,
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("OBJECT_FACTORIES")).weight(0.35), cell(OBJECT_FACTORIES_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("STATE_FACTORIES")).weight(0.35), cell(STATE_FACTORIES_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("URL_PKG_PREFIXES")).weight(0.35), cell(URL_PKG_PREFIXES_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("DNS_URL")).weight(0.35), cell(DNS_URL_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("AUTHORITATIVE")).weight(0.35), cell(AUTHORITATIVE_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("BATCHSIZE")).weight(0.35), cell(BATCHSIZE_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("REFERRAL")).weight(0.35), cell(REFERRAL_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("SECURITY_PROTOCOL")).weight(0.35), cell(SECURITY_PROTOCOL_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("SECURITY_AUTHENTICATION")).weight(0.35), cell(SECURITY_AUTHENTICATION_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("LANGUAGE")).weight(0.35), cell(LANGUAGE_TF)).weight(0.65),
row(LayoutConstants.HORIZONTAL_GAP, cell(new UILabel("APPLET")).weight(0.35), cell(APPLET_TF)).weight(0.65)
).getComponent());
this.add(northFlowPane, BorderLayout.NORTH);
}
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Other_Attributes");
}
}
// 主力Context属性
class ContextTextField extends UITextField {
private String contextName;
public ContextTextField(String contextName) {
this.setContextName(contextName);
this.setColumns(24);
}
public String getContextName() {
return contextName;
}
public void setContextName(String contextName) {
this.contextName = contextName;
}
/*
* 更新Properties.
*/
public void applyProperties(Properties properties) {
properties.put(contextName, this.getText());
}
}
}

9
designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java

@ -6,6 +6,7 @@ import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.security.ssl.Ssl;
import com.fr.data.security.ssl.SslException;
import com.fr.data.security.ssl.SslType;
import com.fr.data.security.ssl.SslUtils;
import com.fr.data.security.ssl.impl.NormalSsl;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.data.datapane.connect.SshPane.KeyFileUITextField;
@ -19,6 +20,7 @@ import com.fr.file.FILE;
import com.fr.file.FILEChooserPane;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
@ -47,6 +49,7 @@ public class SslPane extends BasicPane {
private final UIButton fileChooserButtonClientKey = new UIButton();
private final UICheckBox verifyCa = new UICheckBox(i18nText("Fine-Design_Basic_Ssl_Verify_Ca"));
private final JPanel sslSettingPane;
private static final String TRIM = SslUtils.CERTIFICATES + ProjectConstants.FORWARD_SLASH;
public SslPane() {
initDotButtons();
@ -151,7 +154,11 @@ public class SslPane extends BasicPane {
if (file == null) {
textField.setText(StringUtils.EMPTY);
} else {
textField.setText(file.getPath());
String path = file.getPath();
if (path.startsWith(TRIM)) {
path = path.substring(TRIM.length());
}
textField.setText(path);
}
}
fileChooser.removeAllFilter();

5
designer-base/src/main/java/com/fr/design/data/datapane/preview/ConnectionInfoBeanHelper.java

@ -40,6 +40,7 @@ import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.connection.ConnectionCacheEvent;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.DataEncryptionHelper;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
@ -123,8 +124,12 @@ public class ConnectionInfoBeanHelper {
/**
* 根据bean创建连接
*/
@Nullable
public static Connection createConnection(ConnectionInfoBean infoBean) {
try {
if (infoBean == null) {
return null;
}
Connection connection = cache.get(VALUE).get(infoBean.getConnectionName());
if (connection != null) {
connection.setConnectionName(infoBean.getConnectionName());

11
designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java

@ -14,7 +14,6 @@ import com.fr.data.desensitize.base.DesensitizationTableData;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.EmbeddedTableData;
import com.fr.data.impl.NameDataModel;
import com.fr.data.operator.DataOperator;
import com.fr.design.DesignerEnvManager;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.preview.desensitization.TableDataPreviewDesensitizeManager;
@ -23,6 +22,7 @@ import com.fr.design.data.datapane.preview.desensitization.view.PreviewTableDese
import com.fr.design.data.datapane.preview.desensitization.view.setting.TableDataDesensitizationSettingPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.CollapsibleDetailDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
@ -56,7 +56,6 @@ import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
@ -100,7 +99,8 @@ public class PreviewTablePane extends BasicPane {
private PreviewTableDesensitizationPane desensitizationPane;
private static final int PREVIEW_TABLE_MIN_COLUMN_WIDTH = FineUIScale.scale(75);
private static final int PREVIEW_TABLE_WIDTH = FineUIScale.scale(610);
private static final int PREVIEW_TABLE_WIDTH = FineUIUtils.getScaledI18nDimension(
"com.fr.design.data.datapane.preview.PreviewTablePane").width;
private static final int TAB_MAX_COUNT_WITH_LINE = 7;
/**
@ -579,8 +579,9 @@ public class PreviewTablePane extends BasicPane {
} catch (Exception e) {
if (!(e instanceof CancellationException)) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), e.getMessage(),
Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon"));
CollapsibleDetailDialog detailDialog = new CollapsibleDetailDialog(DesignerContext.getDesignerFrame(),
new UILabel(Toolkit.i18nText("Fine-Design_Dataset_Query_Fail-Tip")), e.getMessage());
detailDialog.setVisible(true);
}
dialog.setVisible(false);
} finally {

6
designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DCTableDataPane.java

@ -1,5 +1,6 @@
package com.fr.design.data.tabledata.datacenter;
import com.fanruan.workplace.conetxt.WorkplaceContext;
import com.fanruan.workplace.http.ServiceType;
import com.fr.datacenters.tabledata.DCTableData;
import com.fr.datacenters.tabledata.bean.DCNameBean;
@ -31,9 +32,10 @@ import static com.fr.design.ui.ModernUIConstants.SCHEME_HEADER;
*/
public class DCTableDataPane extends AbstractTableDataPane<DCTableData> {
private static final JxEngine JX_ENGINE = JxEngine.newInstance(false);
private static final JxEngine JX_ENGINE = JxEngine.newInstance(true);
private static final String DATA_CENTER = "dc";
private static final String LANGUAGE = "language";
private static final String DATA_CENTER_HELPER = "dcHelper";
private static final String DATA_CENTER_INJECT_URL = "fineServletURL";
private static final String DC_INDEX_HTML = "com/fr/design/data/tabledata/datacenter/web/data-choose.prod.html";
@ -70,6 +72,7 @@ public class DCTableDataPane extends AbstractTableDataPane<DCTableData> {
.engine(JX_ENGINE)
.namespace(DATA_CENTER)
.bindWindow(DATA_CENTER_HELPER, DCTableDataJSBridge::getBridge)
.bindNamespace(LANGUAGE, WorkplaceContext.getLocale().toString())
.withURL(DATACENTERS_URL, ImmutableMap.of(DATA_CENTER_INJECT_URL, getDatacentersUrl()))
.build();
} else {
@ -77,6 +80,7 @@ public class DCTableDataPane extends AbstractTableDataPane<DCTableData> {
.engine(JX_ENGINE)
.namespace(DATA_CENTER)
.bindWindow(DATA_CENTER_HELPER, DCTableDataJSBridge::getBridge)
.bindNamespace(LANGUAGE, WorkplaceContext.getLocale().toString())
.withEMB(DC_INDEX_HTML, ImmutableMap.of(DATA_CENTER_INJECT_URL, getDatacentersUrl()))
.build();
}

16
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java

@ -10,7 +10,6 @@ import com.fr.data.core.db.TableProcedure;
import com.fr.data.impl.Connection;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.JNDIDatabaseConnection;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.UpdateAction;
@ -63,11 +62,8 @@ import com.fr.stable.ArrayUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
@ -80,7 +76,6 @@ import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -88,11 +83,13 @@ import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import static com.fine.theme.utils.FineClientProperties.COMBO_BOX_TYPE;
import static com.fine.theme.utils.FineClientProperties.ADAPTIVE_COMBO_BOX;
import static com.fine.theme.utils.FineClientProperties.COMBO_BOX_TYPE;
/**
* @author rinoux
@ -194,8 +191,7 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> implemen
@Override
protected void filter(Connection connection, String conName, List<String> nameList) {
connection.addConnection(nameList, conName, new Class[]{
JDBCDatabaseConnection.class,
JNDIDatabaseConnection.class
JDBCDatabaseConnection.class
});
}
@ -562,7 +558,9 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> implemen
}
//保存
this.configHandler.save(this.dbTableData, this.strategyConfig);
if (this.configHandler != null) {
this.configHandler.save(this.dbTableData, this.strategyConfig);
}
}
private void updateDBTableData() {

3
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java

@ -14,6 +14,7 @@ import com.fr.design.gui.iprogressbar.AutoProgressBar;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.ui.util.UIUtil;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
@ -200,7 +201,7 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
throw new Exception(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"));
} finally {
connectionBar.close();
UIUtil.invokeLaterIfNeeded(() -> connectionBar.close());
}
}

5
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java

@ -13,6 +13,7 @@ import com.fr.design.gui.iprogressbar.AutoProgressBar;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.ui.util.UIUtil;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.server.entity.connection.ConnectionBean;
@ -185,10 +186,10 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper {
ConnectionRepository.getInstance().testConnection(ConnectionInfoBeanHelper.createConnectionInfoBean(((StoreProcedure) getTableData()).getDatabaseConnection()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
connectionBar.close();
throw new Exception(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"));
} finally {
UIUtil.invokeLaterIfNeeded(() -> connectionBar.close());
}
connectionBar.close();
storeProcedure.resetDataModelList();
createStore(true);
return null;

30
designer-base/src/main/java/com/fr/design/debug/edt/StrictEDTException.java

@ -0,0 +1,30 @@
package com.fr.design.debug.edt;
/**
* Swing组件严格限制EDT运行
*
* @author vito
* @since 11.0
* Created on 2023/8/9
*/
public class StrictEDTException extends RuntimeException {
public StrictEDTException() {
}
public StrictEDTException(String message) {
super(message);
}
public StrictEDTException(String message, Throwable cause) {
super(message, cause);
}
public StrictEDTException(Throwable cause) {
super(cause);
}
public StrictEDTException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

130
designer-base/src/main/java/com/fr/design/debug/edt/StrictEdtListeners.java

@ -0,0 +1,130 @@
package com.fr.design.debug.edt;
import com.fr.design.ui.util.EdtInvocationManager;
import com.fr.log.FineLoggerFactory;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* Swing组件严格限制EDT运行监听器
*
* @author vito
* @since 11.0
* Created on 2023/8/9
*/
public class StrictEdtListeners implements HierarchyListener, PropertyChangeListener, ComponentListener, MouseListener,
MouseWheelListener, MouseMotionListener, KeyListener {
@Override
public void componentResized(ComponentEvent e) {
checkEventDispatchThread();
}
@Override
public void componentMoved(ComponentEvent e) {
checkEventDispatchThread();
}
@Override
public void componentShown(ComponentEvent e) {
checkEventDispatchThread();
}
@Override
public void componentHidden(ComponentEvent e) {
checkEventDispatchThread();
}
@Override
public void hierarchyChanged(HierarchyEvent e) {
checkEventDispatchThread();
}
@Override
public void keyTyped(KeyEvent e) {
checkEventDispatchThread();
}
@Override
public void keyPressed(KeyEvent e) {
checkEventDispatchThread();
}
@Override
public void keyReleased(KeyEvent e) {
checkEventDispatchThread();
}
@Override
public void mouseClicked(MouseEvent e) {
checkEventDispatchThread();
}
@Override
public void mousePressed(MouseEvent e) {
checkEventDispatchThread();
}
@Override
public void mouseReleased(MouseEvent e) {
checkEventDispatchThread();
}
@Override
public void mouseEntered(MouseEvent e) {
checkEventDispatchThread();
}
@Override
public void mouseExited(MouseEvent e) {
checkEventDispatchThread();
// redispatchMouseEvent(e);
}
@Override
public void mouseDragged(MouseEvent e) {
checkEventDispatchThread();
}
@Override
public void mouseMoved(MouseEvent e) {
checkEventDispatchThread();
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
checkEventDispatchThread();
}
@Override
public void propertyChange(PropertyChangeEvent e) {
checkEventDispatchThread();
}
/**
* 检查当前是否处于EDT中并发出告警
*/
public static void checkEventDispatchThread() {
if (!EdtInvocationManager.getInstance().isEventDispatchThread()) {
String s = String.format(
"[StrictEDT] The current operation can only be in an EDT (Event Dispatch Thread). Current thread is: %s",
Thread.currentThread().getName()
);
StrictEDTException strictEdtException = new StrictEDTException(s);
FineLoggerFactory.getLogger().warn(s, strictEdtException);
}
}
}

135
designer-base/src/main/java/com/fr/design/debug/edt/StrictEdtManager.java

@ -0,0 +1,135 @@
package com.fr.design.debug.edt;
import com.fanruan.gui.InspectorWindow;
import com.fr.design.mainframe.DesignerContext;
import com.fr.log.FineLoggerFactory;
import org.jetbrains.annotations.NotNull;
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.Container;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.ContainerEvent;
/**
* 严格UI线程运行管理器
*
* @author vito
* @since 11.0
* Created on 2024/12/20
*/
public class StrictEdtManager {
private static final StrictEdtListeners LISTENERS = new StrictEdtListeners();
private static void installContainerEDTCheckers(@NotNull final Container component, int level) {
if (FineLoggerFactory.getLogger().isDebugEnabled()) {
for (int i = 0; i < level; i++) {
FineLoggerFactory.getLogger().debug(" ");
}
FineLoggerFactory.getLogger().debug(component.toString());
}
int count = component.getComponentCount();
level += 1;
for (int i = 0; i < count; i++) {
Component comp = component.getComponent(i);
addEDTCheckersListener(comp);
if (comp instanceof Container) {
installContainerEDTCheckers((Container) comp, level);
}
}
}
private static void addEDTCheckersListener(Component comp) {
comp.addHierarchyListener(LISTENERS);
comp.addPropertyChangeListener(LISTENERS);
comp.addComponentListener(LISTENERS);
comp.addMouseListener(LISTENERS);
comp.addMouseMotionListener(LISTENERS);
comp.addKeyListener(LISTENERS);
}
private static void installEDTCheckers(Container container, int level) {
installContainerEDTCheckers(container, level);
level += 1;
if (container instanceof Window) {
Window[] children = ((Window) container).getOwnedWindows();
for (Window child : children) {
if (child instanceof InspectorWindow) {
continue;
}
installEDTCheckers(child, level);
}
}
}
private static final AWTEventListener AWT_EVENT_LISTENER = (AWTEvent event) -> {
if (event instanceof ContainerEvent) {
Component child = event.getID() == ContainerEvent.COMPONENT_ADDED ? ((ContainerEvent) event).getChild() : null;
if (child != null) {
addEDTCheckersListener(child);
}
}
};
/**
* 监听组件警告不在EDT中执行的UI操作
*/
public static void install() {
// 监听当前的组件
installEDTCheckers(DesignerContext.getDesignerFrame(), 0);
// 监听新增的组件
Toolkit.getDefaultToolkit().addAWTEventListener(AWT_EVENT_LISTENER, AWTEvent.CONTAINER_EVENT_MASK);
FineLoggerFactory.getLogger().info("[StrictEDT] install Strict EDT Checkers");
}
private static void uninstallContainerEDTCheckers(@NotNull final Container component, int level) {
int count = component.getComponentCount();
level += 1;
for (int i = 0; i < count; i++) {
Component comp = component.getComponent(i);
removeEDTCheckersListener(comp);
if (comp instanceof Container) {
uninstallContainerEDTCheckers((Container) comp, level);
}
}
}
private static void removeEDTCheckersListener(Component comp) {
comp.removeHierarchyListener(LISTENERS);
comp.removePropertyChangeListener(LISTENERS);
comp.removeComponentListener(LISTENERS);
comp.removeMouseListener(LISTENERS);
comp.removeMouseMotionListener(LISTENERS);
comp.removeKeyListener(LISTENERS);
}
private static void removeEDTCheckers(Container container, int level) {
uninstallContainerEDTCheckers(container, level);
level += 1;
if (container instanceof Window) {
Window[] children = ((Window) container).getOwnedWindows();
for (Window child : children) {
if (child instanceof InspectorWindow) {
continue;
}
removeEDTCheckers(child, level);
}
}
}
/**
* 监听组件警告不在EDT中执行的UI操作
*/
public static void uninstall() {
// 取消监听新增的组件
Toolkit.getDefaultToolkit().removeAWTEventListener(AWT_EVENT_LISTENER);
// 解除监听当前的组件
removeEDTCheckers(DesignerContext.getDesignerFrame(), 0);
FineLoggerFactory.getLogger().info("[StrictEDT] uninstall Strict EDT Checkers");
}
}

2
designer-base/src/main/java/com/fr/design/remote/ui/debug/HeaderRenderer.java → designer-base/src/main/java/com/fr/design/debug/remote/HeaderRenderer.java

@ -1,4 +1,4 @@
package com.fr.design.remote.ui.debug;
package com.fr.design.debug.remote;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineTableHeaderUI;

14
designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkAction.java → designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkAction.java

@ -1,22 +1,19 @@
package com.fr.design.remote.ui.debug;
package com.fr.design.debug.remote;
import com.fine.theme.utils.FineUIUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.workspace.WorkContext;
import javax.swing.JDialog;
import javax.swing.KeyStroke;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import static com.fine.theme.utils.FineUIScale.createScaleDimension;
import static com.fine.theme.utils.FineUIScale.unscale;
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER;
/**
@ -42,7 +39,7 @@ public class RemoteDesignNetWorkAction extends UpdateAction {
return;
}
JDialog jDialog = new JDialog(DesignerContext.getDesignerFrame(), TITLE);
jDialog.setSize(calculatePaneDimension());
jDialog.setSize(FineUIUtils.calPaneDimensionByContext(0.8, 0.6));
RemoteDesignNetWorkTablePane netWorkPane = new RemoteDesignNetWorkTablePane();
jDialog.add(netWorkPane);
jDialog.addWindowListener(new WindowAdapter() {
@ -56,10 +53,5 @@ public class RemoteDesignNetWorkAction extends UpdateAction {
jDialog.setVisible(true);
}
private static Dimension calculatePaneDimension() {
DesignerFrame parent = DesignerContext.getDesignerFrame();
return createScaleDimension((int) (unscale(parent.getWidth()) * 0.8),
(int) (unscale(parent.getHeight()) * 0.6));
}
}

2
designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkHelper.java → designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkHelper.java

@ -1,4 +1,4 @@
package com.fr.design.remote.ui.debug;
package com.fr.design.debug.remote;
import com.fr.stable.StringUtils;

8
designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkTablePane.java → designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkTablePane.java

@ -1,4 +1,4 @@
package com.fr.design.remote.ui.debug;
package com.fr.design.debug.remote;
import com.fanruan.workplace.http.debug.RequestInfo;
import com.fine.theme.icon.LazyIcon;
@ -24,9 +24,9 @@ import java.awt.Component;
import java.util.concurrent.atomic.AtomicLong;
import static com.fanruan.workplace.http.debug.RemoteDesignDebugEvent.REMOTE_HTTP_REQUEST;
import static com.fr.design.remote.ui.debug.RemoteDesignNetWorkHelper.dateFormat;
import static com.fr.design.remote.ui.debug.RemoteDesignNetWorkHelper.simpleSize;
import static com.fr.design.remote.ui.debug.RemoteDesignNetWorkHelper.simpleTime;
import static com.fr.design.debug.remote.RemoteDesignNetWorkHelper.dateFormat;
import static com.fr.design.debug.remote.RemoteDesignNetWorkHelper.simpleSize;
import static com.fr.design.debug.remote.RemoteDesignNetWorkHelper.simpleTime;
/**
* 远程设计网络调试面板

2
designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkTableRowSorter.java → designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkTableRowSorter.java

@ -1,4 +1,4 @@
package com.fr.design.remote.ui.debug;
package com.fr.design.debug.remote;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

4
designer-base/src/main/java/com/fr/design/remote/ui/debug/SizeColorCellRenderer.java → designer-base/src/main/java/com/fr/design/debug/remote/SizeColorCellRenderer.java

@ -1,10 +1,10 @@
package com.fr.design.remote.ui.debug;
package com.fr.design.debug.remote;
import com.fine.theme.light.ui.FineTableHeaderUI;
import java.awt.Color;
import static com.fr.design.remote.ui.debug.RemoteDesignNetWorkHelper.DEFAULT_COLOR;
import static com.fr.design.debug.remote.RemoteDesignNetWorkHelper.DEFAULT_COLOR;
/**
* 大小多颜色渲染

4
designer-base/src/main/java/com/fr/design/remote/ui/debug/TimeColorCellRenderer.java → designer-base/src/main/java/com/fr/design/debug/remote/TimeColorCellRenderer.java

@ -1,10 +1,10 @@
package com.fr.design.remote.ui.debug;
package com.fr.design.debug.remote;
import com.fine.theme.light.ui.FineTableHeaderUI;
import java.awt.Color;
import static com.fr.design.remote.ui.debug.RemoteDesignNetWorkHelper.DEFAULT_COLOR;
import static com.fr.design.debug.remote.RemoteDesignNetWorkHelper.DEFAULT_COLOR;
/**
* 时间多颜色渲染

48
designer-base/src/main/java/com/fr/design/debug/ui/LatencyInfo.java

@ -0,0 +1,48 @@
package com.fr.design.debug.ui;
/**
* UI卡顿信息Bean
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/07
*/
public class LatencyInfo {
// swing事件编号
private long seq;
// 耗时 ms
private long cost;
// 堆栈信息
private StackTraceElement[] detailStack;
public LatencyInfo(long seq, long cost, StackTraceElement[] detailStack) {
this.seq = seq;
this.cost = cost;
this.detailStack = detailStack;
}
public long getCost() {
return cost;
}
public void setCost(long cost) {
this.cost = cost;
}
public StackTraceElement[] getDetailStack() {
return detailStack;
}
public void setDetailStack(StackTraceElement[] detailStack) {
this.detailStack = detailStack;
}
public long getSeq() {
return seq;
}
public void setSeq(long seq) {
this.seq = seq;
}
}

17
designer-base/src/main/java/com/fr/design/debug/ui/LatencyMonitorEvent.java

@ -0,0 +1,17 @@
package com.fr.design.debug.ui;
import com.fr.event.Event;
/**
* UI性能监控事件
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/08
*/
public enum LatencyMonitorEvent implements Event<LatencyInfo> {
/**
* 超出卡顿阈值
*/
OFF_THRESHOLD_EVENT
}

56
designer-base/src/main/java/com/fr/design/debug/ui/UIInspectorHolder.java

@ -0,0 +1,56 @@
package com.fr.design.debug.ui;
import com.fanruan.gui.UiInspector;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* UIInspectorHolder 单例管理
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/08
*/
public class UIInspectorHolder {
private UiInspector uiInspector;
private final AtomicBoolean installed = new AtomicBoolean(false);
private final static class InstanceHolder {
static final UIInspectorHolder INSTANCE = new UIInspectorHolder();
}
/**
* 单例
*/
public static UIInspectorHolder getInstance() {
return UIInspectorHolder.InstanceHolder.INSTANCE;
}
/**
* 是否已启用UIInspector
* @return 是否启用
*/
public boolean isInstalled() {
return installed.get();
}
/**
* 启用UIInspector
*/
public void install() {
if (installed.compareAndSet(false, true)) {
uiInspector = new UiInspector();
}
}
/**
* 注销UIInspector
*/
public void uninstall() {
if (uiInspector != null) {
uiInspector.dispose();
installed.set(false);
}
}
}

46
designer-base/src/main/java/com/fr/design/debug/ui/UILatencyInfoHandler.java

@ -0,0 +1,46 @@
package com.fr.design.debug.ui;
import com.fr.design.carton.DispatchInfo;
import com.fr.design.carton.latency.AbstractUIDispatchHandler;
/**
* UI卡顿实时监控Handler
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/07
*/
public class UILatencyInfoHandler extends AbstractUIDispatchHandler {
private long threshold = 200;
private final static class InstanceHolder {
static final UILatencyInfoHandler INSTANCE = new UILatencyInfoHandler();
}
/**
* 单例
*/
public static UILatencyInfoHandler getInstance() {
return UILatencyInfoHandler.InstanceHolder.INSTANCE;
}
public long getThreshold() {
return threshold;
}
public void setThreshold(long threshold) {
this.threshold = threshold;
}
@Override
protected boolean accept(DispatchInfo info) {
return info.timeSoFar() > threshold;
}
@Override
protected void doHandle(DispatchInfo info) {
LatencyInfo infoBean = new LatencyInfo(info.getEventSeq(), info.timeSoFar(), info.getEventDispatchThread().getStackTrace());
UILatencyWorker.getInstance().submit(infoBean);
}
}

124
designer-base/src/main/java/com/fr/design/debug/ui/UILatencyWorker.java

@ -0,0 +1,124 @@
package com.fr.design.debug.ui;
import com.fr.design.carton.latency.UIDispatchManager;
import com.fr.event.EventDispatcher;
import com.fr.third.guava.cache.Cache;
import com.fr.third.guava.cache.CacheBuilder;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
* UI性能监控Worker
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/07
*/
public class UILatencyWorker {
private ExecutorService executorService;
private final AtomicBoolean initialized = new AtomicBoolean(false);
// 默认允许存储300卡顿信息
private final Cache<Long, LatencyInfo> infoContainer = CacheBuilder.newBuilder()
.maximumSize(300).build();
private final static class InstanceHolder {
static final UILatencyWorker INSTANCE = new UILatencyWorker();
}
/**
* 单例
*/
public static UILatencyWorker getInstance() {
return InstanceHolder.INSTANCE;
}
/**
* 开始监控: 启动异步提交线程启动定时堆栈检测任务
*/
public void start() {
if (initialized.compareAndSet(false, true)) {
executorService = Executors.newSingleThreadExecutor();
UIDispatchManager.getInstance().registerHandler(UILatencyInfoHandler.getInstance());
UIDispatchManager.getInstance().startScheduler();
}
}
/**
* 停止监控关闭异步提交线程及定时堆栈任务
*/
public void stop() {
UIDispatchManager.getInstance().unregisterHandler(UILatencyInfoHandler.getInstance());
UIDispatchManager.getInstance().stopSchedulerIfNecessary();
if (this.executorService != null) {
this.executorService.shutdown();
}
initialized.set(false);
}
/**
* 是否监控中
*
* @return 是否监控中
*/
public boolean isMonitoring() {
return initialized.get();
}
/**
* 设置UI卡顿堆栈阈值
* @param threshold 阈值 ms
*/
public void resetThreshold(long threshold) {
UILatencyInfoHandler.getInstance().setThreshold(threshold);
}
/**
* 提交卡顿堆栈信息
* @param latencyInfo 卡顿信息
*/
public void submit(LatencyInfo latencyInfo) {
executorService.submit(() -> {
if (UIMonitorHelper.isIgnoreEvent(latencyInfo.getDetailStack())) {
return;
}
LatencyInfo existInfo = infoContainer.getIfPresent(latencyInfo.getSeq());
// 确保记录的是最深的堆栈信息
if (existInfo == null || latencyInfo.getDetailStack().length > existInfo.getDetailStack().length) {
infoContainer.put(latencyInfo.getSeq(), latencyInfo);
EventDispatcher.fire(LatencyMonitorEvent.OFF_THRESHOLD_EVENT, latencyInfo);
}
});
}
/**
* 输出卡顿文本信息
*
* @return 卡顿文本信息
*/
public String getLatencyData() {
return getAllLatencyInfo().stream().map(info -> "seq:" + info.getSeq() + "\n" +
"cost:" + info.getCost() + "ms\n" +
"stack:" + UIMonitorHelper.convertStack(info.getDetailStack()) + "\n").collect(Collectors.joining("\n"));
}
/**
* 获取当前记录的所有卡顿信息
* @return 全量卡顿信息
*/
public Collection<LatencyInfo> getAllLatencyInfo() {
return infoContainer.asMap().values();
}
/**
* 清空全量卡顿信息
*/
public void clearData() {
infoContainer.invalidateAll();
}
}

40
designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorAction.java

@ -0,0 +1,40 @@
package com.fr.design.debug.ui;
import com.fine.theme.utils.FineUIUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.JDialog;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER;
/**
* UI实时监控
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/07
*/
public class UIMonitorAction extends UpdateAction {
public static final String TITLE = "UI Monitor";
public UIMonitorAction() {
this.setName(TITLE);
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, DEFAULT_MODIFIER));
}
@Override
public void actionPerformed(ActionEvent e) {
JDialog jDialog = new JDialog(DesignerContext.getDesignerFrame(), TITLE);
jDialog.setSize(FineUIUtils.calPaneDimensionByContext(0.5, 0.7));
UIMonitorPane monitorPane = new UIMonitorPane();
jDialog.add(monitorPane);
GUICoreUtils.centerWindow(jDialog);
jDialog.setVisible(true);
}
}

44
designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorHelper.java

@ -0,0 +1,44 @@
package com.fr.design.debug.ui;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* UI性能监控工具类
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/08
*/
public class UIMonitorHelper {
/**
* 判断是否特定的堆栈
*/
public static boolean stackTraceElementIs(StackTraceElement e, String className, String methodName, boolean isNative) {
return e.getClassName().equals(className) && e.getMethodName().equals(methodName) && e.isNativeMethod() == isNative;
}
/**
* 用于判断是否为需要忽略记录的堆栈信息
*/
public static boolean isIgnoreEvent(StackTraceElement[] currentStack) {
return currentStack != null && currentStack.length >= 1 && (
stackTraceElementIs(currentStack[0], "java.lang.Object", "wait", true)
|| stackTraceElementIs(currentStack[0], "sun.misc.Unsafe", "park", true)
);
}
/**
* 堆栈格式化
* @param stackTrace 堆栈信息
*
* @return 格式化后的堆栈信息
*/
public static String convertStack(StackTraceElement[] stackTrace) {
return Arrays.stream(stackTrace)
.map(st -> "\t" + st.toString()).collect(Collectors.joining("\n"));
}
}

285
designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorPane.java

@ -0,0 +1,285 @@
package com.fr.design.debug.ui;
import com.fine.swing.ui.layout.Row;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineClientProperties;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.extension.FileExtension;
import com.fr.design.border.FineBorderFactory;
import com.fr.design.carton.latency.LatencyLevel;
import com.fr.design.debug.edt.StrictEdtManager;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.icontainer.UITableScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itable.FineUITable;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.mainframe.DesignerContext;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.file.FILE;
import com.fr.file.FILEChooserPane;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.general.GeneralUtils;
import com.fr.log.FineLoggerFactory;
import org.jetbrains.annotations.NotNull;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Arrays;
import java.util.Date;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* UI监控面板
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/11/07
*/
public class UIMonitorPane extends JPanel {
private DefaultTableModel model;
private UICheckBox inspector;
private UICheckBox strictEDTChecker;
private UICheckBox monitor;
public UIMonitorPane() {
setLayout(new BorderLayout());
setBorder(new ScaledEmptyBorder(10, 10, 10, 10));
initComponent();
}
private void initComponent() {
UITableScrollPane tablePane = initLatencyTable();
Row topSettingRow = initTopSettingRow();
inspector = new UICheckBox("Open UI Inspector");
strictEDTChecker = new UICheckBox("Open Strict EDT Checker");
monitor = new UICheckBox("Open Latency Monitor");
JPanel monitorPane = column(10,
cell(monitor), cell(topSettingRow), cell(tablePane).weight(1)
).getComponent();
add(column(10,
cell(FineUIUtils.wrapComponentWithTitle(inspector, "UI Inspector")),
cell(FineUIUtils.wrapComponentWithTitle(strictEDTChecker, "Strict EDT Checker")),
cell(FineUIUtils.wrapComponentWithTitle(monitorPane, "UI Latency Monitor"))
).getComponent(), BorderLayout.CENTER);
topSettingRow.setVisible(false);
tablePane.setVisible(false);
initMonitorStatus(topSettingRow, tablePane);
}
private void initMonitorStatus(Row topSettingRow, UITableScrollPane tablePane) {
inspector.setSelected(UIInspectorHolder.getInstance().isInstalled());
monitor.setSelected(UILatencyWorker.getInstance().isMonitoring());
// 注册事件监听
inspector.addActionListener(e -> {
if (inspector.isSelected()) {
UIInspectorHolder.getInstance().install();
} else {
UIInspectorHolder.getInstance().uninstall();
}
});
strictEDTChecker.addActionListener(e -> {
if (strictEDTChecker.isSelected()) {
StrictEdtManager.install();
} else {
StrictEdtManager.uninstall();
}
});
monitor.addActionListener(e -> {
topSettingRow.setVisible(monitor.isSelected());
tablePane.setVisible(monitor.isSelected());
if (monitor.isSelected()) {
startMonitor();
} else {
stopMonitor();
}
});
// 初始化卡顿堆栈表
if (monitor.isSelected()) {
SwingUtilities.invokeLater(() -> UILatencyWorker.getInstance().getAllLatencyInfo()
.forEach(info -> model.addRow(parseInfo2Row(info))));
}
}
private Row initTopSettingRow() {
UIComboBox comboBox = initThresholdComboBox();
UIButton export = new UIButton(new LazyIcon("export"));
export.setToolTipText("Export latency log");
UIButton clear = new UIButton(new LazyIcon("remove"));
clear.setToolTipText("Clear latency log");
JToolBar toolbar = new UIToolbar();
toolbar.add(comboBox);
toolbar.add(clear);
toolbar.add(export);
export.addActionListener(e -> exportData());
clear.addActionListener(e -> {
model.setRowCount(0);
UILatencyWorker.getInstance().clearData();
});
return row(5, cell(new UILabel("Latency Threshold")), cell(toolbar)).getComponent();
}
private static @NotNull UIComboBox initThresholdComboBox() {
UIComboBox comboBox = new UIComboBox(Arrays.stream(LatencyLevel.values())
.filter(it -> it != LatencyLevel.FLASH).map(LatencyLevel::getStart).toArray());
comboBox.putClientProperty(FineClientProperties.COMBO_BOX_TYPE, FineClientProperties.ADAPTIVE_COMBO_BOX);
comboBox.setSelectedItem(UILatencyInfoHandler.getInstance().getThreshold());
comboBox.addActionListener(e -> {
if (comboBox.getSelectedItem() != null) {
UILatencyWorker.getInstance().resetThreshold((Long) comboBox.getSelectedItem());
}
});
// 阈值初始化
comboBox.setSelectedItem(comboBox.getSelectedItem());
return comboBox;
}
private UITableScrollPane initLatencyTable() {
model = new DefaultTableModel();
model.addColumn("seq");
model.addColumn("cost(ms)");
model.addColumn("stack");
FineUITable table = new FineUITable(model) {
public boolean isCellEditable(int row, int column) {
return false;
}
};
UITableScrollPane tablePane = new UITableScrollPane(table);
table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int row = table.rowAtPoint(e.getPoint());
if (row >= 0) {
String stack = (String) table.getValueAt(row, 2);
StackPane stackPane = new StackPane(stack);
BasicDialog dialog = stackPane.showLargeWindow(SwingUtilities.getWindowAncestor(e.getComponent()), null);
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
}
}
});
TableColumnModel columnModel = table.getColumnModel();
adjustColumnWidth(columnModel.getColumn(0));
adjustColumnWidth(columnModel.getColumn(1));
return tablePane;
}
private void adjustColumnWidth(TableColumn column) {
column.setPreferredWidth(100);
column.setMinWidth(100);
column.setMaxWidth(100);
}
/**
* 开启性能监控
*/
public void startMonitor() {
EventDispatcher.listen(LatencyMonitorEvent.OFF_THRESHOLD_EVENT, latencyInfoListener);
UILatencyWorker.getInstance().start();
}
/**
* 关闭性能监控
*/
public void stopMonitor() {
UILatencyWorker.getInstance().stop();
EventDispatcher.stopListen(latencyInfoListener);
model.setRowCount(0);
}
private void exportData() {
// 导出为txt文件
FILEChooserPane fileChooserPane = FILEChooserPane.getMultiEnvInstance(true, false);
String fileName = "latency_log_" + GeneralUtils.objectToString(new Date()).replaceAll(":", "_");
fileChooserPane.setFileNameTextField(fileName, ".txt");
fileChooserPane.addChooseFILEFilter(new ChooseFileFilter(FileExtension.TXT));
int saveValue = fileChooserPane.showSaveDialog(DesignerContext.getDesignerFrame());
if (saveValue == FILEChooserPane.JOPTIONPANE_OK_OPTION || saveValue == FILEChooserPane.OK_OPTION) {
FILE target = fileChooserPane.getSelectedFILE();
try {
target.mkfile();
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(target.getPath(), true))) {
bufferedWriter.write(UILatencyWorker.getInstance().getLatencyData());
}
} catch (Exception exp) {
FineLoggerFactory.getLogger().error("[Latency] Error export latency log.", exp);
}
}
}
private final Listener<LatencyInfo> latencyInfoListener = new Listener<LatencyInfo>() {
@Override
public void on(Event event, LatencyInfo latencyInfo) {
SwingUtilities.invokeLater(() -> {
// 存量卡顿堆栈信息更新
for (int i = 0; i < model.getRowCount(); i++) {
if (latencyInfo.getSeq() == (Long) model.getValueAt(i, 0)) {
model.removeRow(i);
break;
}
}
model.addRow(parseInfo2Row(latencyInfo));
});
}
};
private Object[] parseInfo2Row(LatencyInfo latencyInfo) {
return new Object[]{
latencyInfo.getSeq(),
latencyInfo.getCost(),
UIMonitorHelper.convertStack(latencyInfo.getDetailStack())};
}
static class StackPane extends BasicPane {
public StackPane(String stack) {
setLayout(new BorderLayout());
UITextArea textArea = new UITextArea();
textArea.setBorder(null);
textArea.setEditable(false);
textArea.setText(stack);
UIScrollPane scrollPane = new UIScrollPane(textArea);
scrollPane.setBorder(FineBorderFactory.createWrappedRoundBorder());
add(scrollPane);
SwingUtilities.invokeLater(() -> scrollPane.getViewport().setViewPosition(new Point(0, 0)));
}
@Override
protected String title4PopupWindow() {
return "Latency Stack";
}
}
}

6
designer-base/src/main/java/com/fr/design/dialog/BasicScrollPane.java

@ -113,12 +113,12 @@ public abstract class BasicScrollPane<T> extends BasicBeanPane<T>{
}
/**
* 插入图表后单元格元素使用cardLayout布局,需要滚动效果获取高度在子类中重新计算
* 插入图表后单元格元素使用cardLayout布局获取可视窗口高度用于判断面板是否需要滚动效果
*
* @return height
* @return 可见区域的高度
*/
protected int getMaxHeight(){
return getHeight();
return getVisibleRect().height;
}
protected class BarLayout implements LayoutManager {

85
designer-base/src/main/java/com/fr/design/editor/editor/ColumnRowGroupEditor.java

@ -1 +1,84 @@
package com.fr.design.editor.editor; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.stable.ColumnRowGroup; import java.awt.*; /** * Author : Shockway * Date: 14-1-10 * Time: 下午1:46 */ public class ColumnRowGroupEditor extends Editor<ColumnRowGroup> { private UITextField crEditor; public ColumnRowGroupEditor() { this(""); } public ColumnRowGroupEditor(String name) { this(null, name); } public ColumnRowGroupEditor(ColumnRowGroup value) { this(value, ""); } public ColumnRowGroupEditor(ColumnRowGroup value, String name) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); crEditor = new UITextField(); this.add(crEditor, BorderLayout.CENTER); this.setValue(value); this.setName(name); } @Override public ColumnRowGroup getValue() { return new ColumnRowGroup(this.crEditor.getText()); } @Override public void setValue(ColumnRowGroup value) { if (value == null) { this.crEditor.setText(""); } else { this.crEditor.setText(value.toString()); } } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); this.crEditor.setEnabled(enabled); } /** * 获取焦点 */ public void requestFocus() { this.crEditor.requestFocus(); } public String getIconName() { return "cell_group"; } /** * 是否接收/支持这个对象 * @param object 检测对象 * @return 是否支持 */ public boolean accept(Object object) { return object instanceof ColumnRowGroup; } }
package com.fr.design.editor.editor;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.stable.ColumnRowGroup;
import java.awt.*;
/**
* 单元格组编辑
*
* @author Shockway
* @since 2014-01-10
* Created on 2024-01-10
*/
public class ColumnRowGroupEditor extends Editor<ColumnRowGroup> {
private UITextField crEditor;
public ColumnRowGroupEditor() {
this("");
}
public ColumnRowGroupEditor(String name) {
this(null, name);
}
public ColumnRowGroupEditor(ColumnRowGroup value) {
this(value, "");
}
public ColumnRowGroupEditor(ColumnRowGroup value, String name) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
crEditor = new UITextField();
this.add(crEditor, BorderLayout.CENTER);
this.setValue(value);
this.setName(name);
}
@Override
public ColumnRowGroup getValue() {
return new ColumnRowGroup(this.crEditor.getText());
}
@Override
public void setValue(ColumnRowGroup value) {
if (value == null) {
this.crEditor.setText("");
} else {
this.crEditor.setText(value.toString());
}
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
this.crEditor.setEnabled(enabled);
}
/**
* 获取焦点
*/
public void requestFocus() {
this.crEditor.requestFocus();
}
public String getIconName() {
return "cell_group";
}
public String getIconId() {
return "cell_group_popup";
}
/**
* 是否接收/支持这个对象
* @param object 检测对象
* @return 是否支持
*/
public boolean accept(Object object) {
return object instanceof ColumnRowGroup;
}
}

3
designer-base/src/main/java/com/fr/design/editor/editor/ColumnSelectedEditor.java

@ -35,7 +35,7 @@ public class ColumnSelectedEditor extends Editor<SimpleDSColumn> implements Prep
public ColumnSelectedEditor() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_DS_Column"));
this.setLayout(new BorderLayout());
tableDataComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource());
tableDataComboBox = new TableDataComboBox();
columnNames = new String[0];
tableDataComboBox.addItemListener(new ItemListener() {
@ -117,6 +117,5 @@ public class ColumnSelectedEditor extends Editor<SimpleDSColumn> implements Prep
@Override
public void registerDSChangeListener() {
tableDataComboBox.registerGlobalDSChangeListener();
}
}

3
designer-base/src/main/java/com/fr/design/env/HttpWorkspaceConnector.java vendored

@ -3,6 +3,7 @@ package com.fr.design.env;
import com.fanruan.workplace.http.HttpConstants;
import com.fanruan.workplace.http.HttpServiceMap;
import com.fanruan.workplace.http.RepositoryManager;
import com.fanruan.workplace.http.exception.RemoteServiceErrorException;
import com.fanruan.workplace.http.info.Stub;
import com.fanruan.workplace.network.RemoteNetworkRepository;
import com.fr.decision.webservice.bean.authentication.LoginRequestInfoBean;
@ -86,7 +87,7 @@ public class HttpWorkspaceConnector implements WorkspaceConnector {
client.setTimeout(timeout);
try {
return RemoteNetworkRepository.getInstance().testConnect();
} catch (RemoteDesignNoAuthException e) {
} catch (RemoteDesignNoAuthException | RemoteServiceErrorException e) {
throw e;
} catch (Exception e) {
throw new RemoteDesignConnectionException(e, StringUtils.EMPTY);

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

@ -404,11 +404,9 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi
if (moveSuccess) {
ToastMsgDialog dialog = DesignerToastMsgUtil.createPromptDialog(Toolkit.i18nText("Fine-Design_Basic_Template_Moved_Success"));
dialog.setVisible(true);
DesignerFrameFileDealerPane.getInstance().getSelectedOperation().refresh();
SwingUtilities.invokeLater(() -> {
LocateAction.gotoEditingTemplateLeaf(targetFile);
});
NodeAuthProcessor.getInstance().refresh();
DesignerFrameFileDealerPane.getInstance().refreshRightToolBarBy(null);
LocateAction.gotoEditingTemplateLeaf(targetFile);
}
}

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

@ -116,7 +116,6 @@ public class MultiTemplateTabPane extends Row {
private boolean hoverMoreAction = false;
private Icon clodeIcon = new LazyIcon("clear");
private boolean isShowList = false;
private JButton leadingActionButton;
private final UIToolbar leadingToolBar = new UIToolbar();
//自动新建的模板B若没有进行任何编辑,切换到其他
@ -203,17 +202,6 @@ public class MultiTemplateTabPane extends Row {
updateLeadingToolBar();
}
/**
* 为前导动作添加监听
*
* @param l 监听器
*/
public void addLeadingAction(ActionListener l) {
newTemplateAction = l;
leadingActionButton.removeActionListener(newTemplateAction);
leadingActionButton.addActionListener(newTemplateAction);
}
public void setToolBarEnable(boolean enable) {
leadingToolBar.setEnabled(enable);
}
@ -787,7 +775,9 @@ public class MultiTemplateTabPane extends Row {
public void mouseClicked(MouseEvent e) {
// 双击添加模板
if (e.getClickCount() == DOUBLE_CLICK
&& isOverBlank(e.getX())) {
&& isOverBlank(e.getX())
&& newTemplateAction != null
) {
newTemplateAction.actionPerformed(null);
}
}
@ -1003,6 +993,7 @@ public class MultiTemplateTabPane extends Row {
/**
* 创建新建模板的前导区工具按钮
*
* @return
*/
private ToolBarDef createLeadingToolBarDef() {
@ -1013,17 +1004,21 @@ public class MultiTemplateTabPane extends Row {
/**
* 创建新建文件的按钮数组
*
* @return
*/
public ShortCut[] createNewTemplateShortCuts() {
ArrayList<ShortCut> shortCuts = new ArrayList<ShortCut>();
shortCuts.add(new NewWorkBookToolButtonAction());
NewWorkBookToolButtonAction action = new NewWorkBookToolButtonAction();
shortCuts.add(action);
newTemplateAction = action;
return shortCuts.toArray(new ShortCut[0]);
}
/**
* 插入插件中的按钮
*
* @return
*/
protected void insertLeadingToolButton(ToolBarDef toolBarDef, String anchor) {

1
designer-base/src/main/java/com/fr/design/gui/frpane/UICorrelationPane.java

@ -165,7 +165,6 @@ public class UICorrelationPane extends JPanel implements UIObserver {
protected void initComponents() {
tablePane = initUITable();
tablePane.setShowVerticalLines(false);
initAddButton();
}

21
designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/RefreshableJTree.java

@ -108,17 +108,18 @@ public abstract class RefreshableJTree extends CheckBoxTree {
for (int i = 0; i < nodes.length; i++) {
treeNode.add(nodes[i]);
}
DefaultTreeModel treeModel = (DefaultTreeModel) RefreshableJTree.this.getModel();
// 主要耗时是用在了treeUI的渲染上了,所以把这个放到工作线程里面
if (treeNode.getChildCount() >= 1 && ((ExpandMutableTreeNode) treeNode.getFirstChild()).getUserObject() == PENDING) {
treeNode.remove(0);
}
treeModel.nodeStructureChanged(treeNode);
return System.currentTimeMillis() - startTime;
}
@Override
protected void done() {
DefaultTreeModel treeModel = (DefaultTreeModel) RefreshableJTree.this.getModel();
treeModel.nodeStructureChanged(treeNode);
RefreshableJTree.this.updateUI();
// 恢复Tree的可用性
RefreshableJTree.this.setEnabled(true);
@ -315,4 +316,20 @@ public abstract class RefreshableJTree extends CheckBoxTree {
tip.setOpaque(false);
return tip;
}
@Override
public TreePath getPathForLocation(int x, int y) {
// NewUI树组件全选行,仅考虑y坐标即可
TreePath closestPath = getClosestPathForLocation(x, y);
if (closestPath != null) {
Rectangle pathBounds = getPathBounds(closestPath);
if(pathBounds != null &&
y >= pathBounds.y && y < (pathBounds.y + pathBounds.height)) {
return closestPath;
}
}
return null;
}
}

56
designer-base/src/main/java/com/fr/design/i18n/DesignExtendLanguageConfig.java

@ -0,0 +1,56 @@
package com.fr.design.i18n;
import com.fr.config.ConfigContext;
import com.fr.config.DefaultConfiguration;
import com.fr.config.Identifier;
import com.fr.config.holder.factory.Holders;
import com.fr.config.holder.impl.MapConf;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* 设计器语言扩展配置
*
* @author obo
* @since 11.0
* Created on 2024/09/26
*/
public class DesignExtendLanguageConfig extends DefaultConfiguration {
private static volatile DesignExtendLanguageConfig designExtendLanguageConfig = null;
/**
* 获取实例
*/
public static DesignExtendLanguageConfig getInstance() {
if (designExtendLanguageConfig == null) {
designExtendLanguageConfig = ConfigContext.getConfigInstance(DesignExtendLanguageConfig.class);
}
return designExtendLanguageConfig;
}
/**
* 设计器扩展的语言
* key为localeString例如en_US或envalue为改语言对应的国际化翻译key
*/
@Identifier("extendDesignLocales")
private MapConf<Map<String, String>> extendDesignLocales = Holders.map(new HashMap<>(), String.class, String.class);
public Map<String, String> getExtendedDesignLocales() {
return Collections.unmodifiableMap(extendDesignLocales.get());
}
public void setExtendedDesignLocales(Map<String, String> map) {
extendDesignLocales.set(map);
}
@Override
public Object clone() throws CloneNotSupportedException {
DesignExtendLanguageConfig cloned = (DesignExtendLanguageConfig) super.clone();
cloned.extendDesignLocales = ( MapConf<Map<String, String>>) extendDesignLocales.clone();
return cloned;
}
}

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

@ -51,7 +51,6 @@ public class JxEngine {
EngineOptions.Builder builder = EngineOptions
.newBuilder(RenderingMode.HARDWARE_ACCELERATED)
.addSwitch("--disable-google-traffic")
.addSwitch("--disable-web-security")
.addScheme(Scheme.of(ModernUIConstants.EMB_TAG),
new NxInterceptRequestCallback(this::getComponent, this::getParameterMap));
if (disableWebSecurity) {
@ -144,6 +143,15 @@ public class JxEngine {
return ENGINE.getValue();
}
/**
* 是否禁用安全属性
* 对客户端来说安全属性可以忽略
*
* @return 是否禁用
*/
public boolean isDisableWebSecurity() {
return disableWebSecurity;
}
/**
* 添加XHR请求头

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

@ -13,6 +13,7 @@ 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.CertificateErrorCallback;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.event.Observer;
import com.teamdev.jxbrowser.frame.Frame;
@ -81,6 +82,11 @@ public class JxUIPane<T> extends BasicPane {
}
initDebugIfNeeded();
browser = jxEngine.getEngine().newBrowser();
if (jxEngine.isDisableWebSecurity()) {
// 忽略证书验证,兼容有些情况下自定义证书与实际域名不匹配的情况。
// 虽然不是个正确的方式,但真有这么用的还是兼容一下
browser.set(CertificateErrorCallback.class, (params, action) -> action.allow());
}
add(BrowserView.newInstance(browser), BorderLayout.CENTER);
}

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

@ -98,8 +98,7 @@ public class CenterRegionContainerPane extends JPanel {
}
private MultiTemplateTabPane initTemplateTabPane() {
MultiTemplateTabPane templateTabPane = MultiTemplateTabPane.getInstance();
return templateTabPane;
return MultiTemplateTabPane.getInstance();
}
public ToolBarMenuDock getToolBarMenuDock() {

33
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java

@ -1,8 +1,10 @@
package com.fr.design.mainframe;
import com.fanruan.repository.TemplateRepository;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineLayoutBuilder;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.BaseUtils;
@ -641,11 +643,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
this.setModal(true);
// 输入框前提示
UILabel newNameLabel = new UILabel(Toolkit.i18nText(
"Fine-Design_Basic_Enter_New_Folder_Name")
);
newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
UILabel newNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Enter_New_Folder_Name"));
// 文件名输入框
nameField = new UITextField();
@ -667,12 +665,9 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
}
});
nameField.selectAll();
nameField.setPreferredSize(new Dimension(180, 20));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15));
topPanel.add(newNameLabel);
topPanel.add(nameField);
JPanel topPanel = Layouts.row(10, Layouts.cell(newNameLabel), Layouts.cell(nameField).weight(1)).getComponent();
topPanel.setBorder(new ScaledEmptyBorder(15, 10, 0, 10));
// 增加enter以及esc快捷键的支持
nameField.addKeyListener(new KeyAdapter() {
@ -689,15 +684,14 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
});
// 重名提示
warnLabel = new UILabel();
warnLabel.setPreferredSize(new Dimension(300, 50));
warnLabel.setHorizontalAlignment(SwingConstants.LEFT);
warnLabel.setVerticalAlignment(SwingConstants.TOP);
warnLabel.setForeground(Color.RED);
warnLabel.setVisible(false);
FineUIStyle.setStyle(warnLabel, FineUIStyle.LABEL_WARNING_TIP);
JPanel midPanel = new JPanel(new BorderLayout());
midPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15));
midPanel.add(warnLabel, BorderLayout.WEST);
midPanel.setBorder(new ScaledEmptyBorder(0, 10, 0, 10));
midPanel.add(Layouts.column(Layouts.flex(), Layouts.cell(warnLabel), Layouts.flex()).getComponent());
// 确认按钮
confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm"));
@ -719,10 +713,8 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
}
});
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0));
bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 10));
bottomPanel.add(confirmButton);
bottomPanel.add(cancelButton);
JPanel bottomPanel = Layouts.row(10, Layouts.flex(), Layouts.cell(confirmButton), Layouts.cell(cancelButton)).getComponent();
bottomPanel.setBorder(new ScaledEmptyBorder(10, 10, 10, 10));
this.add(
TableLayoutHelper.createTableLayoutPane(
@ -731,13 +723,12 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
new Component[]{midPanel},
new Component[]{bottomPanel}
},
new double[]{TableLayout.FILL, TableLayout.PREFERRED, TableLayout.PREFERRED},
new double[]{TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED},
new double[]{TableLayout.FILL}
),
BorderLayout.CENTER);
this.setSize(380, 200);
this.setSize(FineUIScale.createScaleDimension(380, 200));
this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Mkdir"));
this.setResizable(false);
this.setAlwaysOnTop(true);

6
designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java

@ -385,8 +385,10 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
}
private void initContentPane() {
initRightPane();
initLeftPane();
UIUtil.invokeLaterIfNeeded(() -> {
initRightPane();
initLeftPane();
});
}
// 右侧属性面板

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

@ -2049,8 +2049,10 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
themeAttrMark = new TemplateThemeAttrMark();
getTarget().addAttrMark(themeAttrMark);
}
themeAttrMark.setName(theme.getName());
themeAttrMark.setDark(theme.isDark());
if (theme != null) {
themeAttrMark.setName(theme.getName());
themeAttrMark.setDark(theme.isDark());
}
}
public String getTemplateOpenFailedTip() {

20
designer-base/src/main/java/com/fr/design/mainframe/toolbar/DebugModeMenuDef.java

@ -1,13 +1,11 @@
package com.fr.design.mainframe.toolbar;
import com.fanruan.gui.UiInspector;
import com.fine.theme.light.ui.laf.FineDarkLaf;
import com.fine.theme.light.ui.laf.FineLightLaf;
import com.fr.design.actions.UpdateAction;
import com.fr.design.gui.UILookAndFeel;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.menu.MenuDef;
import com.fr.design.remote.ui.debug.RemoteDesignNetWorkAction;
import com.fr.design.debug.remote.RemoteDesignNetWorkAction;
import com.fr.design.debug.ui.UIMonitorAction;
import java.awt.event.ActionEvent;
@ -24,15 +22,7 @@ public class DebugModeMenuDef extends MenuDef {
super("Debug");
addLookAndFeelMenu();
addRemotePane();
}
private void addUIInspect() {
this.addShortCut(new UpdateAction() {
@Override
public void actionPerformed(ActionEvent e) {
new UiInspector().showInspector(DesignerContext.getDesignerFrame());
}
});
addUIMonitorPane();
}
private void addLookAndFeelMenu() {
@ -48,4 +38,8 @@ public class DebugModeMenuDef extends MenuDef {
private void addRemotePane() {
this.addShortCut(new RemoteDesignNetWorkAction());
}
private void addUIMonitorPane() {
this.addShortCut(new UIMonitorAction());
}
}

2
designer-base/src/main/java/com/fr/design/mainframe/widget/editors/DataBindingEditor.java

@ -65,7 +65,7 @@ public class DataBindingEditor extends Editor<DataBinding> {
int vgap = UIManager.getInt("DataBindingEditor.vgap");
int hgap = UIManager.getInt("DataBindingEditor.hgap");
this.setLayout(new BorderLayout(FineUIScale.scale(hgap), FineUIScale.scale(vgap)));
tableDataComboBox = new TableDataComboBox(getTableDataSource());
tableDataComboBox = new TableDataComboBox();
tableDataComboBox.setPreferredSize(new Dimension(55, 20));
tableDataComboBox.addItemListener(tableDataComboBoxListener);

2
designer-base/src/main/java/com/fr/design/mainframe/widget/editors/DataTableEditor.java

@ -29,7 +29,7 @@ public class DataTableEditor extends Editor<DataTableConfig> {
private void initCompontents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
tableDataComboBox = new TableDataComboBox(getTableDataSource());
tableDataComboBox = new TableDataComboBox();
tableDataComboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent evt) {

4
designer-base/src/main/java/com/fr/design/metric/AbstractDesignerMetric.java

@ -2,7 +2,7 @@ package com.fr.design.metric;
import com.fanruan.carina.Carina;
import com.fanruan.config.bbs.FineBBSConfigProvider;
import com.fr.config.MarketConfig;
import com.fanruan.repository.ConfigRepository;
import com.fr.design.DesignerEnvManager;
import com.fr.general.GeneralUtils;
import com.fr.json.JSONObject;
@ -34,6 +34,6 @@ public abstract class AbstractDesignerMetric {
info.put(DESIGNER_ID, DesignerEnvManager.getEnvManager().getUUID());
info.put(DESIGNER_VERSION, GeneralUtils.getVersion());
info.put(USERID, Carina.config(FineBBSConfigProvider.class).getBbsUid());
info.put(APPID, MarketConfig.getInstance().getCloudOperationMaintenanceId());
info.put(APPID, ConfigRepository.getInstance().getAppID());
}
}

3
designer-base/src/main/java/com/fr/design/present/dict/TableDataDictPane.java

@ -78,7 +78,7 @@ public class TableDataDictPane extends FurtherBasicBeanPane<TableDataDictionary>
}
private void initBasicComponets() {
tableDataNameComboBox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource());
tableDataNameComboBox = new TableDataComboBox();
tableDataNameComboBox.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
tdChange(e);
@ -362,6 +362,5 @@ public class TableDataDictPane extends FurtherBasicBeanPane<TableDataDictionary>
@Override
public void registerDSChangeListener() {
tableDataNameComboBox.registerGlobalDSChangeListener();
}
}

158
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java

@ -1,158 +0,0 @@
package com.fr.design.record.analyzer;
import com.fr.base.OptimizeUtil;
import com.fr.collect.Collect;
import com.fr.design.record.analyzer.Interceptor.CollectInterceptor;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.record.analyzer.advice.CollectAdvice;
import com.fr.design.record.analyzer.advice.DBMonitorAdvice;
import com.fr.design.record.analyzer.advice.FaultToleranceAdvice;
import com.fr.design.record.analyzer.advice.FocusAdvice;
import com.fr.design.record.analyzer.advice.MonitorAdvice;
import com.fr.design.record.analyzer.advice.PerformancePointAdvice;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.intelli.metrics.Compute;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.PerformancePoint;
import com.fr.jvm.assist.FineAssist;
import com.fr.module.Activator;
import com.fr.module.extension.Prepare;
import com.fr.record.analyzer.AnalyzerConfiguration;
import com.fr.record.analyzer.AnalyzerKey;
import com.fr.record.analyzer.Assistant;
import com.fr.record.analyzer.DBMetrics;
import com.fr.record.analyzer.FineAnalyzer;
import com.fr.record.analyzer.advice.AnalyzerAdviceKey;
import com.fr.record.analyzer.advice.FineAdviceAssistant;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.record.analyzer.configuration.FineAnalyzerAssemblyFactory;
import com.fr.stable.collections.CollectionUtils;
import com.fr.third.net.bytebuddy.description.type.TypeDescription;
import com.fr.third.net.bytebuddy.dynamic.DynamicType;
import com.fr.third.net.bytebuddy.implementation.MethodDelegation;
import com.fr.third.net.bytebuddy.matcher.ElementMatchers;
import com.fr.third.net.bytebuddy.utility.JavaModule;
import com.fr.tolerance.FaultTolerance;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.ExecutorService;
/**
* created by Harrison on 2022/03/04
**/
public class DesignerAnalyzerActivator extends Activator implements Prepare {
@Override
public void start() {
OptimizeUtil.open(OptimizeUtil.Module.ANALYZER,() -> {
AnalyzerAssemblyFactory basicFactory = createBasicFactory();
// 兼容逻辑
List<AnalyzerConfiguration> backwardsConfigurations = findMutableBackwards(AnalyzerKey.KEY);
if (!CollectionUtils.isEmpty(backwardsConfigurations)) {
// 直接初始化,不添加默认值,防止和下面的冲突
FineAnalyzer.initDirectly(FineAssist.findInstrumentation(), basicFactory, backwardsConfigurations.toArray(new AnalyzerConfiguration[0]));
}
// 等页面完全打开后,再进行 retransform, 别影响了启动速度
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
ExecutorService es = newSingleThreadExecutor(new NamedThreadFactory("designer-analyzer", true));
try {
// 加入 retransform 部分的逻辑
List<FineAdviceAssistant> adviceConfigurations = findMutable(AnalyzerAdviceKey.KEY);
if (!CollectionUtils.isEmpty(adviceConfigurations)) {
AnalyzerConfiguration[] configurations = convertConfigurations(adviceConfigurations);
es.submit(() -> {
DesignerAnalyzer.init(basicFactory, configurations);
});
}
} finally {
es.shutdown();
}
}
});
});
}
@NotNull
private AnalyzerConfiguration[] convertConfigurations(List<FineAdviceAssistant> list) {
return list.stream()
.map(AnalyzerConfiguration::create)
.toArray(AnalyzerConfiguration[]::new);
}
@Override
public void stop() {
}
@Override
public void prepare() {
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(Focus.class),
FocusAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(Compute.class),
MonitorAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(DBMetrics.class),
DBMonitorAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(PerformancePoint.class),
PerformancePointAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(FaultTolerance.class),
FaultToleranceAdvice.class
));
// 保持M1 可用
addMutable(AnalyzerKey.KEY, AnalyzerConfiguration.create(new Assistant() {
@Override
public DynamicType.Builder<?> supply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
return builder
.method(ElementMatchers.isAnnotatedWith(Collect.class))
.intercept(MethodDelegation.to(CollectInterceptor.class));
}
}));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(Collect.class),
CollectAdvice.class
));
}
private AnalyzerAssemblyFactory createBasicFactory() {
AnalyzerAssemblyFactory factory = findSingleton(AnalyzerAssemblyFactory.class);
FineAnalyzerAssemblyFactory basicFactory = new FineAnalyzerAssemblyFactory();
basicFactory.prepare(factory);
return basicFactory;
}
}

19
designer-base/src/main/java/com/fr/design/utils/DesignUtils.java

@ -13,6 +13,7 @@ import com.fr.design.deeplink.DeepLinkCore;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.fun.DefaultValueAdjustProvider;
import com.fr.design.fun.DesignerEnvProcessor;
import com.fr.design.i18n.DesignExtendLanguageConfig;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.ui.util.UIUtil;
@ -21,10 +22,13 @@ import com.fr.file.FileFILE;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
import com.fr.general.GeneralContext;
import com.fr.general.LocaleType;
import com.fr.general.SupportLocale;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.injectable.PluginModule;
import com.fr.stable.ArrayUtils;
import com.fr.stable.CommonCodeUtils;
import com.fr.stable.CommonUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.bridge.ObjectHolder;
@ -52,7 +56,10 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
@ -491,4 +498,16 @@ public class DesignUtils {
return Utils.getAvailableFontFamilyNames4Report();
}
/**
* 获取设计器可用的开放的语言配置包括默认开放的五种语言和finedb扩展项
* @return Locale和翻译对应的key
*/
public static Map<Locale, String> getAvailableLanguages() {
Map<Locale, String> map = new LinkedHashMap<>(SupportLocale.getInstance().getLocaleMap());
map.remove(LocaleType.RU.getLocale());
for (Map.Entry<String, String> entry : DesignExtendLanguageConfig.getInstance().getExtendedDesignLocales().entrySet()) {
map.put(CommonUtils.stringToLocale(entry.getKey()), entry.getValue());
}
return Collections.unmodifiableMap(map);
}
}

22
designer-base/src/main/java/com/fr/design/write/submit/DBManipulationPane.java

@ -2,11 +2,9 @@ package com.fr.design.write.submit;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.swing.ui.layout.Spacer;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fine.theme.light.ui.FineTableHeaderUI;
import com.fine.theme.utils.FineClientProperties;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.fr.base.BaseFormula;
import com.fr.base.Parameter;
@ -21,7 +19,6 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.data.datapane.ChoosePaneSupportFormula;
import com.fr.design.data.datapane.DataBaseItems;
import com.fr.design.data.tabledata.tabledatapane.FormatExplanationPane;
import com.fr.design.dialog.AttrScrollPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
@ -33,7 +30,6 @@ import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.icontainer.UIVerticalScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.CheckBoxList;
@ -50,6 +46,7 @@ import com.fr.general.data.Condition;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ColumnRow;
import com.fr.stable.ColumnRowGroup;
import com.fr.stable.StringUtils;
import com.fr.write.DBManipulation;
import com.fr.write.NameSubmitJob;
import com.fr.write.config.ColumnConfig;
@ -103,7 +100,6 @@ import java.util.stream.Collectors;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.theme.utils.FineUIScale.scale;
//august:这个东西应该分成两类,一类是有单元格的情况,一类是没有单元格的情况
@ -1225,6 +1221,14 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
public boolean checkSelected(boolean isSelected, Class columnClass) {
return isSelected;
}
@Override
public String getTooltipValue(Object value) {
if (value instanceof ColumnName) {
return ((ColumnName) value).name;
}
return StringUtils.BLANK;
}
}
/*
@ -1255,6 +1259,14 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
public boolean checkSelected(boolean isSelected, Class columnClass) {
return isSelected;
}
@Override
public String getTooltipValue(Object value) {
if (value instanceof ColumnValue) {
return ((ColumnValue) value).obj.toString();
}
return StringUtils.BLANK;
}
}
/**

27
designer-base/src/main/java/com/fr/env/EnvPrepare.java vendored

@ -1,27 +0,0 @@
package com.fr.env;
import com.fr.env.detect.EnvDetectorCenter;
import com.fr.module.Activator;
/**
* 设计器环境准备
* 更多的是一些钩子需要在环境启动切换时进行处理
* 使用监听 {@link com.fr.workspace.WorkspaceEvent} 只能满足
* before -> stop -> start -> after
* 现在支持 =>
* before -> stop -> prepare -> start -> after
*
* created by Harrison on 2022/05/29
**/
public class EnvPrepare extends Activator {
@Override
public void start() {
EnvDetectorCenter.getInstance().init();
}
@Override
public void stop() {
EnvDetectorCenter.getInstance().destroy();
}
}

2
designer-base/src/main/java/com/fr/env/RemoteEnvPane.java vendored

@ -336,7 +336,7 @@ public class RemoteEnvPane extends BasicBeanPane<RemoteDesignerWorkspaceInfo> {
@Override
public RemoteDesignerWorkspaceInfo updateBean() {
String url = removeSpaces(this.remoteWorkspaceURL.getURL());
String url = removeSpaces(this.remoteWorkspaceURL.getStandardURL());
String username = removeSpaces(this.usernameInput.getText());
String password = new String(this.passwordInput.getPassword());
boolean rememberPwd = this.rememberPwdCheckbox.isSelected();

28
designer-base/src/main/java/com/fr/env/RemoteWorkspaceURL.java vendored

@ -1,17 +1,17 @@
package com.fr.env;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.AssistUtils;
import com.fr.stable.FCloneable;
import com.fr.stable.StringUtils;
import java.net.URI;
import java.net.URISyntaxException;
import com.fr.third.guava.base.Strings;
/**
* @author yaohwu
*/
public class RemoteWorkspaceURL implements FCloneable {
private static final String SLASH = "/";
private static final String IPV6_JUDGE_SYMBOL = "[";
private static final String IPV6_JUDGE_SYMBOL2 = "]";
@ -126,25 +126,41 @@ public class RemoteWorkspaceURL implements FCloneable {
this.servlet = servlet != null ? servlet.trim() : StringUtils.EMPTY;
}
/**
* 用于UI联动的URL不一定是标准远程设计URL
*
* @return 原始或生成的URL
*/
public String getURL() {
if (this.url != null) {
return url;
}
String prefix = isHttps ? HTTPS : HTTP;
String portColon = StringUtils.isNotEmpty(port) ? ":" : StringUtils.EMPTY;
String webAppNameSlash = StringUtils.isNotEmpty(web) ? "/" : StringUtils.EMPTY;
String servletNameSlash = "/";
this.url = prefix + host + portColon + port + webAppNameSlash + web + servletNameSlash;
String webAppNameSlash = StringUtils.isNotEmpty(web) ? SLASH : StringUtils.EMPTY;
this.url = prefix + host + portColon + port + webAppNameSlash + web + SLASH + servlet;
return this.url;
}
/**
* 获取用于远程连接的可用URL
*
* @return 远程连接的可用URL
*/
public String getStandardURL() {
String prefix = isHttps ? HTTPS : HTTP;
String portColon = StringUtils.isNotEmpty(port) ? ":" : StringUtils.EMPTY;
String webAppNameSlash = StringUtils.isNotEmpty(web) ? SLASH : StringUtils.EMPTY;
return prefix + host + portColon + port + webAppNameSlash + web + SLASH;
}
/**
* IPV6地址格式不同,处理字符串的方式不同,需要处理的是port和host
* 形如 http://[XXXX::XXXX:XXXX:XXXX:XXXX]:8080/webroot/decision
*/
public void refreshIPV6Format() {
String url = this.url;
if (Strings.isNullOrEmpty(url)) {
if (StringUtils.isEmpty(url)) {
return;
}
if (!url.contains(IPV6_JUDGE_SYMBOL) || !url.contains(IPV6_JUDGE_SYMBOL2)) {

23
designer-base/src/main/java/com/fr/file/FILEChooserPane.java

@ -1926,15 +1926,15 @@ public class FILEChooserPane extends BasicPane {
nameField.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
validInput();
resetInputChecker();
}
public void insertUpdate(DocumentEvent e) {
validInput();
resetInputChecker();
}
public void removeUpdate(DocumentEvent e) {
validInput();
resetInputChecker();
}
});
nameField.selectAll();
@ -1993,7 +1993,9 @@ public class FILEChooserPane extends BasicPane {
}
private void confirmClose() {
if (!validInput()) {
return;
};
String userInput = nameField.getText().trim();
// 处理不合法的文件夹名称
@ -2028,12 +2030,13 @@ public class FILEChooserPane extends BasicPane {
}
private void validInput() {
private boolean validInput() {
boolean valid = true;
String userInput = nameField.getText().trim();
if (StringUtils.isEmpty(userInput)) {
confirmButton.setEnabled(false);
valid = false;
}
boolean duplicate = false;
@ -2045,7 +2048,7 @@ public class FILEChooserPane extends BasicPane {
break;
}
}
valid = valid && !duplicate;
if (duplicate) {
nameField.selectAll();
// 如果文件名已存在,则灰掉确认按钮
@ -2059,6 +2062,12 @@ public class FILEChooserPane extends BasicPane {
warnLabel.setVisible(false);
confirmButton.setEnabled(true);
}
return valid;
}
private void resetInputChecker() {
warnLabel.setVisible(false);
confirmButton.setEnabled(true);
}
}
}

7
designer-base/src/main/java/com/fr/start/server/DesignEmbedHelper.java

@ -7,6 +7,7 @@ import com.fr.design.DesignerEnvManager;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.third.guava.collect.Sets;
import com.fr.third.springframework.web.SpringServletContainerInitializer;
import com.fr.third.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import com.fr.workspace.WorkContext;
@ -16,7 +17,8 @@ import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.StandardRoot;
import org.apache.tomcat.websocket.server.WsSci;
;import java.io.File;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
@ -25,6 +27,8 @@ import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
;
/**
* 内置服务器工具类
*
@ -100,6 +104,7 @@ public class DesignEmbedHelper {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(EmbedWebApplicationInitializer.class);
context.addServletContainerInitializer(initializer, classes);
context.addServletContainerInitializer(new WsSci(), Sets.newHashSet(WebSocketEndpoint.class));
}
/**

156
designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java

@ -1,156 +0,0 @@
package com.fr.start.server;
import com.fr.cbb.websocket.core.WebSocketEndpoint;
import com.fr.design.DesignerEnvManager;
import com.fr.log.FineLoggerFactory;
import com.fr.module.Activator;
import com.fr.module.ModuleRole;
import com.fr.stable.EncodeConstants;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StringUtils;
import com.fr.third.springframework.web.SpringServletContainerInitializer;
import com.fr.third.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import com.fr.workspace.WorkContext;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.StandardRoot;
import org.apache.tomcat.websocket.server.WsSci;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
/**
* Created by juhaoyu on 2018/6/5.
*/
@Deprecated
public class FineEmbedServerActivator extends Activator {
private static final String TOMCAT_MAX_HEADER_SIZE = "tomcat-maxHttpHeaderSize";
private Tomcat tomcat;
@Override
public synchronized void start() {
try {
FineEmbedServerMonitor.getInstance().reset();
//初始化tomcat
initTomcat();
tomcat.start();
} catch (LifecycleException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
FineEmbedServerMonitor.getInstance().setComplete();
}
}
@Override
public synchronized void stop() {
try {
stopSpring();
stopServerActivator();
stopTomcat();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private void initTomcat() {
tomcat = new Tomcat();
tomcat.setPort(DesignerEnvManager.getEnvManager().getEmbedServerPort());
// 设置解码uri使用的字符编码
tomcat.getConnector().setURIEncoding(EncodeConstants.ENCODING_UTF_8);
// 参考 https://jira.atlassian.com/browse/CONFSERVER-57582
// https://tomcat.apache.org/tomcat-8.5-doc/config/http.html
// 8.5.x 请求参数带特殊字符被tomcat拒绝 []|{}^\`"<>
tomcat.getConnector().setProperty("relaxedQueryChars", "[]|{}^&#x5c;&#x60;&quot;&lt;&gt;");
setMaxPostSize();
setMaxHttpHeaderSize();
String docBase = new File(WorkContext.getCurrent().getPath()).getParent();
//内置的上下文使用工程目录比如webroot
String contextPath = "/" + ProductConstants.getAppFolderName();
final Context context = tomcat.addContext(contextPath, docBase);
context.setResources(new StandardRoot(context));
Tomcat.initWebappDefaults(context);
//覆盖tomcat的WebAppClassLoader
context.setLoader(new FRTomcatLoader());
//直接指定initializer,tomcat就不用再扫描一遍了
SpringServletContainerInitializer initializer = new SpringServletContainerInitializer();
Set<Class<?>> classes = new HashSet<Class<?>>();
/// 该Initializer已去除
//classes.add(FineWebApplicationInitializer.class);
context.addServletContainerInitializer(initializer, classes);
// 后面本地设计的内置服务器考虑用XST
// context.addServletContainerInitializer(new WsSci(), Sets.newHashSet(WebSocketEndpoint.class));
}
// tomcat的maxPostSize会影响到post参数获取,默认2M
private void setMaxPostSize() {
if (System.getProperty("tomcat-maxPostSize") != null) {
try {
tomcat.getConnector().setMaxPostSize(Integer.parseInt(System.getProperty("tomcat-maxPostSize")));
} catch (Exception e) {
FineLoggerFactory.getLogger().error("maxPostSize error: " + e.getMessage(), e);
}
}
}
private void setMaxHttpHeaderSize() {
String value = System.getProperty(TOMCAT_MAX_HEADER_SIZE);
if (StringUtils.isNotEmpty(value)) {
try {
tomcat.getConnector().setProperty("maxHttpHeaderSize", value);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
private void stopServerActivator() {
ModuleRole.ServerRoot.stop();
}
private void stopSpring() {
AnnotationConfigWebApplicationContext context = ModuleRole.ServerRoot.findSingleton(AnnotationConfigWebApplicationContext.class);
if (context != null) {
context.stop();
context.destroy();
}
}
private void stopTomcat() throws LifecycleException {
tomcat.stop();
tomcat.destroy();
}
/**
* Created by juhaoyu on 2018/6/5.
* 自定义的tomcat loader主要用于防止内置服务器再加载一遍class
*/
private static class FRTomcatLoader extends WebappLoader {
@Override
public ClassLoader getClassLoader() {
return this.getClass().getClassLoader();
}
}
}

4
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_function.svg

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.1961 5.26821L17.5003 2.55679C16.572 2.02078 15.4283 2.02079 14.5001 2.55679L5.10804 7.97927C4.17972 8.51517 3.60786 9.50566 3.60791 10.5776V21.4225C3.60786 22.4944 4.17972 23.4849 5.10804 24.0208L14.5001 29.4433C15.4283 29.9793 16.572 29.9793 17.5003 29.4433L26.8923 24.0208C27.8207 23.4849 28.3925 22.4944 28.3925 21.4225V10.5776C28.3925 9.50566 27.8207 8.51517 26.8923 7.97927L22.1961 5.26821ZM26.3925 10.5775C26.3925 10.2202 26.2019 9.89 25.8924 9.71137L16.5002 4.28879C16.1908 4.11012 15.8096 4.11012 15.5001 4.28879L6.10795 9.71137C5.79851 9.89 5.60789 10.2202 5.60791 10.5775V21.4226C5.60789 21.7799 5.79851 22.1101 6.10795 22.2887L15.5001 27.7113C15.8096 27.89 16.1908 27.89 16.5002 27.7113L25.8924 22.2887C26.2019 22.1101 26.3925 21.7799 26.3925 21.4226V10.5775Z" fill="#0A1C38" fill-opacity="0.9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 16C22 19.3137 19.3137 22 16 22C12.6863 22 10 19.3137 10 16C10 12.6863 12.6863 10 16 10C19.3137 10 22 12.6863 22 16ZM16 20C18.2091 20 20 18.2091 20 16C20 13.7909 18.2091 12 16 12C13.7909 12 12 13.7909 12 16C12 18.2091 13.7909 20 16 20Z" fill="#0A1C38" fill-opacity="0.9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

4
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_function_disable.svg

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.1961 5.26821L17.5003 2.55679C16.572 2.02078 15.4283 2.02079 14.5001 2.55679L5.10804 7.97927C4.17972 8.51517 3.60786 9.50566 3.60791 10.5776V21.4225C3.60786 22.4944 4.17972 23.4849 5.10804 24.0208L14.5001 29.4433C15.4283 29.9793 16.572 29.9793 17.5003 29.4433L26.8923 24.0208C27.8207 23.4849 28.3925 22.4944 28.3925 21.4225V10.5776C28.3925 9.50566 27.8207 8.51517 26.8923 7.97927L22.1961 5.26821ZM26.3925 10.5775C26.3925 10.2202 26.2019 9.89 25.8924 9.71137L16.5002 4.28879C16.1908 4.11012 15.8096 4.11012 15.5001 4.28879L6.10795 9.71137C5.79851 9.89 5.60789 10.2202 5.60791 10.5775V21.4226C5.60789 21.7799 5.79851 22.1101 6.10795 22.2887L15.5001 27.7113C15.8096 27.89 16.1908 27.89 16.5002 27.7113L25.8924 22.2887C26.2019 22.1101 26.3925 21.7799 26.3925 21.4226V10.5775Z" fill="#0A1C38" fill-opacity="0.29"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 16C22 19.3137 19.3137 22 16 22C12.6863 22 10 19.3137 10 16C10 12.6863 12.6863 10 16 10C19.3137 10 22 12.6863 22 16ZM16 20C18.2091 20 20 18.2091 20 16C20 13.7909 18.2091 12 16 12C13.7909 12 12 13.7909 12 16C12 18.2091 13.7909 20 16 20Z" fill="#0A1C38" fill-opacity="0.29"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

4
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_function_white.svg

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.1961 5.26821L17.5003 2.55679C16.572 2.02078 15.4283 2.02079 14.5001 2.55679L5.10804 7.97927C4.17972 8.51517 3.60786 9.50566 3.60791 10.5776V21.4225C3.60786 22.4944 4.17972 23.4849 5.10804 24.0208L14.5001 29.4433C15.4283 29.9793 16.572 29.9793 17.5003 29.4433L26.8923 24.0208C27.8207 23.4849 28.3925 22.4944 28.3925 21.4225V10.5776C28.3925 9.50566 27.8207 8.51517 26.8923 7.97927L22.1961 5.26821ZM26.3925 10.5775C26.3925 10.2202 26.2019 9.89 25.8924 9.71137L16.5002 4.28879C16.1908 4.11012 15.8096 4.11012 15.5001 4.28879L6.10795 9.71137C5.79851 9.89 5.60789 10.2202 5.60791 10.5775V21.4226C5.60789 21.7799 5.79851 22.1101 6.10795 22.2887L15.5001 27.7113C15.8096 27.89 16.1908 27.89 16.5002 27.7113L25.8924 22.2887C26.2019 22.1101 26.3925 21.7799 26.3925 21.4226V10.5775Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 16C22 19.3137 19.3137 22 16 22C12.6863 22 10 19.3137 10 16C10 12.6863 12.6863 10 16 10C19.3137 10 22 12.6863 22 16ZM16 20C18.2091 20 20 18.2091 20 16C20 13.7909 18.2091 12 16 12C13.7909 12 12 13.7909 12 16C12 18.2091 13.7909 20 16 20Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

11
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_plugin.svg

@ -0,0 +1,11 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_8156_85961)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.5137 8.91632L16.268 3.00095C16.1021 2.90518 15.8978 2.90518 15.7319 3.00095L5.48606 8.91638L15.9998 15.1291L26.5137 8.91632ZM27.3916 10.1399L16.75 16.4281V28.7209L27.1235 22.7318C27.2894 22.636 27.3916 22.459 27.3916 22.2675V10.1399ZM15.25 28.721V16.4283L4.60833 10.14V22.2675C4.60833 22.4591 4.71051 22.636 4.87638 22.7318L15.25 28.721ZM17.0722 1.6081C16.4087 1.22503 15.5912 1.22503 14.9277 1.6081L4.07222 7.87553C3.40873 8.25859 3 8.96653 3 9.73266V22.2675C3 23.0336 3.40873 23.7416 4.07222 24.1247L14.9277 30.3921C15.5912 30.7751 16.4087 30.7751 17.0722 30.3921L27.9277 24.1247C28.5911 23.7416 28.9999 23.0336 28.9999 22.2675V9.73266C28.9999 8.96653 28.5911 8.25859 27.9277 7.87553L17.0722 1.6081Z" fill="#0A1C38" fill-opacity="0.9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.018 8.91882L16.143 3.21746C16.0545 3.16635 15.9454 3.16635 15.8569 3.21746L5.98172 8.91888L15.9998 14.8387L26.018 8.91882ZM16.268 3.00095C16.1021 2.90518 15.8978 2.90518 15.7319 3.00095L5.48606 8.91638L15.9998 15.1291L26.5137 8.91632L16.268 3.00095ZM17 16.5707V28.2879L26.9985 22.5153C27.087 22.4642 27.1416 22.3697 27.1416 22.2675V10.578L17 16.5707ZM16.75 16.4281V28.7209L27.1235 22.7318C27.2894 22.636 27.3916 22.459 27.3916 22.2675V10.1399L16.75 16.4281ZM15 16.5709L4.85833 10.5781V22.2675C4.85833 22.3697 4.91286 22.4642 5.00138 22.5153L15 28.288V16.5709ZM15.25 16.4283L4.60833 10.14V22.2675C4.60833 22.4591 4.71051 22.636 4.87638 22.7318L15.25 28.721V16.4283ZM14.8027 1.39159C15.5436 0.96387 16.4563 0.96387 17.1972 1.39159L28.0527 7.65902C28.7935 8.08675 29.2499 8.87721 29.2499 9.73266V22.2675C29.2499 23.123 28.7935 23.9134 28.0527 24.3412L17.1972 30.6086C16.4563 31.0363 15.5436 31.0363 14.8027 30.6086L3.94722 24.3412C3.20638 23.9134 2.75 23.123 2.75 22.2675V9.73266C2.75 8.87721 3.20638 8.08675 3.94722 7.65902L14.8027 1.39159ZM14.9277 1.6081C15.5912 1.22503 16.4087 1.22503 17.0722 1.6081L27.9277 7.87553C28.5911 8.25859 28.9999 8.96653 28.9999 9.73266V22.2675C28.9999 23.0336 28.5911 23.7416 27.9277 24.1247L17.0722 30.3921C16.4087 30.7751 15.5912 30.7751 14.9277 30.3921L4.07222 24.1247C3.40873 23.7416 3 23.0336 3 22.2675V9.73266C3 8.96653 3.40873 8.25859 4.07222 7.87553L14.9277 1.6081Z" fill="#0A1C38" fill-opacity="0.9"/>
</g>
<defs>
<clipPath id="clip0_8156_85961">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

11
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_plugin_disable.svg

@ -0,0 +1,11 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_8156_85969)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.5137 8.91632L16.268 3.00095C16.1021 2.90518 15.8978 2.90518 15.7319 3.00095L5.48606 8.91638L15.9998 15.1291L26.5137 8.91632ZM27.3916 10.1399L16.75 16.4281V28.7209L27.1235 22.7318C27.2894 22.636 27.3916 22.459 27.3916 22.2675V10.1399ZM15.25 28.721V16.4283L4.60833 10.14V22.2675C4.60833 22.4591 4.71051 22.636 4.87638 22.7318L15.25 28.721ZM17.0722 1.6081C16.4087 1.22503 15.5912 1.22503 14.9277 1.6081L4.07222 7.87553C3.40873 8.25859 3 8.96653 3 9.73266V22.2675C3 23.0336 3.40873 23.7416 4.07222 24.1247L14.9277 30.3921C15.5912 30.7751 16.4087 30.7751 17.0722 30.3921L27.9277 24.1247C28.5911 23.7416 28.9999 23.0336 28.9999 22.2675V9.73266C28.9999 8.96653 28.5911 8.25859 27.9277 7.87553L17.0722 1.6081Z" fill="#0A1C38" fill-opacity="0.29"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.018 8.91882L16.143 3.21746C16.0545 3.16635 15.9454 3.16635 15.8569 3.21746L5.98172 8.91888L15.9998 14.8387L26.018 8.91882ZM16.268 3.00095C16.1021 2.90518 15.8978 2.90518 15.7319 3.00095L5.48606 8.91638L15.9998 15.1291L26.5137 8.91632L16.268 3.00095ZM17 16.5707V28.2879L26.9985 22.5153C27.087 22.4642 27.1416 22.3697 27.1416 22.2675V10.578L17 16.5707ZM16.75 16.4281V28.7209L27.1235 22.7318C27.2894 22.636 27.3916 22.459 27.3916 22.2675V10.1399L16.75 16.4281ZM15 16.5709L4.85833 10.5781V22.2675C4.85833 22.3697 4.91286 22.4642 5.00138 22.5153L15 28.288V16.5709ZM15.25 16.4283L4.60833 10.14V22.2675C4.60833 22.4591 4.71051 22.636 4.87638 22.7318L15.25 28.721V16.4283ZM14.8027 1.39159C15.5436 0.96387 16.4563 0.96387 17.1972 1.39159L28.0527 7.65902C28.7935 8.08675 29.2499 8.87721 29.2499 9.73266V22.2675C29.2499 23.123 28.7935 23.9134 28.0527 24.3412L17.1972 30.6086C16.4563 31.0363 15.5436 31.0363 14.8027 30.6086L3.94722 24.3412C3.20638 23.9134 2.75 23.123 2.75 22.2675V9.73266C2.75 8.87721 3.20638 8.08675 3.94722 7.65902L14.8027 1.39159ZM14.9277 1.6081C15.5912 1.22503 16.4087 1.22503 17.0722 1.6081L27.9277 7.87553C28.5911 8.25859 28.9999 8.96653 28.9999 9.73266V22.2675C28.9999 23.0336 28.5911 23.7416 27.9277 24.1247L17.0722 30.3921C16.4087 30.7751 15.5912 30.7751 14.9277 30.3921L4.07222 24.1247C3.40873 23.7416 3 23.0336 3 22.2675V9.73266C3 8.96653 3.40873 8.25859 4.07222 7.87553L14.9277 1.6081Z" fill="#0A1C38" fill-opacity="0.29"/>
</g>
<defs>
<clipPath id="clip0_8156_85969">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

11
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_plugin_white.svg

@ -0,0 +1,11 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_8156_86033)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.5137 8.91632L16.268 3.00095C16.1021 2.90518 15.8978 2.90518 15.7319 3.00095L5.48606 8.91638L15.9998 15.1291L26.5137 8.91632ZM27.3916 10.1399L16.75 16.4281V28.7209L27.1235 22.7318C27.2894 22.636 27.3916 22.459 27.3916 22.2675V10.1399ZM15.25 28.721V16.4283L4.60833 10.14V22.2675C4.60833 22.4591 4.71051 22.636 4.87638 22.7318L15.25 28.721ZM17.0722 1.6081C16.4087 1.22503 15.5912 1.22503 14.9277 1.6081L4.07222 7.87553C3.40873 8.25859 3 8.96653 3 9.73266V22.2675C3 23.0336 3.40873 23.7416 4.07222 24.1247L14.9277 30.3921C15.5912 30.7751 16.4087 30.7751 17.0722 30.3921L27.9277 24.1247C28.5911 23.7416 28.9999 23.0336 28.9999 22.2675V9.73266C28.9999 8.96653 28.5911 8.25859 27.9277 7.87553L17.0722 1.6081Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.018 8.91882L16.143 3.21746C16.0545 3.16635 15.9454 3.16635 15.8569 3.21746L5.98172 8.91888L15.9998 14.8387L26.018 8.91882ZM16.268 3.00095C16.1021 2.90518 15.8978 2.90518 15.7319 3.00095L5.48606 8.91638L15.9998 15.1291L26.5137 8.91632L16.268 3.00095ZM17 16.5707V28.2879L26.9985 22.5153C27.087 22.4642 27.1416 22.3697 27.1416 22.2675V10.578L17 16.5707ZM16.75 16.4281V28.7209L27.1235 22.7318C27.2894 22.636 27.3916 22.459 27.3916 22.2675V10.1399L16.75 16.4281ZM15 16.5709L4.85833 10.5781V22.2675C4.85833 22.3697 4.91286 22.4642 5.00138 22.5153L15 28.288V16.5709ZM15.25 16.4283L4.60833 10.14V22.2675C4.60833 22.4591 4.71051 22.636 4.87638 22.7318L15.25 28.721V16.4283ZM14.8027 1.39159C15.5436 0.96387 16.4563 0.96387 17.1972 1.39159L28.0527 7.65902C28.7935 8.08675 29.2499 8.87721 29.2499 9.73266V22.2675C29.2499 23.123 28.7935 23.9134 28.0527 24.3412L17.1972 30.6086C16.4563 31.0363 15.5436 31.0363 14.8027 30.6086L3.94722 24.3412C3.20638 23.9134 2.75 23.123 2.75 22.2675V9.73266C2.75 8.87721 3.20638 8.08675 3.94722 7.65902L14.8027 1.39159ZM14.9277 1.6081C15.5912 1.22503 16.4087 1.22503 17.0722 1.6081L27.9277 7.87553C28.5911 8.25859 28.9999 8.96653 28.9999 9.73266V22.2675C28.9999 23.0336 28.5911 23.7416 27.9277 24.1247L17.0722 30.3921C16.4087 30.7751 15.5912 30.7751 14.9277 30.3921L4.07222 24.1247C3.40873 23.7416 3 23.0336 3 22.2675V9.73266C3 8.96653 3.40873 8.25859 4.07222 7.87553L14.9277 1.6081Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_8156_86033">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

3
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_template.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C2.89543 3 2 3.89543 2 5V27C2 28.1046 2.89543 29 4 29H28C29.1046 29 30 28.1046 30 27V5C30 3.89543 29.1046 3 28 3H4ZM28 5H4V11H28V5ZM4 27V13H10V27H4ZM12 27H28V13H12V27Z" fill="#0A1C38" fill-opacity="0.9"/>
</svg>

After

Width:  |  Height:  |  Size: 361 B

3
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_template_disable.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C2.89543 3 2 3.89543 2 5V27C2 28.1046 2.89543 29 4 29H28C29.1046 29 30 28.1046 30 27V5C30 3.89543 29.1046 3 28 3H4ZM28 5H4V11H28V5ZM4 27V13H10V27H4ZM12 27H28V13H12V27Z" fill="#0A1C38" fill-opacity="0.29"/>
</svg>

After

Width:  |  Height:  |  Size: 362 B

3
designer-base/src/main/resources/com/fine/theme/icon/alphafine/alphaFine_template_white.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C2.89543 3 2 3.89543 2 5V27C2 28.1046 2.89543 29 4 29H28C29.1046 29 30 28.1046 30 27V5C30 3.89543 29.1046 3 28 3H4ZM28 5H4V11H28V5ZM4 27V13H10V27H4ZM12 27H28V13H12V27Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 340 B

16
designer-base/src/main/resources/com/fine/theme/icon/alphafine/internet_error.svg

@ -0,0 +1,16 @@
<svg width="110" height="110" viewBox="0 0 110 110" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.75">
<path opacity="0.8" fill-rule="evenodd" clip-rule="evenodd" d="M41.7854 31.6035C29.0822 34.2778 17.7425 40.6533 8.94681 49.5495C7.26139 51.2542 7.46782 54.0066 9.27928 55.5767C11.0926 57.1484 13.8258 56.938 15.5302 55.2487C22.1993 48.6387 30.5086 43.6807 39.7933 41.0396L41.7854 31.6035ZM68.3034 40.4028L71.2237 32.1731C82.9283 35.1193 93.3743 41.233 101.597 49.5495C103.282 51.2542 103.076 54.0066 101.264 55.5767C99.451 57.1484 96.7178 56.938 95.0135 55.2488C90.6463 50.9202 85.5757 47.3001 79.9885 44.5751L80.6903 43.1204C81.2468 41.967 80.4064 40.6285 79.1258 40.6285H69.2237C68.9179 40.5507 68.6112 40.4755 68.3034 40.4028ZM38.137 48.8852C31.5936 51.2992 25.7002 55.056 20.7913 59.8212C19.0718 61.4904 19.2812 64.246 21.0921 65.8156C22.9059 67.3877 25.6368 67.1705 27.3897 65.5307C29.9465 63.1387 32.8113 61.0718 35.9181 59.3958L38.137 48.8852ZM73.1934 58.6595L76.9685 50.8348C81.7025 53.1466 86.013 56.1913 89.7523 59.8212C91.4719 61.4904 91.2625 64.246 89.4516 65.8156C87.6377 67.3877 84.9069 67.1705 83.154 65.5307C80.2087 62.7754 76.855 60.4514 73.1934 58.6595ZM40.3114 64.9482C37.5237 66.3227 34.9523 68.0694 32.6623 70.1234C30.8795 71.7224 31.0937 74.4846 32.9034 76.0532C34.7182 77.6262 37.446 77.3917 39.3024 75.868C41.3356 74.1992 43.6347 72.8425 46.1266 71.8711L47.2535 64.9482H40.3114ZM66.3983 72.7439L70.1734 64.9192C72.9838 66.2981 75.5752 68.0549 77.8813 70.1234C79.6641 71.7224 79.4499 74.4846 77.6402 76.0532C75.8254 77.6262 73.0977 77.3917 71.2413 75.868C69.7588 74.6513 68.1351 73.6005 66.3983 72.7439ZM44.7279 80.4626C44.3989 80.6961 44.078 80.9402 43.7656 81.1944C42.3741 82.327 42.5391 84.405 43.8949 85.5802L44.7279 80.4626ZM59.6027 86.8293L63.3781 79.0039C64.271 79.4476 65.1223 79.9623 65.9248 80.5406C67.8625 81.9371 67.6413 84.7199 65.8364 86.2843L65.3802 86.6798C63.8135 88.0377 61.4501 87.7704 59.6027 86.8293Z" fill="url(#paint0_linear_11857_159065)"/>
<path d="M66.7091 19.7832H53.3121C51.6699 19.7832 50.252 20.933 49.9128 22.5398L43.1283 54.6766C42.6724 56.8365 44.3201 58.8684 46.5277 58.8684H54.4032L49.4309 89.4131C49.2455 90.552 50.8171 91.0475 51.3185 90.0083L71.0065 49.2005C71.563 48.0471 70.7226 46.7086 69.4419 46.7086H59.6146L68.3463 22.1012C68.7475 20.9705 67.9089 19.7832 66.7091 19.7832Z" fill="url(#paint1_linear_11857_159065)"/>
</g>
<defs>
<linearGradient id="paint0_linear_11857_159065" x1="8.00001" y1="25.5" x2="124.871" y2="153.289" gradientUnits="userSpaceOnUse">
<stop stop-color="#DADEE7"/>
<stop offset="1" stop-color="#5D6B81"/>
</linearGradient>
<linearGradient id="paint1_linear_11857_159065" x1="71" y1="96" x2="57" y2="20" gradientUnits="userSpaceOnUse">
<stop stop-color="#5D6B81"/>
<stop offset="1" stop-color="#A3ADBD"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

13
designer-base/src/main/resources/com/fine/theme/icon/editor/cell_group_popup.svg

@ -0,0 +1,13 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_13814_85902)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.90625 3.53125C1.90625 2.53023 2.71773 1.71875 3.71875 1.71875H14.5V3.53125H3.71875V13.5H1.90625V3.53125ZM25.2812 23.4688V13.5H27.0938V23.4688C27.0938 24.4698 26.2823 25.2812 25.2812 25.2812H14.5V23.4688H25.2812Z" fill="#0A1C38" fill-opacity="0.9"/>
<path d="M1.90625 13.5H14.5V25.2812H3.71875C2.71773 25.2812 1.90625 24.4698 1.90625 23.4688V13.5Z" fill="#2576EF"/>
<path d="M27.0938 13.5H14.5V1.71875H25.2812C26.2823 1.71875 27.0938 2.53023 27.0938 3.53125V13.5Z" fill="#2576EF"/>
<path d="M24.2851 30C24.0316 30 23.9047 29.6935 24.0839 29.5143L29.5143 24.0839C29.6935 23.9047 30 24.0316 30 24.2851V29.6C30 29.8209 29.8209 30 29.6 30H24.2851Z" fill="#0A1C38" fill-opacity="0.9"/>
</g>
<defs>
<clipPath id="clip0_13814_85902">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 985 B

13
designer-base/src/main/resources/com/fine/theme/icon/editor/cell_group_popup_disable.svg

@ -0,0 +1,13 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_13814_85916)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.90625 3.53125C1.90625 2.53023 2.71773 1.71875 3.71875 1.71875H14.5V3.53125H3.71875V13.5H1.90625V3.53125ZM25.2812 23.4688V13.5H27.0938V23.4688C27.0938 24.4698 26.2823 25.2812 25.2812 25.2812H14.5V23.4688H25.2812Z" fill="#0A1C38" fill-opacity="0.29"/>
<path d="M1.90625 13.5H14.5V25.2812H3.71875C2.71773 25.2812 1.90625 24.4698 1.90625 23.4688V13.5Z" fill="#0A1C38" fill-opacity="0.29"/>
<path d="M27.0938 13.5H14.5V1.71875H25.2812C26.2823 1.71875 27.0938 2.53023 27.0938 3.53125V13.5Z" fill="#0A1C38" fill-opacity="0.29"/>
<path d="M24.2851 30C24.0316 30 23.9047 29.6935 24.0839 29.5143L29.5143 24.0839C29.6935 23.9047 30 24.0316 30 24.2851V29.6C30 29.8209 29.8209 30 29.6 30H24.2851Z" fill="#0A1C38" fill-opacity="0.29"/>
</g>
<defs>
<clipPath id="clip0_13814_85916">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

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

@ -393,6 +393,7 @@
"date_popup": "editor/date_popup.svg",
"param_popup": "editor/param_popup.svg",
"cellelement_popup": "editor/cellelement_popup.svg",
"cell_group_popup": "editor/cell_group_popup.svg",
"bind_column_popup": "editor/bind_column_popup.svg",
"preview_mobile": "preview/preview_mobile.svg",
"preview_paging": "preview/preview_paging.svg",
@ -487,6 +488,29 @@
"bulb_hover": "alphafine/bulb_hover.svg",
"minimize": "alphafine/minimize.svg",
"search_hint": "alphafine/search_hint.svg",
"no_result": "alphafine/no_result.svg"
"no_result": "alphafine/no_result.svg",
"internet_error": "alphafine/internet_error.svg",
"alphafine1": {
"normal": "alphafine/alphaFine_function.svg",
"disable": "alphafine/alphaFine_function_disable.svg",
"white": "alphafine/alphaFine_function_white.svg"
},
"alphafine2": "toolbar/help.svg",
"alphafine3": {
"normal": "alphafine/alphaFine_template.svg",
"disable": "alphafine/alphaFine_template_disable.svg",
"white": "alphafine/alphaFine_template_white.svg"
},
"alphafine4": {
"normal": "alphafine/alphaFine_plugin.svg",
"disable": "alphafine/alphaFine_plugin_disable.svg",
"white": "alphafine/alphaFine_plugin_white.svg"
},
"alphafine8": "toolbar/help.svg",
"alphafine10": {
"normal": "alphafine/alphaFine_template.svg",
"disable": "alphafine/alphaFine_template_disable.svg",
"white": "alphafine/alphaFine_template_white.svg"
}
}
}

BIN
designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/business_model_card_direct.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

24
designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/business_model_card_direct.svg

@ -1,24 +0,0 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M51 28H56C58.7614 28 61 30.2386 61 33V52C61 54.7614 58.7614 57 56 57H51V28Z" fill="url(#paint0_linear_250_216134)"/>
<path d="M7 12C7 9.23858 9.23858 7 12 7H46C48.7614 7 51 9.23858 51 12V52C51 54.7614 53.2386 57 56 57H12C9.23859 57 7.00001 54.7614 7.00001 52L7 12Z" fill="url(#paint1_linear_250_216134)"/>
<path d="M43.5 45C43.7761 45 44 45.2239 44 45.5V48C44 48.2761 43.7761 48.5 43.5 48.5L14.5 48.5C14.2239 48.5 14 48.2761 14 48L14 45.5C14 45.2239 14.2239 45 14.5 45L43.5 45Z" fill="white" fill-opacity="0.66"/>
<g filter="url(#filter0_f_250_216134)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.2855 19.1084C29.0301 18.9639 28.7199 18.9639 28.4645 19.1084L20.1862 23.794C19.917 23.9463 19.75 24.2358 19.75 24.55V33.95C19.75 34.2642 19.917 34.5537 20.1862 34.706L28.4645 39.3916C28.7199 39.5361 29.0301 39.5361 29.2855 39.3916L37.5638 34.706C37.833 34.5537 38 34.2642 38 33.95V24.55C38 24.2358 37.833 23.9463 37.5638 23.794L29.2855 19.1084ZM27.8887 35.1905V29.9569L23.1012 27.3146C22.9021 27.2048 22.828 26.9509 22.9356 26.7477L23.5201 25.6435C23.6277 25.4403 23.8763 25.3646 24.0754 25.4744L28.9131 28.1444L33.7507 25.4744C33.9498 25.3646 34.1984 25.4403 34.306 25.6435L34.8905 26.7477C34.9981 26.9509 34.924 27.2048 34.7249 27.3146L29.9374 29.9569V35.1905C29.9374 35.4215 29.754 35.6089 29.5277 35.6089H28.2985C28.0722 35.6089 27.8887 35.4215 27.8887 35.1905Z" fill="#6D5ECD"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.2855 19.1084C29.0301 18.9639 28.7199 18.9639 28.4645 19.1084L20.1862 23.794C19.917 23.9463 19.75 24.2358 19.75 24.55V33.95C19.75 34.2642 19.917 34.5537 20.1862 34.706L28.4645 39.3916C28.7199 39.5361 29.0301 39.5361 29.2855 39.3916L37.5638 34.706C37.833 34.5537 38 34.2642 38 33.95V24.55C38 24.2358 37.833 23.9463 37.5638 23.794L29.2855 19.1084ZM27.8887 35.1905V29.9569L23.1012 27.3146C22.9021 27.2048 22.828 26.9509 22.9356 26.7477L23.5201 25.6435C23.6277 25.4403 23.8763 25.3646 24.0754 25.4744L28.9131 28.1444L33.7507 25.4744C33.9498 25.3646 34.1984 25.4403 34.306 25.6435L34.8905 26.7477C34.9981 26.9509 34.924 27.2048 34.7249 27.3146L29.9374 29.9569V35.1905C29.9374 35.4215 29.754 35.6089 29.5277 35.6089H28.2985C28.0722 35.6089 27.8887 35.4215 27.8887 35.1905Z" fill="white"/>
<defs>
<filter id="filter0_f_250_216134" x="15.75" y="15" width="26.25" height="28.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="2" result="effect1_foregroundBlur_250_216134"/>
</filter>
<linearGradient id="paint0_linear_250_216134" x1="56" y1="28" x2="56" y2="57" gradientUnits="userSpaceOnUse">
<stop stop-color="#7568CF"/>
<stop offset="1" stop-color="#5848C7"/>
</linearGradient>
<linearGradient id="paint1_linear_250_216134" x1="31.5" y1="7" x2="31.5" y2="57" gradientUnits="userSpaceOnUse">
<stop stop-color="#A48DFF"/>
<stop offset="1" stop-color="#886EF2"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

BIN
designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/business_model_card_spider.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

23
designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/business_model_card_spider.svg

@ -1,23 +0,0 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M51 28H56C58.7614 28 61 30.2386 61 33V52C61 54.7614 58.7614 57 56 57H51V28Z" fill="url(#paint0_linear_250_216132)"/>
<path d="M7 12C7 9.23858 9.23858 7 12 7H46C48.7614 7 51 9.23858 51 12V52C51 54.7614 53.2386 57 56 57H12C9.23859 57 7.00001 54.7614 7.00001 52L7 12Z" fill="url(#paint1_linear_250_216132)"/>
<g filter="url(#filter0_f_250_216132)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.3305 20.619C29.0471 20.4603 28.7029 20.4603 28.4195 20.619L19.234 25.7617C18.9353 25.9289 18.75 26.2466 18.75 26.5915V36.9085C18.75 37.2534 18.9353 37.5711 19.234 37.7383L28.4195 42.881C28.7029 43.0397 29.0471 43.0397 29.3305 42.881L38.516 37.7383C38.8147 37.5711 39 37.2534 39 36.9085V26.5915C39 26.2466 38.8147 25.9289 38.516 25.7617L29.3305 20.619ZM27.7806 38.2701V32.5259L22.4685 29.6258C22.2476 29.5052 22.1653 29.2266 22.2847 29.0035L22.9333 27.7917C23.0527 27.5686 23.3285 27.4855 23.5494 27.6061L28.9172 30.5365L34.285 27.6061C34.5059 27.4855 34.7818 27.5686 34.9012 27.7917L35.5498 29.0035C35.6692 29.2266 35.5869 29.5052 35.366 29.6258L30.0539 32.5259V38.2701C30.0539 38.5237 29.8503 38.7292 29.5992 38.7292H28.2353C27.9842 38.7292 27.7806 38.5237 27.7806 38.2701Z" fill="#6D5ECD"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.3305 20.619C29.0471 20.4603 28.7029 20.4603 28.4195 20.619L19.234 25.7617C18.9353 25.9289 18.75 26.2466 18.75 26.5915V36.9085C18.75 37.2534 18.9353 37.5711 19.234 37.7383L28.4195 42.881C28.7029 43.0397 29.0471 43.0397 29.3305 42.881L38.516 37.7383C38.8147 37.5711 39 37.2534 39 36.9085V26.5915C39 26.2466 38.8147 25.9289 38.516 25.7617L29.3305 20.619ZM27.7806 38.2701V32.5259L22.4685 29.6258C22.2476 29.5052 22.1653 29.2266 22.2847 29.0035L22.9333 27.7917C23.0527 27.5686 23.3285 27.4855 23.5494 27.6061L28.9172 30.5365L34.285 27.6061C34.5059 27.4855 34.7818 27.5686 34.9012 27.7917L35.5498 29.0035C35.6692 29.2266 35.5869 29.5052 35.366 29.6258L30.0539 32.5259V38.2701C30.0539 38.5237 29.8503 38.7292 29.5992 38.7292H28.2353C27.9842 38.7292 27.7806 38.5237 27.7806 38.2701Z" fill="white"/>
<defs>
<filter id="filter0_f_250_216132" x="14.75" y="16.5" width="28.25" height="30.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="2" result="effect1_foregroundBlur_250_216132"/>
</filter>
<linearGradient id="paint0_linear_250_216132" x1="56" y1="28" x2="56" y2="57" gradientUnits="userSpaceOnUse">
<stop stop-color="#7568CF"/>
<stop offset="1" stop-color="#5848C7"/>
</linearGradient>
<linearGradient id="paint1_linear_250_216132" x1="31.5" y1="7" x2="31.5" y2="57" gradientUnits="userSpaceOnUse">
<stop stop-color="#A48DFF"/>
<stop offset="1" stop-color="#886EF2"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

BIN
designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/dimension_card_direct.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

24
designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/dimension_card_direct.svg

@ -1,24 +0,0 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M51 28H56C58.7614 28 61 30.2386 61 33V52C61 54.7614 58.7614 57 56 57H51V28Z" fill="url(#paint0_linear_250_216128)"/>
<path d="M7 12C7 9.23858 9.23858 7 12 7H46C48.7614 7 51 9.23858 51 12V52C51 54.7614 53.2386 57 56 57H12C9.23859 57 7.00001 54.7614 7.00001 52L7 12Z" fill="url(#paint1_linear_250_216128)"/>
<g filter="url(#filter0_f_250_216128)">
<path d="M33.8331 39.1854C35.5175 40.4297 37.8824 40.2279 39.3355 38.7213C40.7886 37.2126 40.8941 34.8451 39.5826 33.213C38.271 31.581 35.933 31.1729 34.1431 32.2602L33.9746 32.3634L29.8063 29.7628V25.2837L30.0466 25.221C32.0836 24.6986 33.4199 22.7325 33.1549 20.6498C32.8899 18.5693 31.1066 17 29.0045 17C26.8934 17 25.1079 18.5693 24.8429 20.6498C24.5779 22.7347 25.9142 24.6986 27.9534 25.221L28.1937 25.2815V29.7628L24.0254 32.3634L23.8569 32.2602C22.0692 31.1729 19.729 31.5832 18.4174 33.213C17.1059 34.8451 17.2114 37.2126 18.6645 38.7213C20.1176 40.2279 22.4825 40.4297 24.1669 39.1854C25.8513 37.9434 26.3544 35.6275 25.337 33.7982L25.1888 33.5336L29 31.1572L32.8112 33.5336L32.663 33.7982C31.6434 35.6275 32.1465 37.9434 33.8331 39.1854Z" fill="#537BC6"/>
</g>
<path d="M33.8331 39.1854C35.5175 40.4297 37.8824 40.2279 39.3355 38.7213C40.7886 37.2126 40.8941 34.8451 39.5826 33.213C38.271 31.581 35.933 31.1729 34.1431 32.2602L33.9746 32.3634L29.8063 29.7628V25.2837L30.0466 25.221C32.0836 24.6986 33.4199 22.7325 33.1549 20.6498C32.8899 18.5693 31.1066 17 29.0045 17C26.8934 17 25.1079 18.5693 24.8429 20.6498C24.5779 22.7347 25.9142 24.6986 27.9534 25.221L28.1937 25.2815V29.7628L24.0254 32.3634L23.8569 32.2602C22.0692 31.1729 19.729 31.5832 18.4174 33.213C17.1059 34.8451 17.2114 37.2126 18.6645 38.7213C20.1176 40.2279 22.4825 40.4297 24.1669 39.1854C25.8513 37.9434 26.3544 35.6275 25.337 33.7982L25.1888 33.5336L29 31.1572L32.8112 33.5336L32.663 33.7982C31.6434 35.6275 32.1465 37.9434 33.8331 39.1854Z" fill="white"/>
<path d="M43.5 45C43.7761 45 44 45.2239 44 45.5V48C44 48.2761 43.7761 48.5 43.5 48.5L14.5 48.5C14.2239 48.5 14 48.2761 14 48L14 45.5C14 45.2239 14.2239 45 14.5 45L43.5 45Z" fill="white" fill-opacity="0.66"/>
<defs>
<filter id="filter0_f_250_216128" x="13.5" y="13" width="31" height="31" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="2" result="effect1_foregroundBlur_250_216128"/>
</filter>
<linearGradient id="paint0_linear_250_216128" x1="56.25" y1="28" x2="56.25" y2="57" gradientUnits="userSpaceOnUse">
<stop offset="0.132925" stop-color="#537BC6"/>
<stop offset="1" stop-color="#4062A5"/>
</linearGradient>
<linearGradient id="paint1_linear_250_216128" x1="31.5" y1="7" x2="31.5" y2="57" gradientUnits="userSpaceOnUse">
<stop stop-color="#8FB1EC"/>
<stop offset="1" stop-color="#668ACC"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

BIN
designer-base/src/main/resources/com/fr/design/data/tabledata/datacenter/web/assets/images/dimension_card_spider.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

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

Loading…
Cancel
Save