Browse Source

Merge remote-tracking branch 'origin/fbp/release' into fbp/release

fbp/merge
Destiny.Lin 4 months ago
parent
commit
3a968c15d4
  1. 1
      build.gradle
  2. 2
      designer-base/src/main/java/com/fine/theme/light/ui/FineComboBoxUI.java
  3. 12
      designer-base/src/main/java/com/fine/theme/light/ui/FineTableHeaderUI.java
  4. 18
      designer-base/src/main/java/com/fine/theme/utils/FineComponentsFactory.java
  5. 3
      designer-base/src/main/java/com/fine/theme/utils/FineUIStyle.java
  6. 14
      designer-base/src/main/java/com/fine/theme/utils/FineUIUtils.java
  7. 2
      designer-base/src/main/java/com/fr/design/EnvSwitcherSubmitTask.java
  8. 2
      designer-base/src/main/java/com/fr/design/actions/file/RenameAction.java
  9. 45
      designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConstants.java
  10. 5
      designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java
  11. 3
      designer-base/src/main/java/com/fr/design/backup/EnvBackupHelper.java
  12. 21
      designer-base/src/main/java/com/fr/design/carton/CartonUtils.java
  13. 68
      designer-base/src/main/java/com/fr/design/carton/DispatchInfo.java
  14. 193
      designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java
  15. 8
      designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java
  16. 33
      designer-base/src/main/java/com/fr/design/carton/latency/AbstractUIDispatchHandler.java
  17. 104
      designer-base/src/main/java/com/fr/design/carton/latency/UIDispatchManager.java
  18. 48
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  19. 15
      designer-base/src/main/java/com/fr/design/data/datapane/GlobalTableDataComboBox.java
  20. 2
      designer-base/src/main/java/com/fr/design/data/datapane/GlobalTreeTableDataDictPane.java
  21. 301
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataComboBox.java
  22. 3
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java
  23. 3
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataComboBox.java
  24. 3
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java
  25. 6
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java
  26. 39
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java
  27. 36
      designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java
  28. 264
      designer-base/src/main/java/com/fr/design/data/datapane/connect/JNDIDefPane.java
  29. 77
      designer-base/src/main/java/com/fr/design/data/datapane/connect/SshPane.java
  30. 74
      designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java
  31. 73
      designer-base/src/main/java/com/fr/design/data/datapane/preview/ConnectionInfoBeanHelper.java
  32. 24
      designer-base/src/main/java/com/fr/design/data/datapane/preview/TableDataBeanHelper.java
  33. 10
      designer-base/src/main/java/com/fr/design/data/datapane/preview/desensitization/view/setting/TableDataDesensitizationTablePane.java
  34. 5
      designer-base/src/main/java/com/fr/design/data/datapane/sqlpane/SQLEditPane.java
  35. 30
      designer-base/src/main/java/com/fr/design/data/tabledata/datacenter/DCTableDataPane.java
  36. 22
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  37. 8
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/EmbeddedTableDataPane.java
  38. 6
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/MaxMemRowCountPanel.java
  39. 11
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java
  40. 5
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java
  41. 2
      designer-base/src/main/java/com/fr/design/debug/remote/HeaderRenderer.java
  42. 14
      designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkAction.java
  43. 2
      designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkHelper.java
  44. 8
      designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkTablePane.java
  45. 2
      designer-base/src/main/java/com/fr/design/debug/remote/RemoteDesignNetWorkTableRowSorter.java
  46. 4
      designer-base/src/main/java/com/fr/design/debug/remote/SizeColorCellRenderer.java
  47. 4
      designer-base/src/main/java/com/fr/design/debug/remote/TimeColorCellRenderer.java
  48. 48
      designer-base/src/main/java/com/fr/design/debug/ui/LatencyInfo.java
  49. 17
      designer-base/src/main/java/com/fr/design/debug/ui/LatencyMonitorEvent.java
  50. 56
      designer-base/src/main/java/com/fr/design/debug/ui/UIInspectorHolder.java
  51. 46
      designer-base/src/main/java/com/fr/design/debug/ui/UILatencyInfoHandler.java
  52. 124
      designer-base/src/main/java/com/fr/design/debug/ui/UILatencyWorker.java
  53. 40
      designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorAction.java
  54. 44
      designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorHelper.java
  55. 274
      designer-base/src/main/java/com/fr/design/debug/ui/UIMonitorPane.java
  56. 145
      designer-base/src/main/java/com/fr/design/dialog/CollapsibleDetailDialog.java
  57. 1
      designer-base/src/main/java/com/fr/design/dialog/UIDetailErrorLinkDialog.java
  58. 3
      designer-base/src/main/java/com/fr/design/editor/editor/ColumnSelectedEditor.java
  59. 5
      designer-base/src/main/java/com/fr/design/foldablepane/UIExpandablePane.java
  60. 2
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  61. 4
      designer-base/src/main/java/com/fr/design/gui/columnrow/ColumnRowVerticalPane.java
  62. 8
      designer-base/src/main/java/com/fr/design/gui/controlpane/JControlPane.java
  63. 4
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java
  64. 24
      designer-base/src/main/java/com/fr/design/gui/controlpane/UISimpleListControlPane.java
  65. 2
      designer-base/src/main/java/com/fr/design/gui/core/ReactiveCardPane.java
  66. 44
      designer-base/src/main/java/com/fr/design/gui/core/SimpleCardPane.java
  67. 38
      designer-base/src/main/java/com/fr/design/gui/frpane/RegPane.java
  68. 2
      designer-base/src/main/java/com/fr/design/gui/icombobox/UIComboBox.java
  69. 8
      designer-base/src/main/java/com/fr/design/gui/icontainer/UIModeControlContainer.java
  70. 12
      designer-base/src/main/java/com/fr/design/gui/ilist/TableViewList.java
  71. 47
      designer-base/src/main/java/com/fr/design/gui/style/AlignmentPane.java
  72. 4
      designer-base/src/main/java/com/fr/design/hyperlink/popup/MobilePopupRegularPane.java
  73. 14
      designer-base/src/main/java/com/fr/design/hyperlink/popup/StyleSettingPane.java
  74. 2
      designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java
  75. 4
      designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java
  76. 34
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  77. 2
      designer-base/src/main/java/com/fr/design/mainframe/theme/ThemedCellStyleListPane.java
  78. 20
      designer-base/src/main/java/com/fr/design/mainframe/toolbar/DebugModeMenuDef.java
  79. 2
      designer-base/src/main/java/com/fr/design/mainframe/widget/editors/DataBindingEditor.java
  80. 2
      designer-base/src/main/java/com/fr/design/mainframe/widget/editors/DataTableEditor.java
  81. 3
      designer-base/src/main/java/com/fr/design/present/dict/TableDataDictPane.java
  82. 158
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java
  83. 2
      designer-base/src/main/java/com/fr/design/roleAuthority/ReportAndFSManagePane.java
  84. 40
      designer-base/src/main/java/com/fr/design/style/background/impl/NullBackgroundPane.java
  85. 6
      designer-base/src/main/java/com/fr/design/utils/DesignUtils.java
  86. 23
      designer-base/src/main/java/com/fr/design/write/submit/DBManipulationPane.java
  87. 27
      designer-base/src/main/java/com/fr/env/EnvPrepare.java
  88. 2
      designer-base/src/main/java/com/fr/env/RemoteEnvPane.java
  89. 28
      designer-base/src/main/java/com/fr/env/RemoteWorkspaceURL.java
  90. 3
      designer-base/src/main/java/com/fr/start/ServerStarter.java
  91. 156
      designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java
  92. 4
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/bulb.svg
  93. 4
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/bulb_click.svg
  94. 4
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/bulb_hover.svg
  95. 3
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/minimize.svg
  96. 3
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/minimize_disable.svg
  97. 20
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/no_result.svg
  98. 28
      designer-base/src/main/resources/com/fine/theme/icon/alphafine/search_hint.svg
  99. 6
      designer-base/src/main/resources/com/fine/theme/icon/formExport.svg
  100. 2
      designer-base/src/main/resources/com/fine/theme/icon/saveFile.svg
  101. Some files were not shown because too many files have changed in this diff Show More

1
build.gradle

@ -110,6 +110,7 @@ allprojects {
implementation 'com.fr.datasource:fine-datasource-core:' + fdlVersion
implementation 'com.fr.datasource:fine-datasource-web:' + fdlVersion
implementation 'com.fr.decision:decision-i18n:' + frVersion
implementation 'com.fr.decision:decision-report:' + frVersion
implementation 'com.fr.report:engine-report:' + frDevVersion
implementation 'com.fr.report:engine-x:' + frDevVersion
implementation 'com.fr.report:engine-chart:' + frDevVersion

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

@ -88,7 +88,7 @@ public class FineComboBoxUI extends FlatComboBoxUI {
// 限制最大宽度,如超出则高度预留展示横向滚动条所需宽度
int comboWidth = comboBox.getWidth();
if (fitRectangle.width > comboWidth) {
return new Rectangle(px, py, comboWidth, fitRectangle.height + FlatUIUtils.getUIInt("ScrollBar.width", 10));
return new Rectangle(px, py, comboWidth, fitRectangle.height + FineUIUtils.getAndScaleInt("ScrollBar.width", 10));
}
return fitRectangle;
}

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

@ -84,6 +84,16 @@ public class FineTableHeaderUI extends FlatTableHeaderUI {
setHorizontalAlignment(SwingConstants.LEFT);
}
/**
* 是否选中修改背景
* @param isSelected 被选中
* @param columnClass 列类型
* @return 是否修改
*/
public boolean checkSelected(boolean isSelected, Class columnClass) {
return isSelected && columnClass != Boolean.class;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Class<?> columnClass = table.getColumnClass(0);
@ -95,7 +105,7 @@ public class FineTableHeaderUI extends FlatTableHeaderUI {
border = BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, UIManager.getColor("defaultBorderColor")),
UIManager.getBorder("Table.cellNoFocusBorder"));
}
if (isSelected && columnClass != Boolean.class) {
if (checkSelected(isSelected, columnClass)) {
selectionBackground = UIManager.getColor( "Table.selectionBackground");
} else {
selectionBackground = UIManager.getColor("Table.background");

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

@ -3,9 +3,11 @@ 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.FineBorderFactory;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.i18n.Toolkit;
import com.fr.stable.Constants;
@ -13,10 +15,12 @@ import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import java.awt.Color;
import java.awt.Dimension;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.flex;
@ -92,4 +96,18 @@ public class FineComponentsFactory {
return sampleLabel;
}
/**
* 创建一个固定高度可上下滚动的文本域面板
* @param textArea 文本域
* @param height 高度
* @return 滚动面板
*/
public static JScrollPane createFixHeightTextArea(UITextArea textArea, int height) {
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(scrollPane.getPreferredSize().width, height));
scrollPane.setBorder(FineBorderFactory.createWrappedRoundBorder());
textArea.setBorder(null);
return scrollPane;
}
}

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

