Browse Source

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

* commit 'b09cf5abd277f3a9a14838a088e122e0cfb886e7': (287 commits)
  REPORT-136473 & EPORT-136480 fix: 懒加载导致控件输入框事件异常
  REPORT-135233 调整VcsOperator
  REPORT-135233 调整AuthorityOperator
  REPORT-135233 调整DecisionOperator
  REPORT-135233 调整TplOperator
  REPORT-135233 调整DataBaseTypeOperator
  REPORT-135233 调整TemplateExportOperator
  REPORT-135233 调整OrganizationOperator
  REPORT-135233 调整TemplateChecker
  REPORT-135233 调整VcsAutoCleanOperator
  REPORT-135233 调整DataFetcher,CommitHelper
  REPORT-135233 调整LockInfoOperator
  REPORT-135233 调整ShareEmbeddedConverter
  REPORT-135233 调整TableDataOperator和ConnectionOperator
  REPORT-135233 调整FileNodes
  REPORT-135996 fix: 视觉二次验收问题修复
  REPORT-136212 fix: 图表创建面板优化
  REPORT-136120 fix: 本地设计器启动日志级别需要全部配置保持一致
  REPORT-135874 fix: 修复无法获取远程环境脱敏规则的问题
  修改拖拽条颜色
  ...
fbp/master
superman 4 months ago
parent
commit
1873425299
  1. 21
      build.gradle
  2. 49
      designer-base/src/main/java/com/fine/theme/icon/IconManager.java
  3. 127
      designer-base/src/main/java/com/fine/theme/icon/plugin/PluginIconSet.java
  4. 2
      designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java
  5. 59
      designer-base/src/main/java/com/fine/theme/light/ui/FineCalendarPaneUI.java
  6. 37
      designer-base/src/main/java/com/fine/theme/light/ui/FineComboCheckBoxUI.java
  7. 140
      designer-base/src/main/java/com/fine/theme/light/ui/FineDayLabelUI.java
  8. 3
      designer-base/src/main/java/com/fine/theme/light/ui/FineHeaderPaneUI.java
  9. 107
      designer-base/src/main/java/com/fine/theme/light/ui/FineOptionPaneUI.java
  10. 2
      designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java
  11. 2
      designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java
  12. 2
      designer-base/src/main/java/com/fine/theme/light/ui/FineReportComponentBorder.java
  13. 2
      designer-base/src/main/java/com/fine/theme/light/ui/FineReportComponentCompositeUI.java
  14. 5
      designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java
  15. 21
      designer-base/src/main/java/com/fine/theme/light/ui/FineTableHeaderUI.java
  16. 23
      designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java
  17. 3
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineDarkLaf.java
  18. 2
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java
  19. 3
      designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLightLaf.java
  20. 1
      designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java
  21. 30
      designer-base/src/main/java/com/fine/theme/utils/FineComponentsFactory.java
  22. 15
      designer-base/src/main/java/com/fine/theme/utils/FineLayoutBuilder.java
  23. 12
      designer-base/src/main/java/com/fine/theme/utils/FineUIScale.java
  24. 6
      designer-base/src/main/java/com/fine/theme/utils/FineUIStyle.java
  25. 108
      designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java
  26. 143
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  27. 15
      designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
  28. 214
      designer-base/src/main/java/com/fr/design/EnvSwitcherSubmitTask.java
  29. 5
      designer-base/src/main/java/com/fr/design/actions/TableDataSourceAction.java
  30. 7
      designer-base/src/main/java/com/fr/design/actions/file/LocalePane.java
  31. 81
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  32. 26
      designer-base/src/main/java/com/fr/design/actions/file/export/AbstractExportAction.java
  33. 12
      designer-base/src/main/java/com/fr/design/actions/help/SystemInfoPane.java
  34. 24
      designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java
  35. 5
      designer-base/src/main/java/com/fr/design/backup/DesignContext.java
  36. 26
      designer-base/src/main/java/com/fr/design/backup/EnvBackupHelper.java
  37. 28
      designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java
  38. 13
      designer-base/src/main/java/com/fr/design/condition/ConditionAttributesPane.java
  39. 4
      designer-base/src/main/java/com/fr/design/condition/DSColumnLiteConditionPane.java
  40. 27
      designer-base/src/main/java/com/fr/design/condition/SingleConditionPane.java
  41. 57
      designer-base/src/main/java/com/fr/design/constants/UIConstants.java
  42. 7
      designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java
  43. 25
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  44. 4
      designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java
  45. 4
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataCreatorProducer.java
  46. 40
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java
  47. 6
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTree.java
  48. 40
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java
  49. 14
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataComboBox.java
  50. 3
      designer-base/src/main/java/com/fr/design/data/datapane/connect/AdvancePane.java
  51. 10
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java
  52. 112
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java
  53. 7
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java
  54. 42
      designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java
  55. 9
      designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java
  56. 8
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java
  57. 53
      designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java
  58. 62
      designer-base/src/main/java/com/fr/design/data/datapane/connect/LocalConnectionSource.java
  59. 2
      designer-base/src/main/java/com/fr/design/data/datapane/connect/SshPane.java
  60. 2
      designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java
  61. 1
      designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java
  62. 165
      designer-base/src/main/java/com/fr/design/data/datapane/preview/ConnectionInfoBeanHelper.java
  63. 38
      designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java
  64. 235
      designer-base/src/main/java/com/fr/design/data/datapane/preview/TableDataBeanHelper.java
  65. 7
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/common/DesensitizationOpenPane.java
  66. 15
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleChoosePane.java
  67. 28
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTableModel.java
  68. 12
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTablePane.java
  69. 1
      designer-base/src/main/java/com/fr/design/data/datapane/sqlpane/SQLEditPane.java
  70. 107
      designer-base/src/main/java/com/fr/design/data/tabledata/LocalTableDataSource.java
  71. 28
      designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DCTableDataJSBridge.java
  72. 86
      designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DCTableDataPane.java
  73. 1
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ClassTableDataPane.java
  74. 4
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  75. 121
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/EmbeddedTableDataPane.java
  76. 26
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/FileTableDataPane.java
  77. 12
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/MultiTDTableDataPane.java
  78. 8
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java
  79. 46
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/TableDataPaneHelper.java
  80. 28
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/ServerTableDataWrapper.java
  81. 32
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java
  82. 14
      designer-base/src/main/java/com/fr/design/dialog/BasicScrollPane.java
  83. 115
      designer-base/src/main/java/com/fr/design/dialog/FineJOptionPane.java
  84. 2
      designer-base/src/main/java/com/fr/design/dialog/TipDialog.java
  85. 39
      designer-base/src/main/java/com/fr/design/dialog/UIDetailErrorLinkDialog.java
  86. 9
      designer-base/src/main/java/com/fr/design/editlock/EditLockUtils.java
  87. 2
      designer-base/src/main/java/com/fr/design/editor/ValueEditorPane.java
  88. 4
      designer-base/src/main/java/com/fr/design/editor/editor/ColumnSelectedEditor.java
  89. 5
      designer-base/src/main/java/com/fr/design/editor/editor/CursorEditor.java
  90. 66
      designer-base/src/main/java/com/fr/design/env/HttpWorkspaceConnector.java
  91. 3
      designer-base/src/main/java/com/fr/design/env/RemoteWorkspace.java
  92. 42
      designer-base/src/main/java/com/fr/design/extra/LoginDialog.java
  93. 200
      designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java
  94. 54
      designer-base/src/main/java/com/fr/design/extra/LoginWebPane.java
  95. 2
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  96. 601
      designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java
  97. 112
      designer-base/src/main/java/com/fr/design/extra/PluginWebPane.java
  98. 32
      designer-base/src/main/java/com/fr/design/extra/QQLoginDialog.java
  99. 46
      designer-base/src/main/java/com/fr/design/extra/ShopDialog.java
  100. 31
      designer-base/src/main/java/com/fr/design/extra/ShopManagerPane.java
  101. Some files were not shown because too many files have changed in this diff Show More

21
build.gradle

@ -64,29 +64,19 @@ allprojects {
}
dependencies {
// jar
implementation 'com.fr.decision:fine-decision-webui:' + frVersion
implementation 'com.fr.webui:fine-webui:' + frVersion
//
implementation 'com.fr.decision:fine-decision-report-webui:' + frVersion
//
implementation "org.jasig.cas.client:cas-client-core:3.6.4"
implementation "cas:casclient:2.0.11"
//
implementation 'com.fr.portal:fine-portal-webui:' + apiVersion
//
implementation 'com.fr.messenger:fine-messenger-webui:' + apiVersion
//
implementation 'com.fr.license:fine-license-webui:' + apiVersion
//
implementation 'com.fr.cbb:fine-cbb-common:' + cbbVersion
implementation 'com.fr.auth:fine-auth-webui:' + apiVersion
//
implementation 'com.fr.portal:fine-portal:' + apiVersion
implementation 'com.fr.portal:fine-portal-api:' + apiVersion
// cbb
implementation 'com.fr.essential:fine-essential:' + cbbVersion
implementation 'com.fr.cbb:fine-universal-skeleton:' + cbbVersion
implementation 'com.fr.cbb:fine-cbb-common:' + cbbVersion
implementation 'com.fr.cbb:fine-cbb-extend:' + cbbVersion
// plugin
implementation 'com.fr.plugin:fine-plugin-api:' + apiVersion
implementation 'com.fr.plugin:fine-plugin:' + apiVersion
@ -102,12 +92,9 @@ allprojects {
// lic
implementation 'com.fr.license:fine-license:' + apiVersion
implementation 'com.fr.license:fine-license-api:' + apiVersion
// cluster
implementation 'com.fr.cluster:fine-cluster-api:' + apiVersion
// messenger
implementation 'com.fr.messenger:fine-messenger:' + carinaVersion
implementation 'com.install4j:install4j-runtime:8.0.4'
implementation 'com.fr.third:jxbrowser:6.23'
implementation "com.fr.third:jxbrowser-v7:${jxBrowserVersion}"
implementation "com.fr.third:jxbrowser-swing-v7:${jxBrowserVersion}"
implementation 'com.fr.third.server:servlet-api:3.0'
@ -143,18 +130,14 @@ allprojects {
// mac_x64, mac_aarch64, windows_x64
if (OperatingSystem.current().isMacOsX() && "aarch64".equals(System.getProperty("os.arch"))) {
dependencies {
// jxbrowser 6.23M16.23jar还是需要留着
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation "com.fr.third:jxbrowser-mac-arm-v7:${jxBrowserVersion}"
}
} else if (OperatingSystem.current().isMacOsX()) {
dependencies {
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation "com.fr.third:jxbrowser-mac-v7:${jxBrowserVersion}"
}
} else if (OperatingSystem.current().isWindows()) {
dependencies {
implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation "com.fr.third:jxbrowser-win64-v7:${jxBrowserVersion}"
}
}

49
designer-base/src/main/java/com/fine/theme/icon/IconManager.java

@ -1,5 +1,8 @@
package com.fine.theme.icon;
import com.fine.theme.icon.plugin.PluginIconSet;
import com.fine.theme.light.ui.FineLightIconSet;
import com.formdev.flatlaf.FlatLaf;
import com.fr.base.extension.FileExtension;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
@ -8,10 +11,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import java.awt.Dimension;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* 图标管理器
@ -26,12 +32,42 @@ import java.util.HashMap;
*/
@Immutable
public class IconManager {
public static final String ICON_DISABLE_SUFFIX = "_disable";
public static final Dimension DEFAULT_DIMENSION = new Dimension(16, 16);
private static final ArrayList<IconSet> ICON_SETS = new ArrayList<>(2);
private static final ArrayList<IconSet> ICON_SETS = new ArrayList<>();
private static final HashMap<String, WeakReference<Icon>> CACHE = new HashMap<>(64);
/**
* 初始化 IconFineIconPluginIcon
*/
public static void initializeIcon() {
addIconSet();
}
/**
* 切换 Icon
*/
public static void updateIcon() {
ICON_SETS.clear();
clearCache();
addIconSet();
}
private static void addIconSet() {
boolean dark = false;
LookAndFeel laf = UIManager.getLookAndFeel();
if (laf instanceof FlatLaf) {
dark = ((FlatLaf) laf).isDark();
}
if (dark) {
// dark 主题还没适配
addSet(new FineLightIconSet());
} else {
addSet(new FineLightIconSet());
}
addSet(new PluginIconSet());
}
/**
* 获取图标集
@ -40,10 +76,17 @@ public class IconManager {
* @return 图标集
*/
public static IconSet getSet(String id) {
IconSet iconSet = null;
for (IconSet set : ICON_SETS) {
if (set.getId().equals(id)) {
return set;
iconSet = set;
}
if (set instanceof PluginIconSet && iconSet == null) {
iconSet = PluginIconSet.getIconSet(id);
}
}
if (iconSet != null) {
return iconSet;
}
throw new IconException("[IconManager] Can not find icon set by id: " + id);
}

127
designer-base/src/main/java/com/fine/theme/icon/plugin/PluginIconSet.java

@ -0,0 +1,127 @@
package com.fine.theme.icon.plugin;
import com.fine.theme.icon.AbstractIconSet;
import com.fine.theme.icon.IconSet;
import com.fine.theme.icon.IconType;
import com.fine.theme.icon.JsonIconSet;
import com.fine.theme.icon.UrlIconResource;
import com.formdev.flatlaf.FlatLaf;
import com.fr.design.fun.LazyIconProvider;
import com.fr.general.GeneralContext;
import com.fr.plugin.manage.PluginFilter;
import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener;
import com.fr.plugin.observer.PluginEventType;
import com.fr.stable.AssistUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Set;
import java.util.function.Consumer;
/**
* 管理插件 iconSet
* @author lemon
* @since
* Created on
*/
public class PluginIconSet extends AbstractIconSet {
private static final String NAME = "Plugin Icon Set";
private static final ArrayList<IconSet> PLUGIN_ICON_SETS = new ArrayList<>();
public PluginIconSet() {
name = NAME;
listenPluginIcons();
}
/**
* 适配插件图标 Icon
*/
public static void listenPluginIcons() {
//注册插件监听
PluginFilter filter = context -> context.contain(LazyIconProvider.MARK_STRING);
PluginEventListener insert = new PluginEventListener() {
@Override
public void on(PluginEvent event) {
handlePluginEvent(event, (provider) -> PLUGIN_ICON_SETS.add(generateJsonIconSet(provider)));
}
};
PluginEventListener remove = new PluginEventListener() {
@Override
public void on(PluginEvent event) {
handlePluginEvent(event, (provider) -> PLUGIN_ICON_SETS.removeIf(iconSet -> iconSet.getId().equals(provider.pluginId())));
}
};
GeneralContext.listenPlugin(PluginEventType.AfterRun, insert, filter);
GeneralContext.listenPlugin(PluginEventType.AfterInstall, insert, filter);
GeneralContext.listenPlugin(PluginEventType.AfterForbid, remove, filter);
GeneralContext.listenPlugin(PluginEventType.AfterUninstall, remove, filter);
}
private static void handlePluginEvent(PluginEvent event, Consumer<LazyIconProvider> consumer) {
Set<LazyIconProvider> set = event.getContext().getRuntime().get(LazyIconProvider.MARK_STRING);
for (LazyIconProvider provider : set) {
consumer.accept(provider);
}
}
private static JsonIconSet generateJsonIconSet(LazyIconProvider provider) {
LookAndFeel laf = UIManager.getLookAndFeel();
boolean dark = ((FlatLaf) laf).isDark();
String jsonPath = dark ? provider.darkJsonPath() : provider.lightJsonPath();
return new JsonIconSet(new UrlIconResource(jsonPath)) {
@Override
public @NotNull String getId() {
return provider.pluginId();
}
};
}
@Override
public @Nullable Icon findIcon(@NotNull String id, @NotNull Dimension dimension, IconType type) {
Icon icon;
for (IconSet iconSet : PLUGIN_ICON_SETS) {
icon = iconSet.findIcon(id, dimension, type);
if (icon != null) {
return icon;
}
}
return null;
}
/**
* 根据 id 匹配 icon set
* @param id 对于 plugin icon set, id plugin_id
* @return icon set
*/
public static IconSet getIconSet(@NotNull final String id ) {
for (IconSet iconSet : PLUGIN_ICON_SETS) {
if (iconSet.getId().equals(id)) {
return iconSet;
}
}
return null;
}
@Override
public boolean equals(Object obj) {
return obj instanceof PluginIconSet
&& AssistUtils.equals(this.name, ((PluginIconSet) obj).name);
}
@Override
public int hashCode() {
return AssistUtils.hashCode(name);
}
}

2
designer-base/src/main/java/com/fine/theme/light/ui/FineButtonBorder.java

@ -32,7 +32,7 @@ public class FineButtonBorder extends FlatButtonBorder {
return;
}
g2.setPaint(borderPaint);
FineUIUtils.paintPartRoundButtonBorder(c, g2, x, y, width, height, borderWidth, (float) getArc(c));
FineUIUtils.paintPartRoundButtonBorder(c, g2, x, y, width, height, borderWidth, getArc(c));
} else {
super.paintBorder(c, g, x, y, width, height);
}

59
designer-base/src/main/java/com/fine/theme/light/ui/FineCalendarPaneUI.java

@ -0,0 +1,59 @@
package com.fine.theme.light.ui;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.design.gui.date.UICalendarPanel;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import java.awt.Color;
/**
* {@link UICalendarPanel} UI 样式
*
* @author lemon
* @since 12.0
* Created on 2024/09/22
*/
public class FineCalendarPaneUI extends PanelUI {
protected Color defaultBackground;
/**
* @param shared
* @since 2
*/
protected FineCalendarPaneUI() {
super();
}
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return FlatUIUtils.createSharedUI(FineCalendarPaneUI.class, FineCalendarPaneUI::new);
}
/**
* @param c the component where this UI delegate is being installed
*/
public void installUI(JComponent c) {
super.installUI(c);
defaultBackground = UIManager.getColor("Calendar.background");
//renderer this
c.setBackground(defaultBackground);
c.setBorder(new LineBorder(FlatUIUtils.getUIColor("defaultBorderColor", Color.BLACK)));
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
}

37
designer-base/src/main/java/com/fine/theme/light/ui/FineComboCheckBoxUI.java

@ -0,0 +1,37 @@
package com.fine.theme.light.ui;
import com.formdev.flatlaf.ui.FlatComboBoxUI;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
/**
* {@link com.fr.design.gui.icombocheckbox.UIComboCheckBox} UI 样式
*
* @author lemon
* @since 12.0
* Created on 2024/09/27
*/
public class FineComboCheckBoxUI extends FlatComboBoxUI {
public FineComboCheckBoxUI() {
super();
}
/**
* 创建UI
*/
public static ComponentUI createUI(JComponent c) {
return new FineComboCheckBoxUI();
}
@Override
public void installUI(JComponent c) {
super.installUI(c);
c.setBackground(UIManager.getColor("ComboCheckBox.background"));
c.setBorder(UIManager.getBorder("ComboCheckBox.border"));
}
}

140
designer-base/src/main/java/com/fine/theme/light/ui/FineDayLabelUI.java

@ -0,0 +1,140 @@
package com.fine.theme.light.ui;
import com.formdev.flatlaf.ui.FlatLabelUI;
import com.formdev.flatlaf.ui.FlatRoundBorder;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.design.gui.date.UIDayLabel;
import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
/**
* {@link UIDayLabel} UI 样式
*
* @author lemon
* @since 12.0
* Created on 2024/09/22
*/
public class FineDayLabelUI extends FlatLabelUI {
protected Color defaultBackground;
protected Color selectedBackground;
protected Color hoverBackground;
protected Color pressedBackground;
protected Color otherMonthForeground;
protected int arc;
/**
* @since 2
*/
protected FineDayLabelUI() {
super(false);
}
/**
* 创建UI
*
* @param c 组件
* @return ComponentUI
*/
public static ComponentUI createUI(JComponent c) {
return FlatUIUtils.createSharedUI(FineDayLabelUI.class, FineDayLabelUI::new);
}
/**
* @param c the component where this UI delegate is being installed
*/
public void installUI(JComponent c) {
super.installUI(c);
selectedBackground = UIManager.getColor("Calendar.day.selectedBackground");
hoverBackground = UIManager.getColor("Calendar.day.hoverBackground");
pressedBackground = UIManager.getColor("Calendar.day.pressedBackground");
defaultBackground = UIManager.getColor("Calendar.background");
otherMonthForeground = UIManager.getColor("Calendar.dayOtherMonth.foreground");
arc = UIManager.getInt("Calendar.day.arc");
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
/**
* UICalendarPanel paint, 目前只对 {@link UIDayLabel} 样式自定义其余使用默认样式
*
* @param g the <code>Graphics</code> context in which to paint
* @param c the component being painted;
* this argument is often ignored,
* but might be used if the UI object is stateless
* and shared by multiple components
*/
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (c instanceof UIDayLabel) {
paintDayLabel((UIDayLabel) c);
}
}
private void paintDayLabel(UIDayLabel label) {
if (!label.isSmallLabel()) {
label.setBackground(getBackgroundColor(label));
return;
}
label.setBorder(new DayLabelRoundedBorder());
if (!label.isCurrentMonth()) {
label.setForeground(otherMonthForeground);
}
}
private Color getBackgroundColor(UIDayLabel dayLabel) {
if (dayLabel.isSelected()) {
return selectedBackground;
}
if (dayLabel.isHovered()) {
return hoverBackground;
}
if (dayLabel.isPressed()) {
return pressedBackground;
}
return defaultBackground;
}
/**
* {@link UIDayLabel} border 样式
*/
private class DayLabelRoundedBorder extends FlatRoundBorder {
public DayLabelRoundedBorder() {
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints(g2);
g2.setColor(getBackgroundColor((UIDayLabel) c));
g2.fillRoundRect(0, 0, width, height, arc, arc);
// 避免文字被背景色覆盖
UIDayLabel dayLabel = (UIDayLabel) c;
g2.setColor(dayLabel.getForeground());
FontMetrics metrics = g2.getFontMetrics(dayLabel.getFont());
int x1 = (width - metrics.stringWidth(dayLabel.getText())) / 2;
int y1 = ((height - metrics.getHeight()) / 2) + metrics.getAscent();
g2.drawString(dayLabel.getText(), x1, y1);
} finally {
g2.dispose();
}
}
}
}

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

@ -18,6 +18,7 @@ import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
/**
@ -100,6 +101,8 @@ public class FineHeaderPaneUI extends PanelUI implements AnimatedPainter {
+ FineUIScale.scale(UIManager.getInt("ExpandablePane.HeaderPane.hGap"));
float titleY = (headerPane.getHeight() - (ascent + descent)) / 2.0f + ascent;
FlatUIUtils.setRenderingHints(g2d);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.drawString(headerPane.getTitle(), titleX, titleY);
g2d.dispose();
}

107
designer-base/src/main/java/com/fine/theme/light/ui/FineOptionPaneUI.java

@ -1,14 +1,33 @@
package com.fine.theme.light.ui;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.ui.FlatOptionPaneUI;
import com.fr.design.gui.ilable.UILabel;
import sun.swing.DefaultLookup;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* @author Renekton
@ -35,4 +54,92 @@ public class FineOptionPaneUI extends FlatOptionPaneUI {
}
}
}
protected void installComponents() {
optionPane.setLayout(new BorderLayout());
optionPane.add(createMessageArea());
optionPane.add(createButtonArea(), BorderLayout.SOUTH);
optionPane.applyComponentOrientation(optionPane.getComponentOrientation());
}
protected Container createMessageArea() {
JPanel top = new JPanel();
Border topBorder = (Border) DefaultLookup.get(optionPane, this,
"OptionPane.messageAreaBorder");
if (topBorder != null) {
top.setBorder(topBorder);
}
top.setLayout(new BorderLayout());
/* Fill the body. */
Container body = new JPanel(new GridBagLayout());
Container realBody = new JPanel(new BorderLayout());
body.setName("OptionPane.body");
realBody.setName("OptionPane.realBody");
realBody.add(body, BorderLayout.NORTH);
GridBagConstraints cons = new GridBagConstraints();
cons.gridx = cons.gridy = 0;
cons.gridwidth = GridBagConstraints.REMAINDER;
cons.gridheight = 1;
cons.anchor = DefaultLookup.getInt(optionPane, this,
"OptionPane.messageAnchor", GridBagConstraints.CENTER);
cons.insets = new Insets(0,0,3,0);
addMessageComponents(body, cons, getMessage(),
getMaxCharactersPerLineCount(), false);
top.add(realBody, BorderLayout.CENTER);
addIcon(top);
top.setAlignmentX(Component.CENTER_ALIGNMENT);
return row(flex(), column(flex(), cell(top), flex()), flex()).getComponent();
}
@Override
protected void addIcon(Container top) {
Icon sideIcon = getIcon();
if (sideIcon != null) {
UILabel iconLabel = new UILabel(sideIcon);
iconLabel.setName("OptionPane.iconLabel");
iconLabel.setVerticalAlignment(SwingConstants.TOP);
top.add(row(cell(iconLabel), Layouts.fix(10)).getComponent(), BorderLayout.BEFORE_LINE_BEGINS);
}
}
@Override
protected Icon getIconForType(int messageType) {
String iconId = null;
switch (messageType) {
case 0:
iconId = "error";
break;
case 1:
iconId = "information";
break;
case 2:
iconId = "warning";
break;
case 3:
iconId = "question";
break;
default:
break;
}
if (iconId != null) {
return new LazyIcon(iconId, 20);
}
return null;
}
public Dimension getPreferredSize(JComponent c) {
if (c == optionPane) {
Dimension size = super.getPreferredSize(c);
size.width = Math.max(FineUIScale.scale(360), size.width);
size.height = Math.max(FineUIScale.scale(130), size.height);
return size;
}
return null;
}
}

2
designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuBorder.java

@ -14,6 +14,6 @@ public class FinePopupMenuBorder extends FlatPopupMenuBorder {
@Override
public int getArc() {
return FineUIUtils.getAndScaleInt("PopupMenu.arc", 5);
return FineUIUtils.getAndScaleInt("PopupMenu.arc", 8);
}
}

2
designer-base/src/main/java/com/fine/theme/light/ui/FinePopupMenuUI.java

@ -19,7 +19,7 @@ import java.awt.geom.RoundRectangle2D;
*/
public class FinePopupMenuUI extends FlatPopupMenuUI {
private int arc;
private final int DEFAULT_ARC = 10;
private final int DEFAULT_ARC = 8;
/**
* 创建UI

2
designer-base/src/main/java/com/fine/theme/light/ui/FineReportComponentBorder.java

@ -18,7 +18,7 @@ public class FineReportComponentBorder extends FlatRoundBorder {
@Override
protected int getArc(Component c) {
return FineUIUtils.getAndScaleInt("Center.arc", 10);
return FineUIUtils.getAndScaleInt("Center.arc", 8);
}
@Override

2
designer-base/src/main/java/com/fine/theme/light/ui/FineReportComponentCompositeUI.java

@ -33,7 +33,7 @@ public class FineReportComponentCompositeUI extends FlatPanelUI {
@Override
protected void installDefaults(JPanel p) {
super.installDefaults(p);
this.arc = FineUIUtils.getAndScaleInt("Center.arc", 10);
this.arc = FineUIUtils.getAndScaleInt("Center.arc", 8);
}

5
designer-base/src/main/java/com/fine/theme/light/ui/FineSliderUI.java

@ -50,6 +50,11 @@ public class FineSliderUI extends FlatSliderUI {
defaultLabelHeight = FineUIUtils.getAndScaleInt("Slider.labelHeight", DEFAULT_LABEL_HEIGHT);
}
@Override
protected Color getTrackColor() {
return trackColor;
}
@Override
protected void calculateLabelRect() {

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

@ -17,6 +17,7 @@ import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
/**
@ -87,7 +88,7 @@ public class FineTableHeaderUI extends FlatTableHeaderUI {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Class<?> columnClass = table.getColumnClass(0);
Border border;
if (column == table.getColumnCount() - 1) {
if (column == table.getColumnCount() - 1 && table.getAutoResizeMode() != JTable.AUTO_RESIZE_OFF) {
border = BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIManager.getColor("defaultBorderColor")),
UIManager.getBorder("Table.cellNoFocusBorder"));
} else {
@ -101,8 +102,26 @@ public class FineTableHeaderUI extends FlatTableHeaderUI {
}
setBackground(selectionBackground);
setText(value == null ? StringUtils.BLANK : String.valueOf(value));
setToolTipText(table, value, column);
setBorder(border);
return this;
}
/**
* 显示不全的文字增加了 toolTip
* @param table
* @param value
* @param column
*/
private void setToolTipText(JTable table, Object value, int column) {
String tipText = value == null ? StringUtils.BLANK : String.valueOf(value);
FontMetrics fm = this.getFontMetrics(this.getFont());
int textWidth = fm.stringWidth(String.valueOf(value));
if (textWidth > table.getColumnModel().getColumn(column).getWidth()) {
setToolTipText(tipText);
} else {
setToolTipText(null);
}
}
}
}

23
designer-base/src/main/java/com/fine/theme/light/ui/FineToggleButtonUI.java