@ -30,6 +30,9 @@ public interface FineUIStyle {
String LABEL_BOLD = "boldLabel";
String LABEL_TIP_WINDOW_TITLE = "tipWindowTitleLabel";
String LABEL_SECONDARY = "secondaryLabel";
String LABEL_HIGHLIGHT = "highLightLabel";
String LABEL_PRIMARY = "primaryLabel";
String LABEL_DISABLED = "disabledLabel";
String LABEL_TIP = "tipLabel";
String LABEL_WARNING_TIP = "warningTipLabel";
String LABEL_UILIST = "uiListLabel";

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

@ -6,6 +6,8 @@ import com.fr.design.border.FineBorderFactory;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.stable.os.OperatingSystem;
@ -503,4 +505,16 @@ public class FineUIUtils {
public static JTextArea createAutoWrapTipLabel(String text) {
return LabelUtils.createAutoWrapLabel(text, FineUIUtils.getUIColor("Label.tipColor", "inactiveCaption"));
}
/**
* 基于设计器父面板计算当前面板尺寸
* @param width 宽度比例
* @param height 高度比例
*
* @return 面板尺寸
*/
public static Dimension calPaneDimensionByContext(double width, double height) {
DesignerFrame parent = DesignerContext.getDesignerFrame();
return new Dimension((int) (parent.getWidth() * width),(int) (parent.getHeight() * height));
}
}

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

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

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

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

45
designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConstants.java

@ -1,10 +1,10 @@
package com.fr.design.actions.help.alphafine;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fr.base.extension.FileExtension;
import com.fr.base.svg.IconUtils;
import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.DesignUtils;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.Color;
@ -40,23 +40,20 @@ public class AlphaFineConstants {
public static final int LATEST_SHOW_SIZE = 3;
public static final int HEIGHT = 680;
public static final int HEIGHT = FineUIScale.scale(680);
public static final int WIDTH = 460;
public static final int WIDTH = FineUIScale.scale(460);
public static final int LEFT_WIDTH = 300;
public static final int LEFT_WIDTH = FineUIScale.scale(320);
public static final int RIGHT_WIDTH = 380;
public static final int RIGHT_WIDTH = FineUIScale.scale(320);
public static final int FIELD_HEIGHT = 55;
public static final int CONTENT_HEIGHT = FineUIScale.scale(280);
public static final int CONTENT_HEIGHT = 405;
public static final int CELL_HEIGHT = FineUIScale.scale(24);
public static final int CELL_HEIGHT = 29;
public static final int CELL_TITLE_HEIGHT = FineUIScale.scale(24);
public static final int CELL_TITLE_HEIGHT = 24;
public static final int HOT_ICON_LABEL_HEIGHT = 36;
public static final int HOT_ITEMS = 6;
@ -70,24 +67,20 @@ public class AlphaFineConstants {
*/
public static final long DOCUMENT_SEARCH_GAP = 1000;
public static final Dimension FULL_SIZE = new Dimension(680, 460);
public static final Dimension CONTENT_SIZE = new Dimension(680, 405);
public static final Dimension FULL_SIZE = FineUIScale.createScaleDimension(680, 490);
public static final Dimension FIELD_SIZE = new Dimension(680, 55);
public static final Dimension CONTENT_SIZE = FineUIScale.createScaleDimension(640, 280);
public static final Dimension ICON_LABEL_SIZE = new Dimension(64, 64);
public static final Dimension FIELD_SIZE = FineUIScale.createScaleDimension(680, 55);
public static final Dimension HOT_ICON_LABEL_SIZE = new Dimension(36, 36);
public static final Dimension ICON_LABEL_SIZE = FineUIScale.createScaleDimension(64, 64);
public static final Dimension HOT_ISSUES_JAPNEL_SIZE = new Dimension(213, 182);
public static final Dimension HOT_ISSUES_JAPNEL_SIZE = FineUIScale.createScaleDimension(213, 182);
/**
* 展示面板的尺寸
*/
public static final Dimension PREVIEW_SIZE = new Dimension(680, 305);
public static final Dimension CLOSE_BUTTON_SIZE = new Dimension(40, 40);
public static final Dimension PREVIEW_SIZE = FineUIScale.createScaleDimension(640, 300);
public static final Color WHITE = new Color(0xf9f9f9);
@ -149,7 +142,7 @@ public class AlphaFineConstants {
public static final String BACK_ICON_NAME = "back@1x.png";
public static final Icon NO_RESULT_ICON = IOUtils.readIcon(AlphaFineConstants.IMAGE_URL + "noresult.png");
public static final Icon NO_RESULT_ICON = new LazyIcon("no_result", 110);
public static final Color SUSPENDED_COLOR = new Color(84, 165, 249);
@ -166,11 +159,11 @@ public class AlphaFineConstants {
public static final Color BACKGROUND_COLOR = new Color(245, 245, 247);
public static final Icon BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/bulb.svg");
public static final Icon BULB_ICON = new LazyIcon("bulb");
public static final Icon YELLOW_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/yellow_bulb.svg");
public static final Icon YELLOW_BULB_ICON = new LazyIcon("bulb_hover");
public static final Icon LIGHT_YELLOW_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg");
public static final Icon LIGHT_YELLOW_BULB_ICON = new LazyIcon("bulb_click");
public static final String HOT_SEARCH = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search");

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

@ -24,11 +24,8 @@ import com.fr.design.menu.MenuKeySet;
import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.log.FineLoggerFactory;
import com.fr.report.LockItem;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
import javax.swing.KeyStroke;
@ -85,7 +82,7 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS
// 锁定成功,执行后续操作
final DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
final List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.getCurrentConnectionMap();
final Map<String, TableData> tableDataMap = new HashMap<>();
for (ServerDataSetBean bean : beans) {
try {

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

@ -5,6 +5,7 @@ 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.lock.TemplateLockInfoReSave;
import com.fr.design.mem.MemConfigBackupManager;
import com.fr.design.mem.MemConfigRepositoryBuilder;
import com.fr.log.FineLoggerFactory;
@ -123,6 +124,7 @@ public class EnvBackupHelper {
// 如果原来是远程,要先发请求告诉原来的环境我这边要断开
if (origin instanceof RemoteWorkspace) {
origin.close();
TemplateLockInfoReSave.stopListener();
}
}
@ -131,6 +133,7 @@ public class EnvBackupHelper {
*/
public void rollbackEnv() {
if (origin instanceof RemoteWorkspace && ((RemoteWorkspace) origin).getClient() instanceof FineWorkspaceHttpClient) {
TemplateLockInfoReSave.startListener();
((FineWorkspaceHttpClient) ((RemoteWorkspace) origin).getClient()).connect();
}
}

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -1,7 +1,6 @@
package com.fr.design.data;
import com.fanruan.ComponentUtils;
import com.fanruan.config.impl.data.TableDataConfigProviderFactory;
import com.fr.base.StoreProcedureParameter;
import com.fr.base.TableData;
import com.fr.concurrent.NamedThreadFactory;
@ -20,6 +19,7 @@ import com.fr.data.impl.storeproc.StoreProcedureHelper;
import com.fr.data.operator.DataOperator;
import com.fr.design.DesignModelAdapter;
import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.design.data.tabledata.wrapper.MultiResultTableDataNameWrapper;
import com.fr.design.data.tabledata.wrapper.MultiResultTableDataWrapper;
import com.fr.design.data.tabledata.wrapper.ServerTableDataWrapper;
@ -50,6 +50,7 @@ import javax.swing.JFrame;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
@ -120,6 +121,9 @@ public abstract class DesignTableDataManager {
//增强for循环用的iterator实现的, 如果中间哪个listener修改或删除了(如ChartEditPane.dsChangeListener),
// 由于dsListeners是arraylist, 此时会ConcurrentModifyException
ChangeEvent e = null;
if (dsListeners.get(i) == null) {
continue;
}
dsListeners.get(i).stateChanged(e);
}
}
@ -196,17 +200,27 @@ public abstract class DesignTableDataManager {
* @param l ChangeListener监听器
*/
public static void addDsChangeListener(ChangeListener l) {
getDsListenersForCurrentTemplate().add(l);
}
/**
* 移除模板数据集改变 监听事件.
*
* @param l ChangeListener监听器
*/
public static void removeDsChangeListener(ChangeListener l) {
getDsListenersForCurrentTemplate().remove(l);
}
/**
* 获取当前模板的监听器列表.
*
* @return 模板对应的监听器列表如果列表不存在则新建.
*/
private static List<ChangeListener> getDsListenersForCurrentTemplate() {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String key = StringUtils.EMPTY;
if (JTemplate.isValid(template)) {
key = template.getPath();
}
List<ChangeListener> dsListeners = dsListenersMap.get(key);
if (dsListeners == null) {
dsListeners = new ArrayList<ChangeListener>();
dsListenersMap.put(key, dsListeners);
}
dsListeners.add(l);
String key = JTemplate.isValid(template) ? template.getPath() : StringUtils.EMPTY;
return dsListenersMap.computeIfAbsent(key, k -> new ArrayList<>());
}
/**
@ -316,7 +330,7 @@ public abstract class DesignTableDataManager {
names.add(entry.getKey());
}
//服务器数据集
Map<String, TableData> tableDatas = TableDataConfigProviderFactory.getInstance().getTableDatas();
Map<String, TableData> tableDatas = TableDataBeanHelper.getServerTableDatas();
for (Map.Entry<String, TableData> entry : tableDatas.entrySet()) {
names.add(entry.getKey());
}
@ -596,7 +610,11 @@ public abstract class DesignTableDataManager {
}
} catch (Exception e) {
throw new TableDataException(e.getMessage(), e);
String msg = e.getMessage();
if (e instanceof UndeclaredThrowableException) {
msg = ((UndeclaredThrowableException) e).getUndeclaredThrowable().getMessage();
}
throw new TableDataException(msg, e);
} finally {
ScheduledExecutorService scheduledExecutorService = ComponentUtils
.getExecutor()
@ -622,6 +640,10 @@ public abstract class DesignTableDataManager {
private static boolean checkBean(PreviewSourceBean bean, TableData tableData) {
if (bean.getDataName().isEmpty()) {
if (tableData instanceof ConditionTableData || tableData instanceof RecursionTableData) {
if (bean.getDataSource() instanceof TableDataSourceTailor.EmptyTableDataSource) {
// 用tabledata传的时候不能是EmptyTableDataSource,因此这里得重新弄个source
bean.setDataSource(new TableDataSourceTailor.TableDataOnlySource());
}
bean.getDataSource().putTableData(StringUtils.EMPTY, tableData);
return true;
}

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

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

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

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

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

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

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

@ -336,9 +336,10 @@ public class TableDataPaneListPane extends JListControlPane implements TableData
for (ServerDataSetBean bean : deleteDatas) {
TableDataRepository.getInstance().delete(bean);
}
TableDataRepository.getInstance().invalidCache();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
TableDataRepository.getInstance().invalidCache();
}
}

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

@ -14,7 +14,6 @@ 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.stable.StringUtils;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
import javax.swing.*;
@ -70,7 +69,7 @@ public class TreeTableDataComboBox extends UIComboBox {
// 全局数据集
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
Map<String, TableData> map = new HashMap<>();
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.getCurrentConnectionMap();
try {
for (ServerDataSetBean bean : beans) {
map.put(bean.getDatasetName() , TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));

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

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

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

@ -1,8 +1,6 @@
package com.fr.design.data.datapane.connect;
import com.fanruan.config.impl.data.ConnectionConfigProviderFactory;
import com.fine.theme.icon.LazyIcon;
import com.fr.base.svg.IconUtils;
import com.fr.data.impl.AbstractDatabaseConnection;
import com.fr.data.impl.Connection;
import com.fr.data.impl.NameDatabaseConnection;
@ -15,9 +13,7 @@ import com.fr.design.gui.ibutton.UILockButton;
import com.fr.report.LockItem;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
@ -91,7 +87,7 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
if (noAuthConnections == null) {
return nameList.iterator();
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.getCurrentConnectionMap();
for (Map.Entry<String, Connection> connectionEntry : connectionMap.entrySet()) {
String conName = connectionEntry.getKey();
if (noAuthConnections.contains(conName)) {

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

@ -5,7 +5,6 @@ import com.fine.theme.utils.FineUIScale;
import com.fr.config.remote.RemoteConfigEvent;
import com.fr.data.impl.Connection;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.JNDIDatabaseConnection;
import com.fr.decision.webservice.bean.datasource.ConnectionInfoBean;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.data.MapCompareUtils;
@ -36,8 +35,9 @@ import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -172,17 +172,8 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
"JDBC", new LazyIcon("dataLink"),
JDBCDatabaseConnection.class, DatabaseConnectionPane.JDBC.class
);
NameObjectCreator jndi = new NameObjectCreator(
"JNDI", new LazyIcon("dataLink"),
JNDIDatabaseConnection.class, DatabaseConnectionPane.JNDI.class
);
NameableCreator[] creators;
if (WorkplaceConstants.isLimitDatabaseType()) {
// 不支持JNDI,屏蔽接口
creators = new NameableCreator[]{jdbc};
} else {
creators = new NameableCreator[]{jdbc, jndi};
}
creators = new NameableCreator[]{jdbc};
Set<ConnectionProvider> pluginCreators = ExtraDesignClassManager.getInstance().getArray(ConnectionProvider.XML_TAG);
for (ConnectionProvider provider : pluginCreators) {
NameObjectCreator creator = new NameObjectCreator(
@ -207,7 +198,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
public void populate(Map<String, Connection> connectionMap) {
List<NameObject> nameObjectList = new ArrayList<NameObject>();
populatedConnectionsSnapshot.clear();
final Map<String, Connection> map = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, Connection> map = ConnectionInfoBeanHelper.getCurrentConnectionMap();
for (Map.Entry<String, Connection> entry : map.entrySet()) {
nameObjectList.add(new NameObject(entry.getKey(), entry.getValue()));
try {
@ -231,7 +222,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
List<String> removedConnNames = new ArrayList<>();
List<ConnectionInfoBean> addConnections = new ArrayList<>();
List<ConnectionInfoBean> updateConnection = new ArrayList<>();
List<Connection> validConnection = new ArrayList<>();
Map<String, Connection> validConnection = new HashMap<>();
MapCompareUtils.contrastMapEntries(populatedConnectionsSnapshot, updatedMap, (entryEventKind, s, connection) -> {
try {
switch (entryEventKind) {
@ -242,7 +233,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
ConnectionInfoBean add = ConnectionInfoBeanHelper.createConnectionInfoBean(s, connection, true);
if (StringUtils.isNotEmpty(add.getConnectionData())) {
addConnections.add(add);
validConnection.add(connection);
validConnection.put(s, connection);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", connection.getClass());
}
@ -251,7 +242,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
ConnectionInfoBean update = ConnectionInfoBeanHelper.createConnectionInfoBean(s, connection, true);
if (StringUtils.isNotEmpty(update.getConnectionData())) {
updateConnection.add(update);
validConnection.add(connection);
validConnection.put(s, connection);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", connection.getClass());
}
@ -292,12 +283,12 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
* @return
*/
private boolean isEmbedConnection(Connection connection) {
return connection instanceof JDBCDatabaseConnection || connection instanceof JNDIDatabaseConnection;
return connection instanceof JDBCDatabaseConnection;
}
});
/// 先不管
//this.validateDatabaseType(validConnection);
this.alterConnections(addConnections, removedConnNames, updateConnection);
this.alterConnections(addConnections, removedConnNames, updateConnection, validConnection);
}
/**
@ -344,32 +335,36 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
}
private void alterConnections(List<ConnectionInfoBean> addConnections, List<String> removedConnNames, List<ConnectionInfoBean> updateConnection) throws Exception {
private void alterConnections(List<ConnectionInfoBean> addConnections, List<String> removedConnNames, List<ConnectionInfoBean> updateConnection, Map<String, Connection> validConnection) throws Exception {
try {
for (ConnectionInfoBean bean : addConnections) {
ConnectionRepository.getInstance().add(bean);
populatedConnectionsSnapshot.put(bean.getConnectionName(), validConnection.get(bean.getConnectionName()));
}
for (ConnectionInfoBean bean : updateConnection) {
ConnectionRepository.getInstance().update(bean);
populatedConnectionsSnapshot.put(bean.getConnectionName(), validConnection.get(bean.getConnectionName()));
}
for (String name : removedConnNames) {
ConnectionRepository.getInstance().delete(new ConnectionInfoBean(name));
populatedConnectionsSnapshot.remove(name);
}
// hades:远程环境时,由于时直接RPC调用远程修改,因此设计器本地配置需要失效
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.fire(RemoteConfigEvent.EDIT, "ConnectionConfig");
}
ConnectionRepository.getInstance().invalidCache();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
throw e;
} finally {
ConnectionRepository.getInstance().invalidCache();
}
}
public static void showDialog(Window parent) {
try {
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.getCurrentConnectionMap();
final ConnectionManagerPane connectionManagerPane = new ConnectionManagerPane() {
@Override
public void complete() {

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

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

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

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

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

@ -1,6 +1,5 @@
package com.fr.design.data.datapane.connect;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIUtils;
import com.fr.data.impl.JDBCDatabaseConnection;
@ -14,7 +13,7 @@ import com.fr.data.security.ssl.SslUtils;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.editor.editor.NotNegativeIntegerEditor;
import com.fr.design.gui.core.ReactiveCardPane;
import com.fr.design.gui.core.SimpleCardPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
@ -28,6 +27,7 @@ import com.fr.file.filter.ChooseFileFilter;
import com.fr.stable.StringUtils;
import com.fr.third.guava.collect.HashBiMap;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
@ -35,9 +35,10 @@ import java.awt.event.KeyEvent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.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;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
@ -62,12 +63,10 @@ public class SshPane extends BasicPane {
private final JPasswordField password = new UIPasswordFieldWithFixedLength(20);
private final JPasswordField secret = new UIPasswordFieldWithFixedLength(20);
private final KeyFileUITextField keyPath = new KeyFileUITextField(18);
private ReactiveCardPane coreCardPane;
private ReactiveCardPane verifyCardPane;
private JPanel sshSettingPane;
private SimpleCardPane verifyCardPane;
private final UIButton fileChooserButton = new UIButton();
private static final String USE_SSH = "useSSH";
private static final String NOT_USE_SSH = "notUseSSH";
private static final String USE_PASSWORD = "usePassword";
private static final String USE_KEY = "useKey";
@ -82,13 +81,14 @@ public class SshPane extends BasicPane {
type.setSelectedItem(Toolkit.i18nText("Fine-Design_Basic_Ssh_Private_Key"));
initVerifyCardPane();
initCoreCardPane();
initSshSettingPane();
initListeners();
this.add(Layouts.column(LayoutConstants.VERTICAL_GAP,
this.add(column(LayoutConstants.VERTICAL_GAP,
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Settings"))).with(FineUIUtils::wrapBoldLabelWithUnderline),
cell(coreCardPane)
row(cell(usingSsh)),
cell(sshSettingPane)
).getComponent());
}
@ -112,10 +112,8 @@ public class SshPane extends BasicPane {
});
}
private void initCoreCardPane() {
coreCardPane = ReactiveCardPane.create()
.addSupplier(NOT_USE_SSH, () -> cell(usingSsh).getComponent())
.addSupplier(USE_SSH, () -> Layouts.column(LayoutConstants.VERTICAL_GAP,
private void initSshSettingPane() {
sshSettingPane = column(LayoutConstants.VERTICAL_GAP,
row(cell(usingSsh)),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Host"))).weight(1),
@ -138,47 +136,46 @@ public class SshPane extends BasicPane {
flex(6)
),
cell(verifyCardPane)
).getComponent());
coreCardPane.select(USE_SSH).populate();
).getComponent();
}
private void initVerifyCardPane() {
verifyCardPane = ReactiveCardPane.create()
.addSupplier(USE_PASSWORD, () -> Layouts.row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Password"))).weight(1),
cell(password).weight(5),
verifyCardPane = new SimpleCardPane();
verifyCardPane.add(USE_PASSWORD, row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Password"))).weight(1),
cell(password).weight(5),
flex(6)
).getComponent());
verifyCardPane.add(USE_KEY, column(LayoutConstants.VERTICAL_GAP,
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Private_Key"))).weight(1),
cell(keyPath).weight(4.5),
flex(0.1),
cell(fileChooserButton).weight(0.4),
flex(6)
).getComponent())
.addSupplier(USE_KEY, () -> Layouts.column(LayoutConstants.VERTICAL_GAP,
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Private_Key"))).weight(1),
cell(keyPath).weight(4.5),
flex(0.1),
cell(fileChooserButton).weight(0.4),
flex(6)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Secret"))).weight(1),
cell(secret).weight(5),
flex(6)
)
).getComponent());
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Secret"))).weight(1),
cell(secret).weight(5),
flex(6)
)
).getComponent());
verifyCardPane.select(USE_KEY).populate();
verifyCardPane.show(USE_KEY);
}
private void changePane() {
coreCardPane.select(usingSsh.isSelected() ? USE_SSH: NOT_USE_SSH).populate();
sshSettingPane.setVisible(usingSsh.isSelected());
}
private void changePaneForType() {
switch (typeMap.get(type.getSelectedItem())) {
case NORMAL:
verifyCardPane.select(USE_PASSWORD).populate();
verifyCardPane.show(USE_PASSWORD);
break;
case KEY:
verifyCardPane.select(USE_KEY).populate();
verifyCardPane.show(USE_KEY);
break;
default:
throw new SshException("un support ssh type");

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

@ -1,18 +1,15 @@
package com.fr.design.data.datapane.connect;
import com.fine.swing.ui.layout.Layouts;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIUtils;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.security.ssl.Ssl;
import com.fr.data.security.ssl.SslException;
import com.fr.data.security.ssl.SslType;
import com.fr.data.security.ssl.SslUtils;
import com.fr.data.security.ssl.impl.NormalSsl;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.data.datapane.connect.SshPane.KeyFileUITextField;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.core.ReactiveCardPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
@ -23,14 +20,16 @@ import com.fr.file.FILEChooserPane;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.stable.StringUtils;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.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;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
@ -47,45 +46,44 @@ public class SslPane extends BasicPane {
private final KeyFileUITextField keyPathClientKey = new KeyFileUITextField(18);
private final UIButton fileChooserButtonClientKey = new UIButton();
private final UICheckBox verifyCa = new UICheckBox(i18nText("Fine-Design_Basic_Ssl_Verify_Ca"));
private final ReactiveCardPane cardPane;
private final JPanel sslSettingPane;
public SslPane() {
initDotButtons();
this.setLayout(new BorderLayout());
usingSsl.setSelected(true);
cardPane = ReactiveCardPane.create()
.addSupplier("notUseSSL", () -> cell(usingSsl).getComponent())
.addSupplier("useSSL", () -> Layouts.column(LayoutConstants.VERTICAL_GAP,
cell(usingSsl),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Ca"), SwingConstants.LEFT)).weight(1),
cell(keyPathCa).weight(1.3),
flex(0.05),
cell(fileChooserButtonCa).weight(0.15),
flex(2)
),
cell(verifyCa),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Client_Key"), SwingConstants.LEFT)).weight(1),
cell(keyPathClientKey).weight(1.3),
flex(0.05),
cell(fileChooserButtonClientKey).weight(0.15),
flex(2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Client_Cert"), SwingConstants.LEFT)).weight(1),
cell(keyPathClientCert).weight(1.3),
flex(0.05),
cell(fileChooserButtonClientCert).weight(0.15),
flex(2)
)
).getComponent()
);
cardPane.select("useSSL").populate();
this.add(Layouts.column(LayoutConstants.VERTICAL_GAP,
sslSettingPane = column(10,
cell(usingSsl),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Ca"), SwingConstants.LEFT)).weight(1),
cell(keyPathCa).weight(1.3),
flex(0.05),
cell(fileChooserButtonCa).weight(0.15),
flex(2)
),
cell(verifyCa),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Client_Key"), SwingConstants.LEFT)).weight(1),
cell(keyPathClientKey).weight(1.3),
flex(0.05),
cell(fileChooserButtonClientKey).weight(0.15),
flex(2)
),
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Client_Cert"), SwingConstants.LEFT)).weight(1),
cell(keyPathClientCert).weight(1.3),
flex(0.05),
cell(fileChooserButtonClientCert).weight(0.15),
flex(2)
)
).getComponent();
this.add(column(LayoutConstants.VERTICAL_GAP,
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Settings"))).with(FineUIUtils::wrapBoldLabelWithUnderline),
cell(cardPane)
cell(usingSsl),
cell(sslSettingPane)
).getComponent());
usingSsl.addActionListener(e -> changePane());
}
@ -99,7 +97,7 @@ public class SslPane extends BasicPane {
}
private void changePane() {
cardPane.select(usingSsl.isSelected() ? "useSSL" : "notUseSSL").populate();
sslSettingPane.setVisible(usingSsl.isSelected());
}

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

@ -22,20 +22,30 @@ 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.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
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.databind.ObjectMapper;
import com.fr.third.guava.cache.CacheBuilder;
import com.fr.third.guava.cache.CacheLoader;
import com.fr.third.guava.cache.LoadingCache;
import com.fr.third.springframework.beans.BeanUtils;
import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.connection.ConnectionCacheEvent;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.DataEncryptionHelper;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* 数据连接传输工具类
@ -50,19 +60,38 @@ public class ConnectionInfoBeanHelper {
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;
public static final int CACHE_MAX_SIZE = 1;
public static final String VALUE = "value";
private static LoadingCache<String, Map<String, Connection>> cache = CacheBuilder.newBuilder()
// 缓存容量1
.maximumSize(CACHE_MAX_SIZE)
// 默认写入过60S后过期
.expireAfterWrite(60, TimeUnit.SECONDS)
.build(new CacheLoader<String, Map<String, Connection>>() {
@Override
public Map<String, Connection> load(String s) throws Exception {
return updateCache();
}
});
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);
// 监听数据连接缓存失效
EventDispatcher.listen(ConnectionCacheEvent.REMOVE, new Listener<Null>() {
@Override
public void on(Event event, Null aNull) {
cache.invalidateAll();
}
});
}
/**
* 获取连接Map
*/
public static Map<String, Connection> createConnectionMap(ConnectionInfoBean[] beans) {
private static Map<String, Connection> updateCache() {
Map<String, Connection> ans = new HashMap<>();
ConnectionInfoBean[] beans = ConnectionRepository.getInstance().getAll();
for (ConnectionInfoBean infoBean : beans) {
try {
if (JDBCConnectionProcessor.KEY.acceptConnectionTypes().contains(infoBean.getConnectionType())) {
@ -77,23 +106,33 @@ public class ConnectionInfoBeanHelper {
return ans;
}
/**
* 获取连接Map
*/
public static Map<String, Connection> getCurrentConnectionMap() {
try {
return cache.get(VALUE);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
/**
* 根据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;
try {
Connection connection = cache.get(VALUE).get(infoBean.getConnectionName());
if (connection != null) {
connection.setConnectionName(infoBean.getConnectionName());
}
return connection;
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
/**

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

@ -25,13 +25,10 @@ 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;
@ -52,7 +49,7 @@ 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, Connection> connectionMap = ConnectionInfoBeanHelper.getCurrentConnectionMap();
final Map<String, TableData> tableDataMap = new HashMap<>();
try {
for (ServerDataSetBean bean : beans) {
@ -159,7 +156,12 @@ public class TableDataBeanHelper {
if (dataSet.getDatabase() instanceof NameDatabaseConnection) {
bean.setDatabase(((NameDatabaseConnection) dataSet.getDatabase()).getName());
}
bean.setQuery(DataEncryptionHelper.encrypt(dataSet.getQuery()));
if (dataSet.getQuery() != null) {
bean.setQuery(DataEncryptionHelper.encrypt(dataSet.getQuery()));
}
if (dataSet.getPageQuerySql() != null) {
bean.setPageQuery(DataEncryptionHelper.encrypt(dataSet.getPageQuerySql()));
}
List<ParameterBean> parameterBeans = new ArrayList<>();
ParameterProvider[] parameters = dataSet.getParameters(Calculator.createCalculator());
for (ParameterProvider parameter : parameters) {
@ -189,11 +191,15 @@ public class TableDataBeanHelper {
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()));
if (bean.getQuery() != null) {
tableData.setQuery(DataEncryptionHelper.decrypt(bean.getQuery()));
}
if (bean.getPageQuery() != null) {
tableData.setPageQuerySql(DataEncryptionHelper.decrypt(bean.getPageQuery()));
}
Connection connection = connectionMap.get(bean.getDatabase());
if (connection != null) {
tableData.setDatabase(new NameDatabaseConnection(bean.getDatabase()));
} else {
tableData.setDatabase(new NameDatabaseConnection(bean.getDatabase()));
if (connection == null) {
FineLoggerFactory.getLogger().info("not find conn by {}", bean.getDatabase());
}
String sql = SqlUtils.clearSqlComments(DataEncryptionHelper.decrypt(bean.getQuery()));

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

@ -12,8 +12,11 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.server.repository.authority.RemoteAuthorityRepository;
import javax.swing.*;
import java.awt.*;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@ -89,7 +92,8 @@ public class TableDataDesensitizationTablePane extends JPanel {
// 获取当前所有用户组
roleMap.putAll(RemoteAuthorityRepository.getInstance().getAllRoles4Desensitization());
// 获取当前最新的所有规则
latestRules.putAll(DesensitizationRuleManager.getInstance().getAllRules());
latestRules.put(DesensitizationRuleSource.SERVER, RemoteAuthorityRepository.getInstance().getAllRoles().getSourceRuleMap().get(DesensitizationRuleSource.SERVER));
latestRules.put(DesensitizationRuleSource.CUSTOM, DesensitizationRuleManager.getInstance().getRulesBySource(DesensitizationRuleSource.CUSTOM));
return null;
}

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

@ -1,5 +1,6 @@
package com.fr.design.data.datapane.sqlpane;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.data.core.DataCoreUtils;
import com.fr.data.core.db.TableProcedure;
import com.fr.design.actions.UpdateAction;
@ -10,7 +11,6 @@ import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import javax.swing.Icon;
import javax.swing.JPopupMenu;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
@ -57,8 +57,7 @@ public class SQLEditPane extends RSyntaxTextArea {
if (requestDroptarget) {
new SQLPaneDropTarget(this);
}
setBorder(null);
setBorder(new ScaledEmptyBorder(2, 2, 2, 2));
}

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

@ -9,6 +9,7 @@ import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.jxbrowser.JxEngine;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.mainframe.DesignerUIModeConfig;
import com.fr.json.revise.EmbedJson;
import com.fr.stable.StringUtils;
import com.fr.third.guava.collect.ImmutableMap;
@ -36,6 +37,7 @@ public class DCTableDataPane extends AbstractTableDataPane<DCTableData> {
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 static final String DATACENTERS_URL = System.getProperty("devMode.datacenters.url");
private final JxUIPane<String> dataCenterJxUIPane;
private final JxTableDataNamePane namePane = new JxTableDataNamePane(this);
// 用于复制粘贴场景
@ -62,13 +64,22 @@ public class DCTableDataPane extends AbstractTableDataPane<DCTableData> {
}
private static JxUIPane<String> getJxUIPane() {
return new JxUIPane.Builder<String>()
.engine(JX_ENGINE)
.namespace(DATA_CENTER)
.bindWindow(DATA_CENTER_HELPER, DCTableDataJSBridge::getBridge)
.withEMB(DC_INDEX_HTML, ImmutableMap.of(DATA_CENTER_INJECT_URL, getDatacentersUrl()))
.build();
if (DesignerUIModeConfig.getInstance().isUIDevMode()
&& StringUtils.isNotBlank(DATACENTERS_URL)) {
return new JxUIPane.Builder<String>()
.engine(JX_ENGINE)
.namespace(DATA_CENTER)
.bindWindow(DATA_CENTER_HELPER, DCTableDataJSBridge::getBridge)
.withURL(DATACENTERS_URL, ImmutableMap.of(DATA_CENTER_INJECT_URL, getDatacentersUrl()))
.build();
} else {
return new JxUIPane.Builder<String>()
.engine(JX_ENGINE)
.namespace(DATA_CENTER)
.bindWindow(DATA_CENTER_HELPER, DCTableDataJSBridge::getBridge)
.withEMB(DC_INDEX_HTML, ImmutableMap.of(DATA_CENTER_INJECT_URL, getDatacentersUrl()))
.build();
}
}
private static String getDatacentersUrl() {
@ -96,7 +107,10 @@ public class DCTableDataPane extends AbstractTableDataPane<DCTableData> {
}
private void reload() {
dataCenterJxUIPane.redirect(EMB_TAG + SCHEME_HEADER + DC_INDEX_HTML,
dataCenterJxUIPane.redirect(
DesignerUIModeConfig.getInstance().isUIDevMode() && StringUtils.isNotBlank(DATACENTERS_URL)
? DATACENTERS_URL
: EMB_TAG + SCHEME_HEADER + DC_INDEX_HTML,
ImmutableMap.of(DATA_CENTER_INJECT_URL, getDatacentersUrl()));
}

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

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

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

@ -16,9 +16,11 @@ import com.fr.general.DateUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
@ -350,10 +352,12 @@ public class EmbeddedTableDataPane extends AbstractTableDataPane<EmbeddedTableDa
private class CellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (column == 0) {
setBackground(new Color(229, 229, 229));
setHorizontalAlignment(CENTER);
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
//居中文本不需要设置 borderInsets
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, UIManager.getColor("defaultBorderColor")));
return component;
}
}

6
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/MaxMemRowCountPanel.java

@ -17,6 +17,7 @@ import com.fr.stable.StringUtils;
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.FineUIScale.scale;
public class MaxMemRowCountPanel extends UIToolbar {
@ -24,9 +25,9 @@ public class MaxMemRowCountPanel extends UIToolbar {
private static final int MAX_IN_MEMORY = 1;
private static final String[] CACHE_LIST = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Save_All_Records_In_Memory"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Max_Mem_Row_Count") };
private static final int MAX_WIDTH = getMaxComBoBoxWidth() > 200 ? 350 : 280;
private static final int MAX_WIDTH = getMaxWidth();
private static final int MAX_COMPONENT_COUNT_OF_MAX_MEMORY = 4;
private static int getMaxComBoBoxWidth() {
private static int getMaxWidth() {
int maxWidth = GraphHelper.getWidth(CACHE_LIST[0]);
for (int i = 1; i < CACHE_LIST.length; i++) {
int width = GraphHelper.getWidth(CACHE_LIST[i]);
@ -34,6 +35,7 @@ public class MaxMemRowCountPanel extends UIToolbar {
maxWidth = width;
}
}
maxWidth = maxWidth > scale(200) ? scale(350) : scale(280);
return maxWidth;
}

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

@ -4,18 +4,18 @@ import com.fr.base.TableData;
import com.fr.data.MultiResultTableData;
import com.fr.data.impl.NameDataModel;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.data.operator.DataOperator;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.dialog.CollapsibleDetailDialog;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.iprogressbar.AutoProgressBar;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import javax.swing.Icon;
@ -230,7 +230,12 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper {
loadingBar.close();
if (!(e instanceof CancellationException)) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
FineJOptionPane.showMessageDialog(parent, e.getMessage());
if (tableData instanceof StoreProcedure) {
CollapsibleDetailDialog dialog = new CollapsibleDetailDialog(DesignerContext.getDesignerFrame(), new UILabel(Toolkit.i18nText("Fine-Design_Stored_Procedure_Query_Failed")), e.getMessage());
dialog.setVisible(true);
} else {
FineJOptionPane.showMessageDialog(parent, e.getMessage());
}
}
}
}

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

@ -31,7 +31,6 @@ import com.fr.design.data.tabledata.tabledatapane.TreeTableDataPane;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
import javax.swing.Icon;
@ -205,7 +204,7 @@ public abstract class TableDataFactory {
clearAll();
try {
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.getCurrentConnectionMap();
Map<String, TableData> tableDataMap = new HashMap<>();
for (ServerDataSetBean bean : beans) {
tableDataMap.put(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
@ -229,7 +228,7 @@ public abstract class TableDataFactory {
Map<String, TableData> tableDataMap = new HashMap<>();
try {
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.getCurrentConnectionMap();
for (ServerDataSetBean bean : beans) {
tableDataMap.put(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

145
designer-base/src/main/java/com/fr/design/dialog/CollapsibleDetailDialog.java

@ -0,0 +1,145 @@
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.ui.FlatUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.gui.ibutton.UIButton;
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 java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
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.column;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.fix;
/**
* 折叠弹窗
*
* @author Richard
* @since 11.0
* Created on 2024/10/22
*/
public class CollapsibleDetailDialog extends JDialog implements ActionListener {
public JPanel upInTopPanel;
private JPanel downInTopPanel;
private JPanel topPanel;
public JPanel hiddenPanel;
private JPanel bottomPanel;
private UILabel directUILabel;
private UILabel detailLabel;
// 内容标题
private final UILabel messageLabel;
// 详情
private final String detailText;
private final Dimension collapseDimension = FineUIScale.createScaleDimension(450, 185);
private final Dimension unfoldDimension = FineUIScale.createScaleDimension(450, 280);
public CollapsibleDetailDialog(Frame parent, UILabel label, String detailText) {
super(parent, true);
this.detailText = detailText;
this.messageLabel = label;
initComponent();
}
private void initComponent() {
initTopPanel();
initHiddenPanel();
initBottomPanel();
addListeners();
this.setResizable(false);
this.add(topPanel, BorderLayout.NORTH);
this.add(hiddenPanel, BorderLayout.CENTER);
this.add(bottomPanel, BorderLayout.SOUTH);
this.setSize(this.collapseDimension);
GUICoreUtils.centerWindow(this);
this.setAlwaysOnTop(true);
}
private void initTopPanel() {
initUpInTopPanel();
// 查看详情按钮
directUILabel = new UILabel();
directUILabel.setIcon(new LazyIcon("plus"));
detailLabel = new UILabel();
detailLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine_Designer_Look_Detail"));
downInTopPanel = row(fix(30), row(cell(directUILabel), cell(detailLabel), flex())).getComponent();
topPanel = column(cell(upInTopPanel), cell(downInTopPanel)).getComponent();
}
private void initUpInTopPanel() {
upInTopPanel = row(LayoutConstants.HORIZONTAL_GAP,
column(cell(new UILabel(new LazyIcon("error", 20))), flex()),
column(cell(messageLabel))).getComponent();
upInTopPanel.setBorder(new ScaledEmptyBorder(10, 10, 10, 10));
}
private void initHiddenPanel() {
hiddenPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
JScrollPane scrollPane = new JScrollPane();
JTextArea textArea = new JTextArea(detailText);
scrollPane.setViewportView(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBackground(FlatUIUtils.getUIColor("background.normal", Color.WHITE));
scrollPane.getViewport().setOpaque(false);
textArea.setOpaque(false);
textArea.setEditable(false);
hiddenPanel = row(fix(30), cell(scrollPane).weight(1)).getComponent();
hiddenPanel.setVisible(false);
hiddenPanel.setBorder(new ScaledEmptyBorder(0, 0, 0, 10));
}
private void initBottomPanel() {
//底部的按钮面板
UIButton okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK"));
FineUIStyle.setStyle(okButton, FineUIStyle.STYLE_PRIMARY);
okButton.addActionListener(this);
bottomPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
bottomPanel.setBorder(new ScaledEmptyBorder(10, 10, 10, 10));
bottomPanel.add(okButton, BorderLayout.EAST);
}
private void addListeners() {
downInTopPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
toggleHiddenPanel();
}
});
}
private void toggleHiddenPanel() {
if (hiddenPanel.isVisible()) {
hiddenPanel.setVisible(false);
setSize(collapseDimension);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
directUILabel.setIcon(new LazyIcon("plus"));
} else {
setSize(unfoldDimension);
hiddenPanel.setVisible(true);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail"));
directUILabel.setIcon(new LazyIcon("minus"));
}
}
@Override
public void actionPerformed(ActionEvent e) {
this.dispose();
}
}

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

@ -76,6 +76,7 @@ public class UIDetailErrorLinkDialog extends UIDialog {
// 顶部 图标和提示
UILabel errorIcon = new UILabel(new LazyIcon("error", 20));
UILabel errorInfo= new UILabel(builder.reason);
errorInfo.setToolTipText(builder.reason);
FineUIStyle.setStyle(errorInfo, FineUIStyle.LABEL_TIP_WINDOW_TITLE);
// 中部 详细内容

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

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

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

@ -59,15 +59,14 @@ public class UIExpandablePane extends JPanel {
headerPanel = new HeaderPane(title);
headerPanel.addMouseListener(new PanelAction());
setcontentPanelontentPanelBorder();
this.add(headerPanel, BorderLayout.NORTH);
this.add(contentPanel, BorderLayout.CENTER);
if (withUnderline) {
this.add(column(
cell(headerPanel), cell(contentPanel).with(it -> it.setBorder(new ScaledEmptyBorder(0, 0, 10, 0))),
fix(1).with(it -> it.setBorder(FineBorderFactory.createDefaultUnderlineBorder())))
.getComponent());
} else {
this.add(column(cell(headerPanel), cell(contentPanel)).getComponent());
this.add(headerPanel, BorderLayout.NORTH);
this.add(contentPanel, BorderLayout.CENTER);
}
setOpaque(false);

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

@ -315,7 +315,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
// text
initFormulaTextArea();
UIScrollPane formulaTextAreaScrollPane = new UIScrollPane(formulaTextArea);
formulaTextArea.setBorder(null);
formulaTextArea.setBorder(new ScaledEmptyBorder(2, 2, 2, 2));
formulaTextAreaScrollPane.setBorder(FineBorderFactory.createWrappedRoundBorder());
// buttonPane

4
designer-base/src/main/java/com/fr/design/gui/columnrow/ColumnRowVerticalPane.java

@ -35,8 +35,8 @@ public class ColumnRowVerticalPane extends ColumnRowPane {
initRowSpinner();
pane.add(column(10,
row(cell(rowLabel).weight(0.15), cell(rowSpinner).weight(0.85)),
row(cell(colLabel).weight(0.15), cell(columnSpinner).weight(0.85))
row(cell(colLabel).weight(0.15), cell(columnSpinner).weight(0.85)),
row(cell(rowLabel).weight(0.15), cell(rowSpinner).weight(0.85))
).getComponent());
this.addDocumentListener(d);

8
designer-base/src/main/java/com/fr/design/gui/controlpane/JControlPane.java

@ -212,10 +212,10 @@ abstract class JControlPane extends BasicPane implements UnrepeatedNameHelper, S
}
/**
* 刷新 NameableCreator
*
* @param creators 生成器
*/
* 刷新 NameableCreator
*
* @param creators 生成器
*/
public void refreshNameableCreator(NameableCreator[] creators) {
this.creators = creators;
shorts = this.createShortcuts();

4
designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java

@ -243,8 +243,8 @@ public abstract class UIControlPane extends JControlPane {
}
/**
* 是否需要隐藏popupEditDialog
*/
* 是否需要隐藏popupEditDialog
*/
protected boolean needToHidePopupEditDialog() {
// 检查是否有子弹窗,如果有,则不隐藏
for (Window window : popupEditDialog.getOwnedWindows()) {

24
designer-base/src/main/java/com/fr/design/gui/controlpane/UISimpleListControlPane.java

@ -1,6 +1,9 @@
package com.fr.design.gui.controlpane;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.design.actions.UpdateAction;
import com.fr.design.border.FineBorderFactory;
import com.fr.design.constants.UIConstants;
@ -9,6 +12,7 @@ import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.UIList;
import com.fr.design.gui.ilist.UINameEdList;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.menu.ShortCut;
@ -26,12 +30,14 @@ import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
@ -49,7 +55,7 @@ import java.util.Comparator;
public class UISimpleListControlPane extends BasicPane {
public static final String LIST_NAME = "UISimpleControl_List";
protected UIList nameList;
protected UINameEdList nameList;
protected String selectedName;
private ShortCut4JControlPane[] shorts;
private ToolBarDef toolbarDef;
@ -108,10 +114,8 @@ public class UISimpleListControlPane extends BasicPane {
protected void initListPane(JPanel listPane) {
nameList = createJNameList();
nameList.setName(LIST_NAME);
nameList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS);
listPane.add(new UIScrollPane(nameList), BorderLayout.CENTER);
nameList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
nameList.addMouseListener(listMouseListener);
nameList.addListSelectionListener(new ListSelectionListener() {
@ -124,8 +128,12 @@ public class UISimpleListControlPane extends BasicPane {
});
}
public UIList createJNameList() {
UIList nameList = new UIList(new DefaultListModel()) {
/**
* 构造 list设置 render
* @return UINameEdList
*/
public UINameEdList createJNameList() {
UINameEdList nameList = new UINameEdList(new DefaultListModel()) {
@Override
public int locationToIndex(Point location) {
int index = super.locationToIndex(location);
@ -411,6 +419,7 @@ public class UISimpleListControlPane extends BasicPane {
label = new UILabel();
initialLabelForeground = label.getForeground();
this.setLayout(new BorderLayout());
label.setBorder(new ScaledEmptyBorder(0, 6, 0, 0));
this.add(label, BorderLayout.CENTER);
}
@ -425,6 +434,7 @@ public class UISimpleListControlPane extends BasicPane {
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
setPreferredSize(new Dimension(list.getWidth(), FineUIScale.scale(UIManager.getInt("List.cellRender.height"))));
setComponentOrientation(list.getComponentOrientation());
Color bg = null;
@ -442,9 +452,7 @@ public class UISimpleListControlPane extends BasicPane {
}
if (isSelected) {
setBackground(bg == null ? list.getSelectionBackground() : bg);
setForeground(fg == null ? list.getSelectionForeground() : fg);
label.setForeground(Color.WHITE);
setBackground(FlatUIUtils.getUIColor("List.selectionInactiveBackground", Color.GRAY));
}
else {
setBackground(list.getBackground());

2
designer-base/src/main/java/com/fr/design/gui/core/ReactiveCardPane.java

@ -9,11 +9,13 @@ import java.util.function.Supplier;
/**
* 简单的响应式面板容器提供切换布局的功能
* <p> 懒加载无法兼容事件初始化如需实现类似功能可考虑 {@link SimpleCardPane} </>
*
* @author Levy.Xie
* @since 11.0
* Created on 2023/12/25
*/
@Deprecated
public class ReactiveCardPane extends JPanel {
String selectKey;

44
designer-base/src/main/java/com/fr/design/gui/core/SimpleCardPane.java

@ -0,0 +1,44 @@
package com.fr.design.gui.core;
import javax.swing.JPanel;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
/**
* 自适应尺寸大小变更的Card面板
*
* @author Levy.Xie
* @since 11.0
* Created on 2024/10/22
*/
public class SimpleCardPane extends JPanel {
private final CardLayout cardLayout;
public SimpleCardPane() {
cardLayout = new CardLayout();
setLayout(cardLayout);
}
/**
* 显示卡片
* @param key 卡片名
*/
public void show(String key) {
setVisible(true);
cardLayout.show(this, key);
}
@Override
public Dimension getPreferredSize() {
for (Component comp : getComponents()) {
if (comp.isVisible()) {
return comp.getPreferredSize();
}
}
setVisible(false);
return new Dimension(0, 0);
}
}

38
designer-base/src/main/java/com/fr/design/gui/frpane/RegPane.java

@ -2,20 +2,34 @@ package com.fr.design.gui.frpane;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.core.ReactiveCardPane;
import com.fr.design.gui.core.SimpleCardPane;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.form.ui.reg.*;
import com.fr.form.ui.reg.CustomReg;
import com.fr.form.ui.reg.IDCardReg;
import com.fr.form.ui.reg.LengthReg;
import com.fr.form.ui.reg.MailReg;
import com.fr.form.ui.reg.MobileReg;
import com.fr.form.ui.reg.NoneReg;
import com.fr.form.ui.reg.PhoneReg;
import com.fr.form.ui.reg.PostCardReg;
import com.fr.form.ui.reg.RegExp;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.util.EventListener;
import java.util.EventObject;
@ -86,10 +100,10 @@ public class RegPane extends BasicPane {
regPhonePane = new RegPhonePane();
customRegRexPane = new CustomRegRexPane();
final ReactiveCardPane cardPane = ReactiveCardPane.create()
.addSupplier("Length", () -> regLengthPane)
.addSupplier("Phone", () -> regPhonePane)
.addSupplier("Custom", () -> customRegRexPane);
final SimpleCardPane cardPane = new SimpleCardPane();
cardPane.add(regLengthPane, "Length");
cardPane.add(regPhonePane, "Phone");
cardPane.add(customRegRexPane, "Custom");
cardPane.setVisible(false);
corePane.add(comboPane);
@ -97,19 +111,19 @@ public class RegPane extends BasicPane {
initComboListener(cardPane);
}
private void initComboListener(ReactiveCardPane cardPane) {
private void initComboListener(SimpleCardPane cardPane) {
regComboBox.addActionListener(e -> {
RegExp regExp = (RegExp)regComboBox.getSelectedItem();
if(regExp instanceof PhoneReg) {
Object selectItem = regPhonePane.dataTypeComboBox.getSelectedItem();
String regString = selectItem == null ? StringUtils.EMPTY : selectItem.toString();
firePhoneRegAction(regString);
cardPane.select("Phone").populate();
cardPane.show("Phone");
} else {
if (regExp instanceof LengthReg){
cardPane.select("Length").populate();
cardPane.show("Length");
} else if (regExp instanceof CustomReg){
cardPane.select("Custom").populate();
cardPane.show("Custom");
} else {
cardPane.setVisible(false);
}

2
designer-base/src/main/java/com/fr/design/gui/icombobox/UIComboBox.java

@ -162,7 +162,7 @@ public class UIComboBox extends JComboBox implements UIObserver, GlobalNameObser
int renderFix = FineUIScale.scale(5);
int comboHeight = FineUIUtils.getAndScaleInt("ComboBox.comboHeight", 24);
//renderFix的原因在于:render里,每一个项前面了空了一格,要多几像素
return new Dimension(FineUIScale.scale(super.getPreferredSize().width) + renderFix, comboHeight);
return new Dimension(super.getPreferredSize().width + renderFix, comboHeight);
}
public void refreshBoxItems(List list) {

8
designer-base/src/main/java/com/fr/design/gui/icontainer/UIModeControlContainer.java

@ -44,6 +44,7 @@ public class UIModeControlContainer extends JLayeredPane {
private static final int NUM5 = 5;
private JComponent upPane;
private JComponent downPane;
private JComponent sheetNameTabPane;
private JPanel horizontToolPane;
private CoverPane coverPane;
@ -115,6 +116,10 @@ public class UIModeControlContainer extends JLayeredPane {
this.downPane = downPane;
}
public void setSheetNameTabPane(JComponent sheetNameTabPane) {
this.sheetNameTabPane = sheetNameTabPane;
}
protected void onResize(int distance) {
}
@ -215,7 +220,8 @@ public class UIModeControlContainer extends JLayeredPane {
}
if (DesignerMode.isAuthorityEditing() && isSheeetCovered) {
sheetInvisibleCoverPane.setBounds(0, toolPaneY + toolPaneHeight + UIConstants.SIZE, getWidth(), getHeight() - toolPaneY - toolPaneHeight - sheetCorverGap);
sheetInvisibleCoverPane.setBounds(0, toolPaneY + toolPaneHeight + UIConstants.SIZE,
getWidth(), downPane.getHeight() - sheetNameTabPane.getHeight());
UIModeControlContainer.this.add(sheetInvisibleCoverPane);
UIModeControlContainer.this.setLayer(sheetInvisibleCoverPane, 2);
sheetInvisibleCoverPane.setVisible(true);

12
designer-base/src/main/java/com/fr/design/gui/ilist/TableViewList.java

@ -3,8 +3,6 @@ package com.fr.design.gui.ilist;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.fanruan.config.impl.data.ConnectionConfigProviderFactory;
import com.fr.base.BaseUtils;
import com.fr.data.core.DataCoreUtils;
import com.fr.data.core.db.TableProcedure;
import com.fr.data.core.db.dialect.base.key.check.DataBaseDetail;
@ -19,7 +17,6 @@ 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 javax.swing.DefaultListCellRenderer;
@ -47,9 +44,10 @@ import java.util.concurrent.CancellationException;
* 表或者视图或者存储过程组成的一个下拉列表
*
* @author zhou
* @since 2012-3-28下午10:07:34
* @Created on 2012-3-28下午10:07:34
* @since 11.0
*/
public class TableViewList extends UIList {
public class TableViewList extends JList {
/**
*
@ -162,7 +160,7 @@ public class TableViewList extends UIList {
* augustdatabaseName是数据库名字searchFilter是输入的过滤条件,typesFilter是视图
* 存储过程中的一者或者几者
*
* @param databaseName
* @param datasource
* @param searchFilter
* @param typesFilter
*/
@ -267,7 +265,7 @@ public class TableViewList extends UIList {
icon = new LazyIcon("store_procedure");
}
this.setIcon(icon);
this.setToolTipText(getPreferredSize().width > list.getVisibleRect().width ? this.getText() : null);
return this;
}

47
designer-base/src/main/java/com/fr/design/gui/style/AlignmentPane.java

@ -4,7 +4,7 @@ package com.fr.design.gui.style;
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved.
*/
import com.fine.swing.ui.layout.Layouts;
import com.fine.swing.ui.layout.Row;
import com.fine.theme.icon.LazyIcon;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.BaseUtils;
@ -15,7 +15,6 @@ import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
import com.fr.design.foldablepane.UIExpandablePane;
import com.fr.design.fun.IndentationUnitProcessor;
import com.fr.design.gui.core.ReactiveCardPane;
import com.fr.design.gui.frpane.UINumberDragPane;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.icombobox.UIComboBox;
@ -25,7 +24,6 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.event.EventDispatcher;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.plugin.ExtraClassManager;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.manage.PluginFilter;
@ -46,9 +44,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.row;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.column;
import static com.fine.swing.ui.layout.Layouts.fix;
import static com.fine.swing.ui.layout.Layouts.flex;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* Pane to edit cell alignment.
@ -61,7 +60,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
private static final String[] LAYOUT = {Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Default"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Titled"),
Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Extend"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Adjust")};
private ReactiveCardPane rotationBarPane;
private JPanel rotationBarPane;
private UIComboBox textComboBox;
private UIComboBox textRotationComboBox;
@ -91,7 +90,6 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
imageLayoutComboBox = new UIComboBox(LAYOUT);
initTextRotationComboBox();
// todo: 换新图标及反白问题
Icon[][] hAlignmentIconArray = {{new LazyIcon("h_left"), new LazyIcon("h_left").white()},
{new LazyIcon("h_center"), new LazyIcon("h_center").white()},
{new LazyIcon("h_right"), new LazyIcon("h_right").white()},
@ -177,7 +175,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
private JPanel createPane() {
JPanel basicPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Basic"), 290, 24, basicPane());
JPanel seniorPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Basic_Advanced"), 290, 24, seniorPane());
return Layouts.column(
return column(
cell(basicPane),
fix(1).with(it -> it.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIManager.getColor("defaultBorderColor")))),
cell(seniorPane)
@ -189,7 +187,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
UILabel verticalLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical") + " ", SwingConstants.LEFT);
UIComponentUtils.setLineWrap(horizontalLabel);
UIComponentUtils.setLineWrap(verticalLabel);
return Layouts.column(LayoutConstants.VERTICAL_GAP,
return column(LayoutConstants.VERTICAL_GAP,
row(
cell(horizontalLabel).weight(1.2),
cell(hAlignmentPane).weight(3)),
@ -201,7 +199,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
}
private JPanel seniorPane() {
return Layouts.column(LayoutConstants.VERTICAL_GAP,
return column(LayoutConstants.VERTICAL_GAP,
cell(seniorUpPane()),
cell(seniorMiddlePane()),
cell(seniorDownPane())
@ -210,7 +208,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
}
private JPanel seniorUpPane() {
return Layouts.column(LayoutConstants.VERTICAL_GAP,
return column(LayoutConstants.VERTICAL_GAP,
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Image_Layout"), SwingConstants.LEFT))
.with(it -> it.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Image_Layout"))).weight(1.2),
@ -224,28 +222,19 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
}
private JPanel seniorMiddlePane() {
rotationBarPane = ReactiveCardPane.create()
.addSupplier("hide", () -> Layouts.row(
Row rotationRow = row(flex(1.2),cell(rotationPane).weight(3)).getComponent();
rotationBarPane = column(10,
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"), SwingConstants.LEFT))
.with(it -> it.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"))).weight(1.2),
cell(textRotationComboBox).weight(3)
).getComponent())
.addSupplier("show", () -> Layouts.column(LayoutConstants.VERTICAL_GAP,
row(
cell(new UILabel(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"), SwingConstants.LEFT))
.with(it -> it.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"))).weight(1.2),
cell(textRotationComboBox).weight(3)
),
row(
flex(1.2),
cell(rotationPane).weight(3)
)
).getComponent());
rotationBarPane.select("show").populate();
),
cell(rotationRow)
).getComponent();
textRotationComboBox.addItemListener(e -> {
String key = (textRotationComboBox.getSelectedIndex() == 0) ? "show" : "hide";
rotationBarPane.select(key).populate();
rotationRow.setVisible(textRotationComboBox.getSelectedIndex() == 0);
});
return rotationBarPane;
}
@ -257,7 +246,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO
partSpacingLabel.setToolTipText(partSpacingLabel.getText());
UILabel spacingLabel = new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing")), SwingConstants.LEFT);
spacingLabel.setToolTipText(spacingLabel.getText());
return Layouts.column(
return column(
row(
cell(indentationLabel).weight(1.2),
cell(leftIndentSpinner).weight(1.4),

4
designer-base/src/main/java/com/fr/design/hyperlink/popup/MobilePopupRegularPane.java

@ -45,7 +45,7 @@ public class MobilePopupRegularPane extends BasicPane {
spinnerGroupPane = this.createSpinnerPane();
this.add(column(LayoutConstants.VERTICAL_GAP,
cell(this.createRadioButtonGroupPane()),
row(flex(1), cell(spinnerGroupPane).weight(3))
row(flex(1.5), cell(spinnerGroupPane).weight(3))
).getComponent());
}
@ -62,7 +62,7 @@ public class MobilePopupRegularPane extends BasicPane {
radioButtons.add(autoRadio);
radiosPane.add(row(30, cell(customRadio), cell(autoRadio), flex()).getComponent());
return row(cell(new UILabel(this.label, FineUIStyle.LABEL_SECONDARY)).weight(1), cell(radiosPane).weight(3)).getComponent();
return row(cell(new UILabel(this.label, FineUIStyle.LABEL_SECONDARY)).weight(1.5), cell(radiosPane).weight(3)).getComponent();
}
private ActionListener radioActionListener = new ActionListener() {

14
designer-base/src/main/java/com/fr/design/hyperlink/popup/StyleSettingPane.java

@ -83,9 +83,9 @@ public class StyleSettingPane extends BasicBeanPane<MobilePopupHyperlink> {
UILabel borderLabel = new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Border"));
borderPane.add(column(LayoutConstants.VERTICAL_GAP,
row(cell(borderLabel).weight(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Line"), FineUIStyle.LABEL_SECONDARY)).weight(1), cell(borderType).weight(2), flex(3)),
row(flex(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Colors"), FineUIStyle.LABEL_SECONDARY)).weight(1), cell(borderColor).weight(2), flex(3)),
row(flex(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Radius"), FineUIStyle.LABEL_SECONDARY)).weight(1), cell(borderRadiusSpinner).weight(2), flex(3))
row(cell(borderLabel).weight(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Line"), FineUIStyle.LABEL_SECONDARY)).weight(1.5), cell(borderType).weight(2), flex(2.5)),
row(flex(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Colors"), FineUIStyle.LABEL_SECONDARY)).weight(1.5), cell(borderColor).weight(2), flex(2.5)),
row(flex(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Radius"), FineUIStyle.LABEL_SECONDARY)).weight(1.5), cell(borderRadiusSpinner).weight(2), flex(2.5))
).getComponent());
return borderPane;
}
@ -102,8 +102,8 @@ public class StyleSettingPane extends BasicBeanPane<MobilePopupHyperlink> {
JLabel bgLabel = new JLabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Background"));
bgPane.add(column(LayoutConstants.VERTICAL_GAP,
row(cell(bgLabel).weight(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Colors"), FineUIStyle.LABEL_SECONDARY)).weight(1), cell(bgColor).weight(2), flex(3)),
row(flex(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Opacity"), FineUIStyle.LABEL_SECONDARY)).weight(1), cell(transparencyPane).weight(3), flex(2))
row(cell(bgLabel).weight(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Colors"), FineUIStyle.LABEL_SECONDARY)).weight(1.5), cell(bgColor).weight(2), flex(2.5)),
row(flex(1), cell(new UILabel(Toolkit.i18nText("FR-Plugin-Designer_Mobile_Popup_Opacity"), FineUIStyle.LABEL_SECONDARY)).weight(1.5), cell(transparencyPane).weight(3), flex(1.5))
).getComponent());
return bgPane;
}
@ -117,9 +117,9 @@ public class StyleSettingPane extends BasicBeanPane<MobilePopupHyperlink> {
sizePane.add(column(LayoutConstants.VERTICAL_GAP,
row(
column(LayoutConstants.VERTICAL_GAP, cell(sizeLabel), flex()).weight(1),
cell(mobileRegularPane).weight(4), flex(2)
cell(mobileRegularPane).weight(4.5), flex(1.5)
),
row(flex(1), cell(padRegularPane).weight(4), flex(2))
row(flex(1), cell(padRegularPane).weight(4.5), flex(1.5))
).getComponent());
return sizePane;
}

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

@ -1,6 +1,7 @@
package com.fr.design.javascript;
import com.fine.theme.icon.LazyIcon;
import com.fine.theme.utils.FineUIScale;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.design.DesignerEnvManager;
@ -187,6 +188,7 @@ public class JSContentPane extends BasicPane {
JPanel jsParaPane = new JPanel(new BorderLayout());
funNameLabel.setBackground(FineUIUtils.getUIColor("background.normal", "background.normal"));
UIScrollPane scrollPane = new UIScrollPane(funNameLabel);
scrollPane.setPreferredSize(new Dimension(super.getPreferredSize().width, FineUIScale.scale(80)));
scrollPane.setOpaque(true);
jsParaPane.add(row(4,
cell(scrollPane).weight(1),

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

@ -6,6 +6,7 @@ import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerUIModeConfig;
import com.fr.design.ui.ModernUIConstants;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
@ -99,7 +100,8 @@ public class JxUIPane<T> extends BasicPane {
* 按需初始化debug界面UI
*/
private void initDebugIfNeeded() {
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
if (DesignerEnvManager.getEnvManager().isOpenDebug()
|| DesignerUIModeConfig.getInstance().isUIDevMode()) {
UIToolbar toolbar = new UIToolbar();
add(toolbar, BorderLayout.NORTH);
UIButton openDebugButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Open_Debug_Window"));

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

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

2
designer-base/src/main/java/com/fr/design/mainframe/theme/ThemedCellStyleListPane.java

@ -115,7 +115,7 @@ public class ThemedCellStyleListPane extends FurtherBasicBeanPane<ThemedCellStyl
private static class RadioButtonListCellRangeRenderer extends JPanel implements ListCellRenderer<ThemedCellStyle>, Serializable {
private static final Icon SELECTEDMARK_ICON = new LazyIcon("selectedMark");
private static final Icon SELECTEDMARK_ICON = new LazyIcon("selectedMark", 32);
private final CellRectangleStylePreviewPane previewArea;
private boolean selected = false;

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

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

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

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

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

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

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

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

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

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

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

@ -109,7 +109,7 @@ public class ReportAndFSManagePane extends DockingView implements Prepare4DataSo
cell(scrollPane).weight(1)
).getComponent());
this.add(jPanel, BorderLayout.CENTER);
jPanel.setBorder(new ScaledEmptyBorder(0, 4, 4, 4));
jPanel.setBorder(new ScaledEmptyBorder(0, 12, 4, 4));
registerDSChangeListener();
}

40
designer-base/src/main/java/com/fr/design/style/background/impl/NullBackgroundPane.java

@ -1,20 +1,15 @@
package com.fr.design.style.background.impl;
import com.fine.theme.utils.FineUIScale;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.style.background.BackgroundDetailPane;
import com.fr.general.Background;
import com.fr.general.locale.image.I18nImage;
import javax.swing.*;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
@ -25,23 +20,14 @@ import static com.fine.swing.ui.layout.Layouts.flex;
*/
public class NullBackgroundPane extends BackgroundDetailPane {
private static final String NULL_BACKGROUND = "/com/fr/design/images/background/null_background.png";
private static final Image DEFAULT_NULL_BACKGROUND_IMAGE;
static {
DEFAULT_NULL_BACKGROUND_IMAGE = I18nImage.getImage(NULL_BACKGROUND);
}
public NullBackgroundPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
UILabel centerLabel = new UILabel(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background_Background_Is_Null"));
ImagePanel imagePane = new ImagePanel();
JPanel pane = column(
10,
flex(),
cell(imagePane),
cell(centerLabel),
flex()
).getComponent();
@ -60,30 +46,4 @@ public class NullBackgroundPane extends BackgroundDetailPane {
public void addChangeListener(ChangeListener changeListener) {
// do nothing.
}
/**
* 水平居中绘制 Image
*/
public class ImagePanel extends JPanel {
public ImagePanel() {
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (DEFAULT_NULL_BACKGROUND_IMAGE != null) {
int x = (this.getWidth() - DEFAULT_NULL_BACKGROUND_IMAGE.getWidth(null)) / 2;
g.drawImage(DEFAULT_NULL_BACKGROUND_IMAGE, x, 0, this);
}
}
@Override
public Dimension getPreferredSize() {
if (DEFAULT_NULL_BACKGROUND_IMAGE == null) {
return super.getPreferredSize();
}
return FineUIScale.scale(new Dimension(DEFAULT_NULL_BACKGROUND_IMAGE.getWidth(null), DEFAULT_NULL_BACKGROUND_IMAGE.getHeight(null)));
}
}
}

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

@ -1,8 +1,8 @@
package com.fr.design.utils;
import com.fanruan.workplace.http.HttpConstants;
import com.fine.theme.light.ui.laf.FineLightLaf;
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
import com.fanruan.workplace.http.HttpConstants;
import com.fr.base.FeedBackInfo;
import com.fr.base.ServerConfig;
import com.fr.base.Utils;
@ -377,10 +377,10 @@ public class DesignUtils {
}
/**
* 访问服务器环境-空参数
* 默认情况下访问服务器环境
*/
public static void visitEnvServer() {
visitEnvServerByParameters(StringUtils.EMPTY, new String[]{}, new String[]{});
visitEnvServerByParameters(ServerStarter.DEFAULT_SERVER_BASE_ROUTE, new String[]{}, new String[]{});
}
/**

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

@ -733,7 +733,6 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
// 设置column1的editor
columnsComboBox = new UIComboBox(new DefaultComboBoxModel());
columnsComboBox.setRenderer(new UIComboBoxRenderer() {
@Override
@ -754,7 +753,7 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
return super.stopCellEditing();
}
});
((DefaultCellEditor) column1.getCellEditor()).setClickCountToStart(1);
((DefaultCellEditor) column1.getCellEditor()).setClickCountToStart(2);
//设置Column 2的Editor
column2.setCellEditor(new ColumnValueEditor());
@ -963,12 +962,12 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
}
/*
* 击以编辑
* 击以编辑
*/
@Override
public boolean isCellEditable(EventObject anEvent) {
if (anEvent instanceof MouseEvent) {
return ((MouseEvent) anEvent).getClickCount() >= 1;
return ((MouseEvent) anEvent).getClickCount() >= 2;
}
return true;
}
@ -1221,6 +1220,11 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
return this;
}
@Override
public boolean checkSelected(boolean isSelected, Class columnClass) {
return isSelected;
}
}
/*
@ -1246,6 +1250,11 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
return this;
}
@Override
public boolean checkSelected(boolean isSelected, Class columnClass) {
return isSelected;
}
}
/**
@ -1264,7 +1273,11 @@ public class DBManipulationPane extends BasicBeanPane<DBManipulation> {
setSelected((value != null && ((Boolean) value).booleanValue()));
setUI(getUICheckBoxUI());
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, UIManager.getColor("defaultBorderColor")));
setBackground(Color.WHITE);
if (isSelected) {
setBackground(UIManager.getColor( "Table.selectionBackground"));
} else {
setBackground(UIManager.getColor("Table.background"));
}
return this;
}
}

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

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

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

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

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

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

3
designer-base/src/main/java/com/fr/start/ServerStarter.java

@ -15,6 +15,9 @@ import java.util.concurrent.Executors;
public class ServerStarter {
// FBP 下默认进入管理系统
public static final String DEFAULT_SERVER_BASE_ROUTE = "#/management";
/**
* 预览Demo
* 找默认工作目录不应该按照名字去找而应该按照安装路径因为默认工作目录的名字可能会改变

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

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

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

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.8057 27.1943C10.8057 26.5285 11.3454 25.9888 12.0112 25.9888H19.9334C20.5992 25.9888 21.139 26.5285 21.139 27.1943C21.139 27.8602 20.5992 28.3999 19.9334 28.3999H12.0112C11.3454 28.3999 10.8057 27.8602 10.8057 27.1943Z" fill="#0A1C38" fill-opacity="0.9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8066 19.2888C10.8053 19.3183 10.8047 19.3481 10.8047 19.3779V21.0121C8.21305 19.3219 6.5 16.3972 6.5 13.0723C6.5 7.84096 10.7409 3.6001 15.9722 3.6001C21.2036 3.6001 25.4444 7.84096 25.4444 13.0723C25.4444 16.3971 23.7315 19.3218 21.14 21.012V22.545C21.14 23.4961 20.3689 24.2672 19.4177 24.2672H12.5289C11.5777 24.2672 10.8066 23.4961 10.8066 22.545V19.2888ZM23.0333 13.0723C23.0333 15.113 22.1676 16.9516 20.7834 18.2407C20.7834 18.2406 20.7835 18.2408 20.7834 18.2407C20.1858 18.7972 19.4918 19.2516 18.7289 19.5754V21.8561H13.2177V19.5763C12.4535 19.2523 11.7582 18.7974 11.1598 18.2399C11.1598 18.24 11.1599 18.2398 11.1598 18.2399C9.77624 16.9508 8.91111 15.1125 8.91111 13.0723C8.91111 9.17258 12.0725 6.01121 15.9722 6.01121C19.872 6.01121 23.0333 9.17258 23.0333 13.0723Z" fill="#0A1C38" fill-opacity="0.9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

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

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.14 21.012C23.7315 19.3218 25.4444 16.3971 25.4444 13.0723C25.4444 7.84096 21.2036 3.6001 15.9722 3.6001C10.7409 3.6001 6.5 7.84096 6.5 13.0723C6.5 16.398 8.21391 19.3234 10.8066 21.0134V22.545C10.8066 23.4961 11.5777 24.2672 12.5289 24.2672H19.4177C20.3689 24.2672 21.14 23.4961 21.14 22.545V21.012ZM11.0282 12.4647C11.2947 9.95547 13.4196 8 16 8V6C12.3859 6 9.4127 8.73804 9.03941 12.2535L11.0282 12.4647ZM11.6227 15.4188C11.421 15.0546 11.2635 14.6629 11.1575 14.2507L9.22059 14.7493C9.36955 15.328 9.59055 15.8777 9.87325 16.388L11.6227 15.4188Z" fill="#FEC148"/>
<path d="M10.8057 27.1943C10.8057 26.5285 11.3454 25.9888 12.0112 25.9888H19.9334C20.5993 25.9888 21.139 26.5285 21.139 27.1943C21.139 27.8601 20.5993 28.3999 19.9334 28.3999H12.0112C11.3454 28.3999 10.8057 27.8601 10.8057 27.1943Z" fill="#FEC148"/>
</svg>

After

Width:  |  Height:  |  Size: 973 B

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

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.14 21.012C23.7315 19.3218 25.4444 16.3971 25.4444 13.0723C25.4444 7.84096 21.2036 3.6001 15.9722 3.6001C10.7409 3.6001 6.5 7.84096 6.5 13.0723C6.5 16.398 8.21391 19.3234 10.8066 21.0134V22.545C10.8066 23.4961 11.5777 24.2672 12.5289 24.2672H19.4177C20.3689 24.2672 21.14 23.4961 21.14 22.545V21.012ZM11.0282 12.4647C11.2947 9.95547 13.4196 8 16 8V6C12.3859 6 9.4127 8.73804 9.03941 12.2535L11.0282 12.4647ZM11.6227 15.4188C11.421 15.0546 11.2635 14.6629 11.1575 14.2507L9.22059 14.7493C9.36955 15.328 9.59055 15.8777 9.87325 16.388L11.6227 15.4188Z" fill="#F9AE31"/>
<path d="M10.8057 27.1943C10.8057 26.5285 11.3454 25.9888 12.0112 25.9888H19.9334C20.5993 25.9888 21.139 26.5285 21.139 27.1943C21.139 27.8601 20.5993 28.3999 19.9334 28.3999H12.0112C11.3454 28.3999 10.8057 27.8601 10.8057 27.1943Z" fill="#F9AE31"/>
</svg>

After

Width:  |  Height:  |  Size: 973 B

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

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.39961 17.4C4.62641 17.4 3.99961 16.7732 3.99961 16V16C3.99961 15.2268 4.62641 14.6 5.39961 14.6L26.5996 14.6C27.3728 14.6 27.9996 15.2268 27.9996 16V16C27.9996 16.7732 27.3728 17.4 26.5996 17.4L5.39961 17.4Z" fill="#0A1C38" fill-opacity="0.9"/>
</svg>

After

Width:  |  Height:  |  Size: 400 B

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

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.39961 17.4C4.62641 17.4 3.99961 16.7732 3.99961 16V16C3.99961 15.2268 4.62641 14.6 5.39961 14.6L26.5996 14.6C27.3728 14.6 27.9996 15.2268 27.9996 16V16C27.9996 16.7732 27.3728 17.4 26.5996 17.4L5.39961 17.4Z" fill="#0A1C38" fill-opacity="0.29"/>
</svg>

After

Width:  |  Height:  |  Size: 401 B

20
designer-base/src/main/resources/com/fine/theme/icon/alphafine/no_result.svg

@ -0,0 +1,20 @@
<svg width="110" height="110" viewBox="0 0 110 110" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.75">
<path d="M16.589 46.6279C16.589 45.5234 17.4844 44.6279 18.589 44.6279H72.2392C73.3437 44.6279 74.2392 45.5234 74.2392 46.6279V99.1374H20.589C18.3799 99.1374 16.589 97.3465 16.589 95.1374V46.6279Z" fill="#CFD4DC"/>
<path d="M73.429 46.6279C73.429 45.5234 74.3244 44.6279 75.429 44.6279H93.125C94.2296 44.6279 95.125 45.5234 95.125 46.6279V95.1374C95.125 97.3465 93.3341 99.1374 91.125 99.1374H73.429V46.6279Z" fill="url(#paint0_linear_11857_159075)"/>
<path d="M6.87805 34.2639C5.81283 32.9574 6.74244 31 8.4281 31H62.5379C63.8239 31 65.0316 31.6184 65.7833 32.6618L75.222 45.763H17.2037C16.6027 45.763 16.0335 45.4927 15.6537 45.0268L6.87805 34.2639Z" fill="#E6E9EF"/>
<path d="M75.3136 45.1376L65.4428 31.5H97.1673C98.1963 31.5 98.9198 32.5125 98.5864 33.486L94.9433 44.1236C94.7356 44.7302 94.1654 45.1376 93.5242 45.1376H75.3136Z" fill="#CFD4DC" stroke="#CFD4DC"/>
<path d="M104.514 59.1721C105.345 60.5043 104.387 62.2305 102.817 62.2305L85.9881 62.2305C85.3122 62.2305 84.6819 61.889 84.3128 61.3227L73.429 44.6285L94.334 44.6285C95.0243 44.6285 95.6657 44.9844 96.031 45.5701L104.514 59.1721Z" fill="#E6E9EF"/>
<path d="M25.1956 87.7715C25.1956 87.1496 25.6998 86.6455 26.3216 86.6455H43.4347C44.0566 86.6455 44.5607 87.1496 44.5607 87.7715C44.5607 88.3933 44.0566 88.8975 43.4347 88.8975H26.3216C25.6998 88.8975 25.1956 88.3933 25.1956 87.7715Z" fill="#8A95A6"/>
<path d="M25.1956 76.415C25.1956 75.7932 25.6998 75.2891 26.3216 75.2891H56.3448C56.9666 75.2891 57.4707 75.7932 57.4707 76.415C57.4707 77.0369 56.9666 77.541 56.3447 77.541H26.3216C25.6998 77.541 25.1956 77.0369 25.1956 76.415Z" fill="#8A95A6"/>
<path d="M72.0593 13.0465C71.5392 12.8606 70.9132 13.1083 70.661 13.5996L67.3221 20.1044C67.0699 20.5958 67.2871 21.1448 67.8072 21.3306C68.3272 21.5165 68.9533 21.2689 69.2055 20.7776L72.5443 14.2728C72.7965 13.7814 72.5793 13.2324 72.0593 13.0465Z" fill="#5D697C"/>
<path d="M53.582 11.2031C53.0511 11.3552 52.8367 11.8707 53.1031 12.3545L58.1773 21.5702C58.4437 22.054 59.09 22.3229 59.6209 22.1708C60.1518 22.0186 60.3663 21.5031 60.0999 21.0193L55.0257 11.8036C54.7593 11.3199 54.113 11.051 53.582 11.2031Z" fill="#5D697C"/>
<path d="M84.9809 18.496C84.5947 18.1012 83.8924 18.0025 83.4122 18.2755L73.1291 24.1223C72.649 24.3953 72.5729 24.9366 72.9592 25.3314C73.3454 25.7261 74.0478 25.8248 74.5279 25.5518L84.811 19.705C85.2911 19.432 85.3672 18.8907 84.9809 18.496Z" fill="#5D697C"/>
</g>
<defs>
<linearGradient id="paint0_linear_11857_159075" x1="84.277" y1="44.6279" x2="84.277" y2="99.1374" gradientUnits="userSpaceOnUse">
<stop stop-color="#8A95A6"/>
<stop offset="1" stop-color="#B8BDC5"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

28
designer-base/src/main/resources/com/fine/theme/icon/alphafine/search_hint.svg

@ -0,0 +1,28 @@
<svg width="110" height="110" viewBox="0 0 110 110" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.75" clip-path="url(#clip0_11857_128092)">
<rect x="8.41439" y="24.8418" width="56.5622" height="67.2295" rx="4" transform="rotate(-15 8.41439 24.8418)" fill="url(#paint0_linear_11857_128092)"/>
<path d="M23.527 42.1796C23.3957 41.6894 23.6866 41.1855 24.1768 41.0542L48.0736 34.651C48.5638 34.5197 49.0677 34.8106 49.199 35.3008C49.3304 35.791 49.0394 36.2949 48.5492 36.4263L24.6525 42.8294C24.1623 42.9607 23.6584 42.6698 23.527 42.1796Z" fill="#8A95A6"/>
<path d="M21.6243 35.079C21.493 34.5888 21.7839 34.0849 22.2741 33.9536L48.0147 27.0564C48.5049 26.925 49.0088 27.216 49.1402 27.7062C49.2715 28.1964 48.9806 28.7003 48.4904 28.8316L22.7498 35.7288C22.2596 35.8601 21.7557 35.5692 21.6243 35.079Z" fill="#8A95A6"/>
<path d="M26.0325 48.9442C25.9011 48.454 26.1921 47.9502 26.6823 47.8188L52.4229 40.9216C52.9131 40.7903 53.417 41.0812 53.5483 41.5714C53.6797 42.0616 53.3888 42.5655 52.8986 42.6968L27.1579 49.594C26.6677 49.7254 26.1638 49.4345 26.0325 48.9442Z" fill="#8A95A6"/>
<path d="M27.9352 56.0448C27.8038 55.5546 28.0947 55.0507 28.5849 54.9194L54.3256 48.0222C54.8158 47.8909 55.3196 48.1818 55.451 48.672C55.5823 49.1622 55.2914 49.6661 54.8012 49.7974L29.0606 56.6946C28.5704 56.826 28.0665 56.535 27.9352 56.0448Z" fill="#8A95A6"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M91.8499 27.1967L50.4554 19.8977C48.2799 19.5141 46.2052 20.9668 45.8216 23.1424L34.7082 86.1694C34.3246 88.345 35.7773 90.4196 37.9529 90.8033L88.0749 99.6411C90.2505 100.025 92.3252 98.5721 92.7088 96.3965L102.19 42.6248L91.8499 27.1967Z" fill="#DADEE7"/>
<path d="M102.201 42.5596L93.5353 41.0315C91.3597 40.6479 89.907 38.5732 90.2906 36.3977L91.9113 27.2062L102.201 42.5596Z" fill="#8A95A6"/>
<rect x="51.6104" y="33.5654" width="33.2983" height="2" rx="1" transform="rotate(10 51.6104 33.5654)" fill="#B8BFCB"/>
<rect x="50.1899" y="41.6211" width="45.2857" height="2" rx="1" transform="rotate(10 50.1899 41.6211)" fill="#B8BFCB"/>
<rect x="48.7693" y="49.6758" width="45.2857" height="2" rx="1" transform="rotate(10 48.7693 49.6758)" fill="#B8BFCB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M87.3897 85.3897C92.482 80.2974 92.482 72.0411 87.3897 66.9488C82.2974 61.8564 74.0411 61.8565 68.9488 66.9488C63.8565 72.0411 63.8565 80.2974 68.9488 85.3897C74.0411 90.482 82.2974 90.482 87.3897 85.3897ZM89.6026 64.7359C95.3236 70.4568 95.8613 79.3983 91.2158 85.7246L97.0196 91.5284C97.7908 92.2996 97.7908 93.5499 97.0196 94.3211C96.2484 95.0922 94.9981 95.0922 94.227 94.3211L88.5083 88.6024C82.1558 93.8974 72.6974 93.5641 66.7359 87.6026C60.4214 81.2881 60.4214 71.0503 66.7359 64.7359C73.0503 58.4214 83.2881 58.4214 89.6026 64.7359ZM84.172 72.9285C84.172 69.8569 81.4776 67.3626 78.2323 67.3626C75.0958 67.3626 72.645 69.6663 72.3275 72.3618C72.2891 72.6876 72.5586 72.9546 72.8866 72.9546H74.7355C75.0635 72.9546 75.3222 72.6853 75.3937 72.3652C75.6485 71.2253 76.6508 70.3325 78.2323 70.3325C79.9592 70.3325 81.1352 71.4708 81.1352 72.9285C81.1352 73.6574 80.7481 74.2822 80.2122 74.9069L77.8899 77.6402C77.1754 78.4732 76.8777 79.15 76.8777 80.2173V80.4299C76.8777 80.758 77.1436 81.0239 77.4716 81.0239H79.6183C79.9463 81.0239 80.2122 80.758 80.2122 80.4299V80.3475C80.2122 79.931 80.4206 79.3322 80.7481 78.9418L83.0407 76.1304C83.8445 75.1672 84.172 74.178 84.172 72.9285ZM80.2521 85.1826C80.2521 86.1667 79.4543 86.9645 78.4701 86.9645C77.486 86.9645 76.6882 86.1667 76.6882 85.1826C76.6882 84.1985 77.486 83.4007 78.4701 83.4007C79.4543 83.4007 80.2521 84.1985 80.2521 85.1826Z" fill="url(#paint1_linear_11857_128092)"/>
</g>
<defs>
<linearGradient id="paint0_linear_11857_128092" x1="25.6508" y1="55.506" x2="51.8986" y2="218.348" gradientUnits="userSpaceOnUse">
<stop stop-color="#B8BFCB"/>
<stop offset="1" stop-color="#8A95A6"/>
</linearGradient>
<linearGradient id="paint1_linear_11857_128092" x1="50.0919" y1="82.603" x2="96.1368" y2="80.8275" gradientUnits="userSpaceOnUse">
<stop stop-color="#223553"/>
<stop offset="1" stop-color="#8A95A6"/>
</linearGradient>
<clipPath id="clip0_11857_128092">
<rect width="110" height="110" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

6
designer-base/src/main/resources/com/fine/theme/icon/formExport.svg

@ -0,0 +1,6 @@
<svg width="31" height="29" viewBox="0 0 31 29" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 2C0 0.895431 0.895431 0 2 0H25C26.1046 0 27 0.895431 27 2V11.8321C26.365 11.5546 25.6956 11.3412 25 11.2V2H2V26H14.3378C14.7601 26.73 15.272 27.4017 15.8586 28H2C0.895431 28 0 27.1046 0 26V2Z" fill="#0A1C38" fill-opacity="0.9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5968 20.25C15.5968 16.5755 18.5755 13.5968 22.25 13.5968C25.9245 13.5968 28.9032 16.5755 28.9032 20.25C28.9032 23.9245 25.9245 26.9032 22.25 26.9032C18.5755 26.9032 15.5968 23.9245 15.5968 20.25ZM22.25 12C17.6937 12 14 15.6937 14 20.25C14 24.8063 17.6937 28.5 22.25 28.5C26.8063 28.5 30.5 24.8063 30.5 20.25C30.5 15.6937 26.8063 12 22.25 12ZM22.25 14.9274C22.8379 14.9274 23.3145 15.404 23.3145 15.9919V19.1855H26.5081C27.096 19.1855 27.5726 19.6621 27.5726 20.25C27.5726 20.8379 27.096 21.3145 26.5081 21.3145H23.3145V24.5081C23.3145 25.096 22.8379 25.5726 22.25 25.5726C21.6621 25.5726 21.1855 25.096 21.1855 24.5081V21.3145H17.9919C17.404 21.3145 16.9274 20.8379 16.9274 20.25C16.9274 19.6621 17.404 19.1855 17.9919 19.1855H21.1855V15.9919C21.1855 15.404 21.6621 14.9274 22.25 14.9274Z" fill="#0A1C38" fill-opacity="0.9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.1429 8H11.4286V14.4286H14.2139C15.9469 11.9759 18.8361 10.3184 22.1429 10.156V8ZM13.5579 15.5C12.8807 16.791 12.4999 18.2462 12.4999 19.7857C12.4999 20.9128 12.704 21.9946 13.079 23H5V15.5H13.5579Z" fill="#0A1C38" fill-opacity="0.9"/>
<path d="M5 8H10.5V14.5H5V8Z" fill="#0A1C38" fill-opacity="0.78"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

2
designer-base/src/main/resources/com/fine/theme/icon/saveFile.svg

@ -1,3 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.5 28V9.46837C28.5 9.34773 28.4564 9.23115 28.3772 9.14014L23.6185 3.67177C23.5236 3.56265 23.386 3.5 23.2414 3.5H20V10.6C20 11.3732 19.3732 12 18.6 12H9.4C8.6268 12 8 11.3732 8 10.6V3.5H4C3.72386 3.5 3.5 3.72386 3.5 4V28C3.5 28.2761 3.72386 28.5 4 28.5H8V19.4C8 18.6268 8.6268 18 9.4 18H22.6C23.3732 18 24 18.6268 24 19.4V28.5H28C28.2761 28.5 28.5 28.2761 28.5 28ZM24 30H8H4C2.89543 30 2 29.1046 2 28V4C2 2.89543 2.89543 2 4 2H8H20H23.2414C23.82 2 24.3702 2.2506 24.7501 2.68709L29.5087 8.15546C29.8255 8.51949 30 8.9858 30 9.46837V28C30 29.1046 29.1046 30 28 30H24ZM22.5 28.5V19.5H9.5V28.5H22.5ZM9.5 3.5H18.5V10.5H9.5V3.5Z" fill="#0A1C38" fill-opacity="0.9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 4V28H8V20C8 18.8954 8.89543 18 10 18H22C23.1046 18 24 18.8954 24 20V28H28V9.73985L23.0801 4H20V10C20 11.1046 19.1046 12 18 12H10C8.89543 12 8 11.1046 8 10V4H4ZM24 30H28C29.1046 30 30 29.1046 30 28V9.73985C30 9.26243 29.8292 8.80075 29.5185 8.43827L24.5986 2.69842C24.2187 2.25513 23.664 2 23.0801 2H20H8H4C2.89543 2 2 2.89543 2 4V28C2 29.1046 2.89543 30 4 30H8H24ZM22 28V20H10V28H22ZM10 4H18V10H10V4Z" fill="#0A1C38" fill-opacity="0.9"/>
</svg>

Before

Width:  |  Height:  |  Size: 817 B

After

Width:  |  Height:  |  Size: 593 B

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

Loading…
Cancel
Save