@ -22,6 +22,7 @@ import java.awt.Shape;
import java.awt.Rectangle;
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_GROUP;
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_GROUP_FIT;
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE;
import static com.fine.theme.utils.FineClientProperties.BUTTON_TYPE_TAB;
import static com.fine.theme.utils.FineClientProperties.BUTTON_GROUP_POSITION;
@ -96,13 +97,21 @@ public class FineToggleButtonUI extends FlatToggleButtonUI {
}
static boolean isGroupButton(Component c) {
if (!(c instanceof UIButton)) {
return false;
}
String buttonType = getButtonTypeStr((UIButton) c);
return BUTTON_TYPE_GROUP.equals(buttonType) || BUTTON_TYPE_GROUP_FIT.equals(buttonType);
}
static boolean isGroupButtonNotFit(Component c) {
return c instanceof UIButton && BUTTON_TYPE_GROUP.equals(getButtonTypeStr((UIButton) c));
}
@Override
public void paint(Graphics g, JComponent c) {
if (isGroupButton(c) || isTabButton(c)) {
((AbstractButton)c).setMargin(FineUIUtils.getUIInsets("ToggleButton.compact.margin", "ToggleButton.margin"));
if (isGroupButtonNotFit(c) || isTabButton(c)) {
((AbstractButton) c).setMargin(FineUIUtils.getUIInsets("ToggleButton.compact.margin", "ToggleButton.margin"));
}
super.paint(g, c);
}
@ -125,7 +134,7 @@ public class FineToggleButtonUI extends FlatToggleButtonUI {
// paint background
Color background;
if(c.isEnabled() && selected) {
if (c.isEnabled() && selected) {
background = tabSelectedBackground;
} else {
Color enabledColor = selected ? clientPropertyColor(c, TAB_BUTTON_SELECTED_BACKGROUND, tabSelectedBackground) : null;
@ -161,9 +170,7 @@ public class FineToggleButtonUI extends FlatToggleButtonUI {
float focusWidth = FlatUIUtils.getBorderFocusWidth(c);
FlatUIUtils.paintComponentBackground(g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, 0);
} else {
float arc = FlatUIUtils.getBorderArc( c ) / 2;
Shape path2D = getGroupButtonPath2D(c, position, arc);
g2.fill(path2D);
g2.fill(getGroupButtonPath2D(c, position, FlatUIUtils.getBorderArc(c)));
}
} finally {
g2.dispose();
@ -200,7 +207,7 @@ public class FineToggleButtonUI extends FlatToggleButtonUI {
@Override
protected Color getForeground(JComponent c) {
if (isGroupButton(c) && ((AbstractButton)c).isSelected()) {
if (isGroupButton(c) && ((AbstractButton) c).isSelected()) {
return groupSelectedForeground;
}
return super.getForeground(c);
@ -209,7 +216,7 @@ public class FineToggleButtonUI extends FlatToggleButtonUI {
@Override
protected Color getBackground(JComponent c) {
if (isGroupButton(c)) {
return ((AbstractButton)c).isSelected() ? groupSelectedBackground : groupBackground;
return ((AbstractButton) c).isSelected() ? groupSelectedBackground : groupBackground;
}
return super.getBackground(c);
}

3
designer-base/src/main/java/com/fine/theme/light/ui/laf/FineDarkLaf.java

@ -2,7 +2,6 @@ package com.fine.theme.light.ui.laf;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.IconManager;
import com.fine.theme.light.ui.FineLightIconSet;
import com.formdev.flatlaf.util.UIScale;
import com.fr.stable.StringUtils;
@ -25,7 +24,7 @@ public class FineDarkLaf extends FineLaf {
* @return 是否安装成功
*/
public static boolean setup() {
IconManager.addSet(new FineLightIconSet());
IconManager.initializeIcon();
Layouts.setScaleFactor(UIScale.getUserScaleFactor());
UIScale.addPropertyChangeListener(evt -> {
if (StringUtils.equals(evt.getPropertyName(), USER_SCALE_FACTOR)) {

2
designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLaf.java

@ -18,7 +18,6 @@ public abstract class FineLaf extends FlatLaf {
private static final String NAME = "FineLaf";
@Override
public String getName() {
return NAME;
@ -53,4 +52,5 @@ public abstract class FineLaf extends FlatLaf {
System.setProperty("flatlaf.menuBarEmbedded", "false");
}
}
}

3
designer-base/src/main/java/com/fine/theme/light/ui/laf/FineLightLaf.java

@ -2,7 +2,6 @@ package com.fine.theme.light.ui.laf;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.IconManager;
import com.fine.theme.light.ui.FineLightIconSet;
import com.formdev.flatlaf.util.UIScale;
import com.fr.stable.StringUtils;
@ -25,7 +24,7 @@ public class FineLightLaf extends FineLaf {
* @return 是否安装成功
*/
public static boolean setup() {
IconManager.addSet(new FineLightIconSet());
IconManager.initializeIcon();
Layouts.setScaleFactor(UIScale.getUserScaleFactor());
UIScale.addPropertyChangeListener(evt -> {
if (StringUtils.equals(evt.getPropertyName(), USER_SCALE_FACTOR)) {

1
designer-base/src/main/java/com/fine/theme/utils/FineClientProperties.java

@ -13,6 +13,7 @@ public interface FineClientProperties extends FlatClientProperties {
//--------------------------- ButtonGroup -----------------------
String BUTTON_TYPE_GROUP = "group";
String BUTTON_TYPE_GROUP_FIT = "groupFit";
String BUTTON_BORDER = "buttonBorder";
String BUTTON_BORDER_LEFT_ROUND_RECT = "leftRoundRect";

30
designer-base/src/main/java/com/fine/theme/utils/FineComponentsFactory.java

@ -1,12 +1,22 @@
package com.fine.theme.utils;
import com.fine.theme.icon.LazyIcon;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.data.core.FormatField;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.stable.Constants;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import java.awt.Color;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.flex;
@ -62,4 +72,24 @@ public class FineComponentsFactory {
flex(), cell(confirmButton), cell(cancelButton)).getComponent();
}
/**
* 创建示例文本圆角边框&浅灰背景
*
* @return 示例文本Label
*/
public static UILabel createSampleLabel() {
Color labelColor = FineUIUtils.getUIColor("Label.tipColor", "inactiveCaption");
Border interBorder = new UIRoundedBorder(labelColor, 0, 4);
Border border = BorderFactory.createTitledBorder(interBorder, Toolkit.i18nText("Fine-Design_Report_Base_StyleFormat_Sample"),
TitledBorder.ABOVE_TOP, 0, null, labelColor);
UILabel sampleLabel = new UILabel(FormatField.getInstance().getFormatValue());
sampleLabel.setHorizontalAlignment(UILabel.CENTER);
sampleLabel.setBorder(BorderFactory.createCompoundBorder(border, new ScaledEmptyBorder(2, 0, 8, 0)));
FineUIStyle.setStyle(sampleLabel, FineUIStyle.LABEL_TIP);
return sampleLabel;
}
}

15
designer-base/src/main/java/com/fine/theme/utils/FineLayoutBuilder.java

@ -4,8 +4,10 @@ import com.fine.swing.ui.layout.Column;
import com.fine.swing.ui.layout.Layouts;
import com.fine.swing.ui.layout.Row;
import com.fine.swing.ui.layout.Spacer;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.collections.combination.Pair;
@ -75,7 +77,7 @@ public class FineLayoutBuilder {
Row row = new Row();
List<Component> visibleComponents = Arrays.stream(componentArray)
.filter(com -> com != null && com.isVisible()).collect(Collectors.toList());
if (visibleComponents.size() >= 1) {
if (!visibleComponents.isEmpty()) {
// 仅当存在可见组件时处理布局
dealWithVisibleComponents(weight, column, componentArray, row, visibleComponents);
}
@ -87,6 +89,17 @@ public class FineLayoutBuilder {
return new JPanel();
}
/**
* 典型的左右网格布局竖向间距为典型间距标签及组件比例采用典型比例
*
* @param components 组件两列多行
* @return 面板
*/
public static JPanel commonLeftRightLayout(Component[][] components) {
return compatibleTableLayout(LayoutConstants.VERTICAL_GAP, components,
new double[]{LayoutConstants.LEFT_WEIGHT, LayoutConstants.RIGHT_WEIGHT});
}
private static void dealWithVisibleComponents(double[] weight, Column column, Component[] value, Row row, List<Component> components) {
if (components.size() == 1 && value[0] != null) {
// 仅存在首个元素,则该元素自适应占满整行

12
designer-base/src/main/java/com/fine/theme/utils/FineUIScale.java

@ -83,4 +83,16 @@ public class FineUIScale {
public static Insets scale(Insets insets) {
return UIScale.scale(insets);
}
/**
* Creates a scaled {@link Dimension} object based on the specified width and height.
* <p>
* This method uses the current user scale factor to adjust the provided width and height values:
* - If the user scale factor is 1 (no scaling), the original width and height values are returned unchanged.
* - If the user scale factor is different from 1, a new {@link Dimension} instance is created and returned,
* with the width and height values scaled according to the user scale factor.
*/
public static Dimension createScaleDimension(int width, int height) {
return scale(new Dimension(width, height));
}
}

6
designer-base/src/main/java/com/fine/theme/utils/FineUIStyle.java

@ -28,6 +28,7 @@ public interface FineUIStyle {
String BRAND_COLOR_LABEL = "brandColorLabel";
String BUTTON_TAB_ACTION = "tabAction";
String LABEL_BOLD = "boldLabel";
String LABEL_TIP_WINDOW_TITLE = "tipWindowTitleLabel";
String LABEL_SECONDARY = "secondaryLabel";
String LABEL_TIP = "tipLabel";
String LABEL_WARNING_TIP = "warningTipLabel";
@ -40,6 +41,7 @@ public interface FineUIStyle {
String POPUP_MENU_TOOL_BAR = "popupMenuToolBar";
String POPUP_MENU_DROPDOWN = "dropdownPopupMenu";
String TRANSPARENT_TEXT_FIELD = "transparentTextField";
String OFFET_LEFT_TEXT_FIELD = "offsetLeftText";
String TRANSPARENT_BACKGROUND = "transparentBackground";
String PURE_LIST = "pureList";
String NO_BORDER_LIST = "noBorderList";
@ -50,7 +52,11 @@ public interface FineUIStyle {
String DEFAULT_TABLE = "defaultTable";
String WHITE_BUTTON = "whiteButton";
String ORIGINAL_BUTTON = "originalButton";
String PLAIN_ARROW_BUTTON = "plainArrowButton";
String GRAY_BUTTON = "grayButton";
String DETAIL_LABEL = "detailLabel";
String WIDGET_EVENT_LABEL = "widgetEventLabel";
String HYPER_LINK_LABEL = "hyperLinkLabel";
/**

108
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.theme.edit.ui.LabelUtils;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.stable.os.OperatingSystem;
import com.fr.value.AtomicClearableLazyValue;
@ -13,9 +15,11 @@ import javax.swing.JLabel;
import javax.swing.JLayer;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.JTextArea;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
@ -40,6 +44,9 @@ import static com.formdev.flatlaf.util.UIScale.scale;
*/
public class FineUIUtils {
public static final String LEFT = "LEFT";
public static final String RIGHT = "RIGHT";
public static final int RETINA_SCALE_FACTOR = 2;
/**
@ -179,10 +186,10 @@ public class FineUIUtils {
* @param background 背景色
* @param width 宽度
* @param height 高度
* @param radius 圆角
* @param arc 圆角
*/
public static void paintWithComposite(Graphics g, Composite composite, Color background,
int width, int height, int radius) {
int width, int height, int arc) {
Graphics2D g2d = (Graphics2D) g;
FlatUIUtils.setRenderingHints(g2d);
@ -190,7 +197,7 @@ public class FineUIUtils {
g2d.setComposite(composite);
g2d.setColor(background);
g2d.fill(new RoundRectangle2D.Float(0, 0, width, height, radius, radius));
g2d.fill(new RoundRectangle2D.Float(0, 0, width, height, arc, arc));
g2d.setComposite(oldComposite);
}
@ -208,17 +215,48 @@ public class FineUIUtils {
*/
public static void paintPartRoundButtonBorder(Component c, Graphics2D g2, int x, int y, int width, int height,
float borderWidth, float arc) {
if (isLeftRoundButton(c)) {
paintPartRoundButtonBorder(g2, x, y, width, height, borderWidth, arc, LEFT, false);
} else {
paintPartRoundButtonBorder(g2, x, y, width, height, borderWidth, arc, RIGHT, false);
}
}
/**
* 绘制部分圆角矩形边框
*
* @param g2 Graphics2D
* @param x x坐标
* @param y y坐标
* @param width 宽度
* @param height 高度
* @param borderWidth 边框宽度
* @param arc 圆角
* @param roundPart 圆角的方位当前只能设置一侧
* @param closedPath 是否封闭非圆角那一侧是否有边框是为有边框
*/
public static void paintPartRoundButtonBorder(Graphics2D g2, int x, int y, int width, int height,
float borderWidth, float arc, String roundPart, boolean closedPath) {
FlatUIUtils.setRenderingHints(g2);
arc = scale(arc);
float t = scale(borderWidth);
float t2x = t * 2;
Path2D path2D = new Path2D.Float(Path2D.WIND_EVEN_ODD);
if (isLeftRoundButton(c)) {
path2D.append(createLeftRoundRectangle(x, y, width, height, arc), false);
path2D.append(createLeftRoundRectangle(x + t, y + t, width - t, height - t2x, arc - t), false);
} else {
path2D.append(createRightRoundRectangle(x, y, width, height, arc), false);
path2D.append(createRightRoundRectangle(x, y + t, width - t, height - t2x, arc - t), false);
switch (roundPart) {
case LEFT: {
path2D.append(createLeftRoundRectangle(x, y, width, height, arc), false);
path2D.append(createLeftRoundRectangle(x + t, y + t,
width - (closedPath ? t2x : t), height - t2x, arc - t2x), false);
break;
}
case RIGHT:
default: {
path2D.append(createRightRoundRectangle(x, y, width, height, arc), false);
path2D.append(createRightRoundRectangle(x + (closedPath ? t : 0), y + t,
width - (closedPath ? t2x : t), height - t2x, arc - t2x), false);
break;
}
}
g2.fill(path2D);
}
@ -242,12 +280,18 @@ public class FineUIUtils {
float t2x = t * 2;
Path2D path2D = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path2D.append(createTopRoundRectangle(x, y, width, height, arc), false);
path2D.append(createTopRoundRectangle(x + t, y + t, width - t2x, height - t, arc - t), false);
path2D.append(createTopRoundRectangle(x + t, y + t, width - t2x, height - t, arc - t2x), false);
g2.fill(path2D);
}
/**
* 创建一个部分圆角的矩形路径
* <p>
* 注意
* 在swing中UI的样式的 arc 数值是直径 css border-radius 为半径
* 因此我们配置的 arc 全部为 border-radius 的2倍但是使用 Path2D 绘制时
* 绘制方式其实是使用半径来进行计算的为了保持调用一致对外 API 还是以 arc
* 的形式因此方法内部需要对 arc 进行取半处理
*
* @param x x坐标
* @param y y坐标
@ -261,16 +305,20 @@ public class FineUIUtils {
*/
public static Path2D createPartRoundRectangle(double x, double y, double width, double height,
double arcTopLeft, double arcTopRight, double arcBottomRight, double arcBottomLeft) {
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD, 7);
path.moveTo(x + arcTopLeft, y);
path.lineTo(x + width - arcTopRight, y);
path.quadTo(x + width, y, x + width, y + arcTopRight);
path.lineTo(x + width, y + height - arcBottomRight);
path.quadTo(x + width, y + height, x + width - arcBottomRight, y + height);
path.lineTo(x + arcBottomLeft, y + height);
path.quadTo(x, y + height, x, y + height - arcBottomLeft);
path.lineTo(x, y + arcTopLeft);
path.quadTo(x, y, x + arcTopLeft, y);
double radiusTopLeft = arcTopLeft / 2;
double radiusTopRight = arcTopRight / 2;
double radiusBottomLeft = arcBottomLeft / 2;
double radiusBottomRight = arcBottomRight / 2;
Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD, 10);
path.moveTo(x + radiusTopLeft, y);
path.lineTo(x + width - radiusTopRight, y);
path.quadTo(x + width, y, x + width, y + radiusTopRight);
path.lineTo(x + width, y + height - radiusBottomRight);
path.quadTo(x + width, y + height, x + width - radiusBottomRight, y + height);
path.lineTo(x + radiusBottomLeft, y + height);
path.quadTo(x, y + height, x, y + height - radiusBottomLeft);
path.lineTo(x, y + radiusTopLeft);
path.quadTo(x, y, x + radiusTopLeft, y);
path.closePath();
return path;
}
@ -435,4 +483,24 @@ public class FineUIUtils {
Font newSizeFont = font.deriveFont(font.getStyle(), scale(size));
c.setFont(newSizeFont);
}
/**
* 获取缩放后的国际化尺寸
*
* @param i18nDimensionKey 国际化key值
* @return 缩放后的国际化尺寸
*/
public static Dimension getScaledI18nDimension(String i18nDimensionKey) {
return FineUIScale.scale(DesignSizeI18nManager.getInstance().i18nDimension(i18nDimensionKey));
}
/**
* 创建一个支持自动换行的提示文本
*
* @param text 显示的文本内容
* @return 自动换行提示文本
*/
public static JTextArea createAutoWrapTipLabel(String text) {
return LabelUtils.createAutoWrapLabel(text, FineUIUtils.getUIColor("Label.tipColor", "inactiveCaption"));
}
}

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

@ -104,12 +104,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
* The manager of Designer GUI.
* 下面的作者日期都是随手写的具体作者已经无法考究
*
* @author anonymous
* @version 11.0
* @author anonymous
* @version 11.0
* created by anonymous on 2002/11/08
*/
public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReadable {
private static final int MAX_SHOW_NUM = 10;
private static final String VERSION_80 = "80";
private static final String VERSION_90 = "90";
@ -122,26 +122,26 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
* 指定默认工作空间
*/
public static final String DEFAULT_WORKSPACE_PATH = "fr.designer.workspace.default";
public static final String LAST_EAST_REGION_LAYOUT = "LastEastRegionLayout";
public static final String LAST_WEST_REGION_LAYOUT = "LastWestRegionLayout";
private static DesignerEnvManager designerEnvManager; // gui.
private String activationKey = null;
private String logLocation = null;
private Rectangle windowBounds = null; // window bounds.
private String DialogCurrentDirectory = null;
private String CurrentDirectoryPrefix = null;
private Map<String, List<String>> recentOpenedFileListMap = new HashMap<>();
private List<String> tempRecentOpenedFilePathList = new ArrayList<String>();
private XmlElement<Map<String, List<String>>> recentOpenedMapping = SimpleXmlElement.of(recentOpenedFileListMap);
private boolean showPaintToolBar = true;
private int maxNumberOrPreviewRow = 200;
private XmlElement<EnvConfiguration> envConfig = SimpleXmlElement.of(new EnvConfiguration());
private boolean showProjectPane = true;
private boolean showDataPane = true;
//p:这是当前选择的数据库连接的名字,这个在新建数据源的时候用到.
@ -159,7 +159,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
private boolean rowHeaderVisible = true;
private boolean verticalScrollBarVisible = true;
private boolean horizontalScrollBarVisible = true;
private Color gridLineColor = Color.lightGray; // line color.
private Color gridLineColor = new Color(230, 233, 239); // line color.
private Color paginationLineColor = Color.black; // line color of paper
private boolean supportCellEditorDef = false;
private boolean isDragPermited = false;
@ -195,12 +195,12 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
private boolean embedServerLazyStartup = false;
//最近使用的颜色
private ColorSelectConfigManager configManager = new ColorSelectConfigManager();
/**
* 环境检测配置
*/
private EnvDetectorConfig envDetectorConfig = EnvDetectorConfig.getInstance();
/**
* alphafine
*/
@ -214,11 +214,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
private DesignerPushUpdateConfigManager designerPushUpdateConfigManager = DesignerPushUpdateConfigManager.getInstance();
private VcsConfigManager vcsConfigManager = VcsConfigManager.getInstance();
private DesignerStartupConfig designerStartupConfig = DesignerStartupConfig.getInstance();
private SwitchForSwingChecker switchForSwingChecker = SwitchForSwingChecker.getInstance();
public static final String CAS_CERTIFICATE_PATH = "certificatePath";
public static final String CAS_CERTIFICATE_PASSWORD = "certificatePass";
@ -267,7 +267,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
designerEnvManager = new DesignerEnvManager();
//REPORT-15332有一个国际化调用比较早,需要在这边就设置好locale,由于后台GeneralContext默认是China
GeneralContext.setLocale(designerEnvManager.getLanguage());
if (!asyncInitEnvManager()) {
// 如果异步读取失败, 则恢复原来的逻辑
compatibleInitEnvManager();
@ -287,9 +287,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
return designerEnvManager;
}
private static void compatibleInitEnvManager() {
try {
XMLTools.readFileXML(designerEnvManager, designerEnvManager.getDesignerEnvFile());
} catch (FileNotFoundException e) {
@ -299,7 +299,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 异步初始化环境管理, 提供配置, 帮助处理预期外的问题
* 1-当优化开启时才走异步逻辑
@ -308,7 +308,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
* @return /
*/
private static boolean asyncInitEnvManager() {
AtomicBoolean noEx = new AtomicBoolean(false);
OptimizeUtil.initiateOpen(DesignerEnvManager.class.getSimpleName().toLowerCase(), () -> {
try {
@ -326,7 +326,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
}
public static void checkNameEnvMap() {
if (designerEnvManager == null || designerEnvManager.getNameEnvMap().size() > 0) {
return;
}
@ -1020,22 +1020,6 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
designerLoginConfigManager.setPluginRemindOnFirstLaunch(pluginRemindOnFirstLaunch);
}
public boolean isUseOldVersionLogin() {
return designerLoginConfigManager.isUseOldVersionLogin();
}
public void setUseOldVersionLogin(boolean useOldVersionLogin) {
designerLoginConfigManager.setUseOldVersionLogin(useOldVersionLogin);
}
public boolean isUseNewPluginFirst() {
return designerLoginConfigManager.isUseNewPluginFirst();
}
public void setUseNewPluginFirst(boolean useNewPluginFirst) {
designerLoginConfigManager.setUseNewPluginFirst(useNewPluginFirst);
}
/**
* 内置服务器是否使用时启动
*
@ -1076,11 +1060,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
public void setLanguage(Locale locale) {
this.language = locale;
}
public boolean isStartupPageEnabled() {
return this.designerStartupConfig.isEnabled();
}
public void setStartupPageEnabled(boolean enabled) {
this.designerStartupConfig.setEnabled(enabled);
}
@ -1207,9 +1191,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
public void setCurrentDirectoryPrefix(String prefix) {
this.CurrentDirectoryPrefix = prefix;
}
public List<String> getRecentOpenedFilePathList4Env(String envName) {
if (StringUtils.isEmpty(envName)) {
return tempRecentOpenedFilePathList;
} else {
@ -1217,7 +1201,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
recentOpenedMapping.getValue().put(envName, tempRecentOpenedFilePathList);
}
}
return recentOpenedMapping.getValue().get(envName);
}
@ -1225,7 +1209,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
* 返回最近打开的文件路径列表
*/
public List<String> getRecentOpenedFilePathList() {
return this.getRecentOpenedFilePathList4Env(getCurEnvName());
}
@ -1729,7 +1713,16 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
}
}
}
Carina.config(LanguageConfigProvider.class).setLocale(CommonUtils.localeToString(designerEnvManager.getLanguage()));
setLocale();
}
private static void setLocale() {
try {
Carina.config(LanguageConfigProvider.class)
.setLocale(CommonUtils.localeToString(designerEnvManager.getLanguage()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
@ -1869,10 +1862,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
public void setLayoutTemplateStyle(int layoutTemplateStyle) {
this.layoutTemplateStyle = layoutTemplateStyle;
}
@Override
public void initElements(File xmlFile) throws XmlException {
try {
backupOldXmlFile();
XmlInitialFactory xmlInitialFactory = XmlInitialFactory.create(xmlFile);
@ -1892,7 +1885,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
});
})
.init("EnvConfigMap", (e) -> {
final EnvConfiguration previousConfig = this.envConfig.getValue();
this.envConfig = AsyncXmlElement.of(DesignerStartupPool.common(), () -> {
DesignerEnvManager.this.readEnvConfigMap(e, previousConfig);
@ -1944,13 +1937,13 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
throw new XmlException(e);
}
}
/**
* 备份老的 xml 文件, 防止第一次修改存在问题
* 但是只备份一次其他都走老逻辑
*/
private void backupOldXmlFile() {
try {
File oldFile = getEnvFile();
String newFilePath = ProductConstants.getEnvHome() + File.separator + ProductConstants.APP_NAME + "Env_backup.xml";
@ -1964,7 +1957,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
} catch (Exception ignored) {
}
}
/**
* Read XML.<br>
* The method will be invoked when read data from XML file.<br>
@ -2056,16 +2049,16 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
}
private void readAlphaFineAttr(XMLableReader reader) {
AlphaFineConfigManager config = AlphaFineConfigManager.getInstance();
reader.readXMLObject(config);
this.alphaFineConfigManager = SimpleXmlElement.of(config);
}
private void readEnvDetectorConfig(XMLableReader reader) {
reader.readXMLObject(this.envDetectorConfig);
}
private void readStartupConfig(XMLableReader reader) {
reader.readXMLObject(this.designerStartupConfig);
}
@ -2174,16 +2167,16 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
this.setUndoLimit(reader.getAttrAsInt("undoLimit", 5));
this.setStartWithEmptyFile(reader.getAttrAsBoolean("startWithEmptyFile", false));
this.setDefaultStringToFormula(reader.getAttrAsBoolean("defaultStringToFormula", false));
if ((tmpVal = reader.getAttrAsString("gridLineColor", null)) != null) {
if ((tmpVal = reader.getAttrAsString("uiGridLineColor", null)) != null) {
this.setGridLineColor(new Color(Integer.parseInt(tmpVal)));
}
if ((tmpVal = reader.getAttrAsString("paginationLineColor", null)) != null) {
if ((tmpVal = reader.getAttrAsString("uiPaginationLineColor", null)) != null) {
this.setPaginationLineColor(new Color(Integer.parseInt(tmpVal)));
}
}
private void readEnvConfigMap(XMLableReader reader, EnvConfiguration envConfigs) {
String currentEnv = reader.getAttrAsString("currentEnv", StringUtils.EMPTY);
envConfigs.setCurEnvName(currentEnv);
reader.readXMLObject(new XMLReadable() {
@ -2248,15 +2241,15 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
}
});
}
private void readRecentOpenFileList(XMLableReader reader) {
readRecentOpenFileList0(reader);
checkRecentOpenedFileNum();
}
private void readRecentOpenFileList0(XMLableReader reader) {
reader.readXMLObject(new XMLReadable() {
@Override
public void readXML(XMLableReader reader) {
@ -2374,13 +2367,13 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
writer.end();
}
}
private void writeEnvDetectorConfig(XMLPrintWriter writer) {
if (this.envDetectorConfig != null) {
this.envDetectorConfig.writeXML(writer);
}
}
private void writeStartupConfig(XMLPrintWriter writer) {
if (this.designerStartupConfig != null) {
this.designerStartupConfig.writeXML(writer);
@ -2609,8 +2602,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
.attr("horizontalScrollBarVisible", this.isHorizontalScrollBarVisible())
.attr("supportCellEditorDef", this.isSupportCellEditorDef())
.attr("isDragPermited", this.isDragPermited())
.attr("gridLineColor", this.getGridLineColor().getRGB())
.attr("paginationLineColor", this.getPaginationLineColor().getRGB())
.attr("uiGridLineColor", this.getGridLineColor().getRGB())
.attr("uiPaginationLineColor", this.getPaginationLineColor().getRGB())
.attr("undoLimit", this.getUndoLimit())
.attr("startWithEmptyFile", this.isStartWithEmptyFile())
.end();
@ -2646,7 +2639,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
}
private void readFvsDesignerConfig(XMLableReader reader) {
SimpleDesignerConfig config = fvsDesignerConfig.getValue();
reader.readXMLObject(config);
fvsDesignerConfig = SimpleXmlElement.of(config);
@ -2688,39 +2681,39 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
public SnapChatConfig getSnapChatConfig() {
return snapChatConfig;
}
private EnvConfiguration getEnvConfig() {
return envConfig.getValue();
}
private Map<String, DesignerWorkspaceInfo> getNameEnvMap() {
return getEnvConfig().getNameEnvMap();
}
private static class EnvConfiguration {
// name和Env的键值对
private Map<String, DesignerWorkspaceInfo> nameEnvMap = new ListMap<>();
// marks: 当前报表服务器名字
private String curEnvName = null;
public Map<String, DesignerWorkspaceInfo> getNameEnvMap() {
return nameEnvMap;
}
public void setNameEnvMap(Map<String, DesignerWorkspaceInfo> nameEnvMap) {
this.nameEnvMap = nameEnvMap;
}
public String getCurEnvName() {
return curEnvName;
}
public void setCurEnvName(String curEnvName) {
this.curEnvName = curEnvName;
}
}
}

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

@ -2,8 +2,6 @@ package com.fr.design;
import com.fr.common.report.ReportState;
import com.fr.design.backup.EnvBackupHelper;
import com.fr.design.mainframe.manager.clip.TemplateTreeClipboard;
import com.fr.design.plugin.remind.PluginErrorDesignReminder;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
@ -52,7 +50,6 @@ import com.fr.workspace.engine.base.FineObjectPool;
import com.fr.workspace.engine.channel.http.FunctionalHttpRequest;
import com.fr.workspace.engine.exception.WorkspaceConnectionException;
import com.fr.workspace.engine.rpc.WorkspaceProxyPool;
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
@ -68,9 +65,10 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
public class EnvChangeEntrance {
private static final String BRANCH_TAG = "#";
private static final String BRANCH_BEGIN = "-";
@ -158,11 +156,11 @@ public class EnvChangeEntrance {
}
/**
* 由云端运维触发切换埋点
* 内部空实现
* <a href="https://kms.fineres.com/pages/viewpage.action?pageId=945327503">实现</a>
* 异步提交埋点
*
*/
private void triggerSwitchMetric() {
EnvSwitcherSubmitTask.asyncSubmit();
}
/**
@ -180,8 +178,9 @@ public class EnvChangeEntrance {
private boolean doSwitch2Env(final String envName, PopTipStrategy strategy) {
DesignerWorkspaceInfo selectedEnv = getSelectedEnv(envName);
EnvBackupHelper.getInstance().backup();
try {
EnvBackupHelper.getInstance().backup();
Workspace workspace = DesignerWorkspaceGenerator.generate(selectedEnv);
if (notValid(workspace, selectedEnv)) {
return false;

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

@ -0,0 +1,214 @@
package com.fr.design;
import com.fr.concurrent.FineExecutors;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.mainframe.SiteCenterToken;
import com.fr.design.metric.AbstractDesignerMetric;
import com.fr.general.CloudCenter;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceSwitchProcess;
import com.fr.workspace.WorkspaceSwitchStatics;
import com.fr.workspace.switcher.WorkspaceSwitchHistory;
import org.jetbrains.annotations.NotNull;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.ExecutorService;
/**
* 设计器环境切换埋点提交
*
* @author Bruce.Deng
* @since 11.0
* Created on 2024/9/5
*/
public class EnvSwitcherSubmitTask extends AbstractDesignerMetric {
private static final String TAG_MODULE = "module";
private static final String TAG_SELF_USED = "selfUsed";
private static final String TAG_SUB = "sub";
private static final String WORK_DIRECTORY_TYPE_BEFORE_SWITCHING = "workDirectoryTypeBeforeSwitching";
private static final String WORK_DIRECTORY_TYPE_AFTER_SWITCHING = "workDirectoryTypeAfterSwitching";
private static final String SWITCH_COMPLETED = "switchCompleted";
private static final String EXCHANGE_TIME = "exchangeTime";
private static final String START_SLOW_MODULE_NAME = "startSlowModuleName";
private static final String STOP_SLOW_MODULE_NAME = "stopSlowModuleName";
private static final int MIN_LIMIT = 100;
private static final String SWITCH_TABLE_SUFFIX = "record_of_fbp_remoteSwitch/single";
private final ExecutorService service;
private EnvSwitcherSubmitTask() {
service = FineExecutors.newSingleThreadExecutor(new NamedThreadFactory("DesignEnvSwitchMetricSubmit"));
}
/**
* 异步提交环境切换的埋点
*/
public static void asyncSubmit() {
new EnvSwitcherSubmitTask().run();
}
/**
* 执行任务
*/
private void run() {
WorkspaceSwitchHistory.consume(workspaceSwitchProcesses -> {
Iterator<WorkspaceSwitchProcess> workspaceSwitchProcessIterator = workspaceSwitchProcesses.descendingIterator();
while (workspaceSwitchProcessIterator.hasNext()) {
WorkspaceSwitchProcess next = workspaceSwitchProcessIterator.next();
// 过滤掉 source 为空的启动过程
if (next != null && next.getSource() != null) {
submitProcess(next);
}
// 提交之后要移除掉
workspaceSwitchProcessIterator.remove();
}
});
}
private void submitProcess(WorkspaceSwitchProcess process) {
service.submit(new Runnable() {
@Override
public void run() {
collectAndSubmit(process);
}
});
}
private void collectAndSubmit(WorkspaceSwitchProcess process) {
Map<String, Object> para = new HashMap<>();
para.put("token", SiteCenterToken.generateToken());
para.put("content", collect(process));
try {
HttpToolbox.post(getUrl(), para);
FineLoggerFactory.getLogger().debug("[EnvSwitcher] submit env switcher metric to cloud.");
} catch (Throwable t) {
FineLoggerFactory.getLogger().debug(t,"[EnvSwitcher] failed to submit env switcher metric to cloud.");
}
}
private JSONObject collect(WorkspaceSwitchProcess process) {
JSONObject info = new JSONObject();
addDefaultMetric(info);
addMeta(info, process);
addStatics(info, process.getStatics());
return info;
}
private static void addMeta(JSONObject info, WorkspaceSwitchProcess process) {
Workspace source = process.getSource();
info.put(WORK_DIRECTORY_TYPE_BEFORE_SWITCHING, workspaceType(source));
Workspace target = process.getTarget();
info.put(WORK_DIRECTORY_TYPE_AFTER_SWITCHING, workspaceType(target));
info.put(SWITCH_COMPLETED, switchCompleted(process));
}
@NotNull
private static String switchCompleted(WorkspaceSwitchProcess process) {
return process.isSwitchSuccess() ? "yes" : "no";
}
@NotNull
private static String workspaceType(Workspace workspace) {
return workspace.isLocal() ? "local" : "remote";
}
private void addStatics(JSONObject info, WorkspaceSwitchStatics statics) {
info.put(EXCHANGE_TIME, statics.getElapsed());
JSONObject startSlowModuleName = convert2CloudModel(statics.getStartModuleUsed());
info.put(START_SLOW_MODULE_NAME, startSlowModuleName);
JSONObject stopSlowModuleName = convert2CloudModel(statics.getStopModuleUsed());
info.put(STOP_SLOW_MODULE_NAME, stopSlowModuleName);
}
/* convert */
@NotNull
private JSONObject convert2CloudModel(JSONObject moduleUsedJO) {
TreeSet<Entry> entries = convert2SortSet(moduleUsedJO);
return convert2JO(entries);
}
@NotNull
private static JSONObject convert2JO(TreeSet<Entry> startEntries) {
JSONObject moduleNames = new JSONObject();
startEntries.stream()
.filter((e) -> e.getSelfUsed() > MIN_LIMIT)
.forEach((e) -> moduleNames.put(e.getModuleName(), e.getSelfUsed()));
return moduleNames;
}
@NotNull
private TreeSet<Entry> convert2SortSet(JSONObject moduleUsedJO) {
TreeSet<Entry> entries = new TreeSet<>(Comparator.comparingInt(Entry::getSelfUsed));
sortBySelfUsed(moduleUsedJO, entries);
return entries;
}
/**
* 循环处理 JSON, 并降序排序
*
* @param moduleUsed 模块用时 {@link com.fr.module.engine.FineModule}
* @param entries 降序排序的树集合
*/
private void sortBySelfUsed(JSONObject moduleUsed, TreeSet<Entry> entries) {
if (moduleUsed == null || moduleUsed.isEmpty()) {
return;
}
String moduleName = moduleUsed.optString(TAG_MODULE);
int selfUsed = moduleUsed.optInt(TAG_SELF_USED);
entries.add(new Entry(moduleName, selfUsed));
JSONArray subModules = moduleUsed.optJSONArray(TAG_SUB);
if (subModules != null) {
int length = subModules.length();
for (int i = 0; i < length; i++) {
JSONObject subModuleUsed = subModules.optJSONObject(i);
sortBySelfUsed(subModuleUsed, entries);
}
}
}
private String getUrl() {
String monitorEntry = CloudCenter.getInstance().acquireUrlByKind("cloud.monitor.api.entrypoint");
String url = (StringUtils.isNotEmpty(monitorEntry) ? monitorEntry : DEFAULT_MONITOR_URL)
+ SWITCH_TABLE_SUFFIX;
return url;
}
private static class Entry {
private final String moduleName;
private final Integer selfUsed;
public Entry(String moduleName, Integer selfUsed) {
this.moduleName = moduleName;
this.selfUsed = selfUsed;
}
public String getModuleName() {
return moduleName;
}
public Integer getSelfUsed() {
return selfUsed;
}
}
}

5
designer-base/src/main/java/com/fr/design/actions/TableDataSourceAction.java

@ -9,10 +9,12 @@ import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.data.tabledata.ResponseDataSourceChange;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.menu.KeySetUtils;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@ -42,7 +44,8 @@ public class TableDataSourceAction extends TemplateComponentAction<JTemplate<?,
populate(tds);
}
};
final BasicDialog reportTableDataDialog = tableDataPane.showLargeWindow(SwingUtilities.getWindowAncestor(this.getEditingComponent()), null);
final BasicDialog reportTableDataDialog = tableDataPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(this.getEditingComponent()), null,
DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.data.tabledata.dialog"));
reportTableDataDialog.addDialogActionListener(new DialogActionAdapter() {
@Override

7
designer-base/src/main/java/com/fr/design/actions/file/LocalePane.java

@ -4,14 +4,14 @@
package com.fr.design.actions.file;
import com.fr.base.FRContext;
import com.fanruan.entity.template.TemplateListBean;
import com.fanruan.repository.TemplateRepository;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.file.filetree.FileNode;
import com.fr.general.GeneralUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
@ -153,8 +153,7 @@ public class LocalePane extends BasicPane {
}
private void initCustomProperties() throws Exception {
FileNode[] fileNodes = FRContext.getFileNodes().list(ProjectConstants.LOCALE_NAME);
FileNode[] fileNodes = TemplateRepository.getInstance().list(new TemplateListBean(ProjectConstants.LOCALE_NAME));
if (ArrayUtils.getLength(fileNodes) == 0) {
return;
}

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

@ -1,6 +1,7 @@
package com.fr.design.actions.file;
import com.fine.swing.ui.layout.Row;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineLayoutBuilder;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
@ -34,7 +35,6 @@ import com.fr.design.gui.iprogressbar.UIProgressBarUI;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jdk.JdkVersion;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.VcsConfigManager;
@ -47,7 +47,6 @@ import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
import com.fr.general.IOUtils;
import com.fr.general.Inter;
import com.fr.general.log.Log4jConfig;
import com.fr.io.attr.ImageExportAttr;
@ -55,7 +54,6 @@ import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.report.ReportConfigManager;
import com.fr.stable.Constants;
import com.fr.stable.os.OperatingSystem;
import com.fr.third.apache.logging.log4j.Level;
import com.fr.third.guava.collect.BiMap;
import com.fr.third.guava.collect.HashBiMap;
@ -63,38 +61,18 @@ import com.fr.transaction.Configurations;
import com.fr.transaction.Worker;
import com.fr.transaction.WorkerAdaptor;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.entity.vcs.VcsTaskBean;
import com.fr.workspace.server.repository.vcs.VcsRepository;
import com.fr.workspace.server.vcs.VcsConfig;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.git.config.GcConfig;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanSchedule;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanService;
import org.jetbrains.annotations.NotNull;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Window;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
@ -110,12 +88,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.fix;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.theme.utils.FineClientProperties.COMBO_BOX_TYPE;
import static com.fine.swing.ui.layout.Layouts.*;
import static com.fine.theme.utils.FineClientProperties.ADAPTIVE_COMBO_BOX;
import static com.fine.theme.utils.FineClientProperties.COMBO_BOX_TYPE;
import static com.fine.theme.utils.FineUIConstants.SCALE_FONT_SIZE_12;
import static com.fr.design.i18n.Toolkit.i18nText;
@ -310,10 +285,6 @@ public class PreferencePane extends BasicPane {
cell(createLengthPane()),
// 服务器设置
cell(createServerPane()),
// 插件管理设置
cell(createUpmSelectorPane()).with(it -> it.setVisible(!OperatingSystem.isLinux() && JdkVersion.LE_8.support())),
// 登录选项
cell(createLoginSelectorPane()).with(it -> it.setVisible(SupportOSImpl.DESIGNER_LOGIN.support())),
// Oracle设置
cell(createOraclePane()),
// 内存设置
@ -346,6 +317,7 @@ public class PreferencePane extends BasicPane {
.addTab(i18nText("Fine-Design_Basic_General"), generalScrollPane)
.addTab(i18nText("Fine-Design_Basic_Advanced"), adviceScrollPane)
.addTab(i18nText("Fine-Design_Vcs_Title"), vcsParentPane)
.withAdaptiveFit()
.build();
contentPane.add(tabbedPane, BorderLayout.CENTER);
@ -544,7 +516,7 @@ public class PreferencePane extends BasicPane {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return WorkContext.getCurrent().get(VcsAutoCleanOperator.class).isSupport();
return VcsRepository.getInstance().isSupport();
}
@Override
protected void done() {
@ -731,10 +703,10 @@ public class PreferencePane extends BasicPane {
private Component createColorSettingPane() {
// Color Setting Pane
gridLineColorTBButton = new UINoThemeColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
gridLineColorTBButton = new UINoThemeColorButton(new LazyIcon("foreground"));
gridLineColorTBButton.setEnabled(this.isEnabled());
paginationLineColorTBButton = new UINoThemeColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
paginationLineColorTBButton = new UINoThemeColorButton(new LazyIcon("foreground"));
paginationLineColorTBButton.setEnabled(this.isEnabled());
JPanel colorPanel = row(10,
@ -967,11 +939,7 @@ public class PreferencePane extends BasicPane {
this.portEditor.setValue(new Integer(designerEnvManager.getEmbedServerPort()));
if (useOptimizedUPMCheckbox != null) {
useOptimizedUPMCheckbox.setSelected(checkOptimizedUPMUse());
}
if (useNewVersionLoginCheckbox != null) {
useNewVersionLoginCheckbox.setSelected(!DesignerEnvManager.getEnvManager().isUseOldVersionLogin());
useOptimizedUPMCheckbox.setSelected(true);
}
useUniverseDBMCheckbox.setSelected(ServerPreferenceConfig.getInstance().isUseUniverseDBM());
@ -1010,15 +978,6 @@ public class PreferencePane extends BasicPane {
this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled());
}
private boolean checkOptimizedUPMUse() {
//如果是没手动配置过则默认开启
//isUseNewPluginFirst如果为true说明没手动配置过,直接开启
//走到这里说明checkBox不为空,机型肯定符合
return DesignerEnvManager.getEnvManager().isUseNewPluginFirst()
|| ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter();
}
private int chooseCase(int sign) {
switch (sign) {
case 0:
@ -1085,8 +1044,6 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setImageCompress(this.imageCompressPanelCheckBox.isSelected());
boolean optimizedUPMFlag = this.useOptimizedUPMCheckbox != null && this.useOptimizedUPMCheckbox.isSelected();
designerEnvManager.setUseOptimizedUPM4Adapter(optimizedUPMFlag);
//只有取消掉使用新插件管理器这个选项才需要把useNewPluginFirst置false(意味着用户手动配置了,如果勾选着的话,这个useNewPluginFirst为true就行了)
designerEnvManager.setUseNewPluginFirst(optimizedUPMFlag);
boolean cloudDelayFlag = this.cloudAnalyticsDelayCheckBox.isSelected();
designerEnvManager.setCloudAnalyticsDelay(cloudDelayFlag);
// cloudDelayFlag默认为true,如果用户手动配置过才会是false,则后续的云端运维配置都按照用户意愿来
@ -1124,10 +1081,6 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setAutoPushUpdateEnabled(this.autoPushUpdateCheckBox.isSelected());
}
if (useNewVersionLoginCheckbox != null) {
designerEnvManager.setUseOldVersionLogin(!this.useNewVersionLoginCheckbox.isSelected());
}
designerEnvManager.setUndoLimit(maxUndoLimit.getSelectedIndex() * SELECTED_INDEX_5);
if (maxUndoLimit.getSelectedIndex() == SELECTED_INDEX_5) {
designerEnvManager.setUndoLimit(MAX_UNDO_LIMIT_50);
@ -1197,12 +1150,12 @@ public class PreferencePane extends BasicPane {
if (useVcsAutoCleanScheduleCheckBox.isEnabled()) {
if (useVcsAutoCleanScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto clean!");
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(
VcsRepository.getInstance().addOrUpdateVcsAutoCleanJob(new VcsTaskBean(
VcsAutoCleanService.VCS_AUTO_CLEAN_JOB_NAME,
getDay(autoCleanIntervalComboBox.getSelectedIndex()),
VcsAutoCleanSchedule.class);
VcsAutoCleanSchedule.class));
} else {
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).stopVcsAutoCleanJob(VcsAutoCleanService.VCS_AUTO_CLEAN_JOB_NAME);
VcsRepository.getInstance().stopVcsAutoCleanJob(VcsAutoCleanService.VCS_AUTO_CLEAN_JOB_NAME);
}
}
}
@ -1251,7 +1204,7 @@ public class PreferencePane extends BasicPane {
@Override
public BasicDialog showWindow(Window window, DialogActionListener l) {
return showWindowWithCustomSize(window, l, new Dimension(BasicDialog.DEFAULT.width, BasicDialog.DEFAULT.height + OFFSET_HEIGHT));
return showWindowWithCustomSize(window, l, new Dimension(BasicDialog.DEFAULT.width + OFFSET_HEIGHT, BasicDialog.DEFAULT.height + OFFSET_HEIGHT));
}
private void tryGc() {
@ -1260,7 +1213,7 @@ public class PreferencePane extends BasicPane {
@Override
protected Boolean doInBackground() {
size = WorkContext.getCurrent().get(VcsOperator.class).immediatelyGc();
size = VcsRepository.getInstance().immediatelyGc();
return true;
}

26
designer-base/src/main/java/com/fr/design/actions/file/export/AbstractExportAction.java

@ -1,5 +1,7 @@
package com.fr.design.actions.file.export;
import com.fanruan.entity.template.TemplateExportBean;
import com.fanruan.repository.TemplateRepository;
import com.fr.design.actions.JTemplateAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.dialog.FineJOptionPane;
@ -15,15 +17,11 @@ import com.fr.file.filter.ChooseFileFilter;
import com.fr.io.exporter.DesignExportType;
import com.fr.io.exporter.ExporterKey;
import com.fr.log.FineLoggerFactory;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.third.jodd.io.FileNameUtil;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.exporter.TemplateExportOperator;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.OutputStream;
import java.util.Map;
@ -211,19 +209,13 @@ public abstract class AbstractExportAction<E extends JTemplate<?, ?>> extends JT
}
private void dealExporter(OutputStream outputStream, String path, final Map<String, Object> para) throws Exception {
if (path.startsWith(ProjectConstants.REPORTLETS_NAME)) {
path = path.substring(ProjectConstants.REPORTLETS_NAME.length());
}
// 没有办法处理这个 isLocal 判断,因为一个是修改参数传递结果,一个是返回值做结果
// todo 后续想想办法
if (WorkContext.getCurrent().isLocal()) {
WorkContext.getCurrent().get(TemplateExportOperator.class)
.export(exportKey(), exportType(), outputStream, path, para);
} else {
byte[] contents =
WorkContext.getCurrent().get(TemplateExportOperator.class)
.export(exportKey(), exportType(), null, path, para);
byte[] contents = TemplateRepository.getInstance().export(new TemplateExportBean().setKey(exportKey()).setType(exportType()).setPath(path).setParas(para));
outputStream.write(contents);
}
outputStream.write(contents);
}
@Override

12
designer-base/src/main/java/com/fr/design/actions/help/SystemInfoPane.java

@ -11,16 +11,20 @@ import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import com.fr.design.gui.icontainer.UITableScrollPane;
import com.fr.design.gui.itable.FineUITable;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fanruan.product.ProductConstants;
import static com.fine.theme.utils.FineUIScale.scale;
public class SystemInfoPane extends JPanel {
public SystemInfoPane() {
super(FRGUIPaneFactory.createBorderLayout());
DefaultTableModel tableModel = new DefaultTableModel();
JTable table = new JTable(tableModel) {
FineUITable table = new FineUITable(tableModel) {
public boolean isCellEditable(int row, int column) {
return false;
}
@ -57,10 +61,10 @@ public class SystemInfoPane extends JPanel {
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
TableColumnModel columnModel = table.getColumnModel();
columnModel.getColumn(0).setPreferredWidth(160);
columnModel.getColumn(1).setPreferredWidth(240);
columnModel.getColumn(0).setPreferredWidth(scale(160));
columnModel.getColumn(1).setPreferredWidth(scale(240));
add(new JScrollPane(table), BorderLayout.CENTER);
add(new UITableScrollPane(table), BorderLayout.CENTER);
}
/**

24
designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java

@ -8,7 +8,8 @@ import com.fr.design.DesignModelAdapter;
import com.fr.design.actions.UpdateAction;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.workspace.server.repository.tabledata.TableDataBeanHelper;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.design.data.tabledata.ResponseDataSourceChange;
import com.fr.design.data.tabledata.tabledatapane.TableDataManagerPane;
import com.fr.design.dialog.BasicDialog;
@ -24,10 +25,9 @@ import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.file.TableDataConfig;
import com.fr.log.FineLoggerFactory;
import com.fr.report.LockItem;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
@ -85,23 +85,15 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS
// 锁定成功,执行后续操作
final DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
final List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final List<ConnectionBean> connectionInfoBeans = ConnectionRepository.getInstance().getAll();
final Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : connectionInfoBeans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, TableData> tableDataMap = new HashMap<>();
try {
TransmissionEncryptionManager.setTransEncryptionLevel(1);
for (ServerDataSetBean bean : beans) {
for (ServerDataSetBean bean : beans) {
try {
tableDataMap.put(bean.getDatasetName() , TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error("[TableData] getTableData :{} failed!", bean.getDatasetName(), e);
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
TransmissionEncryptionManager.removeTransEncryptionLevel();
}
final TableDataManagerPane globalTableDataPane = new TableDataManagerPane() {
public void complete() {
populate(tableDataMap);

5
designer-base/src/main/java/com/fr/design/backup/DesignContext.java

@ -7,6 +7,7 @@ import com.fr.stable.StringUtils;
import javax.servlet.ServletContext;
import java.io.File;
import java.util.Properties;
/**
@ -17,7 +18,7 @@ import java.util.Properties;
* Created on 2024/5/14
*/
public class DesignContext extends CarinaApplicationContext {
public static final String WEB_INF = "\\WEB-INF";
public static final String WEB_INF = "WEB-INF";
private String designWebInfPath;
private String designDataPath;
@ -39,7 +40,7 @@ public class DesignContext extends CarinaApplicationContext {
public void setDesignWebInfPath(String designWebInfPath) {
this.designWebInfPath = designWebInfPath;
if (StringUtils.isNotEmpty(this.designWebInfPath)) {
this.designDataPath = this.designWebInfPath.replace(WEB_INF, StringUtils.EMPTY);
this.designDataPath = this.designWebInfPath.replace(File.separatorChar + WEB_INF, StringUtils.EMPTY);
}
FineLoggerFactory.getLogger().info("[DesignContext] designWebInfPath:{}, designDataPath:{}", this.designWebInfPath, this.designDataPath);
}

26
designer-base/src/main/java/com/fr/design/backup/EnvBackupHelper.java

@ -4,11 +4,13 @@ import com.fanruan.carina.Carina;
import com.fanruan.config.realm.ConfigRepositoryFactory;
import com.fanruan.config.realm.local.LocalConfigRepositoryBuilder;
import com.fr.design.ConfigHelper;
import com.fr.design.env.RemoteWorkspace;
import com.fr.design.mem.MemConfigBackupManager;
import com.fr.design.mem.MemConfigRepositoryBuilder;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.server.repository.connect.FineWorkspaceHttpClient;
import java.util.Properties;
@ -42,11 +44,13 @@ public class EnvBackupHelper {
FineLoggerFactory.getLogger().info("[EnvBackup] 1.back start...");
this.swtiching = true;
local = WorkContext.getCurrent().isLocal();
origin = WorkContext.getCurrent();
if (local) {
properties = ConfigHelper.getEnvProperties();
path = ConfigHelper.getEnvPropertiesPath();
} else {
closeEnv();
}
origin = WorkContext.getCurrent();
}
/**
@ -107,10 +111,30 @@ public class EnvBackupHelper {
} else {
// 如果是远程,则新环境的配置全部弃用,直接走老的
MemConfigBackupManager.getInstance().failed();
rollbackEnv();
}
}
/**
* 关闭环境
*/
public void closeEnv() {
// 如果原来是远程,要先发请求告诉原来的环境我这边要断开
if (origin instanceof RemoteWorkspace) {
origin.close();
}
}
/**
* 重新进入老环境
*/
public void rollbackEnv() {
if (origin instanceof RemoteWorkspace && ((RemoteWorkspace) origin).getClient() instanceof FineWorkspaceHttpClient) {
((FineWorkspaceHttpClient) ((RemoteWorkspace) origin).getClient()).connect();
}
}
public boolean isSwtiching() {
return swtiching;
}

28
designer-base/src/main/java/com/fr/design/components/notification/NotificationDialog.java

@ -1,5 +1,8 @@
package com.fr.design.components.notification;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.function.ThrowableRunnable;
import com.fr.base.svg.IconUtils;
import com.fr.design.components.page.PageControlModel;
@ -53,7 +56,7 @@ public class NotificationDialog extends JDialog {
*/
private static final int CONTENT_SCROLL_WIDTH = 280;
private static final int CONTENT_WIDTH = 300;
private static final int CONTENT_WIDTH = 360;
private static final int CONTENT_HEIGHT = 100;
/**
* 通知框的外部宽高
@ -148,21 +151,20 @@ public class NotificationDialog extends JDialog {
protected JPanel createContentPanel() {
JPanel contentPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
contentPanel.setBorder(BorderFactory.createEmptyBorder(8, 10, 8, 10));
contentPanel.setBorder(new ScaledEmptyBorder(8, 10, 8, 10));
contentPanel.setName("contentPanel");
NotificationModel model = getCurrentModel();
UILabel icon = new UILabel(getIconForType(model.getType()));
icon.setPreferredSize(new Dimension(16, 16));
JPanel iconPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
iconPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 10, 8));
iconPanel.setBorder(new ScaledEmptyBorder(0, 5, 10, 8));
iconPanel.add(icon, BorderLayout.NORTH);
contentPanel.add(iconPanel, BorderLayout.WEST);
JPanel centerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 5));
centerPanel.setBorder(new ScaledEmptyBorder(0, 0, 5, 5));
NotificationMessage[] messages = model.getMessages();
List<? extends JComponent> messageComponents = Arrays.stream(messages)
@ -213,7 +215,7 @@ public class NotificationDialog extends JDialog {
jScrollPane.setBorder(BorderFactory.createEmptyBorder());
centerPanel.add(jScrollPane, BorderLayout.CENTER);
centerPanel.setPreferredSize(CONTENT_SIZE);
centerPanel.setPreferredSize(FineUIScale.scale(CONTENT_SIZE));
contentPanel.add(centerPanel, BorderLayout.CENTER);
@ -282,7 +284,7 @@ public class NotificationDialog extends JDialog {
NotificationAction action = currentModel.getAction();
if (action != null) {
UIButton actionButton = new UIButton(action.name());
actionButton.setPreferredSize(BUTTON_DIMENSION);
actionButton.setPreferredSize(FineUIScale.scale(BUTTON_DIMENSION));
actionButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -293,7 +295,7 @@ public class NotificationDialog extends JDialog {
}
UIButton knowButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Know"));
knowButton.setPreferredSize(BUTTON_DIMENSION);
knowButton.setPreferredSize(FineUIScale.scale(BUTTON_DIMENSION));
knowButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -359,21 +361,21 @@ public class NotificationDialog extends JDialog {
protected Icon getIconForType(NotificationType type) {
String iconPath;
String iconId;
switch (type) {
case ERROR:
iconPath = "/com/fr/design/standard/reminder/reminder_error.svg";
iconId = "error";
break;
case INFO:
iconPath = "/com/fr/design/standard/reminder/reminder_success.svg";
iconId = "success";
break;
case WARNING:
iconPath = "/com/fr/design/standard/reminder/reminder_warning.svg";
iconId = "warning";
break;
default:
return null;
}
return IconUtils.readIcon(iconPath);
return new LazyIcon(iconId, 20);
}
private void destroy() {

13
designer-base/src/main/java/com/fr/design/condition/ConditionAttributesPane.java

@ -2,13 +2,12 @@ package com.fr.design.condition;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.common.annotations.Open;
import com.fr.design.actions.UpdateAction;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.border.FineBorderFactory;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.menu.ToolBarDef;
@ -19,7 +18,6 @@ import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.util.Iterator;
import java.util.LinkedHashMap;
@ -73,18 +71,16 @@ public abstract class ConditionAttributesPane<T> extends BasicBeanPane<T> {
UIToolbar toolBar = ToolBarDef.createJToolBar();
toolBar.setLayout(new BorderLayout());
toolBar.setBorder(new FineRoundBorder());
toolBar.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
toolbarDef.updateToolBar(toolBar);
addItemPane.add(toolBar, BorderLayout.WEST);
addItemPane.setBorder(new FineRoundBorder());
addItemPane.setBorder(FineBorderFactory.createWrappedRoundBorder());
addItemPane.setPreferredSize(new Dimension(addItemPane.getPreferredSize().width, FineUIScale.scale(24)));
selectedItemPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane();
// 选中的添加Itempane
// 选中的添加ItemPane
selectedItemScrollPane.setViewportView(selectedItemPane);
selectedItemScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
@ -93,7 +89,8 @@ public abstract class ConditionAttributesPane<T> extends BasicBeanPane<T> {
this.add(FineUIUtils.wrapComponentWithTitle(column(
10,
row(cell(addItemPane), flex()),
cell(selectedItemScrollPane).with(it -> it.setBorder(new FineRoundBorder())),
cell(selectedItemScrollPane).weight(1).with(
it -> it.setBorder(FineBorderFactory.createWrappedRoundBorder())),
fix(10)
).getComponent(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Property")), BorderLayout.NORTH);
}

4
designer-base/src/main/java/com/fr/design/condition/DSColumnLiteConditionPane.java

@ -123,8 +123,8 @@ public class DSColumnLiteConditionPane extends LiteConditionPane<CommonCondition
UILabel operatorLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_ConditionB_Operator") + ":");
operatorLabel.setPreferredSize(FineUIScale.scale(new Dimension(68, 24)));
Component[][] components = {
{ columLabel, keyColumnPane, null},
{operatorLabel, conditionOPComboBox, conditionValuePane}};
{ columLabel, operatorLabel, null},
{ keyColumnPane,conditionOPComboBox, conditionValuePane}};
double p = TableLayout.PREFERRED;
double rowSize[] = { p, p };

27
designer-base/src/main/java/com/fr/design/condition/SingleConditionPane.java

@ -6,34 +6,37 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.BaseUtils;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.dialog.BasicPane;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.flex;
public abstract class SingleConditionPane<T> extends BasicPane {
private static final long serialVersionUID = -4274960170813368817L;
protected UIButton cancel;
public SingleConditionPane(){
this(true);
}
public SingleConditionPane(boolean isRemove) {
this.setLayout(FRGUIPaneFactory.createScaledBorderLayout(10, 0));
this.setBorder(new ScaledEmptyBorder(4, 8, 4, 8));
if (isRemove) {
if(cancel == null) {
cancel = new UIButton(new LazyIcon("remove"));
cancel.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Action_Remove"));
cancel.addActionListener(cancleListener);
cancel.setMargin(new Insets(0, 0, 0, 0));
cancel.setBorder(new ScaledEmptyBorder(0, 0, 0, 10));
cancel.setBackground(FlatUIUtils.getUIColor("default.background", new Color(246, 248, 250, 255)));
FineUIStyle.setStyle(cancel, FineUIStyle.ORIGINAL_BUTTON);
}
addCancel();
}
@ -43,9 +46,9 @@ public abstract class SingleConditionPane<T> extends BasicPane {
* 添加删除按钮
*/
public void addCancel() {
this.add(cancel, BorderLayout.EAST);
this.add(column(flex(), cell(cancel), flex()).getComponent(), BorderLayout.EAST);
}
ActionListener cancleListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
doCancel();
@ -58,8 +61,8 @@ public abstract class SingleConditionPane<T> extends BasicPane {
public abstract void doCancel();
public abstract void setDefault();
public abstract void populate(T condition);
public abstract T update();
}

57
designer-base/src/main/java/com/fr/design/constants/UIConstants.java

@ -4,7 +4,6 @@
package com.fr.design.constants;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.svg.IconUtils;
import com.fr.base.svg.SVGLoader;
import com.fr.general.IOUtils;
import com.fr.stable.Constants;
@ -27,7 +26,6 @@ import java.awt.image.BufferedImage;
*/
public interface UIConstants {
public static final Icon CPT_ICON = IOUtils.readIcon("/com/fr/base/images/oem/cpt.png");
public static final Icon BLACK_ICON = IOUtils.readIcon("/com/fr/base/images/cell/blank.gif");
public static final String EMPTY_ICON = StringUtils.EMPTY;
@ -153,67 +151,17 @@ public interface UIConstants {
public static final Color CHECK_BOX_TIP_FONT_COLOR = new Color(51, 51, 52, (int)Math.round(0.5 * 255));
public static final BufferedImage DRAG_BAR = IOUtils.readImage("com/fr/design/images/control/bar.png");
public static final BufferedImage DRAG_BAR_LIGHT = IOUtils.readImage("com/fr/design/images/control/bar-light.png");
public static final Image ARROW_NORTH = SVGLoader.load("/com/fr/design/standard/arrowlinear/up_arrow.svg");
public static final Image ARROW_SOUTH = SVGLoader.load("/com/fr/design/standard/arrowlinear/down_arrow.svg");
public static final Image ARROW_EAST = SVGLoader.load("/com/fr/design/standard/arrowlinear/east_arrow.svg");
public static final Image ARROW_WEST = SVGLoader.load("/com/fr/design/standard/arrowlinear/west_arrow.svg");
public static final BufferedImage DRAG_BAR_RIGHT = IOUtils.readImage("com/fr/design/images/control/barm.png");
public static final BufferedImage DRAG_BAR_LEFT = IOUtils.readImage("com/fr/design/images/control/barl.png");
public static final Image DRAG_UP_NORMAL = SVGLoader.load("/com/fr/design/standard/triangle.arrow/up_normal.svg");
public static final Image DRAG_UP_PRESS = SVGLoader.load("/com/fr/design/standard/triangle.arrow/up_hover.svg");
public static final Image DRAG_DOWN_NORMAL = SVGLoader.load("/com/fr/design/standard/triangle.arrow/down_normal.svg");
public static final Image DRAG_DOWN_PRESS = SVGLoader.load("/com/fr/design/standard/triangle.arrow/down_hover.svg");
public static final Image DRAG_RIGHT_NORMAL = SVGLoader.load("/com/fr/design/standard/drag/right_normal.svg");
public static final Image DRAG_RIGHT_PRESS = SVGLoader.load("/com/fr/design/standard/drag/right_pressed.svg");
public static final Image DRAG_LEFT_NORMAL = SVGLoader.load("/com/fr/design/standard/drag/left_normal.svg");
public static final Image DRAG_LEFT_PRESS = SVGLoader.load("/com/fr/design/standard/drag/left_pressed.svg");
public static final BufferedImage DRAG_DOT = IOUtils.readImage("com/fr/design/images/control/dot.png");
public static final Image DRAG_LINE = SVGLoader.load("/com/fr/design/standard/dot_line_normal.svg");
public static final BufferedImage ACCESSIBLE_EDITOR_DOT = IOUtils.readImage("com/fr/design/images/control/dot.png");
public static final BufferedImage DRAG_DOT_VERTICAL = IOUtils.readImage("com/fr/design/images/control/dotv.png");
public static final Image POP_BUTTON_DOWN = SVGLoader.load("/com/fr/design/standard/poparrow/pop_down_arrow.svg");
public static final Image POP_BUTTON_UP = SVGLoader.load("/com/fr/design/standard/poparrow/pop_up_arrow.svg");
public static final BufferedImage DRAG_DOWN_SELECTED_SMALL = IOUtils.readImage("com/fr/design/images/buttonicon/downSelected.png");
public static final BufferedImage DRAG_LEFT_NORMAL_SMALL = IOUtils.readImage("com/fr/design/images/buttonicon/leftNormal.png");
public static final BufferedImage WATERMARK_BACKGROUND = IOUtils.readImage("/com/fr/design/images/dialog/watermark/" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_WaterMark_Background_Icon_File_Name"));
public static final int MODEL_NORMAL = 0;
public static final int MODEL_PRESS = 1;
public static final Icon ARROW_DOWN_ICON = IconUtils.readIcon("/com/fr/design/standard/arrowlinear/down_arrow.svg");
public static final Icon ARROW_UP_ICON = IOUtils.readIcon("com/fr/design/images/buttonicon/arrowup.png");
public static final Icon YES_ICON = IOUtils.readIcon("com/fr/design/images/buttonicon/yes.png");
public static final Icon CHOOSEN_ICON = IOUtils.readIcon("com/fr/design/images/buttonicon/select_item.png");
public static final Icon PRE_WIDGET_ICON = IOUtils.readIcon("com/fr/design/images/buttonicon/prewidget.png");
public static final Icon PRE_WIDGET_NORMAL_ICON = IconUtils.readIcon("com/fr/design/images/buttonicon/prewidget");
public static final Icon EDIT_NORMAL_ICON = IconUtils.readIcon("/com/fr/design/standard/uimode/edit");
public static final Icon EDIT_PRESSED_ICON = IconUtils.readIcon("/com/fr/design/standard/uimode/edit_pressed.svg");
public static final Icon HIDE_NORMAL_ICON = IconUtils.readIcon("/com/fr/design/standard/uimode/hide");
public static final Icon HIDE_PRESSED_ICON = IconUtils.readIcon("/com/fr/design/standard/uimode/hide_pressed.svg");
public static final Icon VIEW_NORMAL_ICON = IconUtils.readIcon("/com/fr/design/standard/uimode/view");
//public static final Icon VIEW_PRESSED_ICON = IconUtils.readIcon("/com/fr/design/standard/uimode/view");
public static final Icon RUN_BIG_ICON = IconUtils.readIcon("/com/fr/design/standard/preview/run24.svg");
public static final Icon RUN_SMALL_ICON = IconUtils.readIcon("/com/fr/design/standard/preview/runs.svg");
public static final Icon PAGE_BIG_ICON = IconUtils.readIcon("/com/fr/design/standard/preview/pageb24.svg");
public static final Icon WRITE_BIG_ICON = IconUtils.readIcon("/com/fr/design/standard/preview/writeb24.svg");
public static final Icon ANA_BIG_ICON = IconUtils.readIcon("/com/fr/design/standard/preview/anab24.svg");
public static final Icon PAGE_SMALL_ICON = IconUtils.readIcon("/com/fr/design/standard/preview/pages.svg");
public static final Icon WRITE_SMALL_ICON = IconUtils.readIcon("/com/fr/design/standard/preview/writes.svg");
public static final Icon ANA_SMALL_ICON = IconUtils.readIcon("/com/fr/design/standard/preview/anas.svg");
public static final Icon REFRESH_ICON = IOUtils.readIcon("com/fr/design/images/buttonicon/refresh.png");
public static final Icon FONT_ICON = IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png");
public static final Icon AUTO_FONT_ICON = IOUtils.readIcon("/com/fr/design/images/gui/color/autoForeground.png");
public static final Icon HISTORY_ICON = IOUtils.readIcon("com/fr/design/images/buttonicon/history.png");
public static final Icon DELETE_ICON = IOUtils.readIcon("com/fr/design/images/m_file/close.png");
public static final Icon EDIT_ICON = IOUtils.readIcon("com/fr/design/images/m_file/edit.png");
public static final Icon SEARCH_ICON = IOUtils.readIcon("/com/fr/design/images/data/search.png");
public static final Icon BLACK_SEARCH_ICON = IOUtils.readIcon("/com/fr/design/images/data/black_search.png");
public static final Icon CLEAR_ICON = IOUtils.readIcon("/com/fr/design/images/data/source/delete.png");
public static final Icon LIST_EDIT_ICON = IOUtils.readIcon("/com/fr/design/images/control/edit.png");
public static final Icon LIST_EDIT_WHITE_ICON = IOUtils.readIcon("/com/fr/design/images/control/edit_white.png");
public static final Icon ARROW_DOWN_ICON = new LazyIcon("down_arrow");
public static final Icon ARROW_UP_ICON = new LazyIcon("up_arrow");
public static final Color PRESSED_DARK_GRAY = new Color(127, 127, 127);
public static final Color GRDIENT_DARK_GRAY = new Color(45, 45, 45);
public static final Color BARNOMAL = new Color(232, 232, 233);
@ -222,7 +170,6 @@ public interface UIConstants {
public static final int BUTTON_GROUP_ARC = 0;
public static final int LARGEARC = 6;
public static final Stroke BS = new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 2f, new float[]{3, 1}, 0);
public static final Icon PREVIEW_DOWN = IconUtils.readIcon("/com/fr/design/standard/preview_down_icon");
public static final int CLOSE_AUTHORITY_HEIGHT_AND_WIDTH = 24;
public static final Icon CLOSE_OF_AUTHORITY = new LazyIcon("platform_close", CLOSE_AUTHORITY_HEIGHT_AND_WIDTH).disabled();
public static final Icon CLOSE_OVER_AUTHORITY = new LazyIcon("platform_close", CLOSE_AUTHORITY_HEIGHT_AND_WIDTH);

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

@ -352,6 +352,13 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp
});
}
}
/**
* 重置
*/
public void resetAddMenuDef() {
this.addMenuDef.clearShortCuts();
this.createAddMenuDef();
}
private abstract class TDAction extends UpdateAction {

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

@ -9,8 +9,10 @@ import com.fr.data.MultiResultTableData;
import com.fr.data.TableDataSource;
import com.fr.data.TableDataSourceTailor;
import com.fr.data.core.DataCoreXmlUtils;
import com.fr.data.impl.ConditionTableData;
import com.fr.data.impl.EmbeddedTableData;
import com.fr.data.impl.NameDataModel;
import com.fr.data.impl.RecursionTableData;
import com.fr.data.impl.storeproc.ProcedureDataModel;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.data.impl.storeproc.StoreProcedureConstants;
@ -586,13 +588,17 @@ public abstract class DesignTableDataManager {
TableDataSource source = TableDataSourceTailor.extractTableData(tableDataSource);
bean.setDataSource(source);
bean.setDataName(DataOperator.getTableDataName(source, tabledata));
bean.setParameterMap(parameterMap);
if (checkBean(bean)) {
bean.setStart(rowCount);
bean.setEnd(-1);
bean.updateConvertMap(parameterMap);
if (checkBean(bean, tabledata)) {
return (EmbeddedTableData) TableDataRepository.getInstance().previewTableData(bean).getTableData();
} else {
PreviewDataBean dataBean = new PreviewDataBean();
dataBean.setDataSource(tabledata);
dataBean.setParameterMap(parameterMap);
dataBean.updateConvertMap(parameterMap);
dataBean.setStart(rowCount);
dataBean.setEnd(-1);
return (EmbeddedTableData) TableDataRepository.getInstance().previewTableData(dataBean).getTableData();
}
@ -620,9 +626,16 @@ public abstract class DesignTableDataManager {
}
}
private static boolean checkBean(PreviewSourceBean bean) {
// dataName为空说明是新建的,得用tabledata传
return !bean.getDataName().isEmpty();
private static boolean checkBean(PreviewSourceBean bean, TableData tableData) {
if (bean.getDataName().isEmpty()) {
if (tableData instanceof ConditionTableData || tableData instanceof RecursionTableData) {
bean.getDataSource().putTableData(StringUtils.EMPTY, tableData);
return true;
}
// dataName为空并且不为特殊的数据集说明是新建的,得用tabledata传
return false;
}
return true;
}
private static boolean needInputParams(boolean mustInputParameters, ParameterProvider[] parameters) {

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

@ -332,7 +332,7 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
List<String> authConnections = getHasAuthConnections();
for (String name : authConnections) {
if (ComparatorUtils.equals(selectedDSName, name)) {
return ConnectionRepository.getInstance().getByName(name).getConnection();
return ConnectionInfoBeanHelper.createConnection(ConnectionRepository.getInstance().getByName(name));
}
}
return null;
@ -442,7 +442,7 @@ public class ChoosePane extends BasicBeanPane<DataBaseItems> implements Refresha
boolean connect = false;
com.fr.data.impl.Connection database = null;
try {
database = ConnectionRepository.getInstance().getByName(paras.getDatabaseName()).getConnection();
database = ConnectionInfoBeanHelper.createConnection(ConnectionRepository.getInstance().getByName(paras.getDatabaseName()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage(), e);
}

4
designer-base/src/main/java/com/fr/design/data/datapane/TableDataCreatorProducer.java

@ -14,7 +14,7 @@ import com.fine.theme.icon.LazyIcon;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.datacenters.tabledata.DCTableData;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.data.tabledata.datacenter.DatacentersPane;
import com.fr.design.data.tabledata.datacenter.DCTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.ClassTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.DBTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.EmbeddedTableDataPane;
@ -95,7 +95,7 @@ public class TableDataCreatorProducer {
return new TableDataNameObjectCreator[]{
new TableDataNameObjectCreator(i18nText("Fine-Design_Basic_DS_Datacenters"),
new LazyIcon("datacenter"),
DCTableData.class, DatacentersPane.class) {
DCTableData.class, DCTableDataPane.class) {
@Override
public boolean shouldInsertSeparator() {
return true;

40
designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java

@ -1,5 +1,6 @@
package com.fr.design.data.datapane;
import com.fine.theme.utils.FineUIScale;
import com.fr.base.TableData;
import com.fr.base.TableDataBean;
import com.fr.data.MultiResultTableData;
@ -10,10 +11,11 @@ import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.design.data.BasicTableDataUtils;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.MapCompareUtils;
import com.fr.workspace.server.repository.tabledata.TableDataBeanHelper;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.controlpane.JListControlPane;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.design.gui.controlpane.ShortCut4JControlPane;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.i18n.Toolkit;
import com.fr.file.ProcedureConfig;
@ -94,6 +96,21 @@ public class TableDataPaneListPane extends JListControlPane implements TableData
return Toolkit.i18nText("Fine-Design_Basic_Table_Data_Duplicate_Name_Tips", getEditingName());
}
@Override
protected ShortCut4JControlPane[] createShortcuts() {
return new ShortCut4JControlPane[]{
shortCutFactory.addItemShortCut(),
shortCutFactory.removeItemShortCut(),
shortCutFactory.copyItemShortCut(),
shortCutFactory.sortItemShortCut(),
};
}
@Override
protected int getLeftPreferredSize() {
return FineUIScale.scale(180);
}
@Override
public Collection getExtraItemsToCheckNameRepeat() {
return DesignTableDataManager.getGlobalDataSet().keySet();
@ -261,13 +278,28 @@ public class TableDataPaneListPane extends JListControlPane implements TableData
try {
switch (entryEventKind) {
case REMOVED:
deleteDatas.add(TableDataBeanHelper.getServerDataSetBean(s, tabledata));
ServerDataSetBean remove = TableDataBeanHelper.getServerDataSetBean(s, tabledata);
if (StringUtils.isNotEmpty(remove.getDatasetData())) {
deleteDatas.add(remove);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", tabledata.getClass());
}
break;
case ADDED:
addDatas.add(TableDataBeanHelper.getServerDataSetBean(s, tabledata));
ServerDataSetBean add = TableDataBeanHelper.getServerDataSetBean(s, tabledata);
if (StringUtils.isNotEmpty(add.getDatasetData())) {
addDatas.add(add);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", tabledata.getClass());
}
break;
case UPDATED:
updateDatas.add(TableDataBeanHelper.getServerDataSetBean(s, tabledata));
ServerDataSetBean update = TableDataBeanHelper.getServerDataSetBean(s, tabledata);
if (StringUtils.isNotEmpty(update.getDatasetData())) {
updateDatas.add(update);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", tabledata.getClass());
}
break;
default:
break;

6
designer-base/src/main/java/com/fr/design/data/datapane/TableDataTree.java

@ -64,11 +64,11 @@ public class TableDataTree extends UserObjectRefreshJTree<TableDataSourceOP> {
} else if (nameObject.getObject() instanceof Integer) {
int num = (Integer) nameObject.getObject();
if (num == TableDataSourceOP.SERVER_TABLE_DATA) {
this.setIcon(IconUtils.readIcon(IconPathConstants.STD_SHOW_ICON_PATH));
this.setIcon(new LazyIcon("server_database"));
} else if (num == TableDataSourceOP.STORE_PRECEDURE_DATA) {
this.setIcon(IconUtils.readIcon(IconPathConstants.SP_SHOW_ICON_PATH));
this.setIcon(new LazyIcon("store_procedure"));
} else {
this.setIcon(IconUtils.readIcon(IconPathConstants.DS_QUERY_ICON_PATH));
this.setIcon(new LazyIcon("database"));
}
} else {
this.setIcon(new LazyIcon("store_procedure"));

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

@ -1,6 +1,7 @@
package com.fr.design.data.datapane;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineRoundBorder;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.TableData;
import com.fr.data.MultiResultTableData;
@ -11,6 +12,7 @@ import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.UpdateAction;
import com.fr.design.cache.DesignCacheManager;
import com.fr.design.data.BasicTableDataTreePane;
import com.fr.design.data.BasicTableDataUtils;
import com.fr.design.data.DesignTableDataManager;
@ -39,6 +41,8 @@ import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.CheckBoxListWithPartialSelect;
import com.fr.design.gui.imenu.UIPopupMenu;
import com.fr.design.gui.iscrollbar.UIBasicVerticalScrollBar;
import com.fr.design.gui.iscrollbar.UIScrollBar;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
@ -73,10 +77,10 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.ToolTipManager;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Color;
@ -457,7 +461,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
if (!ComparatorUtils.equals(oldName, tdName)) {
map.put(oldName, tdName);
}
fireDSChanged(map);
DesignCacheManager.processByCacheTableData(() -> fireDSChanged(map));
tc.fireTargetModified();
tc.parameterChanged();
int[] rows = tableDataTree.getSelectionRows();
@ -504,11 +508,10 @@ public class TableDataTreePane extends BasicTableDataTreePane {
} else if (!ComparatorUtils.equals(oldName, tempName) && isDsNameRepeaded(tempName)) {
nPanel.setShowText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Table_Data_Duplicate_Name_Tips", tempName));
dg.setButtonEnabled(false);
} else if (oldName.length() >= PROCEDURE_NAME_INDEX && tableDataPane.updateBean() instanceof MultiResultTableData) {
if (isIncludeUnderline(tempName)) {
nPanel.setShowText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multi_Result_Table_Data_Name_Tips"));
dg.setButtonEnabled(false);
}
} else if (oldName.length() >= PROCEDURE_NAME_INDEX && tableDataPane.updateBean() instanceof MultiResultTableData
&& isIncludeUnderline(tempName)) {
nPanel.setShowText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multi_Result_Table_Data_Name_Tips"));
dg.setButtonEnabled(false);
} else if (!BasicTableDataUtils.checkName(tempName)) {
dg.setButtonEnabled(false);
} else {
@ -646,10 +649,6 @@ public class TableDataTreePane extends BasicTableDataTreePane {
}
private void resetAddMenuDef() {
this.addMenuDef.clearShortCuts();
this.createAddMenuDef();
}
/**
* 感觉这里把一堆Action和Op之类的送到抽象类里去检查很奇怪抽象类本身定义的Action只有add和connection
@ -1024,7 +1023,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
@Override
public void actionPerformed(ActionEvent e) {
dgEdit(getTableDataInstance().creatTableDataPane(), createDsName(getNamePrefix()), false);
DesignCacheManager.processByCacheTableData(() -> dgEdit(getTableDataInstance().creatTableDataPane(), createDsName(getNamePrefix()), false));
}
}
@ -1110,7 +1109,12 @@ public class TableDataTreePane extends BasicTableDataTreePane {
}
// 可以半选的CheckBoxList
CheckBoxListWithPartialSelect tableDataCheckBoxPane = new CheckBoxListWithPartialSelect(selectedNameObjects);
UIScrollPane scrollPane = new UIScrollPane(tableDataCheckBoxPane);
UIScrollPane scrollPane = new UIScrollPane(tableDataCheckBoxPane) {
@Override
public UIScrollBar createVerticalScrollBar() {
return new UIBasicVerticalScrollBar(JScrollBar.VERTICAL);
}
};
UILabel tips = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Select_Source_To_Remove"));
BasicPane basicPane = new BasicPane() {
@Override
@ -1120,10 +1124,15 @@ public class TableDataTreePane extends BasicTableDataTreePane {
};
basicPane.setLayout(new BorderLayout());
basicPane.add(tips, BorderLayout.NORTH);
scrollPane.setBorder(new FineRoundBorder());
basicPane.add(scrollPane, BorderLayout.CENTER);
BasicDialog basicDialog = basicPane.showSmallWindow(SwingUtilities.getWindowAncestor(TableDataTreePane.this), new DialogActionAdapter() {
@Override
public void doOk() {
DesignCacheManager.processByCacheTableData(this::processRemove);
}
private void processRemove() {
List selectedValues = tableDataCheckBoxPane.getSelectedObjects();
// 删除时如果正在搜索,跳回原树
if (TableDataTreeSearchManager.getInstance().isInSearchMode()) {
@ -1137,7 +1146,6 @@ public class TableDataTreePane extends BasicTableDataTreePane {
}
}
}
@Override
public void doCancel() {
super.doCancel();
@ -1195,6 +1203,10 @@ public class TableDataTreePane extends BasicTableDataTreePane {
@Override
public void actionPerformed(ActionEvent e) {
DesignCacheManager.processByCacheTableData(this::doPaste);
}
private void doPaste() {
// 粘贴时如果正在搜索,跳回原树
if (TableDataTreeSearchManager.getInstance().isInSearchMode()) {
TableDataTreeSearchManager.getInstance().outOfSearchMode();

14
designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataComboBox.java

@ -6,15 +6,14 @@ import com.fr.data.impl.Connection;
import com.fr.data.impl.RecursionTableData;
import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.design.data.DesignTableDataManager;
import com.fr.workspace.server.repository.tabledata.TableDataBeanHelper;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.design.data.tabledata.wrapper.ServerTableDataWrapper;
import com.fr.design.data.tabledata.wrapper.TableDataWrapper;
import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
@ -71,20 +70,13 @@ public class TreeTableDataComboBox extends UIComboBox {
// 全局数据集
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
Map<String, TableData> map = new HashMap<>();
final List<ConnectionBean> connectionInfoBeans = ConnectionRepository.getInstance().getAll();
final Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : connectionInfoBeans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
try {
TransmissionEncryptionManager.setTransEncryptionLevel(1);
for (ServerDataSetBean bean : beans) {
map.put(bean.getDatasetName() , TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
TransmissionEncryptionManager.removeTransEncryptionLevel();
}
for (Map.Entry<String, TableData> entry : map.entrySet()) {
TableData tableData = entry.getValue();

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

@ -53,7 +53,8 @@ public class AdvancePane extends BasicPane {
flex(2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Borrow"), SwingConstants.LEFT)).weight(1),
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Borrow"), SwingConstants.LEFT))
.with(it -> it.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Borrow"))).weight(1),
cell(DBCP_TEST_ON_BORROW).weight(1.5),
flex(2)
),

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

@ -7,6 +7,7 @@ import com.fr.data.impl.AbstractDatabaseConnection;
import com.fr.data.impl.Connection;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.design.DesignerEnvManager;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.editlock.ConnectionLockChangeChecker;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.gui.ibutton.UIButton;
@ -28,6 +29,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* 选择数据连接的下拉框
@ -89,13 +91,13 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
if (noAuthConnections == null) {
return nameList.iterator();
}
List<ConnectionBean> beans = ConnectionRepository.getInstance().getAll();
for (ConnectionBean bean : beans) {
String conName = bean.getName();
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
for (Map.Entry<String, Connection> connectionEntry : connectionMap.entrySet()) {
String conName = connectionEntry.getKey();
if (noAuthConnections.contains(conName)) {
continue;
}
filterConnection(bean.getConnection(), conName, nameList);
filterConnection(connectionEntry.getValue(), conName, nameList);
}
return nameList.iterator();
}

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

@ -1,9 +1,8 @@
package com.fr.design.data.datapane.connect;
import com.fanruan.config.impl.data.ConnectionConfigProviderFactory;
import com.fanruan.config.impl.data.ConnectionConfigWriterFactory;
import com.fr.config.remote.RemoteConfigEvent;
import com.fine.theme.icon.LazyIcon;
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;
@ -12,10 +11,13 @@ import com.fr.design.ExtraDesignClassManager;
import com.fr.design.data.MapCompareUtils;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.fun.ConnectionProvider;
import com.fr.design.gui.controlpane.JListControlPane;
import com.fr.design.gui.controlpane.NameObjectCreator;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.design.gui.controlpane.ShortCut4JControlPane;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.i18n.Toolkit;
import com.fr.event.EventDispatcher;
@ -24,18 +26,18 @@ import com.fr.license.database.DBTypes;
import com.fr.license.database.DataBaseTypePointManager;
import com.fr.license.exception.DataBaseNotSupportedException;
import com.fr.log.FineLoggerFactory;
import com.fr.report.LockItem;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.database.DataBaseTypeOperator;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import org.jetbrains.annotations.NotNull;
import javax.swing.SwingWorker;
import java.awt.Window;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -80,7 +82,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
SwingWorker<List<String>, Void> getSupportedTypesWorker = new SwingWorker<List<String>, Void>() {
@Override
protected List<String> doInBackground() {
return WorkContext.getCurrent().get(DataBaseTypeOperator.class).getSupportedDatabaseTypes();
return WorkplaceConstants.getSupportedDatabaseTypes();
}
@Override
@ -95,6 +97,21 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
getSupportedTypesWorker.execute();
}
@Override
protected ShortCut4JControlPane[] createShortcuts() {
return new ShortCut4JControlPane[]{
shortCutFactory.addItemShortCut(),
shortCutFactory.removeItemShortCut(),
shortCutFactory.copyItemShortCut(),
shortCutFactory.sortItemShortCut(),
};
}
@Override
protected int getLeftPreferredSize() {
return FineUIScale.scale(180);
}
@Override
public String getEmptyNameTip() {
return Toolkit.i18nText("Fine-Design_Basic_Connection_Empty_Name");
@ -160,7 +177,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
JNDIDatabaseConnection.class, DatabaseConnectionPane.JNDI.class
);
NameableCreator[] creators;
if (WorkContext.getCurrent().get(DataBaseTypeOperator.class).limitDatabaseType()) {
if (WorkplaceConstants.isLimitDatabaseType()) {
// 不支持JNDI,屏蔽接口
creators = new NameableCreator[]{jdbc};
} else {
@ -190,11 +207,11 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
public void populate(Map<String, Connection> connectionMap) {
List<NameObject> nameObjectList = new ArrayList<NameObject>();
populatedConnectionsSnapshot.clear();
List<com.fr.workspace.server.entity.connection.ConnectionBean> beans = ConnectionRepository.getInstance().getAll();
for (com.fr.workspace.server.entity.connection.ConnectionBean entry : beans) {
nameObjectList.add(new NameObject(entry.getName(), entry.getConnection()));
final Map<String, Connection> map = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
for (Map.Entry<String, Connection> entry : map.entrySet()) {
nameObjectList.add(new NameObject(entry.getKey(), entry.getValue()));
try {
populatedConnectionsSnapshot.put(entry.getName(), (Connection) entry.getConnection().clone());
populatedConnectionsSnapshot.put(entry.getKey(), (Connection) entry.getValue().clone());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
@ -222,12 +239,22 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
removedConnNames.add(s);
break;
case ADDED:
addConnections.add(ConnectionInfoBeanHelper.createConnectionInfoBean(s, connection, true));
validConnection.add(connection);
ConnectionInfoBean add = ConnectionInfoBeanHelper.createConnectionInfoBean(s, connection, true);
if (StringUtils.isNotEmpty(add.getConnectionData())) {
addConnections.add(add);
validConnection.add(connection);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", connection.getClass());
}
break;
case UPDATED:
updateConnection.add(ConnectionInfoBeanHelper.createConnectionInfoBean(s, connection, true));
validConnection.add(connection);
ConnectionInfoBean update = ConnectionInfoBeanHelper.createConnectionInfoBean(s, connection, true);
if (StringUtils.isNotEmpty(update.getConnectionData())) {
updateConnection.add(update);
validConnection.add(connection);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", connection.getClass());
}
break;
default:
break;
@ -251,7 +278,13 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
* @return
*/
private boolean needUpdate0(Connection origin, Connection connection) {
return !connection.equals(origin) || !isEmbedConnection(connection);
// 先不考虑插件
try {
return !connection.equals(origin);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return false;
}
}
/**
@ -333,41 +366,24 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
}
}
private boolean saveByOldWay(List<String> removedConnNames, List<ConnectionBean> addedOrUpdatedConnections) {
final int remaining = ConnectionConfigProviderFactory.getConfigProvider().getRemainingCon(removedConnNames.size(), addedOrUpdatedConnections.size());
public static void showDialog(Window parent) {
try {
removedConnNames.forEach(n -> ConnectionConfigWriterFactory.getConfigWriter().removeConnection(n));
int innerRemaining = remaining;
for (ConnectionBean cb : addedOrUpdatedConnections) {
if (innerRemaining > 0) {
ConnectionConfigWriterFactory.getConfigWriter().addConnectionWithoutCheck(cb.getName(), cb.getConnection());
innerRemaining--;
} else {
break;
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final ConnectionManagerPane connectionManagerPane = new ConnectionManagerPane() {
@Override
public void complete() {
populate(connectionMap);
}
}
return true;
};
final BasicDialog connectionListDialog = connectionManagerPane.showLargeWindow(parent, null);
connectionListDialog.addDialogActionListener(new ConnectionListDialogActionAdapter(connectionManagerPane, connectionListDialog, connectionMap));
connectionListDialog.setVisible(true);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Remote_Data_Error"),
Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE);
EditLockUtils.unlock(LockItem.CONNECTION);
}
return false;
}
public static void showDialog(Window parent) {
List<ConnectionBean> beans = ConnectionRepository.getInstance().getAll();
Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : beans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final ConnectionManagerPane connectionManagerPane = new ConnectionManagerPane() {
@Override
public void complete() {
populate(connectionMap);
}
};
final BasicDialog connectionListDialog = connectionManagerPane.showLargeWindow(parent, null);
connectionListDialog.addDialogActionListener(new ConnectionListDialogActionAdapter(connectionManagerPane, connectionListDialog, connectionMap));
connectionListDialog.setVisible(true);
}
@Override

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

@ -1,13 +1,13 @@
package com.fr.design.data.datapane.connect;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.data.core.db.TableProcedure;
import com.fr.data.impl.AbstractDatabaseConnection;
import com.fr.data.impl.Connection;
import com.fr.design.border.FineBorderFactory;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.data.tabledata.tabledatapane.loading.SwitchableTableDataPane;
@ -22,7 +22,6 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.general.GeneralContext;
import com.fr.stable.ArrayUtils;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JPanel;
import javax.swing.ToolTipManager;
@ -171,11 +170,13 @@ public class ConnectionTableProcedurePane extends BasicPane {
searchField = new UITextField();
searchField.setPlaceholder(Toolkit.i18nText("Fine-Design_Basic_Table_Search"));
searchField.getDocument().addDocumentListener(searchListener);
searchField.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Table_Search"));
// 搜索图标
UILabel searchLabel = new UILabel(new LazyIcon("search"));
searchLabel.setBorder(new ScaledEmptyBorder(0, 3, 0, 3));
searchField.setBorder(null);
panel.add(row(cell(searchLabel), cell(searchField).weight(1)).with(it -> it.setBorder(new FineRoundBorder())).getComponent());
panel.add(row(cell(searchLabel), cell(searchField).weight(1)).with(
it -> it.setBorder(FineBorderFactory.createWrappedRoundBorder())).getComponent());
panel.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
return panel;
}

42
designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java

@ -1,8 +1,8 @@
package com.fr.design.data.datapane.connect;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.utils.FineUIStyle;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.data.core.db.dialect.DialectFactory;
import com.fr.data.impl.JDBCDatabaseConnection;
@ -15,13 +15,12 @@ import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Window;
import java.awt.event.InputMethodEvent;
import java.awt.event.InputMethodListener;
@ -78,35 +77,14 @@ public class DBCPAttrPane extends BasicPane {
// JPanel northFlowPane
northFlowPane = Layouts.column(LayoutConstants.VERTICAL_GAP,
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_ConnectionPool_Attr"))).with(FineUIUtils::wrapBoldLabelWithUnderline),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Initial_Size"))).weight(1),
cell(DBCP_INITIAL_SIZE).weight(1), flex(1.2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Min_Idle"))).weight(1),
cell(DBCP_MIN_IDLE).weight(1), flex(1.2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Return"))).weight(1),
cell(DBCP_TESTONRETURN).weight(1), flex(1.2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_While_Idle"))).weight(1),
cell(DBCP_TESTWHILEIDLE).weight(1), flex(1.2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Evictionruns_millis"))).weight(1),
cell(DBCP_TIMEBETWEENEVICTIONRUNSMILLS).weight(1), flex(1.2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Num_Test_Per_Evction_Run"))).weight(1),
cell(DBCP_NUMTESTSPEREVICTIONRUN).weight(1), flex(1.2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Mix_Evictable_Idle_Time_Millis"))).weight(1),
cell(DBCP_MINEVICTABLEIDLETIMEMILLIS).weight(1), flex(1.2)
),
cell(new UILabel(Toolkit.i18nText("Fine-Design_Dbcp_Warning"))).with(it -> it.setForeground(FlatUIUtils.getUIColor("Label.strongHintColor", Color.RED)))
row(cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Initial_Size"))).weight(1), cell(DBCP_INITIAL_SIZE).weight(1)),
row(cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Min_Idle"))).weight(1), cell(DBCP_MIN_IDLE).weight(1)),
row(cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_On_Return"))).weight(1), cell(DBCP_TESTONRETURN).weight(1)),
row(cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Test_While_Idle"))).weight(1), cell(DBCP_TESTWHILEIDLE).weight(1)),
row(cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Evictionruns_millis"))).weight(1), cell(DBCP_TIMEBETWEENEVICTIONRUNSMILLS).weight(1)),
row(cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Num_Test_Per_Evction_Run"))).weight(1), cell(DBCP_NUMTESTSPEREVICTIONRUN).weight(1)),
row(cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Connection_Pool_Mix_Evictable_Idle_Time_Millis"))).weight(1), cell(DBCP_MINEVICTABLEIDLETIMEMILLIS).weight(1)),
cell(LabelUtils.createAutoWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Dbcp_Warning"), FineUIUtils.getUIColor("Label.warningColor", "Label.warningColor")))
).getComponent();
defaultPane.add(northFlowPane);
this.add(defaultPane);

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

@ -5,7 +5,6 @@ package com.fr.design.data.datapane.connect;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
@ -13,7 +12,6 @@ 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.operator.DataOperatorProvider;
import com.fr.data.security.ssl.impl.NormalSsl;
import com.fr.data.solution.ExceptionSolutionSelector;
import com.fr.data.solution.entity.DriverPage;
@ -31,14 +29,12 @@ import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.rpc.ExceptionHandler;
import com.fr.rpc.RPCInvokerExceptionInfo;
import com.fr.stable.ArrayUtils;
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.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import javax.swing.JDialog;
@ -479,6 +475,9 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
uiLabel.setIcon(new LazyIcon("error", 20));
message.setText(Toolkit.i18nText("Fine-Design_Basic_Connection_Failed"));
Connection database = DatabaseConnectionPane.this.updateBean();
if (e.getCause() instanceof DriverUnExistException) {
((DriverUnExistException) e.getCause()).setThrowable(new ClassNotFoundException(database.getDriver()));
}
SolutionProcessor select = ExceptionSolutionSelector.get().select(e, database);
String detail = select.getResultException().getDetailMessage();
String solution = select.getResultException().getSolution();

8
designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java

@ -2,8 +2,8 @@ package com.fr.design.data.datapane.connect;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.BaseUtils;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.i18n.Toolkit;
@ -55,16 +55,16 @@ public abstract class ItemEditableComboBoxPanel extends JPanel {
itemComboBox.setEnabled(true);
this.add(itemComboBox, BorderLayout.CENTER);
refreshButton = new UIButton(new LazyIcon("refresh"));
FineUIStyle.setStyle(refreshButton, FineUIStyle.ORIGINAL_BUTTON);
JPanel jPanel = FRGUIPaneFactory.createNColumnGridInnerContainer_Pane(2, 0 ,4);
editButton = initEditButton(editButton, buttonSize);
editButton.setBorder(null);
FineUIStyle.setStyle(editButton, FineUIStyle.ORIGINAL_BUTTON);
editButton.setBackground(FlatUIUtils.getUIColor("default.background", new Color(246, 248, 250, 255)));
jPanel.add(editButton);
jPanel.add(refreshButton);
jPanel.setOpaque(true);
this.add(jPanel, BorderLayout.EAST);
refreshButton.setPreferredSize(buttonSize);
refreshButton.setBorder(null);
refreshButton.setBackground(FlatUIUtils.getUIColor("default.background", new Color(246, 248, 250, 255)));
refreshButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@ -74,7 +74,7 @@ public abstract class ItemEditableComboBoxPanel extends JPanel {
}
protected UIButton initEditButton(UIButton editButton, Dimension buttonSize) {
editButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/control/control-center2.png"));
editButton = new UIButton(new LazyIcon("edit"));
editButton.setPreferredSize(buttonSize);
editButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {

53
designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java

@ -4,9 +4,9 @@ import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIUtils;
import com.fr.data.driver.DriverLoader;
import com.fr.data.driver.config.DriverLoaderConfig;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.solution.entity.DriverClasses;
import com.fr.datasource.connection.impl.DefaultDatabaseType;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.gui.core.ReactiveCardPane;
import com.fr.design.gui.ibutton.UIButton;
@ -22,11 +22,14 @@ import com.fr.design.utils.BrowseUtils;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.general.CloudCenter;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.third.guava.collect.HashBiMap;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
@ -60,6 +63,16 @@ public class JDBCDefPane extends JPanel {
public static final String DRIVER_TYPE = "driver_type";
public static final String USER_NAME = "user_name";
private static final String OTHER_DB = "Others";
public static final String ORACLE = "Oracle";
public static final String DB2 = "DB2";
public static final String SQL_SERVER = "SQL Server";
public static final String MYSQL = "MySQL";
public static final String SYBASE = "Sybase";
public static final String ACCESS = "Access";
public static final String DERBY = "Derby";
public static final String POSTGRE = "Postgre";
public static final String SQLITE = "SQLite";
public static final String INCEPTOR = "Inceptor";
private static final Pattern ORACLE_URL = Pattern.compile("^jdbc:oracle:thin:@[/]*([-0-9a-zA-Z_\\.\\\\]+)(:([0-9]+|port))?([:/](.*))?.*", Pattern.CASE_INSENSITIVE);
private static final Pattern GENERAL_URL = Pattern.compile("^jdbc:(mysql|sqlserver|db2|derby|postgresql|inceptor|inceptor2|hive2)://([-0-9a-zA-Z_\\.\\\\]+)(:([0-9]+|port))?((/|;DatabaseName=)(.*))?.*", Pattern.CASE_INSENSITIVE);
private static final Pattern PORT = Pattern.compile("^0$|^[1-9][\\d]*[\\d]*$");
@ -67,9 +80,22 @@ public class JDBCDefPane extends JPanel {
// 编码转换.
private String originalCharSet = null;
private static Map<String, DriverURLName[]> jdbcMap = new HashMap<String, DriverURLName[]>();
// 用于映射connection的database字段
private static Map<String, String> dbTypeMap = new HashMap<>();
private JPanel linkPanel;
static {
dbTypeMap.put(ORACLE, DefaultDatabaseType.ORACLE.getType());
dbTypeMap.put(DB2, DefaultDatabaseType.IBM_DB2.getType());
dbTypeMap.put(SQL_SERVER, DefaultDatabaseType.MICROSOFT_SQL_SERVER.getType());
dbTypeMap.put(MYSQL, DefaultDatabaseType.MYSQL.getType());
dbTypeMap.put(SYBASE, DefaultDatabaseType.SAP_ASE.getType());
dbTypeMap.put(ACCESS, DefaultDatabaseType.OTHER.getType());
dbTypeMap.put(DERBY, DefaultDatabaseType.DERBY.getType());
dbTypeMap.put(POSTGRE, DefaultDatabaseType.POSTGRESQL.getType());
dbTypeMap.put(SQLITE, DefaultDatabaseType.SQLITE.getType());
dbTypeMap.put(INCEPTOR, DefaultDatabaseType.TRANSWARP_INCEPTOR.getType());
jdbcMap.put(OTHER_DB, new DriverURLName[]{new DriverURLName("sun.jdbc.odbc.JdbcOdbcDriver", "jdbc:odbc:"),
new DriverURLName("org.hsqldb.jdbcDriver", "jdbc:hsqldb:file:[PATH_TO_DB_FILES]"), new DriverURLName("com.inet.tds.TdsDriver", "jdbc:inetdae7:localhost:1433/"),
new DriverURLName("COM.cloudscape.JDBCDriver", "jdbc:cloudscape:/cloudscape/"),
@ -104,7 +130,7 @@ public class JDBCDefPane extends JPanel {
private ReactiveCardPane centerPanel;
private ReactiveCardPane driverSelectRow;
// 请不要改动dbtype,只应该最后添加
private final String[] dbtype = {"Oracle", "DB2", "SQL Server", "MySQL", "Sybase", "Access", "Derby", "Postgre", "SQLite", "Inceptor", OTHER_DB};
private final String[] dbtype = {ORACLE, DB2, SQL_SERVER, MYSQL, SYBASE, ACCESS, DERBY, POSTGRE, SQLITE, INCEPTOR, OTHER_DB};
private JDBCDatabaseConnection jdbcDatabase;
@ -147,13 +173,15 @@ public class JDBCDefPane extends JPanel {
urlTextField.setText(dus[i].getURL());
}
}
// 更改数据库类型后 数据库名称置空和之前逻辑保持一致
if (needRefresh) {
jdbcDatabase.setDatabase(StringUtils.EMPTY);
// 更改数据库类型后更新数据库名称
if (needRefresh || StringUtils.isEmpty(jdbcDatabase.getDatabase())) {
jdbcDatabase.setDatabase(dbTypeMap.getOrDefault(GeneralUtils.objectToString(dbtypeComboBox.getSelectedItem()), DefaultDatabaseType.OTHER.getType()));
}
changePane(dbtypeComboBox.getSelectedItem());
JDBCConnectionDef.getInstance().setConnection((String) dbtypeComboBox.getSelectedItem(), jdbcDatabase);
DatabaseConnectionPane.JDBC.getAdvancedAttrPane().populate(jdbcDatabase);
needRefresh = true;
}
};
private HashBiMap<String, String> nameAndRepresent;
@ -220,10 +248,10 @@ public class JDBCDefPane extends JPanel {
cell(driverComboBox).weight(3), flex(2)
).getComponent())
.addSupplier("odbc", () -> row(
cell(driverComboBox).weight(3), flex(0.2), cell(odbcTipsLink).weight(1.8)
cell(driverComboBox).weight(3), flex(0.2), row(cell(odbcTipsLink)).weight(1.8)
).getComponent())
.addSupplier("define", () -> row(
cell(driverLoaderBox).weight(3), cell(driverManageLabel).weight(2)
cell(driverLoaderBox).weight(3), flex(0.2), row(cell(driverManageLabel)).weight(1.8)
).getComponent());
changeDriverRow();
@ -331,7 +359,14 @@ public class JDBCDefPane extends JPanel {
}
private void initMap() {
Map<String, DriverLoader> driverLoaders = DriverLoaderConfig.getInstance().getDriverLoaders();
Map<String, DriverLoader> driverLoaders = null;
try {
driverLoaders = ConnectionRepository.getInstance().getDriverLoaders();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
driverLoaders = new HashMap<>();
}
driverLoaders.entrySet().removeIf(entry -> StringUtils.isEmpty(entry.getValue().getDriverClass()));
nameAndRepresent = getDriverLoaderAndRepresent(driverLoaders);
}
@ -380,6 +415,7 @@ public class JDBCDefPane extends JPanel {
DriverURLName[] dus = entry.getValue();
for (int i = 0, len = dus.length; i < len; i++) {
if (ComparatorUtils.equals(dus[i].getDriver(), jdbcDatabase.getDriver())) {
needRefresh = false;
this.dbtypeComboBox.setSelectedItem(entry.getKey());
out = true;
break;
@ -420,7 +456,6 @@ public class JDBCDefPane extends JPanel {
} else {
this.charSetComboBox.setSelectedItem(jdbcDatabase.getOriginalCharsetName());
}
needRefresh = false;
}
public JDBCDatabaseConnection update() {

62
designer-base/src/main/java/com/fr/design/data/datapane/connect/LocalConnectionSource.java

@ -1,14 +1,21 @@
package com.fr.design.data.datapane.connect;
import com.fanruan.config.impl.data.ConnectionConfigProviderFactory;
import com.fr.data.driver.DriverClassNotFoundException;
import com.fr.data.impl.Connection;
import com.fr.decision.webservice.bean.datasource.ConnectionInfoBean;
import com.fr.decision.webservice.exception.general.DriverNotFoundException;
import com.fr.decision.webservice.v10.datasource.connection.processor.impl.ConnectionProcessorFactory;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.workspace.engine.exception.DriverUnExistException;
import com.fr.workspace.server.repository.connection.BaseConnectionSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 本地Connection资源操作
@ -20,24 +27,50 @@ import java.sql.SQLException;
public class LocalConnectionSource extends BaseConnectionSource {
@Override
public void testConnection(ConnectionInfoBean database) throws Exception {
public ConnectionInfoBean[] getAll(){
Map<String, Connection> map = ConnectionConfigProviderFactory.getConfigProvider().getConnections();
List<ConnectionInfoBean> beans = new ArrayList<>();
for (String name : map.keySet()) {
try {
beans.add(ConnectionInfoBeanHelper.createConnectionInfoBean(name, map.get(name)));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
return beans.toArray(new ConnectionInfoBean[0]);
}
@Override
public ConnectionInfoBean getByName(String name) {
try {
return ConnectionInfoBeanHelper.createConnectionInfoBean(name, ConnectionConfigProviderFactory.getConfigProvider().getConnection(name));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public String[] testConnection(ConnectionInfoBean database) throws Exception {
try {
// 暂时这么处理,后续最好拉到外层包装一下
TransmissionEncryptionManager.setTransEncryptionLevel(1);
ConnectionProcessorFactory.testConnectionWithSchemaReturn(database);
} finally {
TransmissionEncryptionManager.removeTransEncryptionLevel();
return ConnectionProcessorFactory.testConnectionWithSchemaReturn(database);
} catch (DriverNotFoundException e) {
throw new DriverUnExistException();
}
}
@Override
public void add(ConnectionInfoBean bean) throws Exception {
try {
TransmissionEncryptionManager.setTransEncryptionLevel(1);
Connection connection = ConnectionProcessorFactory.createConnection(bean);
validate(bean.getConnectionName(), connection);
ConnectionProcessorFactory.addConnection(bean);
} finally {
TransmissionEncryptionManager.removeTransEncryptionLevel();
} catch (DriverNotFoundException e) {
throw new DriverUnExistException();
} catch (RuntimeException e) {
if (e.getCause() instanceof DriverNotFoundException) {
throw new DriverUnExistException();
} else {
throw e;
}
}
}
@ -50,12 +83,17 @@ public class LocalConnectionSource extends BaseConnectionSource {
@Override
public void update(ConnectionInfoBean bean) throws Exception {
try {
TransmissionEncryptionManager.setTransEncryptionLevel(1);
Connection connection = ConnectionProcessorFactory.createConnection(bean);
validate(bean.getConnectionName(), connection);
ConnectionProcessorFactory.updateConnection(bean.getConnectionName(), bean);
} finally {
TransmissionEncryptionManager.removeTransEncryptionLevel();
} catch (DriverNotFoundException e) {
throw new DriverUnExistException();
} catch (RuntimeException e) {
if (e.getCause() instanceof DriverNotFoundException) {
throw new DriverUnExistException();
} else {
throw e;
}
}
}

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

@ -116,7 +116,7 @@ public class SshPane extends BasicPane {
coreCardPane = ReactiveCardPane.create()
.addSupplier(NOT_USE_SSH, () -> cell(usingSsh).getComponent())
.addSupplier(USE_SSH, () -> Layouts.column(LayoutConstants.VERTICAL_GAP,
cell(usingSsh),
row(cell(usingSsh)),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Host"))).weight(1),
cell(ip).weight(5),

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

@ -146,7 +146,7 @@ public class SslPane extends BasicPane {
@Override
public void actionPerformed(ActionEvent e) {
FILEChooserPane fileChooser = FILEChooserPane.getInstanceWithDesignatePath(SslUtils.PREFIX, new ChooseFileFilter(true), SslUtils.CERTIFICATES);
FILEChooserPane fileChooser = FILEChooserPane.getFileCAChoosePane(new ChooseFileFilter(true));
int type = fileChooser.showOpenDialog(SslPane.this, StringUtils.EMPTY);
if (type == FILEChooserPane.OK_OPTION) {
final FILE file = fileChooser.getSelectedFILE();

1
designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/FineSearchPane.java

@ -159,7 +159,6 @@ public class FineSearchPane extends JPanel implements HoverAware {
@Override
public void requestFocus() {
super.requestFocus();
searchTextField.requestFocus();
}
}

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

@ -3,6 +3,7 @@ package com.fr.design.data.datapane.preview;
import com.fr.data.auth.AuthenticationType;
import com.fr.data.auth.kerberos.KerberosAuthentication;
import com.fr.data.auth.kerberos.KerberosUtils;
import com.fr.data.core.db.dialect.DialectFactory;
import com.fr.data.impl.Connection;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.NameDatabaseConnection;
@ -10,7 +11,9 @@ import com.fr.data.pool.DBCPConnectionPoolAttr;
import com.fr.data.security.ssh.BaseSsh;
import com.fr.data.security.ssh.SshType;
import com.fr.data.security.ssh.impl.KeyVerifySsh;
import com.fr.data.security.ssh.impl.NormalSsh;
import com.fr.data.security.ssl.BaseSsl;
import com.fr.data.security.ssl.Ssl;
import com.fr.data.security.ssl.SslType;
import com.fr.data.security.ssl.impl.NormalSsl;
import com.fr.decision.privilege.TransmissionTool;
@ -19,11 +22,21 @@ import com.fr.decision.webservice.bean.datasource.JDBCConnectionBean;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.v10.datasource.connection.processor.impl.ConnectionProcessorFactory;
import com.fr.decision.webservice.v10.datasource.connection.processor.impl.JDBCConnectionProcessor;
import com.fr.log.FineLoggerFactory;
import com.fr.module.tool.ActivatorToolBox;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import com.fr.third.fasterxml.jackson.core.JsonProcessingException;
import com.fr.third.fasterxml.jackson.databind.ObjectMapper;
import com.fr.third.springframework.beans.BeanUtils;
import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.DataEncryptionHelper;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* 数据连接传输工具类
@ -34,6 +47,55 @@ import com.fr.workspace.server.repository.connection.ConnectionRepository;
*/
public class ConnectionInfoBeanHelper {
private static ObjectMapper objectMapper = new ObjectMapper();
private static final Map<String, Integer> FETCH_SIZE_MAP = ActivatorToolBox.sandbox(new HashMap<String, Integer>());
private static final int ORACLE_DEFAULT_FETCH_SIZE = 128;
private static final int DB2_DEFAULT_FETCH_SIZE = 50;
private static final int POSTGRE_DEFAULT_FETCH_SIZE = 10000;
static {
FETCH_SIZE_MAP.put("oracle", ORACLE_DEFAULT_FETCH_SIZE);
FETCH_SIZE_MAP.put("ibm-db2", DB2_DEFAULT_FETCH_SIZE);
FETCH_SIZE_MAP.put("postgresql", POSTGRE_DEFAULT_FETCH_SIZE);
}
/**
* 获取连接Map
*/
public static Map<String, Connection> createConnectionMap(ConnectionInfoBean[] beans) {
Map<String, Connection> ans = new HashMap<>();
for (ConnectionInfoBean infoBean : beans) {
try {
if (JDBCConnectionProcessor.KEY.acceptConnectionTypes().contains(infoBean.getConnectionType())) {
ans.put(infoBean.getConnectionName(), createJDBCConnection(infoBean));
} else {
ans.put(infoBean.getConnectionName(), ConnectionProcessorFactory.createConnection(infoBean, true));
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
return ans;
}
/**
* 根据bean创建连接
*/
public static Connection createConnection(ConnectionInfoBean infoBean) {
Connection connection = null;
try {
if (JDBCConnectionProcessor.KEY.acceptConnectionTypes().contains(infoBean.getConnectionType())) {
connection = createJDBCConnection(infoBean);
} else {
connection = ConnectionProcessorFactory.createConnection(infoBean, true);
}
connection.setConnectionName(infoBean.getConnectionName());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return connection;
}
return connection;
}
/**
* 创建数据连接Bean可自定义是否携带密码
@ -41,7 +103,7 @@ public class ConnectionInfoBeanHelper {
public static ConnectionInfoBean createConnectionInfoBean(String name, Connection connection, boolean withPassword) throws Exception {
if (connection instanceof NameDatabaseConnection) {
name = ((NameDatabaseConnection) connection).getName();
connection = ConnectionRepository.getInstance().getByName(name).getConnection();
connection = createConnection(ConnectionRepository.getInstance().getByName(name));
}
if (JDBCConnectionProcessor.KEY.acceptConnections().contains(connection.getClass())) {
ConnectionInfoBean bean = new ConnectionInfoBean();
@ -98,7 +160,7 @@ public class ConnectionInfoBeanHelper {
.user(jdbcConnection.getUser())
.driver(jdbcConnection.getDriver())
// 关键中的关键,由设计器发出的请求如果要携带密码,不能传明文,必须必须必须传加密后的密码
.password(withPassword ? encrypt(jdbcConnection.getPassword()) : DecisionServiceConstants.DEFAULT_PASSWORD)
.password(withPassword ? DataEncryptionHelper.encrypt(jdbcConnection.getPassword()) : DecisionServiceConstants.DEFAULT_PASSWORD)
.schema(jdbcConnection.getSchema())
.url(jdbcConnection.getURL())
.creator(jdbcConnection.getCreator())
@ -129,12 +191,101 @@ public class ConnectionInfoBeanHelper {
.verifyCa(jdbcConnection.getSsl().getSslType() == SslType.NORMAL && ((NormalSsl) jdbcConnection.getSsl()).isVerifyCa());
}
private static String encrypt(String password) {
// 如果是空密码或者默认密码,就返回默认的星号回去
if (StringUtils.isEmpty(password) || StringUtils.equals(password, DecisionServiceConstants.DEFAULT_PASSWORD)) {
return DecisionServiceConstants.DEFAULT_PASSWORD;
private static Connection createJDBCConnection(ConnectionInfoBean connectionInfoBean) throws Exception {
String name = connectionInfoBean.getConnectionName();
if (StringUtils.isNotEmpty(connectionInfoBean.getConnectionId())) {
name = connectionInfoBean.getConnectionId();
}
JDBCDatabaseConnection connection = new JDBCDatabaseConnection();
JDBCConnectionBean bean = objectMapper.readValue(connectionInfoBean.getConnectionData(), JDBCConnectionBean.class);
if (StringUtils.isNotEmpty(name)) {
bean.setConnectionName(name);
}
DBCPConnectionPoolAttr connectionPoolAttr = new DBCPConnectionPoolAttr();
BeanUtils.copyProperties(bean.getConnectionPoolAttr(), connectionPoolAttr);
connectionPoolAttr.setValidationQuery(DataEncryptionHelper.decrypt(connectionPoolAttr.getValidationQuery()));
connectionPoolAttr.setMinEvictableIdleTimeMillis(bean.getConnectionPoolAttr().getMinEvictableIdleTimeMillis() * Constants.MILLS_PER_SECOND);
connectionPoolAttr.setMaxEvictableIdleTimeMillis((long) bean.getConnectionPoolAttr().getMaxEvictableIdleTimeMillis() * Constants.MILLS_PER_SECOND);
connection.setDatabase(bean.getDatabase());
connection.setSchema(bean.getSchema());
connection.setDriver(bean.getDriver());
connection.setURL(bean.getUrl());
connection.setOriginalCharsetName(StringUtils.isEmpty(bean.getOriginalCharsetName()) ? null : bean.getOriginalCharsetName());
connection.setNewCharsetName(StringUtils.isEmpty(bean.getNewCharsetName()) ? null : bean.getNewCharsetName());
connection.setCreator(bean.getCreator());
connection.setDriverSource(bean.getDriverSource());
connection.setDbcpAttr(connectionPoolAttr);
if (StringUtils.isNotEmpty(bean.getAuthType())) {
connection.setAuthentication(new KerberosAuthentication(bean.getPrincipal(), bean.getKeyPath(), bean.isUseJaas()));
}
return TransmissionEncryptionManager.getInstance().getEncryption(WorkplaceConstants.getEncryptionMode()).encrypt(password, WorkplaceConstants.getEncryptionKey());
connection.setUser(bean.getUser());
TransmissionEncryptionManager.getInstance().setCurrentEncryptionMode(WorkplaceConstants.getDecryptionMode());
connection.setPassword(DataEncryptionHelper.decrypt(bean.getPassword()));
connection.setProperties(bean.getProperties());
setFetchSize(bean, connection);
if (bean.getIdentity() != null) {
connection.setIdentity(bean.getIdentity());
}
BaseSsh baseSsh;
String sshType = bean.getSshType();
if (SshType.KEY.toString().equals(sshType)) {
baseSsh = new KeyVerifySsh();
((KeyVerifySsh) baseSsh).setPrivateKeyPath(bean.getSshPrivateKeyPath());
} else {
baseSsh = new NormalSsh();
}
baseSsh.setIp(bean.getSshIp());
baseSsh.setUsingSsh(bean.isUsingSsh());
baseSsh.setPort(bean.getSshPort());
baseSsh.setUser(bean.getSshUser());
baseSsh.setRedirectIp(bean.getRedirectIp());
baseSsh.setRedirectPort(bean.getRedirectPort());
baseSsh.setSecret(DataEncryptionHelper.decrypt(bean.getSshSecret()));
baseSsh.setKeepAlive(bean.getSshKeepAlive());
baseSsh.setTimeOut(bean.getSshTimeOut());
connection.setSsh(baseSsh);
connection.setSsl(createSsl(bean));
return connection;
}
private static Ssl createSsl(JDBCConnectionBean bean) {
//目前只有NormalSsl
BaseSsl baseSsl = new NormalSsl();
if (SslType.NORMAL.toString().equals(bean.getSslType())) {
((NormalSsl) baseSsl).setVerifyCa(bean.isVerifyCa());
((NormalSsl) baseSsl).setCipher(bean.getSslCipher());
}
baseSsl.setUsingSsl(bean.isUsingSsl());
baseSsl.setClientCertificate(bean.getSslClientCertificate());
baseSsl.setClientPrivateKey(bean.getSslClientPrivateKey());
baseSsl.setCaCertificate(bean.getCaCertificate());
return baseSsl;
}
/**
* 前端客户设置了一个fetchSize
* 1. 如果是合法值(>0)就使用
* 2. 如果是非法值(<=0)
* 2.1 如果我们对这种数据库有默认的fetchSize就用默认的
* 2.2 如果没有默认值就不进行任何设置
* @param bean bean
* @param connection connection
*/
private static void setFetchSize(JDBCConnectionBean bean, Connection connection) {
int connectionBeanFetchSize = bean.getFetchSize();
String connectionBeanDatabaseName = bean.getDatabase();
if (DialectFactory.isValidFetchSize(connectionBeanFetchSize)) {
connection.setFetchSize(connectionBeanFetchSize);
} else if (FETCH_SIZE_MAP.containsKey(connectionBeanDatabaseName)) {
Optional.ofNullable(FETCH_SIZE_MAP.get(connectionBeanDatabaseName)).ifPresent(connection::setFetchSize);
}
FineLoggerFactory.getLogger().info("[Connection] fetchSize set to {} for connection {}", connection.getFetchSize(), bean.getConnectionName());
}
}

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

@ -26,7 +26,7 @@ import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.frpane.FineTabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UITableScrollPane;
import com.fr.design.gui.ilable.UILabel;
@ -34,6 +34,7 @@ import com.fr.design.gui.iprogressbar.AutoProgressBar;
import com.fr.design.gui.itable.SortableJTable;
import com.fr.design.gui.itable.TableSorter;
import com.fr.design.gui.itextfield.UINumberField;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
@ -44,7 +45,6 @@ import com.fr.function.TIME;
import com.fr.general.FRFont;
import com.fr.general.data.DataModel;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import javax.swing.BorderFactory;
@ -53,8 +53,6 @@ import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
@ -102,7 +100,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(600);
private static final int PREVIEW_TABLE_WIDTH = FineUIScale.scale(610);
private static final int TAB_MAX_COUNT_WITH_LINE = 7;
/**
* 用于refreshLabel的鼠标监听
@ -258,7 +257,7 @@ public class PreviewTablePane extends BasicPane {
public void doCancel() {
}
}, BasicDialog.DEFAULT);
}, DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.data.datapane.preview.dialog"));
dialog.setVisible(true);
// 关闭预览页面
PreviewTablePane.this.dialog.setVisible(false);
@ -681,7 +680,7 @@ public class PreviewTablePane extends BasicPane {
public static void previewMultiDataModels(NameDataModel[] nameDataModels) {
// tab窗口
UITabbedPane tabbedPane = new UITabbedPane();
FineTabbedPane.TabPaneBuilder tabbedPane = new FineTabbedPane.TabPaneBuilder();
for (NameDataModel nameDataModel : nameDataModels) {
// 单个结果集的展示面板
@ -706,10 +705,33 @@ public class PreviewTablePane extends BasicPane {
};
previewPane.setLayout(FRGUIPaneFactory.createBorderLayout());
previewPane.add(tabbedPane, BorderLayout.CENTER);
if (nameDataModels.length > 0) {
int[] tabLayout = buildTabLayout(nameDataModels);
float headRatio = buildHeadRatio(tabLayout);
previewPane.add(tabbedPane.withHeadRatio(headRatio).withTabLayout(tabLayout).build(), BorderLayout.CENTER);
}
previewPane.showWindow(new JFrame()).setVisible(true);
}
private static float buildHeadRatio(int[] tabLayout) {
float maxLen = 0.8f;
if (tabLayout.length == 1) {
return (float) tabLayout[0] / TAB_MAX_COUNT_WITH_LINE;
}
return maxLen;
}
private static int[] buildTabLayout(NameDataModel[] nameDataModels) {
int length = nameDataModels.length;
int size = (length + TAB_MAX_COUNT_WITH_LINE - 1) / TAB_MAX_COUNT_WITH_LINE;
int[] tabLayout = new int[size];
int index = 0;
for (int i = 0; i < length; i += TAB_MAX_COUNT_WITH_LINE) {
tabLayout[index ++] = Math.min(TAB_MAX_COUNT_WITH_LINE, length - i);
}
return tabLayout;
}
/**
* 直接预览存储过程的所有返回数据集没有实际值和显示值
*

235
designer-base/src/main/java/com/fr/design/data/datapane/preview/TableDataBeanHelper.java

@ -0,0 +1,235 @@
package com.fr.design.data.datapane.preview;
import com.fr.base.DataSetProcessors;
import com.fr.base.Parameter;
import com.fr.base.ParameterHelper;
import com.fr.base.ParameterTypeHandler;
import com.fr.base.StoreProcedureParameter;
import com.fr.base.TableData;
import com.fr.data.impl.Connection;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.decision.fun.UniversalServerTableDataProvider;
import com.fr.decision.webservice.bean.dataset.ParameterBean;
import com.fr.decision.webservice.bean.dataset.ParameterExternal;
import com.fr.decision.webservice.bean.dataset.SQLDataSetBean;
import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.decision.webservice.bean.dataset.StoreProcedureBean;
import com.fr.decision.webservice.bean.dataset.StrategyConfigBean;
import com.fr.decision.webservice.v10.datasource.dataset.processor.impl.SQLDataSetProcessor;
import com.fr.decision.webservice.v10.datasource.dataset.processor.impl.StoreProcedureProcessor;
import com.fr.esd.core.strategy.config.StrategyConfig;
import com.fr.general.GeneralUtils;
import com.fr.general.sql.SqlUtils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.script.Calculator;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.DataEncryptionHelper;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 数据集bean工具类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/8/9
*/
public class TableDataBeanHelper {
/**
* 获取服务器数据集
*/
public static Map<String, TableData> getServerTableDatas() {
final List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, TableData> tableDataMap = new HashMap<>();
try {
for (ServerDataSetBean bean : beans) {
tableDataMap.put(bean.getDatasetName() , TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return tableDataMap;
}
/**
* 根据序列化数据生成tabledata
*/
public static TableData getTableDataSet(Map<String, Connection> connectionMap, String type, String tableDataSetData) throws Exception {
if (DataSetProcessors.getProcessors().containsKey(type)) {
if (StringUtils.equals(SQLDataSetProcessor.TYPE, type)) {
return deserialize4SQL(connectionMap, null, new JSONObject(tableDataSetData));
} else if (StringUtils.equals(StoreProcedureProcessor.TYPE, type)) {
return deserialize4Procedure(connectionMap, null, new JSONObject(tableDataSetData));
} else {
UniversalServerTableDataProvider processor = DataSetProcessors.getProcessors().get(type);
return (TableData) processor.deserialize(null, new JSONObject(tableDataSetData));
}
}
return null;
}
private static TableData deserialize4Procedure(Map<String, Connection> connectionMap, DBTableData oldDataSet, JSONObject object) {
StoreProcedure storeProcedure = new StoreProcedure();
StoreProcedureBean bean = object.mapTo(StoreProcedureBean.class);
storeProcedure.setShare(bean.isShare());
storeProcedure.setMaxMemRowCount(bean.getMaxMemRowCount());
storeProcedure.setQuery(bean.getQuery());
if (StringUtils.isNotEmpty(bean.getDatabase())) {
Connection connection = connectionMap.get(bean.getDatabase());
if (connection != null) {
storeProcedure.setDatabaseConnection(new NameDatabaseConnection(bean.getDatabase()));
} else {
FineLoggerFactory.getLogger().info("not find conn by {}", bean.getDatabase());
}
}
Parameter[] parameters = new Parameter[bean.getParameters().size()];
for (int i = 0; i < parameters.length; i++) {
ParameterBean parameterBean = bean.getParameters().get(i);
parameters[i] = (Parameter) ParameterTypeHandler.getInstance().parseParameter(parameterBean, new Parameter(parameterBean.getName()));
}
List<ParameterExternal> externals = bean.getStoreProcedureParameterBeanList();
StoreProcedureParameter[] procedureParameters = new StoreProcedureParameter[bean.getParameters().size()];
for (int i = 0; i < procedureParameters.length; i++) {
StoreProcedureParameter storeProcedureParameter = new StoreProcedureParameter();
storeProcedureParameter.setName(parameters[i].getName());
storeProcedureParameter.setValue(parameters[i].getValue());
storeProcedureParameter.setSchema(externals.get(i).getSchema());
storeProcedureParameter.setType(externals.get(i).getTypeInt());
procedureParameters[i] = storeProcedureParameter;
}
storeProcedure.setParameters(procedureParameters);
return storeProcedure;
}
/**
* 获取服务器数据集传输的bean
*/
public static ServerDataSetBean getServerDataSetBean(String name, TableData tableData) {
for (UniversalServerTableDataProvider processor : DataSetProcessors.getProcessors().values()) {
if (SQLDataSetProcessor.KEY.classForTableData() == tableData.getClass()) {
return serialize4SQL(name, tableData);
} else if (processor.classForTableData() == tableData.getClass()) {
ServerDataSetBean bean = new ServerDataSetBean();
try {
bean.setDatasetData(processor.serialize(tableData).toString());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
bean.setDatasetData(StringUtils.EMPTY);
}
bean.setDatasetName(name);
bean.setDatasetId(name);
bean.setDatasetType(processor.nameForTableData());
return bean;
}
}
return new ServerDataSetBean(name);
}
private static ServerDataSetBean serialize4SQL(String name, TableData tableData) {
ServerDataSetBean bean = new ServerDataSetBean();
try {
bean.setDatasetData(serialize4SQL0((DBTableData) tableData).toString());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
bean.setDatasetData(StringUtils.EMPTY);
}
bean.setDatasetName(name);
bean.setDatasetId(name);
bean.setDatasetType(SQLDataSetProcessor.KEY.nameForTableData());
return bean;
}
private static Object serialize4SQL0(DBTableData dataSet) {
SQLDataSetBean bean = new SQLDataSetBean();
if (dataSet.getDatabase() instanceof NameDatabaseConnection) {
bean.setDatabase(((NameDatabaseConnection) dataSet.getDatabase()).getName());
}
bean.setQuery(DataEncryptionHelper.encrypt(dataSet.getQuery()));
List<ParameterBean> parameterBeans = new ArrayList<>();
ParameterProvider[] parameters = dataSet.getParameters(Calculator.createCalculator());
for (ParameterProvider parameter : parameters) {
parameterBeans.add(new ParameterBean(parameter.getValue().getClass().getSimpleName(), parameter.getName(), GeneralUtils.objectToString(parameter.getValue())));
}
bean.setParameters(parameterBeans);
StrategyConfig config = dataSet.getStrategyConfig();
if (config != null) {
StrategyConfigBean strategyConfigBean = new StrategyConfigBean();
strategyConfigBean.setUseGlobal(config.isUseGlobal());
strategyConfigBean.setShouldMonitor(config.shouldMonitor());
strategyConfigBean.setShouldEvolve(config.shouldEvolve());
strategyConfigBean.setScheduleBySchema(config.isScheduleBySchema());
strategyConfigBean.setTimeToLive(config.getTimeToLive());
strategyConfigBean.setTimeToIdle(config.getTimeToIdle());
strategyConfigBean.setUpdateInterval(config.getUpdateInterval());
strategyConfigBean.setTerminalTime(config.getTerminalTime());
strategyConfigBean.setUpdateSchema(config.getUpdateSchema());
strategyConfigBean.setActiveInitiation(config.isActiveInitiation());
strategyConfigBean.setShare(config.enabled());
bean.setStrategyConfig(strategyConfigBean);
}
return JSONObject.mapFrom(bean);
}
private static TableData deserialize4SQL(Map<String, Connection> connectionMap, DBTableData oldDataSet, JSONObject object) {
DBTableData tableData = new DBTableData();
SQLDataSetBean bean = object.mapTo(SQLDataSetBean.class);
tableData.setQuery(DataEncryptionHelper.decrypt(bean.getQuery()));
Connection connection = connectionMap.get(bean.getDatabase());
if (connection != null) {
tableData.setDatabase(new NameDatabaseConnection(bean.getDatabase()));
} else {
FineLoggerFactory.getLogger().info("not find conn by {}", bean.getDatabase());
}
String sql = SqlUtils.clearSqlComments(DataEncryptionHelper.decrypt(bean.getQuery()));
Parameter[] parameters = new Parameter[bean.getParameters().size()];
for (int i = 0; i < parameters.length; i++) {
ParameterBean parameterBean = bean.getParameters().get(i);
parameters[i] = (Parameter) ParameterTypeHandler.getInstance().parseParameter(parameterBean, new Parameter(parameterBean.getName()));
}
tableData.setParameters(ParameterHelper.analyzeAndUnionSameParameters(new String[]{sql}, parameters));
if (oldDataSet != null) {
tableData.setMaxMemRowCount(oldDataSet.getMaxMemRowCount());
tableData.setPageQuerySql(oldDataSet.getPageQuerySql());
tableData.setShare(oldDataSet.isShare());
tableData.setDataQueryProcessor(oldDataSet.getDataQueryProcessor());
}
StrategyConfig config = getStrategyConfig(bean.getStrategyConfig());
tableData.setStrategyConfig(config);
return tableData;
}
private static StrategyConfig getStrategyConfig(StrategyConfigBean bean) {
if (bean == null) {
return new StrategyConfig();
}
StrategyConfig config = new StrategyConfig();
config.setEnable(bean.isShare());
config.setUseGlobal(bean.isUseGlobal());
config.setShouldMonitor(bean.isShouldMonitor());
config.setShouldEvolve(bean.isShouldEvolve());
config.setScheduleBySchema(bean.isScheduleBySchema());
config.setTimeToLive(bean.getTimeToLive());
config.setTimeToIdle(bean.getTimeToIdle());
config.setUpdateInterval(bean.getUpdateInterval());
config.setTerminalTime(bean.getTerminalTime());
config.setUpdateSchema(bean.getUpdateSchema());
config.setActiveInitiation(bean.isActiveInitiation());
return config;
}
}

7
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/common/DesensitizationOpenPane.java

@ -1,5 +1,6 @@
package com.fr.design.data.datapane.preview.desensitization.view.common;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIUtils;
import com.fr.base.svg.IconUtils;
import com.fr.design.border.UITitledBorder;
@ -23,6 +24,7 @@ import java.net.URL;
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;
/**
* 启用数据脱敏的面板
@ -56,7 +58,7 @@ public class DesensitizationOpenPane extends JPanel {
// 启用数据脱敏的勾选框
desensitizeOpenCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Desensitization_Opened"));
// 跳转帮助文档Label
hyperlinkLabel = new UILabel(IconUtils.readIcon("/com/fr/design/standard/tip/tips"));
hyperlinkLabel = new UILabel(new LazyIcon("jump_to_references"));
hyperlinkLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Open_Tips"));
hyperlinkLabel.addMouseListener(new MouseAdapter() {
@Override
@ -70,8 +72,7 @@ public class DesensitizationOpenPane extends JPanel {
}
}
});
panel.add(desensitizeOpenCheckBox);
panel.add(hyperlinkLabel);
panel.add(row(4, cell(desensitizeOpenCheckBox), cell(hyperlinkLabel)).getComponent());
// 提示Label
tipsLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Opened_Tooltips"));

15
designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/rule/DesensitizationRuleChoosePane.java

@ -2,6 +2,7 @@ package com.fr.design.data.datapane.preview.desensitization.view.rule;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.base.svg.IconUtils;
import com.fr.data.desensitize.rule.DesensitizationRuleManager;
@ -12,6 +13,7 @@ import com.fr.design.data.datapane.preview.desensitization.view.common.ChooseMar
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itable.FineUITableCellEditor;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itableeditorpane.UITableModelAdapter;
@ -20,12 +22,10 @@ import com.fr.design.i18n.Toolkit;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.CollectionUtils;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.CardLayout;
@ -195,17 +195,15 @@ public class DesensitizationRuleChoosePane extends JPanel {
/**
* 规则状态展示页面
*/
private class DesensitizationRuleStatusPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private class DesensitizationRuleStatusPane extends FineUITableCellEditor {
private UILabel ruleStatusLabel;
DesensitizationRuleStatusPane() {
// 规则状态
this.ruleStatusLabel = new UILabel();
this.ruleStatusLabel.setForeground(Color.RED);
this.ruleStatusLabel.setOpaque(true);
this.ruleStatusLabel.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
this.ruleStatusLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIManager.getColor("defaultBorderColor")));
FineUIStyle.setStyle(ruleStatusLabel, FineUIStyle.LABEL_WARNING_TIP);
}
/**
@ -239,6 +237,9 @@ public class DesensitizationRuleChoosePane extends JPanel {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
refreshRuleStatus(getList().get(row));
JComponent c = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
ruleStatusLabel.setBorder(c.getBorder());
ruleStatusLabel.setBackground(c.getBackground());
return ruleStatusLabel;
}
}

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

@ -1,7 +1,6 @@
package com.fr.design.data.datapane.preview.desensitization.view.setting;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.light.ui.FineRoundBorder;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.data.desensitize.base.DesensitizationTableData;
@ -14,10 +13,10 @@ import com.fr.design.data.datapane.preview.desensitization.view.rule.Desensitiza
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icombobox.ComboCheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombocheckbox.UIComboCheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itable.FineUITableCellEditor;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableModelAdapter;
import com.fr.design.gui.itextfield.UITextField;
@ -38,7 +37,6 @@ import javax.swing.UIManager;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@ -56,6 +54,8 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import static com.fine.theme.utils.FineUIStyle.setStyle;
/**
* 处理TableDataDesensitizationTablePane中TableEditPane的Model
*
@ -127,8 +127,6 @@ public class TableDataDesensitizationTableModel extends UITableModelAdapter<Tabl
this.setDefaultEditor(EffectedRolesChooser.class, effectedRolesChooser);
this.setDefaultEditor(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane());
this.setDefaultRenderer(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane());
this.createTable().getColumnModel().getColumn(TableSequences.DesensitizationRuleStatus.getNum()).setMaxWidth(60);
}
@Override
@ -368,12 +366,6 @@ public class TableDataDesensitizationTableModel extends UITableModelAdapter<Tabl
}
});
setBoxStyle();
}
private void setBoxStyle() {
this.rolesCheckBox.setBorder(new FineRoundBorder());
FineUIStyle.setStyle(this.rolesCheckBox.getEditor(), FineUIStyle.TRANSPARENT_TEXT_FIELD);
}
@Override
@ -434,8 +426,9 @@ public class TableDataDesensitizationTableModel extends UITableModelAdapter<Tabl
protected void setLayoutAndAddComponents() {
// 使用BorderLayout,否则默认使用的FlowLayout会让整个下拉选框使用最小Size,然后TableCell这边会出现空白
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(getEditor(), BorderLayout.CENTER);
this.add(getLabel(), BorderLayout.EAST);
JPanel pane = getClickPane();
pane.setOpaque(false);
this.add(pane, BorderLayout.CENTER);
}
@Override
@ -451,17 +444,15 @@ public class TableDataDesensitizationTableModel extends UITableModelAdapter<Tabl
/**
* 规则状态展示页面
*/
private class DesensitizationRuleStatusPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private class DesensitizationRuleStatusPane extends FineUITableCellEditor {
private UILabel ruleStatusLabel;
DesensitizationRuleStatusPane() {
// 规则状态
this.ruleStatusLabel = new UILabel();
this.ruleStatusLabel.setForeground(Color.RED);
this.ruleStatusLabel.setOpaque(true);
this.ruleStatusLabel.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
this.ruleStatusLabel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIManager.getColor("defaultBorderColor")));
setStyle(ruleStatusLabel, FineUIStyle.LABEL_WARNING_TIP);
}
/**
@ -497,6 +488,9 @@ public class TableDataDesensitizationTableModel extends UITableModelAdapter<Tabl
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
refreshRuleStatus(getList().get(row));
JComponent c = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
ruleStatusLabel.setBorder(c.getBorder());
ruleStatusLabel.setBackground(c.getBackground());
return ruleStatusLabel;
}
}

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

@ -1,6 +1,5 @@
package com.fr.design.data.datapane.preview.desensitization.view.setting;
import com.fr.base.operator.org.OrganizationOperator;
import com.fr.data.desensitize.base.DesensitizationTableData;
import com.fr.data.desensitize.base.TableDataDesensitizationItem;
import com.fr.data.desensitize.rule.DesensitizationRuleManager;
@ -11,13 +10,10 @@ import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@ -91,7 +87,7 @@ public class TableDataDesensitizationTablePane extends JPanel {
// 获取当前数据集的所有列名
columnNames.addAll(TableDataPreviewDesensitizeManager.getInstance().getColumnNamesByTableData(tableData));
// 获取当前所有用户组
roleMap.putAll(WorkContext.getCurrent().get(OrganizationOperator.class).getAllRoles4Desensitization());
roleMap.putAll(RemoteAuthorityRepository.getInstance().getAllRoles4Desensitization());
// 获取当前最新的所有规则
latestRules.putAll(DesensitizationRuleManager.getInstance().getAllRules());
return null;

1
designer-base/src/main/java/com/fr/design/data/datapane/sqlpane/SQLEditPane.java

@ -57,6 +57,7 @@ public class SQLEditPane extends RSyntaxTextArea {
if (requestDroptarget) {
new SQLPaneDropTarget(this);
}
setBorder(null);
}

107
designer-base/src/main/java/com/fr/design/data/tabledata/LocalTableDataSource.java

@ -0,0 +1,107 @@
package com.fr.design.data.tabledata;
import com.fanruan.config.impl.data.ConnectionConfigProviderFactory;
import com.fanruan.config.impl.data.TableDataConfigProviderFactory;
import com.fr.base.TableData;
import com.fr.decision.webservice.bean.dataset.FileDataSetBean;
import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.decision.webservice.bean.entry.FileNodeBean;
import com.fr.decision.webservice.v10.datasource.dataset.processor.impl.FileProcessor;
import com.fr.decision.webservice.v10.file.FileNodeService;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.CommonUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.server.repository.tabledata.BaseTableDataSource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* LocalTableDataSource
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/5/29
*/
public class LocalTableDataSource extends BaseTableDataSource {
@Override
public Set<String> getAllNames(String username) {
Set<String> authServerDataSetNames = new HashSet<>();
for (String authServerDataSetName : TableDataConfigProviderFactory.getInstance().getTableDatas().keySet()) {
authServerDataSetNames.add(authServerDataSetName);
}
return authServerDataSetNames;
}
@Override
public boolean lock(String str) {
// 本地默认锁定成功,让其执行后续动作
return true;
}
@Override
public boolean unlock(String str) {
// 本地默认解锁成功
return true;
}
@Override
public boolean isLock(String str) {
// 本地默认未锁定
return false;
}
@Override
public List<FileNodeBean> getFileList(String fileType) {
return FileProcessor.KEY.getFileList(fileType, StringUtils.EMPTY);
}
@Override
public boolean testFilePath(FileDataSetBean fileDataSetBean) {
try {
return FileProcessor.KEY.testFilePath(fileDataSetBean);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return false;
}
}
@Override
public List<FileNodeBean> getCertificatesFile(String keyword) throws Exception {
String pPath = CommonUtils.pathJoin(ProjectConstants.RESOURCES_NAME, ProjectConstants.CERTIFICATES_DIRECTORY);
return FileNodeService.getInstance().getAllRecursiveFileNodes(pPath, ProjectConstants.RESOURCES_NAME, keyword);
}
@Override
public List<ServerDataSetBean> getAllTableData() {
List<ServerDataSetBean> beans = new ArrayList<>();
TableData[] tableDatas = TableDataConfigProviderFactory.getInstance().getTableDatas().values().toArray(new TableData[0]);
for (TableData data : tableDatas) {
beans.add(TableDataBeanHelper.getServerDataSetBean(data.getName(), data));
}
return beans;
}
@Override
public void add(ServerDataSetBean bean) throws Exception {
TableDataConfigProviderFactory.getInstance().addTableData(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(ConnectionConfigProviderFactory.getConfigProvider().getConnections(), bean.getDatasetType(), bean.getDatasetData()));
}
@Override
public void delete(ServerDataSetBean bean) throws Exception {
TableDataConfigProviderFactory.getInstance().removeTableData(bean.getDatasetName());
}
@Override
public void update(ServerDataSetBean bean) throws Exception {
TableDataConfigProviderFactory.getInstance().updateTableData(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(ConnectionConfigProviderFactory.getConfigProvider().getConnections(), bean.getDatasetType(), bean.getDatasetData()));
}
}

28
designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DatacentersJSBridge.java → designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DCTableDataJSBridge.java

@ -4,7 +4,9 @@ import com.fr.base.BaseFormula;
import com.fr.datacenters.tabledata.bean.DCFilterQueryBean;
import com.fr.datacenters.tabledata.bean.DCTableDataBean;
import com.fr.datacenters.tabledata.filter.DCFilter;
import com.fr.datacenters.tabledata.parameter.DCParameter;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.dialog.DialogActionListener;
import com.fr.design.dialog.UIDialog;
import com.fr.design.formula.FormulaFactory;
@ -37,7 +39,7 @@ import java.util.stream.Collectors;
* Created on 2024/6/17
*/
@JsAccessible
public class DatacentersJSBridge {
public class DCTableDataJSBridge {
private static final String EVENT_FORMULA_UPDATE = "OK";
private static final String EVENT_FORMULA_CANCEL = "CANCEL";
@ -47,25 +49,25 @@ public class DatacentersJSBridge {
* @param window js环境的window对象
* @return 桥接实例
*/
public static DatacentersJSBridge getBridge(JsObject window) {
return new DatacentersJSBridge(window);
public static DCTableDataJSBridge getBridge(JsObject window) {
return new DCTableDataJSBridge(window);
}
private final JsObject window;
private DatacentersJSBridge(JsObject window) {
private DCTableDataJSBridge(JsObject window) {
this.window = window;
}
private static DatacentersPane relationPanel;
private static DCTableDataPane relationPanel;
/**
* 设置窗口用于打开对话框的层级
*
* @param panel 面板
*/
public static void relationPanel(DatacentersPane panel) {
public static void relationPanel(DCTableDataPane panel) {
relationPanel = panel;
}
@ -134,6 +136,16 @@ public class DatacentersJSBridge {
}).setVisible(true);
}
/**
* 当前所有数据集名称
*/
@JSBridge
public void getDatasetNames(final JsFunction callback) {
JxUIPane.DEFAULT_EXECUTOR.submit(() ->
callback.invoke(window, EmbedJson.encode(
DesignTableDataManager.getAllDSNames(DesignTableDataManager.getEditingTableDataSource()))));
}
/**
* 解析公式参数
*/
@ -161,7 +173,9 @@ public class DatacentersJSBridge {
JxUIPane.DEFAULT_EXECUTOR.submit(() -> {
try {
DCTableDataBean decoded = EmbedJson.decodeValue(tableData, DCTableDataBean.class);
DCFilter dcFilter = decoded.getFilter().evalValue(decoded.getParameters(), Calculator.createCalculator());
DCParameter[] dcParameters = Arrays.stream(decoded.getParameters())
.map(DCParameter::fromBean).toArray(DCParameter[]::new);
DCFilter dcFilter = decoded.getFilter().evalValue(dcParameters, Calculator.createCalculator());
DCFilterQueryBean queryBean = dcFilter.toQueryBean();
String encode = EmbedJson.encode(queryBean);
callback.invoke(window, encode);

86
designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DatacentersPane.java → designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DCTableDataPane.java

@ -4,9 +4,9 @@ import com.fanruan.workplace.http.ServiceType;
import com.fr.datacenters.tabledata.DCTableData;
import com.fr.datacenters.tabledata.bean.DCNameBean;
import com.fr.datacenters.tabledata.bean.DCTableDataBean;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.dialog.DialogActionListener;
import com.fr.design.dialog.UIDialog;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jxbrowser.JxEngine;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.json.revise.EmbedJson;
@ -14,9 +14,12 @@ import com.fr.stable.StringUtils;
import com.fr.third.guava.collect.ImmutableMap;
import com.fr.workspace.WorkContext;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Window;
import java.util.Arrays;
import static com.fr.design.ui.ModernUIConstants.DOT;
import static com.fr.design.ui.ModernUIConstants.EMB_TAG;
import static com.fr.design.ui.ModernUIConstants.SCHEME_HEADER;
/**
* 数据中心数据集面板
@ -25,56 +28,46 @@ import java.awt.Window;
* @since 11.0
* Created on 2024/6/17
*/
public class DatacentersPane extends AbstractTableDataPane<DCTableData> {
public class DCTableDataPane extends AbstractTableDataPane<DCTableData> {
private static final JxEngine JX_ENGINE = JxEngine.newInstance(false);
private static final String DATA_CENTER = "dc";
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";
private final JxUIPane<String> dataCenterJxUIPane;
private JxTableDataNamePane namePane;
private final JxTableDataNamePane namePane = new JxTableDataNamePane(this);
// 用于复制粘贴场景
private DCTableData dcTableData;
/**
* 借用只运行一次
* 用于创建带有名称的面板
*
* @param name 名称
*/
private void addDialogActionListener() {
// 保证在窗口加载完成后执行
SwingUtilities.invokeLater(() -> {
Window ancestor = SwingUtilities.getWindowAncestor(DatacentersPane.this);
if (ancestor instanceof UIDialog) {
((UIDialog) ancestor).addDialogActionListener(new DialogActionListener() {
@Override
public void doOk() {
dataCenterJxUIPane.disposeBrowser();
}
@Override
public void doCancel() {
dataCenterJxUIPane.disposeBrowser();
}
});
}
});
public DCTableDataPane(String name) {
this();
namePane.setObjectName(name);
}
public DatacentersPane() {
public DCTableDataPane() {
setLayout(new BorderLayout());
dataCenterJxUIPane = getJxUIPane();
add(dataCenterJxUIPane, BorderLayout.CENTER);
dataCenterJxUIPane.addXHRHeaders(ImmutableMap.of("Authorization",
WorkContext.getCurrent().getConnection().getToken()));
// 关联 bridge 和 pane
DCTableDataJSBridge.relationPanel(this);
}
private static JxUIPane<String> getJxUIPane() {
return new JxUIPane.Builder<String>()
.engine(JX_ENGINE)
.namespace(DATA_CENTER)
.bindWindow(DATA_CENTER_HELPER, DatacentersJSBridge::getBridge)
.withEMB("com/fr/design/data/tabledata/datacenter/web/data-choose.prod.html",
ImmutableMap.of("fineServletURL", getDatacentersUrl()))
.bindWindow(DATA_CENTER_HELPER, DCTableDataJSBridge::getBridge)
.withEMB(DC_INDEX_HTML, ImmutableMap.of(DATA_CENTER_INJECT_URL, getDatacentersUrl()))
.build();
}
@ -89,15 +82,37 @@ public class DatacentersPane extends AbstractTableDataPane<DCTableData> {
@Override
public NamePane asNamePane() {
return namePane = new JxTableDataNamePane(this);
return namePane;
}
@Override
public void populateBean(DCTableData ob) {
DatacentersJSBridge.relationPanel(this);
reload();
dcTableData = ob;
dataCenterJxUIPane.populate(EmbedJson.encode(ob.toBean()));
updateTableDataName(dcTableData, namePane.getObjectName());
dataCenterJxUIPane.populate(EmbedJson.encode(dcTableData.toBean()));
setDatasetNames(dcTableData);
}
private void reload() {
dataCenterJxUIPane.redirect(EMB_TAG + SCHEME_HEADER + DC_INDEX_HTML,
ImmutableMap.of(DATA_CENTER_INJECT_URL, getDatacentersUrl()));
}
private static void updateTableDataName(DCTableData dcTableData, String name) {
if (StringUtils.isNotBlank(name)) {
dcTableData.setDsName(name);
dcTableData.setName(name);
}
}
private void setDatasetNames(DCTableData ob) {
String[] allDSNames = DesignTableDataManager.getAllDSNames(DesignTableDataManager.getEditingTableDataSource());
String[] allName = Arrays.stream(allDSNames)
.filter(name -> !ob.getDsName().equals(name))
.toArray(String[]::new);
dataCenterJxUIPane.executeJS(DATA_CENTER + DOT + "datasetNames=" + EmbedJson.encode(allName));
}
@ -109,7 +124,8 @@ public class DatacentersPane extends AbstractTableDataPane<DCTableData> {
namePane.setObjectName(tableDataBean.getDsName());
return DCTableData.fromBean(tableDataBean);
} else {
// 复制的场景下,不打开界面需要返回数据集
// 复制的场景下,不打开界面需要返回数据集,需同步面板的名称
updateTableDataName(dcTableData, namePane.getObjectName());
return dcTableData;
}
}
@ -125,6 +141,6 @@ public class DatacentersPane extends AbstractTableDataPane<DCTableData> {
@Override
protected String title4PopupWindow() {
return "";
return Toolkit.i18nText("Fine-Design_Basic_DS_Datacenters");
}
}

1
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ClassTableDataPane.java

@ -55,7 +55,6 @@ public class ClassTableDataPane extends AbstractTableDataPane<ClassTableData> {
//类名
classNameTextField = new UITextField();
UIButton browserButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Select"));
browserButton.setPreferredSize(new Dimension(browserButton.getPreferredSize().width, classNameTextField.getPreferredSize().height));
browserButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
final ClassNameSelectPane bPane = new ClassNameSelectPane();

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

@ -165,7 +165,8 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> implemen
ParameterTableModel model = new ParameterTableModel() {
@Override
public UITableEditAction[] createAction() {
return ArrayUtils.add(super.createDBTableAction(), new RefreshAction());
// 当前仅支持刷新参数功能
return ArrayUtils.toArray(new RefreshAction());
}
};
editorPane = new UITableEditorPane<>(model);
@ -208,6 +209,7 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> implemen
@Override
public void keyPressed(KeyEvent e) {
searchField.setToolTipText(searchField.getText());
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
e.setKeyCode(KeyEvent.VK_UP);
DBTableDataPane.this.connectionTableProcedurePane.requestFocus();

121
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/EmbeddedTableDataPane.java

@ -1,6 +1,8 @@
package com.fr.design.data.tabledata.tabledatapane;
import com.fine.theme.light.ui.FineTableHeaderUI;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fr.data.impl.EmbeddedTableData;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.BasicDialog;
@ -19,6 +21,7 @@ import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
@ -27,6 +30,8 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
@ -42,7 +47,7 @@ import static com.fine.swing.ui.layout.Layouts.flex;
public class EmbeddedTableDataPane extends AbstractTableDataPane<EmbeddedTableData> {
private static final int MIN_CELL_WIDTH = 30;
private static final int PREVIEW_TABLE_MIN_COLUMN_WIDTH = FineUIScale.scale(75);
private static final int PREVIEW_TABLE_WIDTH = FineUIScale.scale(600);
private static final int PREVIEW_TABLE_WIDTH = FineUIScale.scale(860);
private JTable dataJTable ;
private UITableScrollPane scrollPane;
private UILabel coordinatelabel;
@ -64,11 +69,14 @@ public class EmbeddedTableDataPane extends AbstractTableDataPane<EmbeddedTableDa
// prepare the data in this way as default if no arguments is passed in
EmbeddedTableModel tableModel = new EmbeddedTableModel(new EmbeddedTableData());
dataJTable = new JTable(tableModel);
dataJTable.setBackground(FlatUIUtils.getUIColor("default.background", new Color(246, 248, 250)));
scrollPane = new UITableScrollPane(dataJTable);;
// 显示double,date类;渲染date类
dataJTable.setDefaultRenderer(Double.class, new DoubleRenderer());
dataJTable.setDefaultRenderer(Date.class, new DateRenderer());
dataJTable.setDefaultRenderer(Integer.class, new DoubleRenderer());
dataJTable.setDefaultRenderer(Number.class, new DoubleRenderer());
dataJTable.setDefaultEditor(Date.class, new DateEditor(new UIDatePicker(UIDatePicker.STYLE_CN_DATE1)));
tableStructureChanged();
@ -82,7 +90,6 @@ public class EmbeddedTableDataPane extends AbstractTableDataPane<EmbeddedTableDa
editbysingleclick(dataJTable, Integer.class);
// AUTO RESIZE
dataJTable.setAutoResizeMode(tableModel.getColumnCount() * PREVIEW_TABLE_MIN_COLUMN_WIDTH <= PREVIEW_TABLE_WIDTH ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF);
dataJTable.setRowSelectionAllowed(true);
dataJTable.setColumnSelectionAllowed(true);
@ -97,6 +104,7 @@ public class EmbeddedTableDataPane extends AbstractTableDataPane<EmbeddedTableDa
selectedChanged();
}
});
addDataTableListener();
// 添加表模型监听器以监听行列变化更新按钮状态
tableModel.addTableModelListener(new TableModelListener() {
@ -108,37 +116,52 @@ public class EmbeddedTableDataPane extends AbstractTableDataPane<EmbeddedTableDa
this.add(column(LayoutConstants.VERTICAL_GAP, cell(getNorthPaneComponents()), cell(scrollPane).weight(1)).getComponent());
}
private void addDataTableListener() {
dataJTable.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
// kel:加上一个鼠标点击的监控,鼠标点击时,返回选中的行坐标和列坐标。
selectedChanged();
}
});
dataJTable.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
selectedChanged();
}
});
dataJTable.addComponentListener(new ComponentListener() {
@Override
public void componentResized(ComponentEvent e) {
adjustTableAutoResizeMode();
}
@Override
public void componentMoved(ComponentEvent e) {
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentHidden(ComponentEvent e) {
}
});
}
private void adjustTableAutoResizeMode() {
int previewTableWidth = scrollPane.getSize().width - FineUIScale.scale(MIN_CELL_WIDTH);
AbstractTableModel tableModel = (AbstractTableModel) dataJTable.getModel();
dataJTable.setAutoResizeMode((tableModel.getColumnCount() - 1) * PREVIEW_TABLE_MIN_COLUMN_WIDTH <= previewTableWidth ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF);
}
private JPanel getNorthPaneComponents() {
// kel:在左上角加一个JLabel用来显示坐标,方便用户查看。
coordinatelabel = new UILabel("0/0,0/0");
coordinatelabel.setHorizontalAlignment(UILabel.CENTER);
// 表结构设置
UIButton columnSetButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Embedded_Table_Design"));
columnSetButton.setMnemonic('C');
columnSetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
final EmbeddedTableModel localDefaultModel = (EmbeddedTableModel) dataJTable.getModel();
final EmbeddedTableDataDefinedPane columnSetPane = new EmbeddedTableDataDefinedPane();
columnSetPane.populate(((EmbeddedTableModel) dataJTable.getModel()).getEditableTableData());
DialogActionAdapter l = new DialogActionAdapter() {
public void doOk() {
localDefaultModel.setEditableTableData(columnSetPane.update());
localDefaultModel.fireTableStructureChanged();
localDefaultModel.fireTableDataChanged();
tableStructureChanged();
selectedChanged();
dataJTable.setAutoResizeMode(localDefaultModel.getColumnCount() * PREVIEW_TABLE_MIN_COLUMN_WIDTH <= PREVIEW_TABLE_WIDTH ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF);
dataJTable.repaint();
}
};
BasicDialog dlg = columnSetPane.showWindow(DesignerContext.getDesignerFrame(), l);
dlg.setAlwaysOnTop(true);
dlg.setVisible(true);
}
});
UIButton columnSetButton = initColumnSetButton();
// DataSourceEditor-Insert_Row
insertRowButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Utils_Insert_Row"));
@ -169,6 +192,35 @@ public class EmbeddedTableDataPane extends AbstractTableDataPane<EmbeddedTableDa
).getComponent();
}
private UIButton initColumnSetButton() {
UIButton columnSetButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tabledata_Embedded_Table_Design"));
columnSetButton.setMnemonic('C');
columnSetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
final EmbeddedTableModel localDefaultModel = (EmbeddedTableModel) dataJTable.getModel();
final EmbeddedTableDataDefinedPane columnSetPane = new EmbeddedTableDataDefinedPane();
columnSetPane.populate(((EmbeddedTableModel) dataJTable.getModel()).getEditableTableData());
DialogActionAdapter l = new DialogActionAdapter() {
public void doOk() {
localDefaultModel.setEditableTableData(columnSetPane.update());
localDefaultModel.fireTableStructureChanged();
localDefaultModel.fireTableDataChanged();
tableStructureChanged();
selectedChanged();
adjustTableAutoResizeMode();
dataJTable.repaint();
}
};
BasicDialog dlg = columnSetPane.showWindow(DesignerContext.getDesignerFrame(), l);
dlg.setAlwaysOnTop(true);
dlg.setVisible(true);
}
});
return columnSetButton;
}
/**
* 更新按钮状态
*/
@ -246,17 +298,24 @@ public class EmbeddedTableDataPane extends AbstractTableDataPane<EmbeddedTableDa
// 行号显示,每次dateJTable的表结构发生变化时都要调用
TableColumn tableColumn = dataJTable.getColumnModel().getColumn(0);
tableColumn.setCellRenderer(new CellRenderer());
tableColumn.setMaxWidth(Math.max(dataJTable.getColumnCount(), MIN_CELL_WIDTH));
tableColumn.setMaxWidth(FineUIScale.scale(Math.max(dataJTable.getColumnCount(), MIN_CELL_WIDTH)));
// 没有列数据的时候, 隐藏行号列
if (dataJTable.getColumnModel().getColumnCount() > 1) {
dataJTable.getTableHeader().setVisible(true);
} else {
dataJTable.getTableHeader().setVisible(false);
}
}
private class DoubleRenderer extends DefaultTableCellRenderer {
private class DoubleRenderer extends FineTableHeaderUI.TableRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setHorizontalAlignment(RIGHT);
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
private class DateRenderer extends DefaultTableCellRenderer {
private class DateRenderer extends FineTableHeaderUI.TableRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Date date2Format = DateUtils.object2Date(value, true);
return super.getTableCellRendererComponent(table, date2Format == null ? StringUtils.EMPTY : DateUtils.DATEFORMAT1.format(date2Format), isSelected, hasFocus, row,

26
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/FileTableDataPane.java

@ -14,6 +14,7 @@ import com.fr.data.impl.ExcelTableData;
import com.fr.data.impl.FileTableData;
import com.fr.data.impl.TextTableData;
import com.fr.data.impl.XMLTableData;
import com.fr.decision.webservice.bean.dataset.FileDataSetBean;
import com.fr.design.actions.UpdateAction;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.data.datapane.preview.PreviewTablePane;
@ -47,6 +48,7 @@ import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.stable.xml.XMLReadable;
import com.fr.stable.xml.XMLableReader;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
import javax.swing.ButtonGroup;
import javax.swing.JOptionPane;
@ -194,16 +196,18 @@ public class FileTableDataPane extends AbstractTableDataPane<FileTableData> {
urlText.setEditable(false);
// 选择按钮
chooseFile = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Selection"));
chooseFile.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Selection"));
chooseFile.addActionListener(chooseFileListener);
// 测试连接按钮
testConnection = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Test_Connection"));
testConnection.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Test_Connection"));
testConnection.setEnabled(false);
testConnection.addActionListener(testConnectionListener);
// 提示信息
tipPanel = column(
cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Type_Parameter_Desc"), FineUIStyle.LABEL_TIP)),
cell(new UILabel("reportlets/excel/FineReport${abc}." + "txt", FineUIStyle.LABEL_TIP)),
cell(new UILabel("http://192.168.100.120:8080/XXServer/Report/excel${abc}.jsp", FineUIStyle.LABEL_TIP))
cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Type_Parameter"), FineUIStyle.LABEL_TIP)),
cell(new UILabel("assets/file_dataset/FineReport${abc}." + "txt", FineUIStyle.LABEL_TIP)),
cell(new UILabel("http://192.168.100.120:8080/webroot/help/excel${abc}.jsp", FineUIStyle.LABEL_TIP))
).getComponent();
return column(
LayoutConstants.VERTICAL_GAP,
@ -233,22 +237,20 @@ public class FileTableDataPane extends AbstractTableDataPane<FileTableData> {
}
params = getEditorPaneParameter();
URLDataSource url = new URLDataSource(urlText.getText().trim(), params);
InputStream in = null;
boolean result = false;
try {
in = url.getSourceStream(params);
String urlText = ParameterHelper.analyze4Templatee(url.getUrl(), params);
FileDataSetBean bean = new FileDataSetBean();
bean.setFilePath(urlText);
result = TableDataRepository.getInstance().testFilePath(bean);
} catch (Throwable e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
if (in == null) {
if (!result) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon"));
} else {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Datasource_Connection_Successfully"));
try {
in.close();
} catch (IOException e) {
in = null;
}
}
}
};
@ -448,7 +450,7 @@ public class FileTableDataPane extends AbstractTableDataPane<FileTableData> {
@Override
public void actionPerformed(ActionEvent e) {
FILEChooserPane fileChooser = FILEChooserPane.getInstance(true, false, new ChooseFileFilter(getFileSuffix()));
FILEChooserPane fileChooser = FILEChooserPane.getFileDataChoosePane(new ChooseFileFilter(getFileSuffix()));
if (fileChooser.showOpenDialog(FileTableDataPane.this) == FILEChooserPane.OK_OPTION) {
final FILE file = fileChooser.getSelectedFILE();
if (file == null) {// 选择的文件不能是 null

12
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/MultiTDTableDataPane.java

@ -102,8 +102,12 @@ public class MultiTDTableDataPane extends AbstractTableDataPane<MultiTDTableData
// 10个正好不会出现滚动条
centerPanel.setLayout(new GridLayout(len < MIN_BAR_NUMBER ? MIN_BAR_NUMBER : len + 1, 1));
centerPanel.add(row(LayoutConstants.HORIZONTAL_GAP,
cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multi_Dataset_Name"))).weight(0.2),
cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multi_Dataset_Conditions"))).weight(0.2),
cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multi_Dataset_Name")))
.with(it -> it.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multi_Dataset_Name")))
.weight(0.2),
cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multi_Dataset_Conditions")))
.with(it -> it.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multi_Dataset_Conditions")))
.weight(0.2),
flex(0.6)
).getComponent());
@ -130,7 +134,7 @@ public class MultiTDTableDataPane extends AbstractTableDataPane<MultiTDTableData
private JPanel initSouthPanel() {
JPanel jpanel = new JPanel();
jpanel.setPreferredSize(new Dimension(-1, 150));
jpanel.setPreferredSize(new Dimension(super.getPreferredSize().width, FineUIScale.scale(150)));
jpanel.setLayout(new BorderLayout());
editorPane = new UITableEditorPane<>(new ParameterTableModel() {
@ -329,7 +333,7 @@ public class MultiTDTableDataPane extends AbstractTableDataPane<MultiTDTableData
).weight(0.2),
//条件公式
row(
cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Conditions_Formula") + "=")).weight(0.15),
cell(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Conditions_Formula") + "=")).with(it -> it.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Conditions_Formula") + "=")).weight(0.15),
row(5, cell(formulaContentTextField).weight(0.95), cell(formulaButton).weight(0.05)).weight(0.85)
).weight(0.77),
flex(0.03)

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

@ -20,6 +20,7 @@ import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane.DoubleClickSelectedNodeOnTreeListener;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.data.datapane.sqlpane.SQLEditPane;
import com.fr.design.data.tabledata.ResponseDataSourceChange;
import com.fr.design.data.tabledata.StoreProcedureWorkerListener;
@ -187,8 +188,11 @@ public class ProcedureDataPane extends AbstractTableDataPane<StoreProcedure> imp
}
private boolean isAutoParameterDatabase() {
ConnectionBean bean = ConnectionRepository.getInstance().getByName(connectionTableProcedurePane.getSelectedDatabaseConnnectonName());
Connection connection = bean == null ? null : bean.getConnection();
String name = connectionTableProcedurePane.getSelectedDatabaseConnnectonName();
if (StringUtils.isEmpty(name)) {
return false;
}
Connection connection = ConnectionInfoBeanHelper.createConnection(ConnectionRepository.getInstance().getByName(name));
return connection != null && ArrayUtils.contains(DRIVERS, connection.getDriver());
}

46
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/TableDataPaneHelper.java

@ -0,0 +1,46 @@
package com.fr.design.data.tabledata.tabledatapane;
import com.fr.base.AbstractTableData;
import com.fr.design.data.tabledata.datacenter.DCTableDataPane;
import com.fr.third.guava.collect.Sets;
import java.util.Set;
/**
* 数据集面板帮助类
*
* @author vito
* @since 11.0
* Created on 2024/9/10
*/
public class TableDataPaneHelper {
/**
* 标记优先使用带名称的构造方法
*/
private final static Set<Class<? extends AbstractTableDataPane<? extends AbstractTableData>>> NAMED_TABLE_DATA_PANE =
Sets.newHashSet(
MultiTDTableDataPane.class,
GlobalMultiTDTableDataPane.class,
TreeTableDataPane.class,
GlobalTreeTableDataPane.class,
DCTableDataPane.class);
/**
* 是否为带名称的数据集面板
*
* @param tableDataPaneClass 数据集面板类
* @return 是否为带名称的数据集面板
*/
public static boolean isNamedTableDataPane(Class<?> tableDataPaneClass) {
return NAMED_TABLE_DATA_PANE.contains(tableDataPaneClass);
}
/**
* 注册需要名称的数据集面板
*
* @param tableDataPaneClass 数据集面板类
*/
public static void registerNamedTableDataPane(Class<? extends AbstractTableDataPane<? extends AbstractTableData>> tableDataPaneClass) {
NAMED_TABLE_DATA_PANE.add(tableDataPaneClass);
}
}

28
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/ServerTableDataWrapper.java

@ -6,6 +6,8 @@ import com.fr.base.svg.SVGLoader;
import com.fr.data.impl.ClassTableData;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.EmbeddedTableData;
import com.fr.data.impl.FileTableData;
import com.fr.data.impl.MultiTDTableData;
import com.fr.data.impl.RecursionTableData;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.design.icon.WarningIcon;
@ -25,13 +27,10 @@ public final class ServerTableDataWrapper extends AbstractTableDataWrapper {
@Override
public Icon getIcon() {
if (tabledata instanceof DBTableData) {
if (StringUtils.isBlank(((DBTableData) tabledata).getQuery())) {
return new LazyIcon("server_database_warning");
}
else {
return new LazyIcon("server_database");
}
} else if (tabledata instanceof ClassTableData) {
return getDBTableDataIcon();
}
if (tabledata instanceof ClassTableData) {
return new LazyIcon("class_table_data");
} else if (tabledata instanceof EmbeddedTableData) {
return new LazyIcon("data_table");
@ -39,10 +38,23 @@ public final class ServerTableDataWrapper extends AbstractTableDataWrapper {
return new LazyIcon("tree");
} else if (tabledata instanceof StoreProcedure) {
return new LazyIcon("store_procedure");
}
} else if (tabledata instanceof FileTableData) {
return new LazyIcon("file");
} else if (tabledata instanceof MultiTDTableData) {
return new LazyIcon("multi");
}
return new LazyIcon("server_database");
}
private Icon getDBTableDataIcon() {
if (StringUtils.isBlank(((DBTableData) tabledata).getQuery())) {
return new LazyIcon("server_database_warning");
}
else {
return new LazyIcon("server_database");
}
}
/**
* 是否异常
* @return

32
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java

@ -15,7 +15,9 @@ import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.datacenters.tabledata.DCTableData;
import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.design.data.datapane.TableDataNameObjectCreator;
import com.fr.design.data.tabledata.datacenter.DatacentersPane;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.design.data.tabledata.datacenter.DCTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.ClassTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.DBTableDataPane;
@ -24,14 +26,12 @@ import com.fr.design.data.tabledata.tabledatapane.EmbeddedTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.FileTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.MultiTDTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.ProcedureDataPane;
import com.fr.design.data.tabledata.tabledatapane.TableDataPaneHelper;
import com.fr.design.data.tabledata.tabledatapane.TreeTableDataPane;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataBeanHelper;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
import javax.swing.Icon;
@ -56,7 +56,7 @@ public abstract class TableDataFactory {
/**
* 有顺序的,用来排序用
*/
private static Map<String, TableDataNameObjectCreator> map = new java.util.LinkedHashMap<>();
private static Map<String, TableDataNameObjectCreator> map = new LinkedHashMap<>();
private static Map<String, TableDataNameObjectCreator> defaultMap = new LinkedHashMap<>();
@ -79,7 +79,7 @@ public abstract class TableDataFactory {
i18nText("Fine-Design_Basic_DS_Datacenters"),
new LazyIcon("datacenter"),
DCTableData.class,
DatacentersPane.class));
DCTableDataPane.class));
map.putAll(defaultMap);
}
@ -129,12 +129,12 @@ public abstract class TableDataFactory {
AbstractTableDataPane datapane = null;
TableDataNameObjectCreator tableDataNameObjectCreator = getTableDataNameObjectCreator(tabledata);
Class<? extends AbstractTableDataPane<?>> creatorClass = (Class<AbstractTableDataPane<?>>) tableDataNameObjectCreator.getUpdatePane();
if (tableDataNameObjectCreator != null && creatorClass != null) {
if (creatorClass != null) {
try {
if (ComparatorUtils.equals(creatorClass, MultiTDTableDataPane.class) || ComparatorUtils.equals(creatorClass, TreeTableDataPane.class)) {
Constructor constructor = creatorClass.getDeclaredConstructor(new Class[]{String.class});
if (TableDataPaneHelper.isNamedTableDataPane(creatorClass)) {
Constructor<? extends AbstractTableDataPane<?>> constructor = creatorClass.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
datapane = (AbstractTableDataPane) constructor.newInstance(name);
datapane = constructor.newInstance(name);
} else {
datapane = creatorClass.newInstance();
}
@ -205,11 +205,7 @@ public abstract class TableDataFactory {
clearAll();
try {
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final List<ConnectionBean> connectionInfoBeans = ConnectionRepository.getInstance().getAll();
final Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : connectionInfoBeans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
Map<String, TableData> tableDataMap = new HashMap<>();
for (ServerDataSetBean bean : beans) {
tableDataMap.put(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
@ -233,11 +229,7 @@ public abstract class TableDataFactory {
Map<String, TableData> tableDataMap = new HashMap<>();
try {
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final List<ConnectionBean> connectionInfoBeans = ConnectionRepository.getInstance().getAll();
final Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : connectionInfoBeans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
for (ServerDataSetBean bean : beans) {
tableDataMap.put(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
}

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

@ -5,6 +5,7 @@ import com.fr.design.gui.iscrollbar.UIScrollBar;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.SwingUtilities;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
@ -111,6 +112,15 @@ public abstract class BasicScrollPane<T> extends BasicBeanPane<T>{
doLayout();
}
/**
* 插入图表后单元格元素使用cardLayout布局,需要滚动效果获取高度在子类中重新计算
*
* @return height
*/
protected int getMaxHeight(){
return getHeight();
}
protected class BarLayout implements LayoutManager {
@Override
@ -135,7 +145,7 @@ public abstract class BasicScrollPane<T> extends BasicBeanPane<T>{
@Override
public void layoutContainer(Container parent) {
if(getHeight() >= leftcontentPane.getPreferredSize().height) {
if(getMaxHeight() >= leftcontentPane.getPreferredSize().height) {
scrollBar.setEnabled(false);
scrollBar.setVisible(false);
} else {
@ -143,7 +153,7 @@ public abstract class BasicScrollPane<T> extends BasicBeanPane<T>{
scrollBar.setEnabled(show);
scrollBar.setVisible(show);
}
maxheight = getHeight() - DET_HEIGHT;
maxheight = getMaxHeight() - DET_HEIGHT;
if ((MAXVALUE - scrollBar.getVisibleAmount()) == 0) {
beginY = 0;
} else {

115
designer-base/src/main/java/com/fr/design/dialog/FineJOptionPane.java

@ -1,5 +1,6 @@
package com.fr.design.dialog;
import com.fine.theme.icon.LazyIcon;
import com.fr.invoke.Reflect;
import com.fr.stable.StringUtils;
@ -31,6 +32,8 @@ public class FineJOptionPane extends JOptionPane {
//选项类型optionType 和 选项字符串数组 一一对应
private final static Map<Integer, String[]> OPTION_MAP = new HashMap<>();
public Icon successMessageIcon;
static {
OPTION_MAP.put(DEFAULT_OPTION, OPTION_DEFAULT);
OPTION_MAP.put(YES_NO_OPTION, OPTION_YES_NO);
@ -42,6 +45,17 @@ public class FineJOptionPane extends JOptionPane {
private final static String CONFIRM_DIALOG_TITLE = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Dialog_Prompt");
private final static String INPUT_DIALOG_TITLE = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips");
public FineJOptionPane(Object message, int messageType, int optionType,
Icon icon, Object[] options, Object initialValue,
boolean successMessage) {
super(message, messageType, optionType, icon, options, initialValue);
if (successMessage) {
successMessageIcon = new LazyIcon("success", 20);
}
}
/**
* 使用默认 标题 消息类型 的消息提示弹出框
* @param parentComponent 父容器
@ -54,6 +68,34 @@ public class FineJOptionPane extends JOptionPane {
INFORMATION_MESSAGE);
}
/**
* 使用 success 图标 默认 标题 消息类型 的消息提示弹出框
* @param parentComponent 父容器
* @param message 具体的提示消息
* @throws HeadlessException
*/
public static void showSuccessMessageDialog(Component parentComponent, Object message)
throws HeadlessException {
showMessageDialog(parentComponent, message, MESSAGE_DIALOG_TITLE, INFORMATION_MESSAGE, true);
}
/**
* 使用默认 标题 消息类型 的消息提示弹出框
* @param parentComponent 父容器
* @param message 具体的提示消息
* @param title 标题
* @param messageType 消息类型
* @param isSuccessMessage 是否使用 success 图标如果不是则根据消息类型生成图标
* @throws HeadlessException
*/
public static void showMessageDialog(Component parentComponent, Object message,
String title, int messageType, boolean isSuccessMessage)
throws HeadlessException {
showOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
messageType, null, OPTION_DEFAULT, null, isSuccessMessage);
}
/**
* 使用默认 Icon 的消息提示弹出框
* @param parentComponent 父容器
@ -101,7 +143,7 @@ public class FineJOptionPane extends JOptionPane {
Icon icon, Object[] options, Object initialValue)
throws HeadlessException {
showOptionDialog(parentComponent, message, title, optionType,
messageType, icon, options, initialValue);
messageType, icon, options, initialValue, false);
}
/**
@ -182,7 +224,7 @@ public class FineJOptionPane extends JOptionPane {
Object[] options, Object initialValue)
throws HeadlessException {
return showOptionDialog(parentComponent, message, title, optionType,
messageType, icon, options, initialValue);
messageType, icon, options, initialValue, false);
}
/**
@ -199,7 +241,7 @@ public class FineJOptionPane extends JOptionPane {
String title, Icon icon, Object initialValue, ActionListener listener)
throws HeadlessException {
int val = showOptionDialog(parentComponent, message, title, JOptionPane.DEFAULT_OPTION,
FineJOptionPane.WARNING_MESSAGE, icon, OPTION_OK_CANCEL, initialValue);
FineJOptionPane.WARNING_MESSAGE, icon, OPTION_OK_CANCEL, initialValue, false);
if (val == JOptionPane.OK_OPTION && listener!=null) {
listener.actionPerformed(null);
}
@ -315,4 +357,71 @@ public class FineJOptionPane extends JOptionPane {
return value;
}
/**
* 根据 message type 生成 icon
* @return
*/
public Icon getIcon() {
if (successMessageIcon != null) {
return successMessageIcon;
}
switch (messageType) {
case ERROR_MESSAGE:
return new LazyIcon("error", 20);
case WARNING_MESSAGE:
return new LazyIcon("warning", 20);
case INFORMATION_MESSAGE:
return new LazyIcon("information", 20);
case QUESTION_MESSAGE:
return new LazyIcon("question", 20);
default:
return icon;
}
}
/**
* 自定义的确认弹出框
* @param parentComponent 父容器
* @param message 具体的提示消息
* @param title 标题
* @param optionType 选项类型
* @param messageType 消息类型
* @param icon 图标
* @param options 选项
* @param initialValue 初始选项
* @param isSuccessMessage 是否使用 success 图标
*/
public static int showOptionDialog(Component parentComponent, Object message,
String title, int optionType, int messageType,
Icon icon, Object[] options, Object initialValue,
boolean isSuccessMessage) {
FineJOptionPane pane = new FineJOptionPane(message, messageType, optionType, icon, options, initialValue, isSuccessMessage);
pane.setInitialValue(initialValue);
pane.setComponentOrientation(((parentComponent == null) ? getRootFrame() : parentComponent).getComponentOrientation());
JDialog dialog = pane.createDialog(parentComponent, title);
pane.selectInitialValue();
dialog.show();
dialog.dispose();
Object selectedValue = pane.getValue();
if (selectedValue == null){
return CLOSED_OPTION;
}
if (options == null) {
if (selectedValue instanceof Integer) {
return ((Integer) selectedValue).intValue();
}
return CLOSED_OPTION;
}
for(int counter = 0, maxCounter = options.length;
counter < maxCounter; counter++) {
if (options[counter].equals(selectedValue)) {
return counter;
}
}
return CLOSED_OPTION;
}
}

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

@ -5,6 +5,7 @@ import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
@ -36,6 +37,7 @@ public abstract class TipDialog extends JDialog implements ActionListener {
iconPane.setPreferredSize(new Dimension(50, 50));
JPanel tipPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
UILabel tipLabel = new UILabel(tip);
UIComponentUtils.setLineWrap(tipLabel);
tipPane.add(tipLabel);
northPane.add(iconPane, BorderLayout.WEST);
northPane.add(tipPane, BorderLayout.CENTER);

39
designer-base/src/main/java/com/fr/design/dialog/UIDetailErrorLinkDialog.java

@ -1,5 +1,9 @@
package com.fr.design.dialog;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIStyle;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.GraphHelper;
import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.gui.ibutton.UIButton;
@ -7,6 +11,7 @@ import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.IOUtils;
@ -30,6 +35,11 @@ import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.fix;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* 带链接的错误详情弹窗
*
@ -40,13 +50,13 @@ import javax.swing.SwingUtilities;
public class UIDetailErrorLinkDialog extends UIDialog {
private static final Color LINK_COLOR = new Color(51, 152, 253);
private static final int GAP_5 = 5;
private static final int GAP_8 = 8;
private static final int GAP_10 = 10;
private static final String TAG_A_START = "<a>";
private static final String TAG_A_END = "</a>";
private static final double SCALE = 1.2;
private final Dimension dimension = new Dimension(300, 180);
private final Dimension dimension = new Dimension(360, 200);
public static Builder newBuilder() {
return new Builder();
@ -65,15 +75,12 @@ public class UIDetailErrorLinkDialog extends UIDialog {
private void init(Builder builder) {
this.setTitle(builder.title);
// 顶部 图标和提示
UILabel errorIcon = new UILabel(IOUtils.readIcon("com/fr/design/images/lookandfeel/Information_Icon_Error_32x32.png"));
UILabel errorIcon = new UILabel(new LazyIcon("error", 20));
UILabel errorInfo= new UILabel(builder.reason);
JPanel topPane = new JPanel(new FlowLayout(FlowLayout.LEFT, GAP_10, GAP_5));
topPane.add(errorIcon);
topPane.add(errorInfo);
FineUIStyle.setStyle(errorInfo, FineUIStyle.LABEL_TIP_WINDOW_TITLE);
// 中部 详细内容
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setBorder(BorderFactory.createEmptyBorder(0, GAP_5,0,0));
JPanel contentPane = new JPanel(FRGUIPaneFactory.createScaledBorderLayout(GAP_10, GAP_10));
UILabel errorCodeLabel = new UILabel(Toolkit.i18nText("Fine_Design_Basic_Error_Code", builder.errorCode));
UILabel link = new UILabel(Toolkit.i18nText("Fine_Design_Basic_Show_Error_Stack"));
link.setForeground(LINK_COLOR);
@ -92,13 +99,19 @@ public class UIDetailErrorLinkDialog extends UIDialog {
contentPane.add(link, BorderLayout.SOUTH);
// 确定 + 取消
JPanel actionPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, GAP_10, GAP_5));
actionPane.add(createButton(Toolkit.i18nText("Fine-Design_Report_OK")));
JPanel actionPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, GAP_8, GAP_10));
UIButton okButton = createButton(Toolkit.i18nText("Fine-Design_Report_OK"));
FineUIStyle.setStyle(okButton, FineUIStyle.STYLE_PRIMARY);
actionPane.add(okButton);
actionPane.add(createButton(Toolkit.i18nText("Fine-Design_Basic_Cancel")));
this.getContentPane().add(topPane, BorderLayout.NORTH);
this.getContentPane().add(contentPane, BorderLayout.CENTER);
this.getContentPane().add(column(10,
row(10, cell(errorIcon), cell(errorInfo)),
row(10, fix(20), cell(contentPane))
).with(it -> it.setBorder(new ScaledEmptyBorder(GAP_10, GAP_10, GAP_10, GAP_10))).getComponent());
this.getContentPane().add(actionPane, BorderLayout.SOUTH);
this.setSize(dimension);
this.setSize(FineUIScale.scale(dimension));
this.setResizable(false);
this.setModal(true);
GUICoreUtils.centerWindow(this);

9
designer-base/src/main/java/com/fr/design/editlock/EditLockUtils.java

@ -1,13 +1,10 @@
package com.fr.design.editlock;
import com.fr.base.svg.IconUtils;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.svg.SVGLoader;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.IOUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.lock.editlock.EditLockOperator;
import com.fr.report.LockItem;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
@ -30,7 +27,7 @@ public class EditLockUtils {
/**
* 数据连接锁定标志
*/
public static final Icon CONNECTION_LOCKED_ICON = IconUtils.readIcon("/com/fr/design/images/m_web/connection_locked");
public static final Icon CONNECTION_LOCKED_ICON = new LazyIcon("connection_locked");
/**
* 小锁图片
@ -40,7 +37,7 @@ public class EditLockUtils {
/**
* 提示弹窗中的提示标志
*/
public static final Icon TOOLTIPS_ICON = IOUtils.readIcon("/com/fr/design/images/m_web/warningIcon.png");
public static final Icon TOOLTIPS_ICON = new LazyIcon("warning");
/**
* 数据连接锁定中

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

@ -58,7 +58,7 @@ public class ValueEditorPane extends BasicPane implements UIObserver, GlobalName
}
public ValueEditorPane(Editor[] cards, String popupName, String textEditorValue) {
initComponents(cards, popupName, textEditorValue, 200);
initComponents(cards, popupName, textEditorValue, FineUIScale.scale(200));
}
public ValueEditorPane(Editor[] cards, String popupName, String textEditorValue, int centerPaneWidth) {

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

@ -1,5 +1,6 @@
package com.fr.design.editor.editor;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.data.DesignTableDataManager;
import com.fr.data.SimpleDSColumn;
import com.fr.design.data.datapane.TableDataComboBox;
@ -18,6 +19,7 @@ import java.util.regex.Pattern;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.fix;
/**
* 选择数据列编辑器
@ -54,7 +56,7 @@ public class ColumnSelectedEditor extends Editor<SimpleDSColumn> implements Prep
}
});
columnNameComboBox = new UIComboBox();
this.add(row(10, cell(tableDataComboBox), cell(columnNameComboBox)).getComponent());
this.add(row(cell(tableDataComboBox).weight(1), fix(LayoutConstants.HGAP_LARGE),cell(columnNameComboBox).weight(1)).getComponent());
}
@Override

5
designer-base/src/main/java/com/fr/design/editor/editor/CursorEditor.java

@ -28,6 +28,11 @@ public class CursorEditor extends Editor<CursorEditor> {
return "type_cursor";
}
@Override
public String getIconId() {
return "type_cursor";
}
@Override
public boolean accept(Object object) {
return object instanceof CursorEditor ;

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

@ -4,17 +4,20 @@ import com.fanruan.workplace.http.HttpConstants;
import com.fanruan.workplace.http.HttpServiceMap;
import com.fanruan.workplace.http.RepositoryManager;
import com.fanruan.workplace.http.info.Stub;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import com.fr.workspace.server.repository.compatible.register.CompatibleRegister;
import com.fr.workspace.server.repository.connect.FineWorkspaceHttpClient;
import com.fanruan.workplace.network.RemoteNetworkRepository;
import com.fr.decision.webservice.bean.authentication.LoginRequestInfoBean;
import com.fr.decision.webservice.bean.authentication.LoginResponseInfoBean;
import com.fr.stable.StringUtils;
import com.fr.workspace.connect.WorkspaceClient;
import com.fr.workspace.connect.WorkspaceConnection;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.connect.WorkspaceConnector;
import com.fr.workspace.engine.exception.RemoteDesignConnectionException;
import com.fr.workspace.engine.exception.RemoteDesignNoAuthException;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import com.fr.workspace.server.repository.authority.RemoteAuthoritySource;
import com.fr.workspace.server.repository.compatible.register.CompatibleRegister;
import com.fr.workspace.server.repository.connect.FineWorkspaceHttpClient;
import java.net.InetAddress;
import java.util.Map;
@ -41,37 +44,20 @@ public class HttpWorkspaceConnector implements WorkspaceConnector {
@Override
public boolean testConnection(WorkspaceConnectionInfo connectionInfo) throws Exception {
FineWorkspaceHttpClient client = FineWorkspaceHttpClient.create("Http-Client", connectionInfo);
LoginResponseInfoBean bean;
try {
bean = RemoteAuthorityRepository.getInstance().login(createLoginBean(connectionInfo));
return testConnect(client, connectionInfo);
} finally {
client.closePool();
}
return StringUtils.isNotEmpty(bean.getAccessToken());
}
@Override
public WorkspaceClient connect(WorkspaceConnectionInfo connectionInfo) throws Exception {
FineWorkspaceHttpClient client = FineWorkspaceHttpClient.create("Http-Client", connectionInfo);
try {
for (Map.Entry<Class, Stub<?>> entry : HttpServiceMap.getInstance().entrySet()) {
Stub<?> stub = entry.getValue();
stub.clearProxy();
if (testConnect(client, connectionInfo)) {
client.connect();
}
LoginResponseInfoBean bean = RemoteAuthorityRepository.getInstance().login(createLoginBean(connectionInfo));
// 服务器如果没返回token,肯定是出问题了,直接抛出异常
if (StringUtils.isEmpty(bean.getAccessToken())) {
throw new RuntimeException("Empty token, try connect again and check server");
}
FineLoggerFactory.getLogger().info("[connector] infos:{}", bean.getAccessToken());
WorkspaceConnection connection = new WorkspaceConnection(
UUID.randomUUID().toString(),
connectionInfo.getUserName(),
HttpConstants.AUTHORIZATION_PREFIX + bean.getAccessToken(),
InetAddress.getLocalHost().getHostAddress());
client.updateConnection(connection);
client.startHeartBeat();
} catch (Exception e) {
client.closePool();
throw e;
@ -81,12 +67,38 @@ public class HttpWorkspaceConnector implements WorkspaceConnector {
return client;
}
private LoginRequestInfoBean createLoginBean(WorkspaceConnectionInfo connectionInfo) {
private boolean testConnect(FineWorkspaceHttpClient client, WorkspaceConnectionInfo connectionInfo) throws Exception {
for (Map.Entry<Class, Stub<?>> entry : HttpServiceMap.getInstance().entrySet()) {
Stub<?> stub = entry.getValue();
stub.clearProxy();
}
Map<String, Object> loginConfigMap = RemoteAuthorityRepository.getInstance().getLoginConfigMap();
long timeout = Long.parseLong(String.valueOf(loginConfigMap.get(RemoteAuthoritySource.LOGIN_TIMEOUT)));
boolean rememberLogin = (boolean) loginConfigMap.get(RemoteAuthoritySource.SUPPORT_REMEMBER_LOGIN);
LoginResponseInfoBean bean = RemoteAuthorityRepository.getInstance().login(createLoginBean(connectionInfo, rememberLogin));
WorkspaceConnection connection = new WorkspaceConnection(
UUID.randomUUID().toString(),
connectionInfo.getUserName(),
HttpConstants.AUTHORIZATION_PREFIX + bean.getAccessToken(),
InetAddress.getLocalHost().getHostAddress());
client.updateConnection(connection);
client.setRememberLogin(rememberLogin);
client.setTimeout(timeout);
try {
return RemoteNetworkRepository.getInstance().testConnect();
} catch (RemoteDesignNoAuthException e) {
throw e;
} catch (Exception e) {
throw new RemoteDesignConnectionException(e, StringUtils.EMPTY);
}
}
private LoginRequestInfoBean createLoginBean(WorkspaceConnectionInfo connectionInfo, boolean rememberLogin) {
LoginRequestInfoBean bean = new LoginRequestInfoBean();
bean.setUsername(connectionInfo.getUserName());
bean.setPassword(connectionInfo.getPassword());
bean.setEncrypted(false);
bean.setValidity(-2);
bean.setValidity(rememberLogin ? -2 : -1);
return bean;
}
}

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

@ -13,6 +13,7 @@ import com.fr.workspace.connect.WorkspaceConnection;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.server.authority.decision.DecisionOperator;
import com.fr.workspace.pool.WorkObjectPool;
import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import javax.swing.SwingWorker;
@ -80,7 +81,7 @@ public class RemoteWorkspace implements Workspace {
if (isRoot == null) {
synchronized (this) {
if (isRoot == null) {
isRoot = RemoteAuthorityRepository.getInstance().isRoot(getConnection().getUserName());
isRoot = WorkplaceConstants.isRoot();
}
}
}

42
designer-base/src/main/java/com/fr/design/extra/LoginDialog.java

@ -1,42 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.StableUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by vito on 2017/5/5.
*/
public class LoginDialog extends UIDialog {
private static final Dimension DEFAULT_SHOP = new Dimension(401, 301);
public LoginDialog(Frame frame, Component pane) {
super(frame);
init(pane);
}
public LoginDialog(Dialog dialog, Component pane) {
super(dialog);
init(pane);
}
private void init(Component pane) {
if (StableUtils.getMajorJavaVersion() >= 8) {
setUndecorated(true);
}
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(DEFAULT_SHOP);
GUICoreUtils.centerWindow(this);
setResizable(false);
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

200
designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java

@ -1,200 +0,0 @@
package com.fr.design.extra;
import com.fanruan.carina.Carina;
import com.fanruan.cloud.FanruanCloud;
import com.fanruan.config.bbs.FineBBSConfigProvider;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.login.service.DesignerLoginClient;
import com.fr.design.login.service.DesignerLoginResult;
import com.fr.general.CloudCenter;
import com.fr.general.http.HttpClient;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javafx.concurrent.Task;
import javafx.scene.web.WebEngine;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author vito
*/
public class LoginWebBridge {
//最低消息的条数
private static final int MIN_MESSAGE_COUNT = 0;
//网络连接失败
private static final String NET_FAILED = "-4";
//用户名,密码为空
private static final String LOGIN_INFO_EMPTY = "-5";
private static final Color LOGIN_BACKGROUND = new Color(184, 220, 242);
private static LoginWebBridge helper;
//消息条数
private int messageCount;
private UIDialog uiDialog;
private UIDialog qqDialog;
private UILabel uiLabel;
private WebEngine webEngine;
private LoginWebBridge() {
}
public static LoginWebBridge getHelper() {
if (helper != null) {
return helper;
}
synchronized (LoginWebBridge.class) {
if (helper == null) {
helper = new LoginWebBridge();
}
return helper;
}
}
public static LoginWebBridge getHelper(WebEngine webEngine) {
getHelper();
helper.setWebEngine(webEngine);
return helper;
}
public void setWebEngine(WebEngine webEngine) {
this.webEngine = webEngine;
}
public int getMessageCount() {
return messageCount;
}
/**
* 设置获取的消息长度并设置显示
*
* @param count
*/
public void setMessageCount(int count) {
if (count == MIN_MESSAGE_COUNT) {
Carina.config(FineBBSConfigProvider.class).setBbsUsername(DesignerEnvManager.getEnvManager().getDesignerLoginUsername());
return;
}
this.messageCount = count;
StringBuilder sb = new StringBuilder();
sb.append(StringUtils.BLANK).append(DesignerEnvManager.getEnvManager().getDesignerLoginUsername())
.append("(").append(this.messageCount)
.append(")").append(StringUtils.BLANK);
Carina.config(FineBBSConfigProvider.class).setBbsUsername(sb.toString());
}
public void setQQDialog(UIDialog qqDialog) {
closeQQWindow();
this.qqDialog = qqDialog;
}
public void setDialogHandle(UIDialog uiDialog) {
closeWindow();
this.uiDialog = uiDialog;
}
public void setUILabel(UILabel uiLabel) {
this.uiLabel = uiLabel;
}
/**
* 测试论坛网络连接
*
* @return
*/
private boolean testConnection() {
HttpClient client = new HttpClient(CloudCenter.getInstance().acquireUrlByKind("bbs.test"));
return client.isServerAlive();
}
/**
* 注册页面
*/
public void registerHref() {
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 忘记密码
*/
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @return 登录信息标志
*/
public void defaultLogin(String username, String password, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new PluginLoginExecutor(username, password));
ExecutorService es = Executors.newSingleThreadExecutor(new NamedThreadFactory("bbsDefaultLogin"));
es.submit(task);
es.shutdown();
}
/**
* 登录操作
*
* @param userInfo 登录信息
* @param password 密码
* @return 登录信息标志
*/
public String login(String userInfo, String password) {
DesignerLoginClient client = new DesignerLoginClient();
DesignerLoginResult result = client.login(userInfo, password);
int uid = result.getUid();
if (uid > 0) {
closeWindow();
}
return String.valueOf(uid);
}
/**
* 关闭窗口
*/
public void closeWindow() {
if (uiDialog != null) {
uiDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
uiDialog.setVisible(false);
}
}
/**
* 关闭QQ授权窗口
*/
public void closeQQWindow() {
if (qqDialog != null) {
qqDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
qqDialog.setVisible(false);
}
}
public void openUrlAtLocalWebBrowser(WebEngine eng, String url) {
// do nothing
}
}

54
designer-base/src/main/java/com/fr/design/extra/LoginWebPane.java

@ -1,54 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.FineJOptionPane;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import javax.swing.*;
/**
* Created by zhaohehe on 16/7/26.
*/
public class LoginWebPane extends JFXPanel {
public LoginWebPane(final String installHome) {
Platform.setImplicitExit(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
BorderPane root = new BorderPane();
Scene scene = new Scene(root);
LoginWebPane.this.setScene(scene);
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.load("file:///" + installHome + "/scripts/login.html");
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
showAlert(event.getData());
}
});
JSObject obj = (JSObject) webEngine.executeScript("window");
obj.setMember("LoginHelper", LoginWebBridge.getHelper(webEngine));
webView.setContextMenuEnabled(false);//屏蔽右键
root.setCenter(webView);
}
});
}
private void showAlert(final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(LoginWebPane.this, message);
}
});
}
}

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

@ -30,13 +30,11 @@ import com.fr.plugin.view.PluginView;
import com.fr.plugin.xml.PluginElementName;
import com.fr.plugin.xml.PluginXmlElement;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.JSArray;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.io.File;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;

601
designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java

@ -1,601 +0,0 @@
package com.fr.design.extra;
import com.fanruan.carina.Carina;
import com.fanruan.cloud.FanruanCloud;
import com.fanruan.config.bbs.FineBBSConfigProvider;
import com.fr.config.MarketConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.RestartHelper;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.exe.GetInstalledPluginsExecutor;
import com.fr.design.extra.exe.GetPluginCategoriesExecutor;
import com.fr.design.extra.exe.GetPluginFromStoreExecutor;
import com.fr.design.extra.exe.GetPluginPrefixExecutor;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.extra.exe.ReadUpdateOnlineExecutor;
import com.fr.design.extra.exe.SearchOnlineExecutor;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.locale.impl.BbsSpaceMark;
import com.fr.design.login.DesignerLoginSource;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.utils.concurrent.ThreadFactoryBuilder;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import javafx.concurrent.Task;
import javafx.scene.web.WebEngine;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 开放给Web组件的接口,用于安装,卸载,更新以及更改插件可用状态
*/
public class PluginWebBridge {
private static final String THREAD_NAME_TEMPLATE = "pluginbridge-thread-%s";
private static final String ACTION = "action";
private static final String KEYWORD = "keyword";
private static final String PLUGIN_INFO = "pluginInfo";
private static final int COREPOOLSIZE = 3;
private static final int MAXPOOLSIZE = 5;
private static PluginWebBridge helper;
private UIDialog uiDialog;
private ACTIONS actions;
private Map<String, Object> config;
private WebEngine webEngine;
private ExecutorService threadPoolExecutor = new ThreadPoolExecutor(COREPOOLSIZE, MAXPOOLSIZE,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(COREPOOLSIZE),
new ThreadFactoryBuilder().setNameFormat(THREAD_NAME_TEMPLATE).build());
private PluginWebBridge() {
}
public static PluginWebBridge getHelper() {
if (helper != null) {
return helper;
}
synchronized (PluginWebBridge.class) {
if (helper == null) {
helper = new PluginWebBridge();
}
return helper;
}
}
public static PluginWebBridge getHelper(WebEngine webEngine) {
getHelper();
helper.setEngine(webEngine);
return helper;
}
/**
* 获取打开动作配置
*
* @return 配置信息
*/
public String getRunConfig() {
if (actions != null) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put(ACTION, actions.getContext());
Set<String> keySet = config.keySet();
for (String key : keySet) {
jsonObject.put(key, config.get(key).toString());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return jsonObject.toString();
}
return StringUtils.EMPTY;
}
/**
* 配置打开动作
*
* @param action 动作
* @param config 参数
*/
public void setRunConfig(ACTIONS action, Map<String, Object> config) {
this.actions = action;
this.config = config;
}
/**
* 清楚打开动作
*/
public void clearRunConfig() {
this.actions = null;
this.config = null;
}
/**
* 打开时搜索
*
* @param keyword 关键词
*/
public void openWithSearch(String keyword) {
HashMap<String, Object> map = new HashMap<String, Object>(2);
map.put(KEYWORD, keyword);
setRunConfig(ACTIONS.SEARCH, map);
}
/**
* 根据插件信息跳转到应用中心
*
* @param keyword
* @param pluginInfo
*/
public void showResultInStore(String keyword, String pluginInfo) {
HashMap<String, Object> map = new HashMap<>();
map.put(KEYWORD, keyword);
map.put(PLUGIN_INFO, pluginInfo);
setRunConfig(ACTIONS.SHOW_RESULT, map);
}
public void setEngine(WebEngine webEngine) {
this.webEngine = webEngine;
}
public void setDialogHandle(UIDialog uiDialog) {
closeWindow();
this.uiDialog = uiDialog;
}
/**
* 从插件服务器上安装插件
*
* @param pluginInfo 插件的ID
* @param callback 回调函数
*/
public void installPluginOnline(final String pluginInfo, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行安装
*
* @param filePath 插件包的路径
*/
public void installPluginFromDisk(final String filePath, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
File file = new File(filePath);
PluginOperateUtils.installPluginFromDisk(file, jsCallback);
}
/**
* 卸载当前选中的插件
*
* @param pluginInfo 插件信息
*/
public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
}
/**
* 从插件服务器上更新选中的插件
*
* @param pluginIDs 插件集合
*/
public void updatePluginOnline(JSObject pluginIDs, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
String[] pluginInfos = jsObjectToStringArray(pluginIDs);
List<PluginMarker> pluginMarkerList = new ArrayList<PluginMarker>();
for (int i = 0; i < pluginInfos.length; i++) {
pluginMarkerList.add(PluginUtils.createPluginMarker(pluginInfos[i]));
}
PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行插件升级
*
* @param filePath 插件包的路径
*/
public void updatePluginFromDisk(String filePath, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
File file = new File(filePath);
PluginOperateUtils.updatePluginFromDisk(file, jsCallback);
}
/**
* 修改选中的插件的活跃状态
*
* @param pluginID 插件ID
*/
public void setPluginActive(String pluginID, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.setPluginActive(pluginID, jsCallback);
}
/**
* 已安装插件检查更新
*/
public void readUpdateOnline(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new ReadUpdateOnlineExecutor());
threadPoolExecutor.submit(task);
}
/**
* 选择文件对话框
*
* @return 选择的文件的路径
*/
public String showFileChooser() {
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param filter 文件的后缀
* @return 选择的文件的路径
* 这里换用JFileChooser会卡死,不知道为什么
*/
public String showFileChooserWithFilter(String des, String filter) {
FileChooser fileChooser = new FileChooser();
if (StringUtils.isNotEmpty(filter)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(des, filter));
}
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile == null) {
return null;
}
return selectedFile.getAbsolutePath();
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param args 文件的后缀
* @return 选择的文件的路径
*/
public String showFileChooserWithFilters(String des, JSObject args) {
FileChooser fileChooser = new FileChooser();
String[] filters = jsObjectToStringArray(args);
if (ArrayUtils.isNotEmpty(filters)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(des, filters));
}
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile == null) {
return null;
}
return selectedFile.getAbsolutePath();
}
/**
* 获取已经安装的插件的数组
*
* @return 已安装的插件组成的数组
*/
public void getInstalledPlugins(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetInstalledPluginsExecutor());
threadPoolExecutor.submit(task);
}
private String[] jsObjectToStringArray(JSObject obj) {
if (obj == null) {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
int len = (int) obj.getMember("length");
List<String> list = new ArrayList<>();
for (int i = 0; i < len; i++) {
list.add(obj.getSlot(i).toString());
}
return list.toArray(new String[len]);
}
/**
* 搜索在线插件
*
* @param keyword 关键字
*/
public void searchPlugin(String keyword, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new SearchOnlineExecutor(keyword));
threadPoolExecutor.submit(task);
}
/**
* 根据条件获取在线插件的
*
* @param category 分类
* @param seller 卖家性质
* @param fee 收费类型
* @param callback 回调函数
*/
public void getPluginFromStore(String category, String seller, String fee, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginFromStoreExecutor(category, seller, fee, ""));
threadPoolExecutor.submit(task);
}
/**
* 根据条件获取在线插件
*
* @param info 插件信息
* @param callback 回调函数
*/
public void getPluginFromStoreNew(String info, final JSObject callback) {
try {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginFromStoreExecutor(new JSONObject(info)));
threadPoolExecutor.submit(task);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
public void getPluginPrefix(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginPrefixExecutor());
threadPoolExecutor.submit(task);
}
/**
* 在线获取插件分类
*
* @param callback 回调函数
*/
public void getPluginCategories(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginCategoriesExecutor());
threadPoolExecutor.submit(task);
}
/**
* 展示一个重启的对话框(少用,莫名其妙会有bug)
*
* @param message 展示的消息
*/
public void showRestartMessage(String message) {
int rv = JOptionPane.showOptionDialog(
null,
message,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Restart_Designer"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Restart_Designer_Later")},
null
);
if (rv == JOptionPane.OK_OPTION) {
RestartHelper.restart();
}
}
/**
* 关闭窗口
*/
public void closeWindow() {
if (uiDialog != null) {
uiDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
uiDialog.setVisible(false);
}
if (uiDialog == DesignerPluginContext.getPluginDialog()) {
DesignerPluginContext.setPluginDialog(null);
}
}
/**
* 窗口是否无装饰(判断是否使用系统标题栏)
*/
public boolean isCustomTitleBar() {
if (uiDialog != null) {
return uiDialog.isUndecorated();
}
return false;
}
/**
* 获取系统登录的用户名
*
* @param callback
*/
public String getLoginInfo(final JSObject callback) {
registerLoginInfo(callback);
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
/**
* 系统登录注册
*
* @param callback
*/
public void registerLoginInfo(final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.getLoginInfo(jsCallback);
}
/**
* 打开论坛消息界面
*/
public void getPriviteMessage() {
try {
LocaleMark<String> spaceMark = LocaleCenter.getMark(BbsSpaceMark.class);
Desktop.getDesktop().browse(new URI(spaceMark.getValue()));
} catch (Exception exp) {
FineLoggerFactory.getLogger().info(exp.getMessage());
}
}
/**
* 打开登录页面
*/
public void loginContent() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
UserLoginContext.fireLoginContextListener(DesignerLoginSource.NORMAL);
}
});
}
/**
* 在本地浏览器里打开url
* tips:重载的时候,需要给js调用的方法需要放在前面,否则可能不会被调用(此乃坑)
* 所以最好的是不要重载在js可以访问的接口文件中
*
* @param url 要打开的地址
*/
public void openShopUrlAtWebBrowser(String url) {
openUrlAtLocalWebBrowser(webEngine, url);
}
/**
* 在本地浏览器里打开url
*
* @param eng web引擎
* @param url 要打开的地址
*/
public void openUrlAtLocalWebBrowser(WebEngine eng, String url) {
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (NullPointerException e) {
//此为uri为空时抛出异常
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} catch (IOException e) {
//此为无法获取系统默认浏览器
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
/**
* 注册页面
*/
public void registerHref() {
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/*-------------------------------登录部分的处理----------------------------------*/
/**
* 忘记密码
*/
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @return 登录信息标志
*/
public void defaultLogin(String username, String password, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new PluginLoginExecutor(username, password));
threadPoolExecutor.submit(task);
}
/**
* 通过QQ登录后通知登录
*/
public void ucsynLogin(long uid, String username, String password, final JSONObject callback) {
}
/**
* 清除用户信息
*/
public void clearUserInfo() {
Carina.config(FineBBSConfigProvider.class).setBbsUsername(StringUtils.EMPTY);
}
public void getPackInfo(final JSObject callback){
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
jsCallback.execute(StringUtils.EMPTY);
}
/**
* 初始化设计器部分
*/
public void initExtraDiff(final JSObject callback) {
//todo 初始化设计器其他部分
}
/**
* 国际化(用来做兼容暂时不删)
*/
public String parseI18(final String key) {
return com.fr.design.i18n.Toolkit.i18nText(key);
}
/**
* 是否是在设计器中操作
*/
public boolean isDesigner() {
return true;
}
/**
* 动作枚举
*/
public enum ACTIONS {
SEARCH("search"), SHOW_RESULT("showResult");
private String context;
ACTIONS(String context) {
this.context = context;
}
public String getContext() {
return context;
}
}
}

112
designer-base/src/main/java/com/fr/design/extra/PluginWebPane.java

@ -1,112 +0,0 @@
package com.fr.design.extra;
import com.fr.base.TemplateUtils;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.general.GeneralContext;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* Created by richie on 16/3/19.
*/
public class PluginWebPane extends JFXPanel {
private static final String RESOURCE_URL = "resourceURL";
private static final String LANGUAGE = "language";
private static final String URL_PLUS = "+";
private static final String URL_SPACING = "%20";
private static final String URL_PREFIX = "file:///";
private WebEngine webEngine;
public PluginWebPane(final String installHome, final String mainJs) {
Platform.setImplicitExit(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
BorderPane root = new BorderPane();
Scene scene = new Scene(root);
PluginWebPane.this.setScene(scene);
WebView webView = new WebView();
webEngine = webView.getEngine();
try{
String htmlString = getRenderedHtml(installHome, mainJs);
webEngine.loadContent(htmlString);
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
showAlert(event.getData());
}
});
JSObject obj = (JSObject) webEngine.executeScript("window");
obj.setMember("PluginHelper", PluginWebBridge.getHelper(webEngine));
webView.setContextMenuEnabled(false);//屏蔽右键
root.setCenter(webView);
}catch (Exception e){
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
});
}
private String getRenderedHtml(String installHome, String mainJs) throws IOException {
InputStream inp = IOUtils.readResource(StableUtils.pathJoin(installHome, mainJs));
if (inp == null) {
throw new IOException("Not found template: " + mainJs);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inp, StableUtils.RESOURCE_ENCODER));
BufferedReader read = new BufferedReader(reader);
StringBuffer sb = new StringBuffer();
String line;
Map<String, Object> map4Tpl = new HashMap<String, Object>();
//URL中关于空格的编码与空格所在位置相关:空格被编码成+的情况只能在查询字符串部分出现,而被编码成%20则可以出现在路径和查询字符串中
//URLEncoder会将空格转成+,这边需要+转成%20
map4Tpl.put(RESOURCE_URL, URL_PREFIX + URLEncoder.encode(installHome, EncodeConstants.ENCODING_UTF_8).replace(URL_PLUS, URL_SPACING));
map4Tpl.put(LANGUAGE, GeneralContext.getLocale().toString());
while ((line = read.readLine()) != null) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append(line);
}
String htmlString = StringUtils.EMPTY;
try{
htmlString = TemplateUtils.renderParameter4Tpl(sb.toString(), map4Tpl);
}catch (Exception e){
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
reader.close();
inp.close();
return htmlString;
}
private void showAlert(final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(PluginWebPane.this, message);
}
});
}
}

32
designer-base/src/main/java/com/fr/design/extra/QQLoginDialog.java

@ -1,32 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by zhaohehe on 16/7/28.
*/
public class QQLoginDialog extends UIDialog {
private static final Dimension DEFAULT_SHOP = new Dimension(700, 500);
public QQLoginDialog(Frame frame, Component pane) {
super(frame);
setUndecorated(true);
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(DEFAULT_SHOP);
GUICoreUtils.centerWindow(this);
setResizable(false);
setTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager"));
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

46
designer-base/src/main/java/com/fr/design/extra/ShopDialog.java

@ -1,46 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.jdk.JdkVersion;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.StableUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by vito on 16/4/18.
*/
public class ShopDialog extends UIDialog {
public ShopDialog(Frame frame, BasicPane pane) {
super(frame);
if (StableUtils.getMajorJavaVersion() >= 8) {
setUndecorated(true);
}
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(createDefaultDimension());
GUICoreUtils.centerWindow(this);
setResizable(false);
DesignerPluginContext.setPluginDialog(this);
}
private Dimension createDefaultDimension() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// jdk11 分辨率较低 缩放较大时 屏幕高度小于或接近设定的高度 需要调整下
if (JdkVersion.GE_9.support() && screenSize.height - 700 < 50) {
return new Dimension(900, screenSize.height - 100);
} else {
return new Dimension(900, 700);
}
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

31
designer-base/src/main/java/com/fr/design/extra/ShopManagerPane.java

@ -1,31 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.BasicPane;
import java.awt.BorderLayout;
import java.awt.Component;
/**
* @author richie
* @date 2015-03-09
* @since 8.0
* 应用中心的构建采用JavaScript代码来动态实现,但是不总是依赖于服务器端的HTML
* 采用JDK提供的JavaScript引擎,实际是用JavaScript语法实现Java端的功能,并通过JavaScript引擎动态调用
* JavaScript放在安装目录下的scripts/store目录下,检测到新版本的时候,可以通过更新这个目录下的文件实现热更新
* 不直接嵌入WebView组件的原因是什么呢?
* 因为如果直接嵌入WebView,和设计器的交互就需要预先设定好,这样灵活性会差很多,而如果使用JavaScript引擎,
* 就可以直接在JavaScript中和WebView组件做交互,而同时JavaScript中可以调用任何的设计器API.
*/
public class ShopManagerPane extends BasicPane {
public ShopManagerPane(Component webPane) {
setLayout(new BorderLayout());
add(webPane, BorderLayout.CENTER);
}
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager");
}
}

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

Loading…
Cancel
Save