Browse Source

Pull request #13479: REPORT-106900【远程设计性能】远程设计协议重构

Merge in DESIGN/design from ~HARRISON/design:new-design to new-design

* commit '2d37d55597a7cd136cee72042ab9a413f8a11fdd': (46 commits)
  REPORT-112641 F0028埋点JDK版本获取有问题
  REPORT-111890 升级到release后,延迟启动云端运维模块不会自动开启
  REPORT-111890 升级到release后,延迟启动云端运维模块不会自动开启
  方法名也改下,以及成员变量名
  改下命名,颜色深浅模式可以作为公共枚举使用,并且层级往上抽一下
  改为枚举实现
  REPORT-111740 【控件显示增强】历史模板升级后,工具栏没有根据背景适配深浅
  改下实现
  REPORT-92893 锁定的模板,重复另存副本,设计器页面模板内容不更新
  REPORT-109129 偶现设计器关闭后进程残留 添加日志
  REPORT-109129 偶现设计器关闭后进程残留
  REPORT-111549 标签控件设置的字体背景样式等,开启控件增强,之前设置的样式丢了
  REPORT-111281 控件内置后,新模版默认开启变成默认关闭
  REPORT-111723 【控件显示增强】删除当前模板主题,按钮和标签控件的字体大小异常
  REPORT-111841 启动后不输出任何日志
  REPORT-111169 数据集含有注释的参数,但参数依然生效
  REPORT-109525 【设计器性能】启动性能优化 代码规范
  REPORT-111690 A用户断网,B用户打开模板,A用户联网保存,副本保存异常
  改个默认颜色,把类中的去掉,不提代码了,就一行
  少提一个类
  ...
new-design
Harrison-刘珂 11 months ago
parent
commit
ef401133e4
  1. 9
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 159
      designer-base/src/main/java/com/fr/design/RPCConnectHandlerCenter.java
  3. 5
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  4. 15
      designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java
  5. 14
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  6. 6
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  7. 4
      designer-base/src/main/java/com/fr/design/extra/PluginUtils.java
  8. 25
      designer-base/src/main/java/com/fr/design/gui/frpane/FontSizeComboPane.java
  9. 64
      designer-base/src/main/java/com/fr/design/lock/LockFileReSaveEnum.java
  10. 46
      designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java
  11. 56
      designer-base/src/main/java/com/fr/design/lock/TemplateLockInfoReSave.java
  12. 15
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  13. 45
      designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStylePane.java
  14. 6
      designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java
  15. 4
      designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java
  16. 7
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java
  17. 15
      designer-base/src/main/java/com/fr/design/update/push/DesignerPushUpdateConfigManager.java
  18. 32
      designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java
  19. 52
      designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java
  20. 2
      designer-base/src/main/java/com/fr/start/server/FineEmbedServer.java
  21. 2
      designer-base/src/main/java/com/fr/startup/metric/DesignerStartupModel.java
  22. 102
      designer-base/src/main/java/com/fr/widgettheme/ParameterBackgroundStyleSettingPane.java
  23. 50
      designer-base/src/main/java/com/fr/widgettheme/designer/WidgetThemeDisplayAction.java
  24. 81
      designer-base/src/main/java/com/fr/widgettheme/designer/WidgetThemeDisplayConfigPane.java
  25. 88
      designer-base/src/main/java/com/fr/widgettheme/theme/edit/ParamContainerBackgroundPane.java
  26. 84
      designer-base/src/main/java/com/fr/widgettheme/theme/edit/ParamContainerStyleEditPane.java
  27. 121
      designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/DesktopWidgetStyleEditPane.java
  28. 78
      designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java
  29. 136
      designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditContainerPane.java
  30. 125
      designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditPane.java
  31. 77
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/ButtonStyleDefinedPane.java
  32. 141
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java
  33. 77
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCellWithIcon.java
  34. 133
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewPane.java
  35. 89
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/ImageUtils.java
  36. 50
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/NormalButtonPreviewCell.java
  37. 51
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/RingControlPreviewCell.java
  38. 45
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/RoundControlPreviewCell.java
  39. 36
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/TextPreviewCell.java
  40. 202
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetDisplayFormThemePreviewPane.java
  41. 119
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetDisplayReportThemePreviewPane.java
  42. 35
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetThemeECComponentPreviewPane.java
  43. 112
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetThemeECPreviewPane.java
  44. 248
      designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetThemeECReportPreviewPane.java
  45. 70
      designer-base/src/main/java/com/fr/widgettheme/util/ThemePreviewPaneInitHelper.java
  46. 40
      designer-base/src/main/java/com/fr/widgettheme/util/ThemeTextStylePaneCreator.java
  47. 46
      designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java
  48. 273
      designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java
  49. 59
      designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/FileEditorMobileStyleDefinePane.java
  50. 93
      designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/FreeButtonMobileStyleDefinePane.java
  51. 77
      designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/LabelMobileStyleDefinePane.java
  52. 151
      designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/MobileStyleFontConfigPane.java
  53. 65
      designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/DisplayEnhanceMobileStyleFactory.java
  54. 84
      designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java
  55. BIN
      designer-base/src/main/resources/com/fr/widgettheme/combobox.png
  56. 3
      designer-base/src/main/resources/com/fr/widgettheme/menu.svg
  57. 41
      designer-base/src/test/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPaneTest.java
  58. 2
      designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java
  59. 5
      designer-form/src/main/java/com/fr/design/widget/ui/btn/AbstractExtraButtonPane.java
  60. 5
      designer-form/src/main/java/com/fr/design/widget/ui/designer/ButtonDefinePane.java
  61. 7
      designer-form/src/main/java/com/fr/design/widget/ui/designer/CheckBoxDefinePane.java
  62. 5
      designer-form/src/main/java/com/fr/design/widget/ui/designer/DateEditorDefinePane.java
  63. 5
      designer-form/src/main/java/com/fr/design/widget/ui/designer/DirectWriteEditorDefinePane.java
  64. 2
      designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java
  65. 11
      designer-form/src/main/java/com/fr/design/widget/ui/designer/LabelDefinePane.java
  66. 2
      designer-form/src/main/java/com/fr/design/widget/ui/designer/MultiFileEditorPane.java
  67. 12
      designer-form/src/main/java/com/fr/design/widget/ui/designer/NumberEditorDefinePane.java
  68. 5
      designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java
  69. 5
      designer-form/src/main/java/com/fr/design/widget/ui/designer/btn/ButtonGroupDefinePane.java
  70. 317
      designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java
  71. 83
      designer-form/src/main/java/com/fr/design/widgettheme/LabelSettingPane.java
  72. 50
      designer-form/src/main/java/com/fr/design/widgettheme/ParaButtonSettingPane.java
  73. 57
      designer-form/src/main/java/com/fr/design/widgettheme/ParaEditorSettingPane.java
  74. 68
      designer-form/src/main/java/com/fr/design/widgettheme/ParaNormalButtonSettingPane.java
  75. 31
      designer-form/src/main/java/com/fr/design/widgettheme/ParaSelectEditorSettingPane.java
  76. 48
      designer-form/src/main/java/com/fr/design/widgettheme/ParaTreeEditorSettingPane.java
  77. 45
      designer-form/src/main/java/com/fr/design/widgettheme/StyleSetting.java
  78. 108
      designer-form/src/main/java/com/fr/design/widgettheme/common/ButtonSettingPane.java
  79. 117
      designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java
  80. 136
      designer-form/src/main/java/com/fr/design/widgettheme/common/NormalButtonSettingPane.java
  81. 32
      designer-form/src/main/java/com/fr/design/widgettheme/common/SelectEditorSettingPane.java
  82. 107
      designer-form/src/main/java/com/fr/design/widgettheme/common/TreeEditorSettingPane.java
  83. 134
      designer-form/src/main/java/com/fr/design/widgettheme/processor/WidgetThemeCreatorPaneAdder.java
  84. 115
      designer-form/src/main/java/com/fr/design/widgettheme/processor/WidgetThemeParaCreatorPaneAdder.java
  85. 15
      designer-realize/src/main/java/com/fr/design/actions/replace/action/content/js/SearchChartJSAction.java
  86. 74
      designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java
  87. 11
      designer-realize/src/main/java/com/fr/design/share/SharableManager.java
  88. 42
      designer-realize/src/main/java/com/fr/design/webattr/EditToolBar.java
  89. 11
      designer-realize/src/main/java/com/fr/design/webattr/FToolBar.java
  90. 2
      designer-realize/src/main/java/com/fr/design/webattr/ToolBarPane.java
  91. 13
      designer-realize/src/main/java/com/fr/design/widget/ui/CheckBoxDefinePane.java
  92. 12
      designer-realize/src/main/java/com/fr/design/widget/ui/FieldEditorDefinePane.java
  93. 61
      designer-realize/src/main/java/com/fr/design/widget/ui/btn/FreeButtonDetailPane.java
  94. 2
      designer-realize/src/main/java/com/fr/start/DesignerInitial.java
  95. 8
      designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java
  96. 10
      designer-realize/src/main/java/com/fr/start/MainDesigner.java
  97. 17
      designer-realize/src/main/java/com/fr/start/SplashContext.java
  98. 14
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java
  99. 9
      designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java
  100. 20
      designer-realize/src/main/java/com/fr/start/module/optimized/DesignerPluginActivator.java
  101. Some files were not shown because too many files have changed in this diff Show More

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

@ -308,7 +308,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
private static boolean asyncInitEnvManager() {
AtomicBoolean noEx = new AtomicBoolean(false);
OptimizeUtil.open(DesignerEnvManager.class.getSimpleName().toLowerCase(), OptimizeUtil.Module.COMMON, () -> {
OptimizeUtil.initiateOpen(DesignerEnvManager.class.getSimpleName().toLowerCase(), () -> {
try {
designerEnvManager.initElements(designerEnvManager.getDesignerEnvFile());
noEx.set(true);
@ -899,13 +899,18 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
}
public boolean isCloudAnalyticsDelay() {
return designerPushUpdateConfigManager.isCloudAnalyticsDelay();
return designerPushUpdateConfigManager.isCloudAnalyticsDelay() || designerPushUpdateConfigManager.isUseCloudAnalyticsDelayFirst();
}
public void setCloudAnalyticsDelay(boolean cloudAnalyticsDelay) {
designerPushUpdateConfigManager.setCloudAnalyticsDelay(cloudAnalyticsDelay);
}
public void setUseCloudAnalyticsDelayFirst(boolean useCloudAnalyticsDelayFirst) {
designerPushUpdateConfigManager.setUseCloudAnalyticsDelayFirst(useCloudAnalyticsDelayFirst);
}
/**
* 设计器登录相关配置
*/

159
designer-base/src/main/java/com/fr/design/RPCConnectHandlerCenter.java

@ -0,0 +1,159 @@
package com.fr.design;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.ui.util.UIUtil;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StableUtils;
import com.fr.third.org.apache.http.client.config.RequestConfig;
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
import com.fr.third.org.apache.http.client.methods.HttpGet;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import com.fr.workspace.base.WorkspaceConstants;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.engine.channel.WorkspaceChannelFactory;
import com.fr.workspace.engine.exception.WorkspaceConnectionException;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
/**
* RPC连接处理中心
*
* @author Roger
* @since 11.0
* Created on 2023/12/13
*/
public class RPCConnectHandlerCenter {
private static volatile boolean alerting = false;
private static final int TIMEOUT = 5000;
private static Listener<Workspace> listener = new Listener<Workspace>() {
@Override
public void on(Event event, Workspace workspace) {
//暂时先不做重连处理,3次RPC连接失败后提示切换工作目录
showRPCDisconnectDialog();
}
};
/**
* 开启事件监听
*/
public static void startListener() {
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.listen(WorkspaceEvent.LostConnect, listener);
}
}
/**
* 弹窗提示连接断开
*/
public static void showRPCDisconnectDialog() {
UIUtil.invokeLaterIfNeeded(RPCConnectHandlerCenter::showDialog);
}
/**
* RPC连接测试
*
* @param info 连接信息
* @return 是否连接成功
*/
public static boolean checkRPCConnect(WorkspaceConnectionInfo info) {
try {
return WorkspaceChannelFactory.testConnection(info);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
return false;
}
}
/**
* http连接检测从DesignerSocketIO中移过来的先保留着
*
* @param info 连接信息
* @return 是否连接成功
*/
public static boolean checkHttpConnect(WorkspaceConnectionInfo info) {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(StableUtils.pathJoin(info.getUrl(), WorkspaceConstants.CONTROLLER_PREFIX, WorkspaceConstants.VT));
RequestConfig requestConfig = RequestConfig
.custom()
.setConnectTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build();
httpGet.setConfig(requestConfig);
try {
CloseableHttpResponse response = httpclient.execute(httpGet);
if (isErrorStatus(response.getStatusLine().getStatusCode())) {
//这边nginx做负载,服务器被kill掉,返回的是502,不会抛错,导致checkRPCConnect通过
//针对500-600的错误码加个判断,其他类型的状态码暂不考虑,如果有遇到再处理,不然怕影响范围大
throw new WorkspaceConnectionException("Response " + response.getStatusLine().toString());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
return false;
}
return true;
}
/**
* 提示连接已经断开如果已经在提示中了就直接返回
*/
private static void showDialog() {
if (alerting) {
return;
}
synchronized (RPCConnectHandlerCenter.class) {
if (alerting) {
return;
}
alerting = true;
try {
FineJOptionPane.showMessageDialog(
DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"),
UIManager.getString("OptionPane.messageDialogTitle"),
JOptionPane.ERROR_MESSAGE,
UIManager.getIcon("OptionPane.errorIcon"));
EnvChangeEntrance.getInstance().chooseEnv();
} finally {
alerting = false;
}
}
}
/**
* 错误状态码
* 5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误 这些错误可能是服务器本身的错误而不是请求出错代码 说明
* 500 (服务器内部错误) 服务器遇到错误无法完成请求
* 501 (尚未实施) 服务器不具备完成请求的功能 例如服务器无法识别请求方法时可能会返回此代码
* 502 (错误网关) 服务器作为网关或代理从上游服务器收到无效响应
* 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护) 通常这只是暂时状态
* 504 (网关超时) 服务器作为网关或代理但是没有及时从上游服务器收到请求
* 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本
*
* @param status 错误状态码
* @return 是否是错误状态码
*/
private static boolean isErrorStatus(int status) {
return status >= 500 && status <= 600;
}
/**
* 停止事件监听
*/
public static void stopListener() {
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.stopListen(listener);
}
}
}

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

@ -1122,7 +1122,10 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setUseOptimizedUPM4Adapter(optimizedUPMFlag);
//只有取消掉使用新插件管理器这个选项才需要把useNewPluginFirst置false(意味着用户手动配置了,如果勾选着的话,这个useNewPluginFirst为true就行了)
designerEnvManager.setUseNewPluginFirst(optimizedUPMFlag);
designerEnvManager.setCloudAnalyticsDelay(this.cloudAnalyticsDelayCheckBox.isSelected());
boolean cloudDelayFlag = this.cloudAnalyticsDelayCheckBox.isSelected();
designerEnvManager.setCloudAnalyticsDelay(cloudDelayFlag);
// cloudDelayFlag默认为true,如果用户手动配置过才会是false,则后续的云端运维配置都按照用户意愿来
designerEnvManager.setUseCloudAnalyticsDelayFirst(cloudDelayFlag);
VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager();
vcsConfigManager.setSaveInterval(this.saveIntervalEditor.getValue());
vcsConfigManager.setVcsEnable(this.vcsEnableCheckBox.isSelected());

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

@ -11,6 +11,11 @@ import com.fr.event.Null;
* @date 2019-06-18
*/
public enum DesignerLaunchStatus implements Event<Null> {
/**
* 界面前置事件初始化完成
*/
UI_PRE_INIT_COMPLETE,
/**
* 初始化环境完成
*/
@ -46,4 +51,14 @@ public enum DesignerLaunchStatus implements Event<Null> {
status = state;
EventDispatcher.fire(DesignerLaunchStatus.getStatus());
}
/**
* 设置状态并异步触发事件
*
* @param state 当前启动状态
*/
public static void setStatusAndAsyncFire(DesignerLaunchStatus state) {
status = state;
EventDispatcher.asyncFire(DesignerLaunchStatus.getStatus());
}
}

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

@ -61,6 +61,7 @@ import com.fr.stable.ArrayUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
import javax.swing.Box;
@ -416,10 +417,7 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> implemen
}
private void checkParameter() {
String[] paramTexts = new String[2];
paramTexts[0] = this.sqlTextPane.getText();
paramTexts[1] = this.pageQuery;
Parameter[] parameters = ParameterHelper.analyze4Parameters(paramTexts, false);
Parameter[] parameters = getParameters();
if (parameters.length < 1 && this.editorPane.update().size() < 1) {
return;
@ -443,6 +441,14 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> implemen
refreshParameters();
}
@NotNull
private Parameter[] getParameters() {
String[] paramTexts = new String[2];
paramTexts[0] = SqlUtils.clearSqlComments(this.sqlTextPane.getText());
paramTexts[1] = SqlUtils.clearSqlComments(this.pageQuery);
return ParameterHelper.analyze4Parameters(paramTexts, false);
}
@Override
public void populateBean(DBTableData dbTableData) {
this.dbTableData = dbTableData;

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

@ -153,9 +153,9 @@ public class PluginOperateUtils {
public void run() {
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginContext plugin = PluginManager.getContext(pluginMarker);
boolean isRunning = plugin.isRunning();
PluginTaskCallback modifyStatusCallback = new ModifyStatusCallback(isRunning, jsCallback);
changePluginActive(isRunning, pluginMarker, modifyStatusCallback, plugin);
boolean running = plugin.isRunning() || plugin.isPrepare();
PluginTaskCallback modifyStatusCallback = new ModifyStatusCallback(running, jsCallback);
changePluginActive(running, pluginMarker, modifyStatusCallback, plugin);
}
});
}

4
designer-base/src/main/java/com/fr/design/extra/PluginUtils.java

@ -270,8 +270,8 @@ public class PluginUtils {
jo.put("vendor", pluginContext.getVendor());
jo.put("price", pluginContext.getPrice());
jo.put("requiredJarTime", pluginContext.getRequiredJarTime());
// 前端需求的active实际上是插件的运行状态,通过isRunning()获取
jo.put("active", pluginContext.isRunning());
// 前端需求的active实际上是插件的运行状态,通过isRunning()或isPrepare()获取
jo.put("active", pluginContext.isRunning() || pluginContext.isPrepare());
jo.put("hidden", pluginContext.isHidden());
jo.put("free", pluginContext.isFree());
jo.put("licDamaged", pluginContext.isLicDamaged());

25
designer-form/src/main/java/com/fr/design/widget/ui/designer/component/FontSizeComboPane.java → designer-base/src/main/java/com/fr/design/gui/frpane/FontSizeComboPane.java

@ -1,7 +1,9 @@
package com.fr.design.widget.ui.designer.component;
package com.fr.design.gui.frpane;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.stable.collections.CollectionUtils;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.util.Vector;
@ -13,15 +15,22 @@ public class FontSizeComboPane extends JPanel{
private static final int MAX_FONT_SIZE = 100;
private UIComboBox comboBox;
public FontSizeComboPane(){
initComponent();
this(null);
}
public void initComponent(){
this.setLayout(FRGUIPaneFactory.createBorderLayout());
Vector<Integer> integerList = new Vector<Integer>();
for (int i = 1; i < MAX_FONT_SIZE; i++) {
integerList.add(i);
public FontSizeComboPane(Vector<Integer> fontSizes){
initComponent(fontSizes);
}
public void initComponent(Vector<Integer> fontSizes){
if(CollectionUtils.isEmpty(fontSizes)) {
fontSizes = new Vector<>();
for (int i = 1; i < MAX_FONT_SIZE; i++) {
fontSizes.add(i);
}
}
comboBox = new UIComboBox(integerList);
this.setLayout(FRGUIPaneFactory.createBorderLayout());
comboBox = new UIComboBox(fontSizes);
comboBox.setEditable(true);
this.add(comboBox, BorderLayout.CENTER);
}

64
designer-base/src/main/java/com/fr/design/lock/LockFileReSaveEnum.java

@ -0,0 +1,64 @@
package com.fr.design.lock;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.TemplateUtils;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.stable.StableUtils;
import com.fr.stable.project.ProjectConstants;
/**
* 被锁住的文件重新保存副本时的处理枚举类
*
* @author Roger
* @since 11.0
* Created on 2023/12/21
*/
public enum LockFileReSaveEnum {
/**
* 保存目录树里面的模板副本
*/
TEMPLATE_TREE() {
@Override
public void action() {
FileNode node = TemplateTreePane.getInstance().getFileNode();
if (node == null) {
return;
}
final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, TemplateTreePane.getInstance().getFilePath());
TemplateUtils.createAndReOpenTemplate(
Toolkit.i18nText("Fine_Design_Template_Lock_Copy"),
new FileNodeFILE(new FileNode(selectedFilePath, false)),
false,
true);
}
},
/**
* 保存设计器里面已经打开的模板副本
*/
HISTORY_TEMPLATE_CACHE() {
@Override
public void action() {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (JTemplate.isValid(template)) {
TemplateUtils.createAndOpenTemplate(
Toolkit.i18nText("Fine_Design_Template_Backup"),
new FileNodeFILE(new FileNode(template.getPath(), false)),
true,
true,
//另存之后需要关闭的模板
template);
}
}
};
/**
* 如何保存模板副本
*/
public abstract void action();
}

46
designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java

@ -8,15 +8,14 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.utils.TemplateUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.general.IOUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.base.UserInfo;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
@ -24,9 +23,6 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JPanel;
/**
* @author hades
@ -37,8 +33,11 @@ public class LockInfoDialog extends JDialog {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
public LockInfoDialog(UserInfo userInfo) {
private final LockFileReSaveEnum saveEnum;
public LockInfoDialog(UserInfo userInfo, LockFileReSaveEnum saveEnum) {
super(DesignerContext.getDesignerFrame());
this.saveEnum = saveEnum;
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
panel.add(createContentPane(userInfo), BorderLayout.CENTER);
@ -94,16 +93,7 @@ public class LockInfoDialog extends JDialog {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
FileNode node = TemplateTreePane.getInstance().getFileNode();
if (node == null) {
return;
}
final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, TemplateTreePane.getInstance().getFilePath());
TemplateUtils.createAndReOpenTemplate(
Toolkit.i18nText("Fine_Design_Template_Lock_Copy"),
new FileNodeFILE(new FileNode(selectedFilePath, false)),
false,
true);
saveEnum.action();
}
});
cancelButton.addActionListener(new ActionListener() {
@ -118,9 +108,25 @@ public class LockInfoDialog extends JDialog {
}
/**
* 显示模板被人锁住了的弹窗信息
*
* @param userInfo 拥有锁的用户信息
*/
public static void show(UserInfo userInfo) {
DesignerFrameFileDealerPane.getInstance().refreshRightToolBarBy(TemplateTreePane.getInstance().getFileNode());
new LockInfoDialog(userInfo);
new LockInfoDialog(userInfo, LockFileReSaveEnum.TEMPLATE_TREE);
}
/**
* 显示模板被人锁住了的弹窗信息,并以指定方式保存副本模板
*
* @param userInfo 拥有锁的用户信息
* @param saveEnum 指定保存副本模板的处理方式
*/
public static void show(UserInfo userInfo, LockFileReSaveEnum saveEnum) {
DesignerFrameFileDealerPane.getInstance().refreshRightToolBarBy(TemplateTreePane.getInstance().getFileNode());
new LockInfoDialog(userInfo, saveEnum);
}
}

56
designer-base/src/main/java/com/fr/design/lock/TemplateLockInfoReSave.java

@ -0,0 +1,56 @@
package com.fr.design.lock;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.JTemplate;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.log.FineLoggerFactory;
import com.fr.report.lock.LockInfoOperator;
import com.fr.stable.collections.CollectionUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import java.util.List;
/**
* 更新模板锁信息
*
* @author Roger
* @since 11.0
* Created on 2023/12/11
*/
public class TemplateLockInfoReSave {
private static Listener<Workspace> listener = new Listener<Workspace>() {
@Override
public void on(Event event, Workspace workspace) {
List<JTemplate<?, ?>> templates = HistoryTemplateListCache.getInstance().getHistoryList();
if (CollectionUtils.isEmpty(templates)) {
return;
}
String[] paths = templates.stream().map(JTemplate::getPath).toArray(String[]::new);
String[] lockedPath = WorkContext.getCurrent().get(LockInfoOperator.class).lockTemplates(paths);
FineLoggerFactory.getLogger().warn("template lock failed:{}", String.join(";", lockedPath));
}
};
/**
* 启动监听
*/
public static void startListener() {
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.listen(WorkspaceEvent.ConnectSuccess, listener);
}
}
/**
* 停止事件监听
*/
public static void stopListener() {
if (!WorkContext.getCurrent().isLocal()) {
EventDispatcher.stopListen(listener);
}
}
}

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

@ -92,6 +92,7 @@ import com.fr.plugin.observer.PluginEventListener;
import com.fr.plugin.observer.PluginEventType;
import com.fr.plugin.observer.PluginListenerRegistration;
import com.fr.report.InconsistentLockException;
import com.fr.report.LockedException;
import com.fr.report.UnLockedException;
import com.fr.report.cell.Elem;
import com.fr.report.cell.cellattr.CellImage;
@ -101,7 +102,9 @@ import com.fr.stable.Filter;
import com.fr.stable.ProductConstants;
import com.fr.stable.StringUtils;
import com.fr.stable.core.UUID;
import com.fr.widgettheme.designer.WidgetThemeDisplayAction;
import com.fr.workspace.WorkContext;
import com.fr.workspace.base.UserInfo;
import com.fr.workspace.server.lock.TplOperator;
import javax.swing.BorderFactory;
@ -1058,13 +1061,20 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
protected void checkBeforeSave() throws Exception {
// 保存前校验下未解锁
if (WorkContext.getCurrent().get(LockInfoOperator.class).isTplUnLocked(getEditingFILE().getPath())) {
LockInfoOperator lockInfoOperator = WorkContext.getCurrent().get(LockInfoOperator.class);
String path = getEditingFILE().getPath();
if (lockInfoOperator.isTplUnLocked(path)) {
throw new UnLockedException();
}
//睡眠超过90s之后,锁信息会被清掉,之后其他人可能打开模板进行锁定,所以定这里还判断一下模板是否被其他人锁
UserInfo userInfo = lockInfoOperator.getUserInfo(path);
if (userInfo != null) {
throw new LockedException(userInfo);
}
// 过滤掉本地文件
boolean localFile = getEditingFILE() instanceof FileFILE;
boolean inconsistent = !localFile && getEditingFILE().exists()
&& !WorkContext.getCurrent().get(LockInfoOperator.class).isConsistentLock(getEditingFILE().getPath());
&& !lockInfoOperator.consistentCheckAndLockIfNecessary(path);
if (inconsistent) {
throw new InconsistentLockException();
}
@ -1126,6 +1136,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
//查找替换
tplMenu.addShortCut(new NameSeparator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Replace_Name_Separate")));
tplMenu.addShortCut((ShortCut) DesignModuleFactory.getITReplaceAction());
tplMenu.insertShortCut(1, new WidgetThemeDisplayAction<>(this));
return new MenuDef[]{tplMenu};
}

45
designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStylePane.java

@ -5,10 +5,6 @@ import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.BasicPane;
import com.fr.design.fun.MobileWidgetStyleProvider;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.mobile.processor.MobileStyleDefinePaneCreator;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WScaleLayout;
import com.fr.form.ui.mobile.MobileCommonExtraStyle;
@ -16,9 +12,8 @@ import com.fr.form.ui.mobile.MobileStyle;
import com.fr.form.ui.mobile.StyleClassMap;
import com.fr.form.ui.widget.CRBoundsWidget;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.observer.PluginEventType;
import com.fr.stable.ArrayUtils;
import com.fr.widgettheme.widget.mobile.provider.WidgetThemeMobileStyleDefinePaneCreator;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
@ -43,8 +38,6 @@ public class MobileStylePane extends BasicPane {
private JList styleList;
private Map<String, BasicBeanPane<MobileStyle>> map = new HashMap<>();
private boolean checkFlag = true;
public MobileStylePane(Widget widget) {
if (widget instanceof WScaleLayout) {
this.widget = ((CRBoundsWidget) ((WScaleLayout) widget).getBoundsWidget()).getWidget();
@ -81,7 +74,6 @@ public class MobileStylePane extends BasicPane {
private void init() {
initComponent();
initPluginListener();
}
private void initComponent() {
@ -129,11 +121,10 @@ public class MobileStylePane extends BasicPane {
listModel.addElement(displayName);
try {
MobileStyleDefinePaneCreator processor = ExtraDesignClassManager.getInstance().getSingle(MobileStyleDefinePaneCreator.XML_TAG);
BasicBeanPane<MobileStyle> mobileStyleBasicBeanPane = new MobileStyleDefinePane(widget, appearanceClazz, mobileStyleClazz);
if (checkFlag && processor != null && processor.createBaseBeanPane(widget, appearanceClazz, mobileStyleClazz) != null) {
mobileStyleBasicBeanPane = processor.createBaseBeanPane(widget, appearanceClazz, mobileStyleClazz);
Class<? extends MobileCommonExtraStyle> extraStyle = processor.classForCommonExtraStyle(widget);
if (WidgetThemeMobileStyleDefinePaneCreator.createBaseBeanPane(widget, appearanceClazz, mobileStyleClazz) != null) {
mobileStyleBasicBeanPane = WidgetThemeMobileStyleDefinePaneCreator.createBaseBeanPane(widget, appearanceClazz, mobileStyleClazz);
Class<? extends MobileCommonExtraStyle> extraStyle = WidgetThemeMobileStyleDefinePaneCreator.classForCommonExtraStyle(widget);
if (extraStyle != null) {
StyleClassMap.putCommonStyle(extraStyle.getName(), extraStyle.getName());
}
@ -164,32 +155,4 @@ public class MobileStylePane extends BasicPane {
return styleProviders;
}
private void initPluginListener() {
EventDispatcher.listen(PluginEventType.AfterRun, new Listener<PluginContext>() {
@Override
public void on(Event event, PluginContext pluginContext) {
if (pluginContext.getRuntime().contain(MobileStyleDefinePaneCreator.XML_TAG)) {
checkFlag = true;
refreshDockingView();
}
}
});
EventDispatcher.listen(PluginEventType.BeforeStop, new Listener<PluginContext>() {
@Override
public void on(Event event, PluginContext pluginContext) {
if (pluginContext.getRuntime().contain(MobileStyleDefinePaneCreator.XML_TAG)) {
checkFlag = false;
refreshDockingView();
}
}
});
}
private void refreshDockingView() {
removeAll();
initComponent();
populate(widget.getMobileStyle());
this.updateUI();
this.repaint();
}
}

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

@ -11,7 +11,11 @@ import com.fr.design.mainframe.theme.edit.ChartStyleFormEditPane;
import com.fr.design.mainframe.theme.edit.ComponentStyleEditPane;
import com.fr.design.mainframe.theme.edit.FormBodyStyleEditPane;
import com.fr.design.mainframe.theme.preview.FormThemePreviewPane;
import com.fr.design.mainframe.theme.preview.ReportThemePreviewPane;
import com.fr.design.mainframe.theme.processor.ThemePreviewPaneProcessor;
import com.fr.widgettheme.theme.panel.WidgetDisplayFormThemePreviewPane;
import com.fr.widgettheme.theme.panel.WidgetDisplayReportThemePreviewPane;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import javax.swing.JPanel;
@ -38,7 +42,7 @@ public class FormThemeProfilePane extends TemplateThemeProfilePane<FormTheme> {
if (processor != null) {
return processor.createFormThemePreviewPane();
}
return new FormThemePreviewPane();
return WidgetThemeDesignerUtils.enableWidgetEnhance() ? new WidgetDisplayFormThemePreviewPane() : new FormThemePreviewPane();
}
@Override

4
designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java

@ -7,6 +7,8 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.theme.edit.ReportBodyStyleEditPane;
import com.fr.design.mainframe.theme.preview.ReportThemePreviewPane;
import com.fr.design.mainframe.theme.processor.ThemePreviewPaneProcessor;
import com.fr.widgettheme.theme.panel.WidgetDisplayReportThemePreviewPane;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
/**
* @author Starryi
@ -26,7 +28,7 @@ public class ReportThemeProfilePane extends TemplateThemeProfilePane<ReportTheme
if (processor != null) {
return processor.createReportThemePreviewPane();
}
return new ReportThemePreviewPane();
return WidgetThemeDesignerUtils.enableWidgetEnhance() ? new WidgetDisplayReportThemePreviewPane() : new ReportThemePreviewPane();
}
@Override

7
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java

@ -5,6 +5,7 @@ import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.base.theme.settings.ThemedColorScheme;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
@ -28,6 +29,8 @@ import com.fr.general.GeneralContext;
import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.StringUtils;
import com.fr.widgettheme.theme.edit.ParamContainerStyleEditPane;
import com.fr.widgettheme.theme.edit.widget.WidgetStyleEditContainerPane;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
@ -202,6 +205,10 @@ public abstract class TemplateThemeEditorPane<T extends TemplateTheme> extends J
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
if(WidgetThemeDesignerUtils.enableWidgetEnhance()) {
extraPaneList.add(new ParamContainerStyleEditPane<>());
extraPaneList.add(new WidgetStyleEditContainerPane<>());
}
Set<TemplateThemePaneProvider<T>> providers = ExtraDesignClassManager.getInstance().getArray(TemplateThemePaneProvider.XML_TAG);
for (TemplateThemePaneProvider<T> provider : providers) {
insertShortCut(provider.getInsertPosition(extraPaneList.size()), provider.getTab());

15
designer-base/src/main/java/com/fr/design/update/push/DesignerPushUpdateConfigManager.java

@ -15,7 +15,8 @@ public class DesignerPushUpdateConfigManager implements XMLReadable, XMLWriter {
private static DesignerPushUpdateConfigManager singleton;
private boolean autoPushUpdateEnabled = true; // 是否开启自动推送更新
private boolean cloudAnalyticsDelay = false; // 是否云端运维模块延迟启动
private boolean cloudAnalyticsDelay = true; // 是否云端运维模块延迟启动
private boolean useCloudAnalyticsDelayFirst = true; // 默认打开,如果有手动改延迟启动配置则按客户配置的来
private String lastIgnoredVersion = StringUtils.EMPTY; // 最近一次跳过的更新版本
private DesignerPushUpdateConfigManager() {
@ -33,7 +34,8 @@ public class DesignerPushUpdateConfigManager implements XMLReadable, XMLWriter {
if (reader.isAttr()) {
this.setAutoPushUpdateEnabled(reader.getAttrAsBoolean("autoPushUpdateEnabled", true));
this.setLastIgnoredVersion(reader.getAttrAsString("lastIgnoredVersion", StringUtils.EMPTY));
this.setCloudAnalyticsDelay(reader.getAttrAsBoolean("cloudAnalyticsDelay", false));
this.setCloudAnalyticsDelay(reader.getAttrAsBoolean("cloudAnalyticsDelay", true));
this.setUseCloudAnalyticsDelayFirst(reader.getAttrAsBoolean("useCloudAnalyticsDelayFirst", true));
}
}
@ -43,6 +45,7 @@ public class DesignerPushUpdateConfigManager implements XMLReadable, XMLWriter {
writer.attr("autoPushUpdateEnabled", autoPushUpdateEnabled);
writer.attr("lastIgnoredVersion", lastIgnoredVersion);
writer.attr("cloudAnalyticsDelay", cloudAnalyticsDelay);
writer.attr("useCloudAnalyticsDelayFirst", useCloudAnalyticsDelayFirst);
writer.end();
}
@ -69,4 +72,12 @@ public class DesignerPushUpdateConfigManager implements XMLReadable, XMLWriter {
public void setCloudAnalyticsDelay(boolean cloudAnalyticsDelay) {
this.cloudAnalyticsDelay = cloudAnalyticsDelay;
}
public boolean isUseCloudAnalyticsDelayFirst() {
return useCloudAnalyticsDelayFirst;
}
public void setUseCloudAnalyticsDelayFirst(boolean useCloudAnalyticsDelayFirst) {
this.useCloudAnalyticsDelayFirst = useCloudAnalyticsDelayFirst;
}
}

32
designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java

@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.SwingWorker;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
@ -65,14 +66,7 @@ public class TemplateUtils {
if (file == null) {
return;
}
Runnable doAfterCreateTemplate;
//判断一下要保存的文件是否已打开
int index = HistoryTemplateListCache.getInstance().contains(file);
JTemplate template = null;
if (index != -1) {
template = HistoryTemplateListCache.getInstance().getHistoryList().get(index);
}
createAndOpenTemplate0(file, oldPath, createByEditingTemplate, openNewTemplate, template);
createAndOpenTemplate0(file, oldPath, createByEditingTemplate, openNewTemplate, null);
}
/**
@ -181,23 +175,29 @@ public class TemplateUtils {
* @param template 需要关闭的模板
*/
private static void openNewTemplateAndCloseOldTemplate(FILE file, boolean openNewTemplate, @Nullable JTemplate<?, ?> template) {
new SwingWorker<Boolean, Void>() {
new SwingWorker<List<JTemplate<?,?>>, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
protected List<JTemplate<?,?>> doInBackground() throws Exception {
List<JTemplate<?,?>> needCloseTemplate = new ArrayList<>();
//判断一下要保存的副本文件是否已打开
int index = HistoryTemplateListCache.getInstance().contains(file);
if (index != -1) {
WorkContext.getCurrent().get(TplOperator.class).closeAndFreeFile(file.getPath());
needCloseTemplate.add(HistoryTemplateListCache.getInstance().getHistoryList().get(index));
}
if (JTemplate.isValid(template)) {
//给要关闭的模板解锁
WorkContext.getCurrent().get(TplOperator.class).closeAndFreeFile(template.getPath());
return true;
needCloseTemplate.add(template);
}
return false;
return needCloseTemplate;
}
@Override
protected void done() {
try {
if (get()) {
//模板释放锁成功后关闭该模板
HistoryTemplateListCache.getInstance().closeSelectedReport(template);
}
//获取需要关闭的模板
List<JTemplate<?, ?>> jTemplates = get();
jTemplates.forEach(jTemplate -> HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate));
if (openNewTemplate) {
DesignerContext.getDesignerFrame().openTemplate(file);
}

52
designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java

@ -2,18 +2,17 @@ package com.fr.design.worker.save;
import com.fr.common.exception.ThrowableHandler;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.i18n.Toolkit;
import com.fr.design.lock.LockFileReSaveEnum;
import com.fr.design.lock.LockInfoDialog;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.TemplateUtils;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.general.IOUtils;
import com.fr.report.InconsistentLockException;
import com.fr.report.LockedException;
import com.fr.report.UnLockedException;
import com.fr.workspace.base.UserInfo;
import com.fr.workspace.exception.DiskSpaceFullException;
import com.fr.report.InconsistentLockException;
import java.awt.Frame;
import javax.swing.JOptionPane;
@ -89,6 +88,25 @@ public class SaveFailureHandler implements ThrowableHandler {
}
},
LOCKED {
@Override
public boolean process(Throwable e) {
LockedException exception = null;
if (e.getCause() instanceof LockedException) {
exception = (LockedException) e.getCause();
}
if (e instanceof LockedException) {
exception = (LockedException) e;
}
if (exception != null) {
UserInfo userInfo = exception.getUserInfo();
LockInfoDialog.show(userInfo, LockFileReSaveEnum.HISTORY_TEMPLATE_CACHE);
return true;
}
return false;
}
},
Other {
@Override
public boolean process(Throwable e) {
@ -112,16 +130,7 @@ public class SaveFailureHandler implements ThrowableHandler {
IOUtils.readIcon("/com/fr/design/images/warnings/warning32.png"),
new Object[] {Toolkit.i18nText("Fine_Design_Template_SaveAs_Backup"), Toolkit.i18nText("Fine-Design_Basic_Button_Cancel")}, null);
if (option == JOptionPane.YES_OPTION) {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (JTemplate.isValid(template)) {
TemplateUtils.createAndOpenTemplate(
Toolkit.i18nText("Fine_Design_Template_Backup"),
new FileNodeFILE(new FileNode(template.getPath(), false)),
true,
true,
//另存之后需要关闭的模板
template);
}
LockFileReSaveEnum.HISTORY_TEMPLATE_CACHE.action();
}
}
@ -134,16 +143,7 @@ public class SaveFailureHandler implements ThrowableHandler {
IOUtils.readIcon("/com/fr/design/images/warnings/warning32.png"),
new Object[] {Toolkit.i18nText("Fine_Design_Template_SaveAs_Backup"), Toolkit.i18nText("Fine-Design_Basic_Button_Cancel")}, null);
if (option == JOptionPane.YES_OPTION) {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (JTemplate.isValid(template)) {
TemplateUtils.createAndOpenTemplate(
Toolkit.i18nText("Fine_Design_Template_Backup"),
new FileNodeFILE(new FileNode(template.getPath(), false)),
true,
true,
//另存之后需要关闭的模板
template);
}
LockFileReSaveEnum.HISTORY_TEMPLATE_CACHE.action();
}
}

2
designer-base/src/main/java/com/fr/start/server/FineEmbedServer.java

@ -2,6 +2,7 @@ package com.fr.start.server;
import com.fr.event.EventDispatcher;
import com.fr.module.ModuleContext;
import com.fr.plugin.listener.SpecialPluginEvent;
/**
* Created by juhaoyu on 2018/6/6.
@ -15,6 +16,7 @@ public abstract class FineEmbedServer {
public synchronized static void start() {
onStarting = true;
EventDispatcher.fire(SpecialPluginEvent.WITH_SERVER_AND_NOT_START_IN_REMOTE);
EventDispatcher.fire(EmbedServerEvent.BeforeStart);
ModuleContext.getModule(FineEmbedServerActivator.class).start();
onStarting = false;

2
designer-base/src/main/java/com/fr/startup/metric/DesignerStartupModel.java

@ -96,7 +96,7 @@ public class DesignerStartupModel {
}
private void fillInfo() {
this.setJdkVersion(System.getProperty("java.runtime.version"));
this.setJdkVersion(System.getProperty("java.version"));
MachineInfo info = new MachineInfo();
AbstractOperatingSystem operatingSystem = OperatingSystem.getOperatingSystem();
info.setSystem(operatingSystem.getDisplayString());

102
designer-base/src/main/java/com/fr/widgettheme/ParameterBackgroundStyleSettingPane.java

@ -0,0 +1,102 @@
package com.fr.widgettheme;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.widget.accessibles.AccessibleBackgroundEditor;
import com.fr.form.ui.container.WParameterLayout;
import com.fr.general.Background;
import org.jetbrains.annotations.Nullable;
import javax.swing.JPanel;
import java.awt.BorderLayout;
/**
* 设计器参数面板的高级设置增加背景的主题样式设置
*
* @author Bruce.Deng
* @since 11.0
* Created on 2023/2/20
*/
public class ParameterBackgroundStyleSettingPane extends BasicBeanPane<WParameterLayout> {
public static final String[] FOLLOWING_THEME_STRING_ARRAYS = new String[]{
Toolkit.i18nText("Fine-Design_Widget_Follow_Theme"),
Toolkit.i18nText("Fine-Design_Widget_Theme_Custom")
};
private UIButtonGroup head;
private JPanel customPane;
private AccessibleBackgroundEditor background;
public ParameterBackgroundStyleSettingPane() {
this.setLayout(new BorderLayout(0, LayoutConstants.VGAP_SMALL));
head = new UIButtonGroup(FOLLOWING_THEME_STRING_ARRAYS) {
@Override
public void setSelectedIndex(int newSelectedIndex, boolean fireChanged) {
//表示从跟随主题切换到自定义
if (selectedIndex != newSelectedIndex && newSelectedIndex == 1) {
background.setValue(getThemeBackground());
}
super.setSelectedIndex(newSelectedIndex, fireChanged);
}
};
customPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
background = new AccessibleBackgroundEditor();
customPane.add(background);
this.add(head, BorderLayout.NORTH);
this.add(customPane, BorderLayout.CENTER);
}
private void attributeChange() {
customPane.setVisible(head.getSelectedIndex() == 1);
}
@Override
public void populateBean(WParameterLayout wParameterLayout) {
if (wParameterLayout.isBackgroundFollowTheme()) {
head.setSelectedIndex(0);
} else {
head.setSelectedIndex(1);
background.setValue(wParameterLayout.getBackground());
}
attributeChange();
}
@Override
@Nullable
public WParameterLayout updateBean() {
return null;
}
@Override
public void updateBean(WParameterLayout wParameterLayout) {
attributeChange();
if (head.getSelectedIndex() != 1) {
wParameterLayout.setBackgroundFollowTheme(true);
wParameterLayout.setBackground(getThemeBackground());
} else {
wParameterLayout.setBackgroundFollowTheme(false);
wParameterLayout.setBackground((Background) background.getValue());
}
}
private Background getThemeBackground() {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (JTemplate.isValid(template)) {
TemplateTheme theme = template.getTemplateTheme();
return theme.getParamContainerStyle().getBackground();
}
return (Background) background.getValue();
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Widget_Theme_ParamContainer_Background");
}
}

50
designer-base/src/main/java/com/fr/widgettheme/designer/WidgetThemeDisplayAction.java

@ -0,0 +1,50 @@
package com.fr.widgettheme.designer;
import com.fr.base.io.BaseBook;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.JTemplateAction;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.widgettheme.control.attr.WidgetDisplayEnhanceMarkAttr;
import java.awt.event.ActionEvent;
/**
* 控件主题显示增强菜单action
*
* @author Bruce.Deng
* @since 11.0
* Created on 2022/11/28
*/
public class WidgetThemeDisplayAction<T extends JTemplate<?, ?>> extends JTemplateAction<T> {
public WidgetThemeDisplayAction(T jwb) {
super(jwb);
setName(Toolkit.i18nText("Fine-Design_Widget_Display_Enhance"));
this.setSmallIcon(IconUtils.readIcon("/com/fr/widgettheme/menu.svg"));
}
@Override
public void actionPerformed(ActionEvent e) {
final T jTemplate = getEditingComponent();
if (!JTemplate.isValid(jTemplate)) {
return;
}
BaseBook baseBook = jTemplate.getTarget();
WidgetDisplayEnhanceMarkAttr attr = WidgetThemeDesignerUtils.getStrongestControlAttrFromTemplate(baseBook);
final WidgetThemeDisplayConfigPane configPane = new WidgetThemeDisplayConfigPane();
configPane.populate(attr);
configPane.showSmallWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
baseBook.addAttrMark(configPane.update());
jTemplate.fireTargetModified();
HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().activeOldJTemplate();
}
}).setVisible(true);
}
}

81
designer-base/src/main/java/com/fr/widgettheme/designer/WidgetThemeDisplayConfigPane.java

@ -0,0 +1,81 @@
package com.fr.widgettheme.designer;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.widgettheme.control.attr.WidgetDisplayEnhanceMarkAttr;
import javax.swing.JPanel;
import java.awt.Color;
/**
* 控件主题显示增强配置窗口
*
* @author Bruce.Deng
* @since 11.0
* Created on 2022/11/28
*/
public class WidgetThemeDisplayConfigPane extends BasicPane {
private UICheckBox widgetEnhance;
public WidgetThemeDisplayConfigPane() {
initComponents();
}
private void initComponents() {
VerticalFlowLayout layout = new VerticalFlowLayout();
layout.setAlignLeft(true);
this.setLayout(layout);
JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.add(northPane);
widgetEnhance = new UICheckBox(Toolkit.i18nText("Fine-Design_Widget_Enable_Display_Enhance"));
widgetEnhance.setSelected(true);
northPane.add(widgetEnhance);
JPanel southPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.add(southPane);
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Widget_Display_Enhance_Tip"));
label.setForeground(Color.GRAY);
southPane.add(label);
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Widget_Display_Enhance");
}
/**
* 根据属性填充pane选项
*
* @param widgetDisplayEnhanceMarkAttr 控件显示增强属性
*/
public void populate(WidgetDisplayEnhanceMarkAttr widgetDisplayEnhanceMarkAttr) {
if (widgetDisplayEnhanceMarkAttr == null) {
widgetDisplayEnhanceMarkAttr = new WidgetDisplayEnhanceMarkAttr();
}
widgetEnhance.setSelected(widgetDisplayEnhanceMarkAttr.isWidgetEnhance());
}
/**
* 更新
*/
public WidgetDisplayEnhanceMarkAttr update() {
WidgetDisplayEnhanceMarkAttr attr = new WidgetDisplayEnhanceMarkAttr();
attr.setWidgetEnhance(widgetEnhance.isSelected());
if (widgetEnhance.isSelected()) {
collectWidgetDisplayEnhanceRecord();
}
return attr;
}
/**
* 记录埋点信息具体实现在云端运维插件这里只作为切入点
*/
private void collectWidgetDisplayEnhanceRecord() {
//记录埋点
}
}

88
designer-base/src/main/java/com/fr/widgettheme/theme/edit/ParamContainerBackgroundPane.java

@ -0,0 +1,88 @@
package com.fr.widgettheme.theme.edit;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.event.UIObserverListener;
import com.fr.design.fun.BackgroundQuickUIProvider;
import com.fr.design.gui.style.BackgroundPane;
import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.ColorBackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.GradientBackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.ImageBackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.NullBackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.PatternBackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.TextureBackgroundQuickPane;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 参数面板背景编辑窗口
*
* @author Bruce.Deng
* @since 11.0
* Created on 2023/1/5
*/
public class ParamContainerBackgroundPane extends BackgroundPane {
private NullBackgroundQuickPane nullBackgroundPane;
private ColorBackgroundQuickPane colorBackgroundPane;
private ImageBackgroundQuickPane imageBackgroundPane;
private GradientBackgroundQuickPane gradientBackgroundPane;
private TextureBackgroundQuickPane textureBackgroundPane;
private PatternBackgroundQuickPane patternBackgroundPane;
public ParamContainerBackgroundPane() {
super();
}
@Override
protected BackgroundQuickPane[] supportKindsOfBackgroundUI() {
nullBackgroundPane = new NullBackgroundQuickPane();
colorBackgroundPane = new ColorBackgroundQuickPane(true);
colorBackgroundPane.registerChangeListener(this::fireStateChanged);
imageBackgroundPane = new ImageBackgroundQuickPane();
imageBackgroundPane.registerChangeListener(this::fireStateChanged);
gradientBackgroundPane = createGradientBackgroundQuickPane();
gradientBackgroundPane.registerChangeListener(this::fireStateChanged);
textureBackgroundPane = new TextureBackgroundQuickPane();
textureBackgroundPane.registerChangeListener(this::fireStateChanged);
patternBackgroundPane = new PatternBackgroundQuickPane();
patternBackgroundPane.registerChangeListener(this::fireStateChanged);
return createBackgroundQuickPanes();
}
private BackgroundQuickPane[] createBackgroundQuickPanes() {
List<BackgroundQuickPane> kinds = new ArrayList<>();
kinds.add(nullBackgroundPane);
kinds.add(colorBackgroundPane);
kinds.add(imageBackgroundPane);
kinds.add(gradientBackgroundPane);
kinds.add(textureBackgroundPane);
kinds.add(patternBackgroundPane);
Set<BackgroundQuickUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(BackgroundQuickUIProvider.MARK_STRING);
for (BackgroundQuickUIProvider provider : providers) {
BackgroundQuickPane newTypePane = provider.appearanceForBackground();
newTypePane.registerChangeListener(this::fireStateChanged);
kinds.add(newTypePane);
}
return kinds.toArray(new BackgroundQuickPane[kinds.size()]);
}
protected GradientBackgroundQuickPane createGradientBackgroundQuickPane() {
// 使用默认的150宽度构建渐变条
return new GradientBackgroundQuickPane();
}
}

84
designer-base/src/main/java/com/fr/widgettheme/theme/edit/ParamContainerStyleEditPane.java

@ -0,0 +1,84 @@
package com.fr.widgettheme.theme.edit;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.AbstractThemedParamContainerStyle;
import com.fr.base.theme.settings.DefaultThemedParamContainerStyle;
import com.fr.widgettheme.theme.widget.style.ThemedParamContainerStyle;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
/**
* 参数面板样式编辑pane
*
* @author Bruce.Deng
* @since 11.0
* Created on 2022/12/16
*/
public class ParamContainerStyleEditPane<T extends TemplateTheme> extends BasicBeanPane<T> {
public static final int LABEL_WIDTH = 60;
public static final int SETTING_WIDTH = 193;
private final ParamContainerBackgroundPane backgroundPane;
public ParamContainerStyleEditPane() {
backgroundPane = new ParamContainerBackgroundPane();
double p = TableLayout.PREFERRED;
JPanel uiLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
uiLabelPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Background")), BorderLayout.NORTH);
uiLabelPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
JPanel backgroundLabeledPane = TableLayoutHelper.createCommonTableLayoutPane(
new Component[][]{ new Component[] { uiLabelPane, backgroundPane } },
new double[] { p }, new double[] { LABEL_WIDTH, SETTING_WIDTH}, IntervalConstants.INTERVAL_L1
);
backgroundLabeledPane.setBorder(BorderFactory.createEmptyBorder(
IntervalConstants.INTERVAL_L1,
IntervalConstants.INTERVAL_L1,
IntervalConstants.INTERVAL_L1,
IntervalConstants.INTERVAL_L1
));
this.add(backgroundLabeledPane);
setBorder(BorderFactory.createEmptyBorder());
}
@Override
public void populateBean(T t) {
AbstractThemedParamContainerStyle paramContainerStyle = t.getParamContainerStyle();
if (paramContainerStyle == null || paramContainerStyle instanceof DefaultThemedParamContainerStyle) {
paramContainerStyle = new ThemedParamContainerStyle();
t.setParamContainerStyle(paramContainerStyle);
}
backgroundPane.populateBean(paramContainerStyle.getBackground());
}
@Override
public T updateBean() {
return null;
}
@Override
public void updateBean(T t) {
ThemedParamContainerStyle style = (ThemedParamContainerStyle) t.getParamContainerStyle();
if (style == null) {
style = new ThemedParamContainerStyle();
t.setParamContainerStyle(style);
}
style.setBackground(backgroundPane.update());
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Widget_Theme_ParamContainer");
}
}

121
designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/DesktopWidgetStyleEditPane.java

@ -0,0 +1,121 @@
package com.fr.widgettheme.theme.edit.widget;
import com.fr.base.background.ColorBackground;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.widgettheme.theme.widget.style.BorderStyle;
import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.widgettheme.util.ThemeTextStylePaneCreator;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import java.awt.Component;
/**
* 桌面端主题面板
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/3/28
*/
public class DesktopWidgetStyleEditPane<T extends TemplateTheme> extends WidgetStyleEditPane<T> {
// 风格1
protected UIRadioButton style1;
// 风格2
protected UIRadioButton style2;
/**
* 下拉面板背景颜色
*/
private NewColorSelectBox selectBackgroundColorBox;
public DesktopWidgetStyleEditPane() {
super();
}
@Override
public Component[][] generateComponent() {
initStyleEditor();
initSelectBackgroundColorBox();
// 容纳风格1和风格2的panel
JPanel stylePane = new JPanel(FRGUIPaneFactory.createBoxFlowLayout());
stylePane.add(style1);
stylePane.add(style2);
return new Component[][]{
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color")), colorSelectBox},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Style")), stylePane},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Line")), lineComboBox},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Radius")), borderRadiusSpinner},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style")), ThemeTextStylePaneCreator.create(fontSizePane, fontColorButton)},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Background_Select_Box")), selectBackgroundColorBox}
};
}
private void initStyleEditor() {
style1 = new UIRadioButton(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_1"));
style2 = new UIRadioButton(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_2"));
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(style1);
buttonGroup.add(style2);
}
private void initSelectBackgroundColorBox() {
selectBackgroundColorBox = new NewColorSelectBox(140, true);
selectBackgroundColorBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR);
}
@Override
public void populateBean(T t) {
ThemedWidgetStyle style = (ThemedWidgetStyle) t.getWidgetStyle();
if (style == null) {
style = new ThemedWidgetStyle();
t.setWidgetStyle(style);
}
if (style.getStyleType() == 1) {
style1.setSelected(true);
} else {
style2.setSelected(true);
}
colorSelectBox.setSelectObject(style.getThemeColor());
lineComboBox.setSelectedLineStyle(style.getBorderStyle().getLineType());
borderRadiusSpinner.setValue(style.getBorderStyle().getRadius());
fontSizePane.setValue(style.getTextStyle().getFontSize());
fontColorButton.setColor(style.getTextStyle().getFontColor());
selectBackgroundColorBox.setSelectObject(style.getSelectBackgroundColor());
}
@Override
public void updateBean(T t) {
ThemedWidgetStyle style = (ThemedWidgetStyle) t.getWidgetStyle();
if (style == null) {
style = new ThemedWidgetStyle();
t.setWidgetStyle(style);
}
style.setThemeColor(colorSelectBox.getSelectObject());
BorderStyle borderStyle = new BorderStyle();
borderStyle.setLineType(lineComboBox.getSelectedLineStyle());
borderStyle.setRadius((int) borderRadiusSpinner.getValue());
style.setBorderStyle(borderStyle);
ThemeTextStyle textStyle = new ThemeTextStyle();
textStyle.setFontSize(fontSizePane.getValue());
textStyle.setFontColor(fontColorButton.getColor());
style.setTextStyle(textStyle);
ButtonBackgroundStyle buttonBackgroundStyle = new ButtonBackgroundStyle();
ColorBackground buttonBackground = ColorBackground.getInstance(style.getThemeColor());
buttonBackgroundStyle.setInitialBackground(buttonBackground);
buttonBackgroundStyle.setOverBackground(buttonBackground);
buttonBackgroundStyle.setClickBackground(buttonBackground);
style.setButtonBackgroundStyle(buttonBackgroundStyle);
style.setStyleType(style1.isSelected() ? 1 : 2);
style.setSelectBackgroundColor(selectBackgroundColorBox.getSelectObject());
}
}

78
designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/MobileWidgetStyleEditPane.java

@ -0,0 +1,78 @@
package com.fr.widgettheme.theme.edit.widget;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.widgettheme.theme.widget.style.BorderStyle;
import com.fr.widgettheme.theme.widget.style.MobileThemedWidgetStyle;
import com.fr.design.gui.icombobox.LineComboBox;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import java.util.Arrays;
import java.util.Vector;
/**
* 移动端控件样式编辑面板
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/3/28
*/
public class MobileWidgetStyleEditPane<T extends TemplateTheme> extends WidgetStyleEditPane<T> {
/**
* 移动端字体列表 12-18
*/
private static Vector<Integer> FONT_SIZES = new Vector<Integer>() {
{
addAll(Arrays.asList(12, 13, 14, 15, 16, 17, 18));
}
};
public MobileWidgetStyleEditPane() {
super();
}
@Override
public void initLineBox() {
lineComboBox = new LineComboBox(WidgetThemeDisplayConstants.MOBILE_BORDER_LINE_STYLE_ARRAY);
lineComboBox.setSelectedLineStyle(com.fr.stable.Constants.LINE_THIN);
}
@Override
protected void initFontSizePane() {
fontSizePane = new FontSizeComboPane(FONT_SIZES);
}
@Override
public void populateBean(T t) {
MobileThemedWidgetStyle style = (MobileThemedWidgetStyle) t.getMobileWidgetStyle();
if (style == null) {
style = new MobileThemedWidgetStyle();
t.setMobileWidgetStyle(style);
}
colorSelectBox.setSelectObject(style.getThemeColor());
lineComboBox.setSelectedLineStyle(style.getBorderStyle().getLineType());
borderRadiusSpinner.setValue(style.getBorderStyle().getRadius());
fontSizePane.setValue(style.getTextStyle().getFontSize());
fontColorButton.setColor(style.getTextStyle().getFontColor());
}
@Override
public void updateBean(T t) {
MobileThemedWidgetStyle style = (MobileThemedWidgetStyle) t.getMobileWidgetStyle();
if (style == null) {
style = new MobileThemedWidgetStyle();
t.setMobileWidgetStyle(style);
}
style.setThemeColor(colorSelectBox.getSelectObject());
BorderStyle borderStyle = new BorderStyle();
borderStyle.setLineType(lineComboBox.getSelectedLineStyle());
borderStyle.setRadius((int) borderRadiusSpinner.getValue());
style.setBorderStyle(borderStyle);
ThemeTextStyle textStyle = new ThemeTextStyle();
textStyle.setFontSize(fontSizePane.getValue());
textStyle.setFontColor(fontColorButton.getColor());
style.setTextStyle(textStyle);
}
}

136
designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditContainerPane.java

@ -0,0 +1,136 @@
package com.fr.widgettheme.theme.edit.widget;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import org.jetbrains.annotations.Nullable;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 组件主题编辑容器包含移动端控制面板和桌面端控制面板
* 默认展开桌面端
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/3/28
*/
public class WidgetStyleEditContainerPane<T extends TemplateTheme> extends BasicBeanPane<T> {
private UIButtonGroup<Integer> terminalStyleGroup;
private WidgetStyleEditPane<T> desktop;
private WidgetStyleEditPane<T> mobile;
public WidgetStyleEditContainerPane() {
initComponent();
}
private void initComponent() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
// 初始化按钮组,桌面端&移动端
initButtonGroup();
// 创建按钮组面板
createButtonGroupPane();
// 默认选中桌面端
terminalStyleGroup.setSelectedIndex(0);
// cardLayout用来切换面板
// 桌面端
initDesktopPanel();
// 移动端
initMobilePanel();
createCardContainer();
initListener();
}
private void createCardContainer() {
JPanel cardPanel = FRGUIPaneFactory.createCardLayout_S_Pane();
cardPanel.add(desktop, BorderLayout.CENTER);
cardPanel.add(mobile, BorderLayout.CENTER);
this.add(cardPanel, BorderLayout.CENTER);
}
private void initMobilePanel() {
mobile = new MobileWidgetStyleEditPane<>();
mobile.setVisible(false);
}
private void initDesktopPanel() {
desktop = new DesktopWidgetStyleEditPane<>();
// 默认可见性
desktop.setVisible(true);
}
private void createButtonGroupPane() {
Component[][] components = {
new Component[]{terminalStyleGroup},
};
final double p = TableLayout.PREFERRED;
double[] rowSize = {p};
double[] columnSize = {p, p};
int[][] rowCount = {{1, 1}};
JPanel groupPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1);
this.add(groupPane, BorderLayout.NORTH);
}
/**
* 初始化按钮组
*/
private void initButtonGroup() {
terminalStyleGroup = new UIButtonGroup<>(new String[]{
Toolkit.i18nText("Fine-Design_Widget_Terminal_Desktop"),
Toolkit.i18nText("Fine-Design_Widget_Terminal_Mobile")});
this.add(terminalStyleGroup, BorderLayout.NORTH);
terminalStyleGroup.setSelectedIndex(0);
}
/**
* 初始化按钮组的listener
*/
private void initListener() {
terminalStyleGroup.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showTerminalPane();
}
});
}
/**
* 展示具体面板
*/
private void showTerminalPane() {
desktop.setVisible(terminalStyleGroup.getSelectedIndex() == 0);
mobile.setVisible(terminalStyleGroup.getSelectedIndex() == 1);
}
@Override
public void populateBean(T ob) {
desktop.populateBean(ob);
mobile.populateBean(ob);
}
@Nullable
@Override
public T updateBean() {
return null;
}
@Override
public void updateBean(T ob) {
desktop.updateBean(ob);
mobile.updateBean(ob);
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Theme_Widget_Style");
}
}

125
designer-base/src/main/java/com/fr/widgettheme/theme/edit/widget/WidgetStyleEditPane.java

@ -0,0 +1,125 @@
package com.fr.widgettheme.theme.edit.widget;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.icombobox.LineComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.style.FRFontPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.stable.StringUtils;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.widgettheme.util.ThemeTextStylePaneCreator;
import org.jetbrains.annotations.Nullable;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
/**
* 组件样式编辑基础类
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/5/22
*/
public class WidgetStyleEditPane<T extends TemplateTheme> extends BasicBeanPane<T> {
// 主题色
protected NewColorSelectBox colorSelectBox;
// 边框线型
protected LineComboBox lineComboBox;
// 圆角边框
protected UISpinner borderRadiusSpinner;
/**
* 文本样式面板
*/
protected FontSizeComboPane fontSizePane;
protected UIColorButton fontColorButton;
public WidgetStyleEditPane() {
initComponents();
}
private void initComponents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
initCommonStyleEditor();
double f = TableLayout.PREFERRED;
final double p = TableLayout.PREFERRED;
double[] rowSize = {p, p, p, p, p, p};
double[] columnSize = {p, p};
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}};
Component[][] components = generateComponent();
JPanel customPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1);
customPane.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 10));
this.add(customPane, BorderLayout.NORTH);
}
/**
* 初始化标签
*
* @return components
*/
public Component[][] generateComponent() {
return new Component[][]{new Component[]{
new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color")), colorSelectBox},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Line")), lineComboBox},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Radius")), borderRadiusSpinner},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style")), ThemeTextStylePaneCreator.create(fontSizePane, fontColorButton)}
};
}
private void initCommonStyleEditor() {
colorSelectBox = new NewColorSelectBox(WidgetThemeDisplayConstants.THEME_WIDGET_COMPONENT_WIDTH, true);
colorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR);
initLineBox();
borderRadiusSpinner = new UISpinner(0, Integer.MAX_VALUE, 1);
initFontSizePane();
fontColorButton = new UIColorButton();
}
protected void initFontSizePane() {
fontSizePane = new FontSizeComboPane(FRFontPane.getFontSizes());
}
/**
* 初始化边框线型
*/
public void initLineBox() {
lineComboBox = new LineComboBox(WidgetThemeDisplayConstants.BORDER_LINE_STYLE_ARRAY);
}
@Override
public void populateBean(T t) {
}
@Nullable
@Override
public T updateBean() {
return null;
}
@Override
public void updateBean(T t) {
}
@Override
protected String title4PopupWindow() {
return StringUtils.EMPTY;
}
}

77
designer-base/src/main/java/com/fr/widgettheme/theme/panel/ButtonStyleDefinedPane.java

@ -0,0 +1,77 @@
package com.fr.widgettheme.theme.panel;
import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.widgettheme.theme.bean.ButtonBackground;
import com.fr.design.mainframe.widget.accessibles.AccessibleImgBackgroundEditor;
import com.fr.general.Background;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
/**
* 按钮样式定义窗口
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public class ButtonStyleDefinedPane extends BasicPane {
protected AccessibleImgBackgroundEditor initBackgroundPane;
protected AccessibleImgBackgroundEditor overBackgroundPane;
protected AccessibleImgBackgroundEditor clickBackgroundPane;
public ButtonStyleDefinedPane() {
this.initComponents();
}
protected void initComponents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
initBackgroundPane = new AccessibleImgBackgroundEditor();
overBackgroundPane = new AccessibleImgBackgroundEditor();
clickBackgroundPane = new AccessibleImgBackgroundEditor();
double f = TableLayout.FILL;
final double p = TableLayout.PREFERRED;
double[] rowSize = {p, p, p};
double[] columnSize = {p, f};
int[][] rowCount = {{1, 1},{1, 1},{1, 1}};
Component[][] components = new Component[][]{
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Background_Initial")), initBackgroundPane},
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Background_Over")), overBackgroundPane},
new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Background_Click")), clickBackgroundPane},
};
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 7, 7);
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
this.add(panel, BorderLayout.CENTER);
}
/**
* 填充
*/
public void populate(ButtonBackground buttonBackground) {
initBackgroundPane.setValue(buttonBackground.getInitialBackground());
overBackgroundPane.setValue(buttonBackground.getOverBackground());
clickBackgroundPane.setValue(buttonBackground.getClickBackground());
}
/**
* 更新
*/
public ButtonBackgroundStyle update() {
return new ButtonBackgroundStyle((Background) initBackgroundPane.getValue(), (Background) overBackgroundPane.getValue(), (Background) clickBackgroundPane.getValue());
}
@Override
protected String title4PopupWindow() {
return null;
}
}

141
designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCell.java

@ -0,0 +1,141 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.BaseUtils;
import com.fr.base.Style;
import com.fr.base.theme.TemplateTheme;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.general.FRFont;
import com.fr.stable.Constants;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
import java.awt.image.BufferedImage;
/**
* 主题界面预览单元格子
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/18
*/
public class ControlPreviewCell extends JPanel {
protected static final LayoutManager DEFAULT = FRGUIPaneFactory.createRightFlowLayout();
protected static final Color DEFAULT_COLOR = new Color(210, 210, 210);
protected static final Color DEFAULT_THEME_COLOR = new Color(54, 133, 242);
protected static final String DEFAULT_MESSAGE = "";
protected static final int NO_SCALE_RESOLUTION = 100;
protected static final int DEFAULT_ALPHA = 255;
/**
* 格子文本数据
*/
protected String value;
protected TemplateTheme reportTheme;
/**
* 字体的颜色
*/
protected Color textColor = DEFAULT_COLOR;
public Color getTextColor() {
return textColor;
}
public void setTextColor(Color textColor) {
this.textColor = textColor;
}
public ControlPreviewCell() {
this(DEFAULT, DEFAULT_MESSAGE);
}
public ControlPreviewCell(String value) {
this(DEFAULT, value);
}
public ControlPreviewCell(LayoutManager layoutManager, String value) {
this.setLayout(layoutManager);
this.setOpaque(false);
this.value = value;
this.setPreferredSize(new Dimension(80, 30));
}
/**
* 主题样式变化后监听改变
*/
public void refresh(TemplateTheme reportTheme) {
this.reportTheme = reportTheme;
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) this.reportTheme.getWidgetStyle();
//主题色设置为透明或者插件启动前已有的主题启动插件后主题色为null
if (widgetStyle.getThemeColor() == null) {
widgetStyle.setThemeColor(DEFAULT_THEME_COLOR);
}
}
/**
* 填充圆角矩形背景色
*/
public void paintBgColor(Graphics g, ThemedWidgetStyle widgetStyle) {
this.paintBgColor(g, widgetStyle, DEFAULT_ALPHA);
}
public boolean isDefaultStyle() {
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle();
return widgetStyle.getStyleType() == ThemedWidgetStyle.DEFAULT_STYLE;
}
public Color getThemeColor() {
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle();
return widgetStyle.getThemeColor();
}
protected Icon setStyleTwoIcon(Icon icon, Icon defaultIcon) {
if (this.reportTheme != null && !isDefaultStyle()) {
if (icon instanceof ImageIcon) {
ImageIcon imageIcon = (ImageIcon) icon;
BufferedImage bufferedImage = ImageUtils.colorImage(ImageUtils.imageIconToBufferedImage(imageIcon), getThemeColor());
return new ImageIcon(bufferedImage);
}
}
return defaultIcon;
}
/**
* 填充圆角矩形背景色
*/
public void paintBgColor(Graphics g, ThemedWidgetStyle widgetStyle, int alpha) {
Color themeColor = widgetStyle.getThemeColor();
g.setColor(new Color(themeColor.getRed(), themeColor.getGreen(), themeColor.getBlue(), alpha));
g.fillRoundRect(0, 0, getSize().width - 1, getSize().height - 1, widgetStyle.getBorderStyle().getRadius(), widgetStyle.getBorderStyle().getRadius());
//需要重新绘制一遍字体,否则会被颜色填充给遮住
Graphics2D g2d = (Graphics2D) g.create();
FRFont font = FRFont.getInstance(FRFont.DEFAULT_FONTNAME, Font.PLAIN, widgetStyle.getTextStyle().getFontSize(), textColor);
BaseUtils.drawStringStyleInRotation(g2d, getWidth(), getHeight(), this.value,
Style.getInstance(font).deriveHorizontalAlignment(Constants.LEFT)
.deriveTextStyle(Style.TEXTSTYLE_SINGLELINE), NO_SCALE_RESOLUTION);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.reportTheme == null) {
return;
}
Graphics2D g2d = (Graphics2D) g.create();
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle();
FRFont font = FRFont.getInstance(FRFont.DEFAULT_FONTNAME, Font.PLAIN, widgetStyle.getTextStyle().getFontSize(), textColor);
//每个预览格子通用的字体绘制
BaseUtils.drawStringStyleInRotation(g2d, getWidth(), getHeight(), this.value,
Style.getInstance(font).deriveHorizontalAlignment(Constants.LEFT)
.deriveTextStyle(Style.TEXTSTYLE_SINGLELINE), NO_SCALE_RESOLUTION);
}
}

77
designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewCellWithIcon.java

@ -0,0 +1,77 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.svg.IconUtils;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import com.fr.design.border.UIRoundedBorder;
import com.fr.stable.StringUtils;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import javax.swing.Icon;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.LayoutManager;
/**
* 主题界面预览控件单元格子,控件图表直接用icon
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/18
*/
public class ControlPreviewCellWithIcon extends ControlPreviewCell {
private static final int CONTROL_ALPHA = 16;
JLabel jLabel;
Icon icon;
Icon defaultIcon;
public ControlPreviewCellWithIcon() {
this(DEFAULT, DEFAULT_MESSAGE);
}
public ControlPreviewCellWithIcon(String value) {
this(DEFAULT, value);
}
public ControlPreviewCellWithIcon(LayoutManager layoutManager, String value) {
this.setLayout(layoutManager);
this.value = value;
this.setPreferredSize(new Dimension(100, 27));
}
/**
* 根据icon地址绘制一个图标,用jlabel进行展示
*
* @param url icon地址
*/
public void drawIcon(String url) {
if (StringUtils.isEmpty(url)) {
return;
}
defaultIcon = IconUtils.readIcon(url);
icon = setStyleTwoIcon(icon, defaultIcon);
this.jLabel = new JLabel(icon);
jLabel.setPreferredSize(new Dimension(21, 17));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle();
//风格一边框不显示主题色
Color borderColor = isDefaultStyle() ? DEFAULT_COLOR : widgetStyle.getThemeColor();
this.setBorder(new UIRoundedBorder(widgetStyle.getBorderStyle().getLineType()
, borderColor, widgetStyle.getBorderStyle().getRadius()));
icon = setStyleTwoIcon(icon, defaultIcon);
this.jLabel.setIcon(icon);
this.add(jLabel, BorderLayout.EAST);
if (widgetStyle.getStyleType() != ThemedWidgetStyle.DEFAULT_STYLE) {
paintBgColor(g, widgetStyle, CONTROL_ALPHA);
}
}
}

133
designer-base/src/main/java/com/fr/widgettheme/theme/panel/ControlPreviewPane.java

@ -0,0 +1,133 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.background.ColorBackground;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.preview.ThemePreviewed;
import com.fr.general.Background;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
/**
* 主题界面页面中的参数界面
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/18
*/
public class ControlPreviewPane extends JPanel implements ThemePreviewed<TemplateTheme> {
public static final int PREVIEW_WIDTH = 615;
public static final int PREVIEW_HEIGHT = 62;
/**
* 参数界面中放置的所有cell用于监听主题样式变更
*/
public final List<ControlPreviewCell> list = new ArrayList<>();
private Background background;
private static final String DATE_ICON_URL = "/com/fr/web/images/form/resources/date_16.png";
private static final String COMBOBOX_ICON_URL = "/com/fr/widgettheme/combobox.png";
@Override
public void refresh(TemplateTheme style) {
this.background = style.getParamContainerStyle().getBackground();
for (ControlPreviewCell controlPreviewCell : list) {
controlPreviewCell.refresh(style);
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
paintBackground((Graphics2D) g);
}
protected void paintBackground(Graphics2D g2d) {
if (background == null) {
background = ColorBackground.getInstance(Color.WHITE);
}
background.paint(g2d, new Rectangle2D.Double(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT));
}
/**
* 初始化参数界面往里面添加各种cell
*/
public void initControlPreviewPane() {
initDateControlPane();
initComboboxControlPane();
initRadioButtonControlPane();
initNormalButtonControlPane();
}
/**
* 初始化日期控件包括文字跟控件
*/
private void initDateControlPane() {
TextPreviewCell dateTextCell = new TextPreviewCell(Toolkit.i18nText("Fine-Design_Theme_Control_Date_Text"));
dateTextCell.setPreferredSize(new Dimension(80, 30));
ControlPreviewCellWithIcon dateEditorCell = new ControlPreviewCellWithIcon(Toolkit.i18nText("Fine-Design_Theme_Control_Date_Editor_Text"));
dateEditorCell.drawIcon(DATE_ICON_URL);
dateEditorCell.setTextColor(ControlPreviewCell.DEFAULT_COLOR);
this.add(dateTextCell);
this.add(dateEditorCell);
this.list.add(dateTextCell);
this.list.add(dateEditorCell);
}
/**
* 初始化下拉框控件包括文件跟控件
*/
private void initComboboxControlPane() {
TextPreviewCell comboBoxTextCell = new TextPreviewCell(Toolkit.i18nText("Fine-Design_Theme_Control_ComboBox_Text"));
comboBoxTextCell.setPreferredSize(new Dimension(60, 30));
ControlPreviewCellWithIcon comboBoxControlPreviewCell = new ControlPreviewCellWithIcon(Toolkit.i18nText("Fine-Design_Theme_Control_ComboBox_Editor_Text"));
comboBoxControlPreviewCell.drawIcon(COMBOBOX_ICON_URL);
comboBoxControlPreviewCell.setTextColor(ControlPreviewCell.DEFAULT_COLOR);
this.add(comboBoxTextCell);
this.add(comboBoxControlPreviewCell);
this.list.add(comboBoxControlPreviewCell);
this.list.add(comboBoxTextCell);
}
/**
* 初始化单选按钮组控件
*/
private void initRadioButtonControlPane() {
RingControlPreviewCell ringControlPreviewCell = new RingControlPreviewCell();
RoundControlPreviewCell roundControlPreviewCell = new RoundControlPreviewCell();
TextPreviewCell yearTextFieldCell = new TextPreviewCell(Toolkit.i18nText("Fine-Design_Theme_Control_Radio_Year"));
yearTextFieldCell.setPreferredSize(new Dimension(38, 30));
TextPreviewCell monthTextFieldCell = new TextPreviewCell(Toolkit.i18nText("Fine-Design_Theme_Control_Radio_Month"));
monthTextFieldCell.setPreferredSize(new Dimension(38, 30));
this.add(ringControlPreviewCell);
this.add(yearTextFieldCell);
this.add(roundControlPreviewCell);
this.add(monthTextFieldCell);
this.list.add(ringControlPreviewCell);
this.list.add(roundControlPreviewCell);
this.list.add(yearTextFieldCell);
this.list.add(monthTextFieldCell);
}
/**
* 初始化按钮预览格子
*/
private void initNormalButtonControlPane() {
NormalButtonPreviewCell normalButton = new NormalButtonPreviewCell(FRGUIPaneFactory.createCenterFlowLayout(), ControlPreviewCell.DEFAULT_MESSAGE);
this.add(normalButton);
this.list.add(normalButton);
}
}

89
designer-base/src/main/java/com/fr/widgettheme/theme/panel/ImageUtils.java

@ -0,0 +1,89 @@
package com.fr.widgettheme.theme.panel;
import javax.swing.ImageIcon;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
/**
* 控件主题Image处理工具类
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public class ImageUtils {
/**
* 根据主题色处理image
*
* @param image 图像
* @param color 主题色
* @return 处理结果
*/
public static BufferedImage colorImage(BufferedImage image, Color color) {
int width = image.getWidth();
int height = image.getHeight();
WritableRaster raster = image.getRaster();
for (int xx = 0; xx < width; xx++) {
for (int yy = 0; yy < height; yy++) {
int[] pixels = raster.getPixel(xx, yy, (int[]) null);
setRedPixels(pixels, color);
setGreenPixels(pixels, color);
setBluePixels(pixels, color);
raster.setPixel(xx, yy, pixels);
}
}
return image;
}
/**
* 处理红像素
*
* @param pixels 像素数组
* @param color 颜色
*/
private static void setRedPixels(int[] pixels, Color color) {
pixels[0] = pixels[0] > 0 && pixels[0] < 255 ? color.getRed() : 255;
}
/**
* 处理绿像素
*
* @param pixels 像素数组
* @param color 颜色
*/
private static void setGreenPixels(int[] pixels, Color color) {
pixels[1] = pixels[1] > 0 && pixels[1] < 255 ? color.getGreen() : 255;
}
/**
* 处理蓝像素
*
* @param pixels 像素数组
* @param color 颜色
*/
private static void setBluePixels(int[] pixels, Color color) {
pixels[2] = pixels[2] > 0 && pixels[2] < 255 ? color.getBlue() : 255;
}
/**
* ImageIcon转换为BufferImage
*
* @param icon imageIcon
* @return BufferedImage
*/
public static BufferedImage imageIconToBufferedImage(ImageIcon icon) {
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
return bi;
}
}

50
designer-base/src/main/java/com/fr/widgettheme/theme/panel/NormalButtonPreviewCell.java

@ -0,0 +1,50 @@
package com.fr.widgettheme.theme.panel;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.general.FRFont;
import java.awt.*;
/**
* 主题参数面板按钮预览格子
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/27
*/
public class NormalButtonPreviewCell extends ControlPreviewCell {
/**
* 按钮上的label
*/
private UILabel uiLabel;
public NormalButtonPreviewCell() {
this(DEFAULT, DEFAULT_MESSAGE);
}
public NormalButtonPreviewCell(String value) {
this(DEFAULT, value);
}
public NormalButtonPreviewCell(LayoutManager layoutManager, String value) {
this.setLayout(layoutManager);
this.value = value;
this.uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Theme_Control_Normal_Button"));
this.setPreferredSize(new Dimension(80, 27));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle();
paintBgColor(g, widgetStyle);
uiLabel.setForeground(Color.WHITE);
FRFont font = FRFont.getInstance(FRFont.DEFAULT_FONTNAME, Font.PLAIN, widgetStyle.getTextStyle().getFontSize(), Color.WHITE);
uiLabel.setFont(font);
this.add(uiLabel, BorderLayout.CENTER);
}
}

51
designer-base/src/main/java/com/fr/widgettheme/theme/panel/RingControlPreviewCell.java

@ -0,0 +1,51 @@
package com.fr.widgettheme.theme.panel;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.Color;
/**
* 主题界面预览控件单元格子,单选按钮组被选中的样子
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/18
*/
public class RingControlPreviewCell extends ControlPreviewCell {
/**
* 圆环厚度
*/
private static final int THICK_NESS = 4;
public RingControlPreviewCell() {
this(DEFAULT, DEFAULT_MESSAGE);
}
public RingControlPreviewCell(String value) {
this(DEFAULT, value);
}
public RingControlPreviewCell(LayoutManager layoutManager, String value) {
this.setLayout(layoutManager);
this.setOpaque(false);
this.value = value;
this.setPreferredSize(new Dimension(20, 30));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle();
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(widgetStyle.getThemeColor());
g2d.fillOval(5, 9, 15, 15);
g2d.setColor(Color.WHITE);
g2d.fillOval(5 + THICK_NESS, 9 + THICK_NESS, 15 - 2 * THICK_NESS, 15 - 2 * THICK_NESS);
}
}

45
designer-base/src/main/java/com/fr/widgettheme/theme/panel/RoundControlPreviewCell.java

@ -0,0 +1,45 @@
package com.fr.widgettheme.theme.panel;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
/**
* 主题界面预览控件单元格子,单选按钮组未被选中的样子
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/18
*/
public class RoundControlPreviewCell extends ControlPreviewCell {
public RoundControlPreviewCell() {
this(DEFAULT, DEFAULT_MESSAGE);
}
public RoundControlPreviewCell(String value) {
this(DEFAULT, value);
}
public RoundControlPreviewCell(LayoutManager layoutManager, String value) {
this.setLayout(layoutManager);
this.setOpaque(false);
this.value = value;
this.setPreferredSize(new Dimension(23, 30));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) reportTheme.getWidgetStyle();
//风格一边框不显示主题色
Color borderColor = isDefaultStyle() ? DEFAULT_COLOR : widgetStyle.getThemeColor();
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(borderColor);
g2d.drawOval(5, 9, 15, 15);
}
}

36
designer-base/src/main/java/com/fr/widgettheme/theme/panel/TextPreviewCell.java

@ -0,0 +1,36 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.theme.TemplateTheme;
import java.awt.*;
/**
* 文字预览格子
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/27
*/
public class TextPreviewCell extends ControlPreviewCell {
public TextPreviewCell(String value) {
this(DEFAULT, value);
}
public TextPreviewCell(LayoutManager layoutManager, String value) {
this.setLayout(layoutManager);
this.value = value;
}
@Override
public void refresh(TemplateTheme reportTheme) {
super.refresh(reportTheme);
// 文字根据是否深色主题自适应改变
if (reportTheme.isDark()) {
textColor = Color.WHITE;
} else {
textColor = Color.BLACK;
}
}
}

202
designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetDisplayFormThemePreviewPane.java

@ -0,0 +1,202 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.background.ColorBackground;
import com.fr.base.theme.FormTheme;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chart.chartdata.NormalChartData;
import com.fr.chart.charttypes.ChartTypeManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.TemplateThemePreviewPane;
import com.fr.design.mainframe.theme.preview.ChartComponentPreviewPane;
import com.fr.design.mainframe.theme.preview.UINoOpaquePanel;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.chart.PiePlot4VanChart;
import com.fr.plugin.chart.attr.VanChartLegend;
import com.fr.plugin.chart.base.VanChartTools;
import com.fr.plugin.chart.column.VanChartColumnPlot;
import com.fr.plugin.chart.type.GradientType;
import com.fr.plugin.chart.type.RadiusType;
import com.fr.plugin.chart.vanchart.VanChart;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import javax.swing.JPanel;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import static com.fr.design.i18n.Toolkit.i18nText;
import static com.fr.widgettheme.util.ThemePreviewPaneInitHelper.initColumnPlot;
import static com.fr.widgettheme.util.ThemePreviewPaneInitHelper.initVanChartYAxis;
import static com.fr.widgettheme.util.ThemePreviewPaneInitHelper.initVanChartsTools;
/**
* 主题界面预览控frm界面,就是主jar里的那个界面做了简单的修改
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/18
*/
public class WidgetDisplayFormThemePreviewPane extends TemplateThemePreviewPane<FormTheme> {
private WidgetThemeECComponentPreviewPane elementCasePane;
private Background background;
private ChartComponentPreviewPane columnChartPreviewPane;
private ChartComponentPreviewPane pieChartPreviewPane;
private ControlPreviewPane controlPreviewPane;
private float alpha = 1.0F;
public WidgetDisplayFormThemePreviewPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
controlPreviewPane = new ControlPreviewPane();
controlPreviewPane.setLayout(FRGUIPaneFactory.createLabelFlowLayout());
controlPreviewPane.setPreferredSize(new Dimension(615, 40));
controlPreviewPane.initControlPreviewPane();
JPanel content = new UINoOpaquePanel();
content.setLayout(new BorderLayout());
add(controlPreviewPane, BorderLayout.NORTH);
JPanel chartContent = createChartContent();
content.add(chartContent, BorderLayout.CENTER);
content.add(elementCasePane = new WidgetThemeECComponentPreviewPane(), BorderLayout.SOUTH);
add(content, BorderLayout.CENTER);
}
private JPanel createChartContent() {
JPanel chartContent = new UINoOpaquePanel();
chartContent.setLayout(new BorderLayout());
JPanel columnChartPanel = new UINoOpaquePanel() {
public Dimension getPreferredSize() {
return new Dimension(379, 314);
}
};
columnChartPanel.setLayout(new BorderLayout());
columnChartPreviewPane = createChartPreviewPane(initColumnChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Comp_Title1"));
columnChartPanel.add(columnChartPreviewPane, BorderLayout.CENTER);
JPanel pieChartPanel = new UINoOpaquePanel() {
public Dimension getPreferredSize() {
return new Dimension(236, 314);
}
};
pieChartPanel.setLayout(new BorderLayout());
pieChartPreviewPane = createChartPreviewPane(initPieChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Comp_Title2"));
pieChartPanel.add(pieChartPreviewPane, BorderLayout.CENTER);
chartContent.add(columnChartPanel, BorderLayout.CENTER);
chartContent.add(pieChartPanel, BorderLayout.EAST);
return chartContent;
}
private ChartComponentPreviewPane createChartPreviewPane(ChartCollection chartCollection, String title) {
ChartComponentPreviewPane chartComponentPreviewPane = new ChartComponentPreviewPane(title);
chartComponentPreviewPane.getContentPane().populate(chartCollection);
chartComponentPreviewPane.getContentPane().setCallbackEvent(this);
return chartComponentPreviewPane;
}
@Override
public void refresh(FormTheme theme) {
background = theme.getBodyStyle().getStyle().getBackground();
alpha = theme.getBodyStyle().getStyle().getAlpha();
elementCasePane.refresh(theme);
columnChartPreviewPane.refresh(theme);
pieChartPreviewPane.refresh(theme);
controlPreviewPane.refresh(theme);
repaint();
}
protected void paintBackground(Graphics2D g2d) {
if (background == null) {
background = ColorBackground.getInstance(Color.WHITE);
}
Composite oldComposite = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
background.paint(g2d, new Rectangle2D.Double(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT));
g2d.setComposite(oldComposite);
}
/**
* 初始化柱形图
*
* @return 存放图表
*/
private ChartCollection initColumnChart() {
try {
VanChart chart = (VanChart) ChartTypeManager.getInstance().getCharts(VanChartColumnPlot.VAN_CHART_COLUMN_PLOT_ID)[0].clone();
initColumnChartDetail(chart);
Object[] category = {
Toolkit.i18nText("Fine-Design_Chart_Category") + "1",
Toolkit.i18nText("Fine-Design_Chart_Category") + "2",
Toolkit.i18nText("Fine-Design_Chart_Category") + "3",
Toolkit.i18nText("Fine-Design_Chart_Category") + "4"
};
Object[] series = {
Toolkit.i18nText("Fine-Design_Chart_Series") + "1",
Toolkit.i18nText("Fine-Design_Chart_Series") + "2"
};
Object[][] value = {
{"250", "540", "300", "410"},
{"180", "190", "170", "100"},
};
NormalChartData normalChartData = new NormalChartData(category, series, value);
chart.setPreViewChartData(normalChartData);
ChartCollection chartCollection = new ChartCollection(chart);
return chartCollection;
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
return null;
}
private void initColumnChartDetail(VanChart chart) {
chart.getTitle().setTitleVisible(false);
initVanChartsTools(chart.getVanChartTools());
VanChartColumnPlot plot = chart.getPlot();
//Form中独有的setPosition,和Report中不同,先单独放在这里,不写在initPlot中
plot.getLegend().setPosition(Constants.TOP);
initColumnPlot(plot);
initVanChartYAxis(plot.getDefaultYAxis());
}
/**
* 初始化饼图
*
* @return chartCollection
*/
private ChartCollection initPieChart() {
try {
VanChart chart = (VanChart) ChartTypeManager.getInstance().getCharts(PiePlot4VanChart.VAN_CHART_PIE_PLOT)[0].clone();
chart.getTitle().setTitleVisible(false);
VanChartTools vanChartTools = chart.getVanChartTools();
vanChartTools.setSort(false);
vanChartTools.setExport(false);
vanChartTools.setFullScreen(false);
PiePlot4VanChart plot = chart.getPlot();
VanChartLegend legend = (VanChartLegend) plot.getLegend();
legend.setPosition(Constants.BOTTOM);
legend.setCustomSize(true);
legend.setMaxHeight(28);
plot.getGradientStyle().setGradientType(GradientType.NONE);
plot.setInnerRadiusPercent(75);
plot.getRadius().setRadiusType(RadiusType.FIXED);
plot.getRadius().setRadius(70);
Object[] category = {StringUtils.EMPTY};
Object[] series = {"A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"};
Object[][] value = {{45}, {24}, {12}, {8}, {5}, {3}, {2}, {1},};
NormalChartData normalChartData = new NormalChartData(category, series, value);
chart.setPreViewChartData(normalChartData);
ChartCollection chartCollection = new ChartCollection(chart);
return chartCollection;
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
return null;
}
}

119
designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetDisplayReportThemePreviewPane.java

@ -0,0 +1,119 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.background.ColorBackground;
import com.fr.base.theme.ReportTheme;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chart.chartdata.NormalChartData;
import com.fr.chart.charttypes.ChartTypeManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.TemplateThemePreviewPane;
import com.fr.design.mainframe.theme.preview.ChartPreviewPane;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.chart.column.VanChartColumnPlot;
import com.fr.plugin.chart.vanchart.VanChart;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import static com.fr.widgettheme.util.ThemePreviewPaneInitHelper.initColumnPlot;
import static com.fr.widgettheme.util.ThemePreviewPaneInitHelper.initVanChartYAxis;
import static com.fr.widgettheme.util.ThemePreviewPaneInitHelper.initVanChartsTools;
/**
* 主题界面预览控cpt界面,就是主jar里的那个界面做了简单的修改
*
* @author John.Ying
* @since 11.0
* Created on 2023/3/18
*/
public class WidgetDisplayReportThemePreviewPane extends TemplateThemePreviewPane<ReportTheme> {
private Background background;
private final WidgetThemeECReportPreviewPane reportPreviewPane;
private final ChartPreviewPane chartPreviewPane;
private final ControlPreviewPane controlPreviewPane;
public WidgetDisplayReportThemePreviewPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
chartPreviewPane = new ChartPreviewPane();
chartPreviewPane.setPreferredSize(new Dimension(615, 207));
chartPreviewPane.populate(initColumnChart());
chartPreviewPane.setCallbackEvent(this);
reportPreviewPane = new WidgetThemeECReportPreviewPane();
reportPreviewPane.setPreferredSize(new Dimension(615, 257));
controlPreviewPane = new ControlPreviewPane();
controlPreviewPane.setLayout(FRGUIPaneFactory.createLabelFlowLayout());
controlPreviewPane.setPreferredSize(new Dimension(615, 40));
controlPreviewPane.initControlPreviewPane();
this.add(reportPreviewPane, BorderLayout.CENTER);
this.add(chartPreviewPane, BorderLayout.SOUTH);
this.add(controlPreviewPane, BorderLayout.NORTH);
}
@Override
public void refresh(ReportTheme theme) {
background = theme.getBodyStyle().getBackground();
reportPreviewPane.refresh(theme);
chartPreviewPane.refresh(theme);
controlPreviewPane.refresh(theme);
repaint();
}
protected void paintBackground(Graphics2D g2d) {
if (background == null) {
background = ColorBackground.getInstance(Color.WHITE);
}
background.paint(g2d, new Rectangle2D.Double(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT));
}
/**
* 初始化柱形图
*
* @return chartCollection
*/
private ChartCollection initColumnChart() {
try {
VanChart chart = (VanChart) ChartTypeManager.getInstance().getCharts(VanChartColumnPlot.VAN_CHART_COLUMN_PLOT_ID)[0].clone();
initColumnChartDetail(chart);
Object[] category = {
Toolkit.i18nText("Fine-Design_Chart_Category") + "1",
Toolkit.i18nText("Fine-Design_Chart_Category") + "2",
Toolkit.i18nText("Fine-Design_Chart_Category") + "3",
Toolkit.i18nText("Fine-Design_Chart_Category") + "4"
};
Object[] series = {
Toolkit.i18nText("Fine-Design_Chart_Series") + "1",
Toolkit.i18nText("Fine-Design_Chart_Series") + "2",
Toolkit.i18nText("Fine-Design_Chart_Series") + "3"
};
Object[][] value = {
{"340", "510", "300", "250"},
{"180", "360", "170", "100"},
{"210", "205", "405", "190"}
};
NormalChartData normalChartData = new NormalChartData(category, series, value);
chart.setPreViewChartData(normalChartData);
ChartCollection chartCollection = new ChartCollection(chart);
return chartCollection;
} catch (Exception ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
return null;
}
private void initColumnChartDetail(VanChart chart) {
initVanChartsTools(chart.getVanChartTools());
VanChartColumnPlot plot = chart.getPlot();
initColumnPlot(plot);
initVanChartYAxis(plot.getDefaultYAxis());
}
}

35
designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetThemeECComponentPreviewPane.java

@ -0,0 +1,35 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.theme.FormTheme;
import com.fr.design.mainframe.theme.preview.ComponentPreviewPane;
import java.awt.Component;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* 决策报表主题界面的那个表格+标题部分
*
* @author John.Ying
* @since 1.0
* Created on 2021/3/18
*/
public class WidgetThemeECComponentPreviewPane extends ComponentPreviewPane {
private WidgetThemeECPreviewPane contentPane;
public WidgetThemeECComponentPreviewPane() {
super(i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Title"));
}
@Override
protected Component createContentPane() {
contentPane = new WidgetThemeECPreviewPane();
return contentPane;
}
@Override
public void refresh(FormTheme theme) {
super.refresh(theme);
contentPane.refresh(theme);
}
}

112
designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetThemeECPreviewPane.java

@ -0,0 +1,112 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.CellBorderSourceFlag;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.preview.UINoOpaquePanel;
import com.fr.design.mainframe.theme.preview.ecpreview.AbstractECPreviewPane;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.AbstractPreviewCell;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.PreviewCell;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
/**
* 主题界面frm里的那个表格,做了简单修改,削减了几行重复内容,腾出控件参数面板的空间
*
* @author John.Ying
* @since 11.0
* Created on 2021/3/18
*/
public class WidgetThemeECPreviewPane extends AbstractECPreviewPane {
private final List<AbstractPreviewCell> headerCellList = new ArrayList<>();
private final List<AbstractPreviewCell> contentCellList = new ArrayList<>();
private final List<AbstractPreviewCell> highLightCellList = new ArrayList<>();
private final List<AbstractPreviewCell> assistCellList = new ArrayList<>();
private static final int COL_COUNT = 5;
private static final int CONTENT_ROW_COUNT = 1;
public WidgetThemeECPreviewPane() {
this.setPreferredSize(new Dimension(517, 158 - 36));
this.setBorder(BorderFactory.createEmptyBorder(0, 1, 2, 1));
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel titlePane = new UINoOpaquePanel(new GridLayout());
JPanel extCenterPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
this.add(extCenterPane, BorderLayout.CENTER);
extCenterPane.add(titlePane, BorderLayout.NORTH);
for (int c = 0; c < COL_COUNT; c++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
int flag = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER;
if (c > 0) {
flag |= CellBorderSourceFlag.LEFT_BORDER_SOURCE_INNER;
}
if (c < COL_COUNT - 1) {
flag |= CellBorderSourceFlag.RIGHT_BORDER_SOURCE_INNER;
}
cell.setBorderSourceFlag(flag);
cell.setPreferredSize(new Dimension(103, 36));
titlePane.add(cell);
headerCellList.add(cell);
}
JPanel contentPane = new UINoOpaquePanel(new GridLayout(1, 5, 0, 0));
extCenterPane.add(contentPane, BorderLayout.CENTER);
for (int i = 0; i < COL_COUNT * CONTENT_ROW_COUNT; i++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text"));
int c = i % COL_COUNT;
int flag = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER;
if (c > 0) {
flag |= CellBorderSourceFlag.LEFT_BORDER_SOURCE_INNER;
}
if (c < COL_COUNT - 1) {
flag |= CellBorderSourceFlag.RIGHT_BORDER_SOURCE_INNER;
}
cell.setBorderSourceFlag(flag);
cell.setPreferredSize(new Dimension(103, 30));
contentPane.add(cell);
contentCellList.add(cell);
}
JPanel endPane = new UINoOpaquePanel(new GridLayout());
extCenterPane.add(endPane, BorderLayout.SOUTH);
for (int c = 0; c < COL_COUNT; c++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text"));
int flag = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER;
if (c > 0) {
flag |= CellBorderSourceFlag.LEFT_BORDER_SOURCE_INNER;
}
if (c < COL_COUNT - 1) {
flag |= CellBorderSourceFlag.RIGHT_BORDER_SOURCE_INNER;
}
cell.setBorderSourceFlag(flag);
cell.setPreferredSize(new Dimension(103, 30));
endPane.add(cell);
highLightCellList.add(cell);
}
JPanel extSouthPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
PreviewCell assistCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Assist_Text"));
assistCell.setBorderSourceFlag(CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER);
assistCell.setPreferredSize(new Dimension(123, 30));
assistCellList.add(assistCell);
extSouthPane.add(assistCell);
this.add(extSouthPane, BorderLayout.SOUTH);
}
@Override
public void refresh(TemplateTheme theme) {
ThemedCellStyleList cellStyleConfig = theme.getCellStyleList();
refresh(headerCellList, cellStyleConfig.getUse4Header());
refresh(contentCellList, cellStyleConfig.getUse4MainText());
refresh(highLightCellList, cellStyleConfig.getUse4HighlightText());
refresh(assistCellList, cellStyleConfig.getUse4SupportInfo());
}
}

248
designer-base/src/main/java/com/fr/widgettheme/theme/panel/WidgetThemeECReportPreviewPane.java

@ -0,0 +1,248 @@
package com.fr.widgettheme.theme.panel;
import com.fr.base.CellBorderSourceFlag;
import com.fr.base.theme.ReportTheme;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.preview.ThemePreviewed;
import com.fr.design.mainframe.theme.preview.UINoOpaquePanel;
import com.fr.design.mainframe.theme.preview.ecpreview.AbstractECPreviewPane;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.AbstractPreviewCell;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.CornerPreviewCell;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.PreviewCell;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
/**
* 主题界面report里的那个表格,做了简单修改,削减了几行重复内容,腾出控件参数面板的空间
*
* @author John.Ying
* @since 1.0
* Created on 2021/3/18
*/
public class WidgetThemeECReportPreviewPane extends UINoOpaquePanel implements ThemePreviewed<ReportTheme> {
private final List<AbstractPreviewCell> headerTitleCellList = new ArrayList<>(); // 大标题样式单元格
private final List<AbstractPreviewCell> headerCellList = new ArrayList<>(); // 表头样式单元格
private final List<AbstractPreviewCell> titleCellList = new ArrayList<>(); // 小标题样式单元格
private final List<AbstractPreviewCell> contentCellList = new ArrayList<>(); // 正文样式单元格
private final List<AbstractPreviewCell> highLightCellList = new ArrayList<>(); // 高亮文本样式单元格
private final List<AbstractPreviewCell> assistCellList = new ArrayList<>(); // 辅助信息样式单元格
private static final int CONTENT_ROW_COUNT = 3;
private static final int COL_COUNT = 3;
private final PreviewPane previewPane;
public WidgetThemeECReportPreviewPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
previewPane = new PreviewPane();
this.add(previewPane, BorderLayout.CENTER);
}
@Override
public void refresh(ReportTheme theme) {
previewPane.refresh(theme);
}
class PreviewPane extends AbstractECPreviewPane {
public PreviewPane() {
this.setPreferredSize(new Dimension(517, 208));
this.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel northPane = createNorthPane();
JPanel centerPane = createCenterPane();
JPanel southPane = createSouthPane();
this.add(northPane, BorderLayout.NORTH);
this.add(centerPane, BorderLayout.CENTER);
this.add(southPane, BorderLayout.SOUTH);
}
private JPanel createNorthPane() {
JPanel northPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
AbstractPreviewCell bigTitleCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Cell_Style_Big_Title"));
bigTitleCell.setBorderSourceFlag(CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER);
bigTitleCell.setPreferredSize(new Dimension(615, 46));
headerTitleCellList.add(bigTitleCell);
northPane.add(bigTitleCell, BorderLayout.NORTH);
CornerPreviewCell cornerCell = createCornerPreviewCell();
titleCellList.add(cornerCell);
northPane.add(cornerCell, BorderLayout.WEST);
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
northPane.add(centerPane, BorderLayout.CENTER);
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title"));
cell.setBorderSourceFlag(CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER);
titleCellList.add(cell);
cell.setPreferredSize(new Dimension(308, 38));
centerPane.add(cell, BorderLayout.NORTH);
JPanel eastSouthPane = new UINoOpaquePanel(new GridLayout());
for (int c = 0; c < CONTENT_ROW_COUNT; c++) {
PreviewCell headerCell = createPreviewCellHeader(c);
headerCellList.add(headerCell);
eastSouthPane.add(headerCell);
}
centerPane.add(eastSouthPane, BorderLayout.CENTER);
return northPane;
}
/**
* 创建CornerPreviewCell
*/
private CornerPreviewCell createCornerPreviewCell() {
CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{Toolkit.i18nText("Fine-Design_Basic_Column_Name"),
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Data"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Row_Name")},
new Point2D[]{new Point(159, 71), new Point(225, 49)});
cornerCell.setBorderSourceFlag(CellBorderSourceFlag.INVALID_BORDER_SOURCE);
cornerCell.setPreferredSize(new Dimension(225, 71));
return cornerCell;
}
/**
* 创建预览单元格标题
*
* @param c 文本行数
* @return PreviewCell
*/
private PreviewCell createPreviewCellHeader(int c) {
PreviewCell headerCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
int flag = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER;
if (c > 0) {
flag |= CellBorderSourceFlag.LEFT_BORDER_SOURCE_INNER;
}
if (c < CONTENT_ROW_COUNT - 1) {
flag |= CellBorderSourceFlag.RIGHT_BORDER_SOURCE_INNER;
}
headerCell.setBorderSourceFlag(flag);
return headerCell;
}
private JPanel createCenterPane() {
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
JPanel westPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
centerPane.add(westPane, BorderLayout.WEST);
PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title"));
titleCellList.add(cell1);
cell1.setPreferredSize(new Dimension(112, 93));
westPane.add(cell1, BorderLayout.WEST);
JPanel gridPane = createGridPane();
westPane.add(gridPane, BorderLayout.CENTER);
JPanel innerCenterPane = new UINoOpaquePanel(new GridLayout(3, 3));
centerPane.add(innerCenterPane, BorderLayout.CENTER);
for (int i = 0; i < COL_COUNT*CONTENT_ROW_COUNT; i++) {
PreviewCell cell ;
int r = i / CONTENT_ROW_COUNT;
int c = i % CONTENT_ROW_COUNT;
if (c == CONTENT_ROW_COUNT - 1) {
cell = createPreviewCellHighlight(r);
highLightCellList.add(cell);
} else {
cell = createPreviewCellMain(r, c);
contentCellList.add(cell);
}
cell.setPreferredSize(new Dimension(123, 31));
innerCenterPane.add(cell);
}
return centerPane;
}
/**
* 创建高亮预览单元格
*
* @param r 计算标志位
* @return 单元格
*/
private PreviewCell createPreviewCellHighlight(int r) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text"));
int flag = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER;
if (r != 0) {
flag |= CellBorderSourceFlag.TOP_BORDER_SOURCE_INNER;
}
if (r != COL_COUNT - 1) {
flag |= CellBorderSourceFlag.BOTTOM_BORDER_SOURCE_INNER;
}
cell.setBorderSourceFlag(flag);
return cell;
}
/**
* 创建正文预览单元格
*
* @param r 计算标志位
* @param c 计算标志位
* @return 单元格
*/
private PreviewCell createPreviewCellMain(int r, int c) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text"));
int flag = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER;
if (r > 0) {
flag |= CellBorderSourceFlag.TOP_BORDER_SOURCE_INNER;
}
if (r < COL_COUNT - 1) {
flag |= CellBorderSourceFlag.BOTTOM_BORDER_SOURCE_INNER;
}
if (c > 0) {
flag |= CellBorderSourceFlag.LEFT_BORDER_SOURCE_INNER;
}
if (c < 1) {
flag |= CellBorderSourceFlag.RIGHT_BORDER_SOURCE_INNER;
}
cell.setBorderSourceFlag(flag);
return cell;
}
private JPanel createGridPane() {
int rowCount = 3;
int columnCount = 1;
JPanel gridPane = new UINoOpaquePanel(new GridLayout(rowCount, columnCount));
for (int r = 0; r < rowCount; r++) {
PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
int flag = CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER;
if (r > 0) {
flag |= CellBorderSourceFlag.TOP_BORDER_SOURCE_INNER;
}
if (r < COL_COUNT - 1) {
flag |= CellBorderSourceFlag.BOTTOM_BORDER_SOURCE_INNER;
}
cell.setBorderSourceFlag(flag);
cell.setPreferredSize(new Dimension(113, 31));
headerCellList.add(cell);
gridPane.add(cell);
}
return gridPane;
}
private JPanel createSouthPane(){
JPanel southPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
PreviewCell assistCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Assist_Text"));
assistCell.setBorderSourceFlag(CellBorderSourceFlag.ALL_BORDER_SOURCE_OUTER);
assistCell.setPreferredSize(new Dimension(123, 30));
assistCellList.add(assistCell);
southPane.add(assistCell, BorderLayout.CENTER);
return southPane;
}
@Override
public void refresh(TemplateTheme theme) {
ThemedCellStyleList cellStyleConfig = theme.getCellStyleList();
refresh(headerTitleCellList, cellStyleConfig.getUse4BigTitle());
refresh(headerCellList, cellStyleConfig.getUse4Header());
refresh(contentCellList, cellStyleConfig.getUse4MainText());
refresh(titleCellList, cellStyleConfig.getUse4SmallTitle());
refresh(highLightCellList, cellStyleConfig.getUse4HighlightText());
refresh(assistCellList, cellStyleConfig.getUse4SupportInfo());
}
}
}

70
designer-base/src/main/java/com/fr/widgettheme/util/ThemePreviewPaneInitHelper.java

@ -0,0 +1,70 @@
package com.fr.widgettheme.util;
import com.fr.base.BaseFormula;
import com.fr.chart.chartattr.Title;
import com.fr.design.i18n.Toolkit;
import com.fr.plugin.chart.attr.axis.VanChartAxis;
import com.fr.plugin.chart.base.AttrLabel;
import com.fr.plugin.chart.base.VanChartTools;
import com.fr.plugin.chart.column.VanChartColumnPlot;
import com.fr.plugin.chart.type.GradientType;
/**
* 辅助report和form的控件显示主题预览窗口做初始化工作
* 没有其他的用途不要用在其他的地方只是抽一些方法出来降低复杂度
*
* @author obo
* @since 11.0
* Created on 2023/11/14
*/
public class ThemePreviewPaneInitHelper {
private ThemePreviewPaneInitHelper() {
}
/**
* 初始化图表工具
*
* @param vanChartTools 图表工具
*/
public static void initVanChartsTools(VanChartTools vanChartTools) {
vanChartTools.setSort(false);
vanChartTools.setExport(false);
vanChartTools.setFullScreen(false);
}
/**
* 初始化柱形图绘图区
*
* @param plot 绘图区
*/
public static void initColumnPlot(VanChartColumnPlot plot) {
AttrLabel defaultAttrLabel = plot.getDefaultAttrLabel();
defaultAttrLabel.setEnable(true);
defaultAttrLabel.getAttrLabelDetail().getBorder().setBorderStyle(0);
defaultAttrLabel.getAttrLabelDetail().getBackground().setBackground(null);
plot.getConditionCollection().getDefaultAttr().addDataSeriesCondition(defaultAttrLabel);
plot.getGradientStyle().setGradientType(GradientType.NONE);
plot.setSeriesOverlapPercent(30);
plot.setCategoryIntervalPercent(30);
}
/**
* 初始化图表Y轴
*
* @param yAxis
*/
public static void initVanChartYAxis(VanChartAxis yAxis) {
Title title = new Title();
title.setTextObject(Toolkit.i18nText("Fine-Design_Chart_Axis_Title"));
title.getTextAttr().setRotation(-90);
title.getTextAttr().setThemed(true);
yAxis.setTitle(title);
yAxis.setShowAxisTitle(true);
yAxis.setCustomMaxValue(true);
yAxis.setCustomMinValue(true);
yAxis.setCustomMainUnit(true);
yAxis.setMaxValue(BaseFormula.createFormulaBuilder().build("=600"));
yAxis.setMinValue(BaseFormula.createFormulaBuilder().build("=0"));
yAxis.setMainUnit(BaseFormula.createFormulaBuilder().build("=200"));
}
}

40
designer-base/src/main/java/com/fr/widgettheme/util/ThemeTextStylePaneCreator.java

@ -0,0 +1,40 @@
package com.fr.widgettheme.util;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import javax.swing.Box;
import javax.swing.JPanel;
import java.awt.Component;
/**
* 创建主题文本样式的工具类
*
* @author obo
* @since 11.0
* Created on 2023/12/21
*/
public class ThemeTextStylePaneCreator {
private ThemeTextStylePaneCreator() {}
/**
* 创建主题文本样式配置面板
* 包含字体大小下拉框和字体颜色按钮
* 可以自适应布局
*
* @param fontSizePane 字体大小配置
* @param fontColorButton 字体颜色配置
* @return 文本样式面板
*/
public static JPanel create(FontSizeComboPane fontSizePane, UIColorButton fontColorButton) {
Component[][] components = {{fontSizePane, Box.createHorizontalStrut(5), fontColorButton}};
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
double[] rowSize = {f};
double[] columnSize = {f, p, p};
int[][] rowCount = {{1, 1, 1}};
return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, 0, 0);
}
}

46
designer-base/src/main/java/com/fr/widgettheme/util/WidgetThemeDesignerUtils.java

@ -0,0 +1,46 @@
package com.fr.widgettheme.util;
import com.fr.base.io.AttrMark;
import com.fr.base.io.IOFile;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.JTemplate;
import com.fr.stable.StringUtils;
import com.fr.widgettheme.control.attr.WidgetDisplayEnhanceMarkAttr;
/**
* 控件主题设计器部分工具类
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public class WidgetThemeDesignerUtils {
private WidgetThemeDesignerUtils() {
}
/**
* WorkBook 中加载 WatermarkAttr 属性对象
*
* @param template AttrMark 对象包括 WorkBook
* @return StrongestControlMarkAttr 对象
*/
public static WidgetDisplayEnhanceMarkAttr getStrongestControlAttrFromTemplate(AttrMark template) {
return template.getAttrMark(WidgetDisplayEnhanceMarkAttr.XML_TAG);
}
/**
* 判断是否启用了控件显示增强
*
* @return 开启与否
*/
public static boolean enableWidgetEnhance() {
JTemplate<?, ?> jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (JTemplate.isValid(jTemplate)) {
IOFile ioFile = (IOFile) jTemplate.getTarget();
WidgetDisplayEnhanceMarkAttr mark = ioFile.getAttrMark(WidgetDisplayEnhanceMarkAttr.XML_TAG);
return mark != null && mark.isWidgetEnhance();
}
return false;
}
}

273
designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/DisplayEnhanceMobileStyleDefinePane.java

@ -0,0 +1,273 @@
package com.fr.widgettheme.widget.mobile.pane;
import com.fr.base.background.ColorBackground;
import com.fr.widgettheme.theme.widget.style.MobileThemedWidgetStyle;
import com.fr.widgettheme.theme.widget.mobile.style.WidgetThemeMobileCommonExtraStyle;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.icombobox.LineComboBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane;
import com.fr.design.style.color.ColorSelectBox;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.form.ui.Widget;
import com.fr.form.ui.mobile.MobileCommonExtraStyle;
import com.fr.form.ui.mobile.MobileStyle;
import com.fr.general.FRFont;
import com.fr.invoke.Reflect;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
/**
* <p> 开启控件显示增强后替换原通用属性面板
* <p> 参考{@link com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane}
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/4/11
*/
public class DisplayEnhanceMobileStyleDefinePane extends BasicBeanPane<MobileStyle> {
public static final int NORMAL_COMBO_WIDTH = 152;
protected Widget widget;
protected MobileStyleCustomDefinePane customBeanPane;
protected Class<? extends MobileStyle> mobileStyleClazz;
protected UIComboBox customCombo;
protected JPanel settingPane;
protected NewColorSelectBox themeColorSelectBox;
protected Color titleColor = new Color(47, 142, 241);
protected JPanel commonPane;
protected LineComboBox borderType;
protected UISpinner borderRadius;
protected MobileStyleFontConfigPane fontConfigPane;
protected ColorSelectBox widgetBackgroundSelectBox;
protected MobileStyle mobileStyle;
public DisplayEnhanceMobileStyleDefinePane(Widget widget, Class<? extends MobileStyleCustomDefinePane> customBeanPaneClass,
Class<? extends MobileStyle> mobileStyleClazz) {
this.widget = widget;
this.customBeanPane = Reflect.on(customBeanPaneClass).create(widget).get();
this.mobileStyleClazz = mobileStyleClazz;
// 一些默认的情况,没有,需要初始化一下。
initMobileStyle(widget);
init();
}
private void initMobileStyle(Widget widget) {
mobileStyle = widget.getMobileStyle() != null ? widget.getMobileStyle() : Reflect.on(mobileStyleClazz).create().get();
}
@Override
public void populateBean(MobileStyle ob) {
MobileCommonExtraStyle extraStyle = ob.getMobileCommonExtraStyle();
if (extraStyle instanceof WidgetThemeMobileCommonExtraStyle) {
WidgetThemeMobileCommonExtraStyle style = (WidgetThemeMobileCommonExtraStyle) extraStyle;
customCombo.setSelectedIndex(style.isCustom() ? 1 : 0);
borderType.setSelectedLineStyle(style.getBorderType());
borderRadius.setValue(style.getBorderRadius());
if (style.getThemeColor() != null) {
themeColorSelectBox.setSelectObject(style.getThemeColor());
}
if (style.getNewFont() != null) {
fontConfigPane.populateBean(style.getNewFont());
}
if (style.getWidgetBackground() != null) {
widgetBackgroundSelectBox.setSelectObject(((ColorBackground) style.getWidgetBackground()).getColor());
}
}
this.customBeanPane.populateBean(ob);
}
@Override
public MobileStyle updateBean() {
mobileStyle = Reflect.on(mobileStyleClazz).create().get();
WidgetThemeMobileCommonExtraStyle extraStyle = new WidgetThemeMobileCommonExtraStyle();
extraStyle.setCustom(customCombo.getSelectedIndex() == 1);
extraStyle.setThemeColor(themeColorSelectBox.getSelectObject());
extraStyle.setBorderType(borderType.getSelectedLineStyle());
extraStyle.setBorderRadius(borderRadius.getValue());
extraStyle.setNewFont(fontConfigPane.updateBean());
extraStyle.setWidgetBackground(ColorBackground.getInstance(widgetBackgroundSelectBox.getSelectObject()));
mobileStyle.setMobileCommonExtraStyle(extraStyle);
this.widget.setMobileStyle(mobileStyle);
this.customBeanPane.updateBean();
return mobileStyle;
}
@Override
protected String title4PopupWindow() {
return StringUtils.EMPTY;
}
private void init() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
createGeneralPane();
createCustomPane();
}
protected void createFontPane(Color defaultFontColor) {
fontConfigPane = new MobileStyleFontConfigPane(defaultFontColor);
settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_Font")), fontConfigPane));
}
private void createGeneralPane() {
createPreviewPane();
createCommonPane();
}
private void createPreviewPane() {
JPanel mobileStylePreviewPane = Reflect.on(customBeanPane).call("createPreviewPane").get();
if (mobileStylePreviewPane != null) {
JPanel previewPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
TitledBorder titledBorder = createTitledBorder(Toolkit.i18nText("Fine-Design_Basic_Widget_Style_Preview"));
previewPane.setBorder(titledBorder);
previewPane.setPreferredSize(new Dimension(500, 83));
previewPane.add(mobileStylePreviewPane, BorderLayout.CENTER);
this.add(previewPane, BorderLayout.NORTH);
}
}
private void createCommonPane() {
TitledBorder titledBorder = createTitledBorder(Toolkit.i18nText("Fine-Design_Mobile_Common_Attribute"));
commonPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 10);
commonPane.setBorder(titledBorder);
this.add(commonPane, BorderLayout.NORTH);
customCombo = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Mobile_Default"), Toolkit.i18nText("Fine-Design_Mobile_Custom")});
customCombo.setSelectedIndex(0);
customCombo.setPreferredSize(new Dimension(NORMAL_COMBO_WIDTH + 15, 20));
customCombo.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
boolean custom = customCombo.getSelectedIndex() == 1;
settingPane.setVisible(custom);
}
});
commonPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Attribute_Settings")), customCombo));
settingPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 10);
settingPane.setBorder(new EmptyBorder(-10, 0, 0, 0));
settingPane.setVisible(false);
commonPane.add(settingPane);
createUniversalPane();
}
protected void createUniversalPane() {
// 主题色
createThemePane();
// 组件背景
createBackgroundPane();
// 边框线型
createBorderLinePane();
// 圆角边框
createBorderRadiusPane();
// 字体
createFontPane(WidgetThemeDisplayConstants.DEFAULT_FONT_COLOR_BLACK);
}
protected void createBackgroundPane() {
widgetBackgroundSelectBox = new ColorSelectBox(NORMAL_COMBO_WIDTH);
initBackgroundColor();
JPanel backgroundPane = createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_Background")), widgetBackgroundSelectBox);
settingPane.add(backgroundPane);
}
protected void initBackgroundColor() {
widgetBackgroundSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_TRANSPARENT_COLOR);
}
protected void createThemePane() {
themeColorSelectBox = new NewColorSelectBox(NORMAL_COMBO_WIDTH);
// 默认为当前模板选中的主题色
themeColorSelectBox.setSelectObject(getCurrentTemplateThemeColor());
settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Basic_Theme_Color")), themeColorSelectBox));
}
protected void createBorderLinePane() {
borderType = new LineComboBox(WidgetThemeDisplayConstants.MOBILE_BORDER_LINE_STYLE_ARRAY);
initDefaultLineType();
borderType.setPreferredSize(new Dimension(NORMAL_COMBO_WIDTH + 15, 20));
// 边框线型
settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_BorderType")), borderType));
}
protected void initDefaultLineType() {
borderType.setSelectedLineStyle(Constants.LINE_THIN);
}
protected void createBorderRadiusPane() {
borderRadius = new UISpinner(0, Integer.MAX_VALUE, 1, 2);
borderRadius.setPreferredSize(new Dimension(NORMAL_COMBO_WIDTH + 20, 20));
// 圆角边框
settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_BorderRadius")), borderRadius));
}
protected void createCustomPane() {
JPanel configPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
TitledBorder titledBorder = createTitledBorder(Toolkit.i18nText("Fine-Design_Report_Set"));
configPane.setBorder(titledBorder);
configPane.add(this.customBeanPane, BorderLayout.CENTER);
this.add(configPane, BorderLayout.CENTER);
}
protected TitledBorder createTitledBorder(String title) {
TitledBorder titledBorder = GUICoreUtils.createTitledBorder(title, titleColor);
titledBorder.setTitleFont(FRFont.getInstance("PingFangSC-Regular", Font.PLAIN, 12));
return titledBorder;
}
protected UILabel createConfigLabel(String title) {
UILabel label = new UILabel(title, UILabel.LEFT);
label.setPreferredSize(new Dimension(75, 20));
label.setBorder(new EmptyBorder(0, 15, 0, 0));
return label;
}
protected JPanel createLeftRightComponentsPane(Component... components) {
JPanel tableLayoutPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{components}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_MEDIUM);
return tableLayoutPane;
}
/**
* 获取当前编辑移动端控件样式主题色
*
* @return
*/
protected Color getCurrentTemplateThemeColor() {
JTemplate<?, ?> jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
Color themeColor = WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR;
if (JTemplate.isValid(jTemplate)) {
MobileThemedWidgetStyle mobileWidgetStyle = (MobileThemedWidgetStyle) jTemplate.getTemplateTheme().getMobileWidgetStyle();
mobileWidgetStyle = mobileWidgetStyle == null ? new MobileThemedWidgetStyle() : mobileWidgetStyle;
themeColor = mobileWidgetStyle.getThemeColor();
}
return themeColor;
}
}

59
designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/FileEditorMobileStyleDefinePane.java

@ -0,0 +1,59 @@
package com.fr.widgettheme.widget.mobile.pane;
import com.fr.base.background.ColorBackground;
import com.fr.widgettheme.theme.widget.mobile.style.FileEditorStyle;
import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane;
import com.fr.form.ui.Widget;
import com.fr.form.ui.mobile.MobileCommonExtraStyle;
import com.fr.form.ui.mobile.MobileStyle;
import com.fr.invoke.Reflect;
/**
* 文件属性定义面板
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/5/19
*/
public class FileEditorMobileStyleDefinePane extends DisplayEnhanceMobileStyleDefinePane {
public FileEditorMobileStyleDefinePane(Widget widget, Class<? extends MobileStyleCustomDefinePane> customBeanPaneClass, Class<? extends MobileStyle> mobileStyleClazz) {
super(widget, customBeanPaneClass, mobileStyleClazz);
}
@Override
public void populateBean(MobileStyle ob) {
MobileCommonExtraStyle extraStyle = ob.getMobileCommonExtraStyle();
if (extraStyle instanceof FileEditorStyle) {
FileEditorStyle style = (FileEditorStyle) extraStyle;
customCombo.setSelectedIndex(style.isCustom() ? 1 : 0);
if (style.getWidgetBackground() != null) {
widgetBackgroundSelectBox.setSelectObject(((ColorBackground) style.getWidgetBackground()).getColor());
}
borderType.setSelectedLineStyle(style.getBorderType());
borderRadius.setValue(style.getBorderRadius());
}
this.customBeanPane.populateBean(ob);
}
@Override
public MobileStyle updateBean() {
mobileStyle = Reflect.on(mobileStyleClazz).create().get();
FileEditorStyle extraStyle = new FileEditorStyle();
extraStyle.setCustom(customCombo.getSelectedIndex() == 1);
extraStyle.setWidgetBackground(ColorBackground.getInstance(widgetBackgroundSelectBox.getSelectObject()));
extraStyle.setBorderType(borderType.getSelectedLineStyle());
extraStyle.setBorderRadius(borderRadius.getValue());
mobileStyle.setMobileCommonExtraStyle(extraStyle);
this.widget.setMobileStyle(mobileStyle);
this.customBeanPane.updateBean();
return mobileStyle;
}
@Override
protected void createUniversalPane() {
createBackgroundPane();
createBorderLinePane();
createBorderRadiusPane();
}
}

93
designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/FreeButtonMobileStyleDefinePane.java

@ -0,0 +1,93 @@
package com.fr.widgettheme.widget.mobile.pane;
import com.fr.base.background.ColorBackground;
import com.fr.widgettheme.theme.widget.mobile.style.FreeButtonStyle;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.form.ui.Widget;
import com.fr.form.ui.mobile.MobileCommonExtraStyle;
import com.fr.form.ui.mobile.MobileStyle;
import com.fr.invoke.Reflect;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
/**
* 按钮控件通用属性面板
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/5/25
*/
public class FreeButtonMobileStyleDefinePane extends DisplayEnhanceMobileStyleDefinePane {
private NewColorSelectBox borderColorSelectBox;
private NewColorSelectBox iconColorSelectBox;
public FreeButtonMobileStyleDefinePane(Widget widget, Class<? extends MobileStyleCustomDefinePane> customBeanPaneClass, Class<? extends MobileStyle> mobileStyleClazz) {
super(widget, customBeanPaneClass, mobileStyleClazz);
}
@Override
public void populateBean(MobileStyle ob) {
super.populateBean(ob);
MobileCommonExtraStyle extraStyle = ob.getMobileCommonExtraStyle();
if (extraStyle instanceof FreeButtonStyle) {
FreeButtonStyle style = (FreeButtonStyle) extraStyle;
if (style.getBorderColor() != null) {
borderColorSelectBox.setSelectObject(style.getBorderColor());
}
if (style.getIconColor() != null) {
iconColorSelectBox.setSelectObject(style.getIconColor());
}
}
}
@Override
public MobileStyle updateBean() {
mobileStyle = Reflect.on(mobileStyleClazz).create().get();
FreeButtonStyle extraStyle = new FreeButtonStyle();
extraStyle.setCustom(customCombo.getSelectedIndex() == 1);
extraStyle.setWidgetBackground(ColorBackground.getInstance(widgetBackgroundSelectBox.getSelectObject()));
extraStyle.setBorderType(borderType.getSelectedLineStyle());
extraStyle.setBorderColor(borderColorSelectBox.getSelectObject());
extraStyle.setBorderRadius(borderRadius.getValue());
extraStyle.setNewFont(fontConfigPane.updateBean());
extraStyle.setIconColor(iconColorSelectBox.getSelectObject());
mobileStyle.setMobileCommonExtraStyle(extraStyle);
this.widget.setMobileStyle(mobileStyle);
this.customBeanPane.updateBean();
return mobileStyle;
}
@Override
protected void createUniversalPane() {
createBackgroundPane();
createBorderLinePane();
initBorderColor();
createBorderRadiusPane();
initIconColor();
createFontPane(WidgetThemeDisplayConstants.DEFAULT_WHITE_COLOR);
}
private void initIconColor() {
iconColorSelectBox = new NewColorSelectBox(NORMAL_COMBO_WIDTH);
iconColorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_WHITE_COLOR);
settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_Icon_Color")), iconColorSelectBox));
}
@Override
protected void initDefaultLineType() {
borderType.setSelectedLineStyle(com.fr.stable.Constants.LINE_NONE);
}
private void initBorderColor() {
borderColorSelectBox = new NewColorSelectBox(NORMAL_COMBO_WIDTH);
borderColorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_THEME_COLOR);
settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_BorderColor")), borderColorSelectBox));
}
@Override
protected void initBackgroundColor() {
widgetBackgroundSelectBox.setSelectObject(getCurrentTemplateThemeColor());
}
}

77
designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/LabelMobileStyleDefinePane.java

@ -0,0 +1,77 @@
package com.fr.widgettheme.widget.mobile.pane;
import com.fr.base.background.ColorBackground;
import com.fr.widgettheme.theme.widget.mobile.style.LabelIconSettingStyle;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.form.ui.Widget;
import com.fr.form.ui.mobile.MobileCommonExtraStyle;
import com.fr.form.ui.mobile.MobileStyle;
import com.fr.invoke.Reflect;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
/**
* 标签控件属性定义面板
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/5/15
*/
public class LabelMobileStyleDefinePane extends DisplayEnhanceMobileStyleDefinePane {
private NewColorSelectBox borderColorSelectBox;
public LabelMobileStyleDefinePane(Widget widget, Class<? extends MobileStyleCustomDefinePane> customBeanPaneClass,
Class<? extends MobileStyle> mobileStyleClazz) {
super(widget, customBeanPaneClass, mobileStyleClazz);
}
@Override
public void populateBean(MobileStyle ob) {
super.populateBean(ob);
MobileCommonExtraStyle extraStyle = ob.getMobileCommonExtraStyle();
if (extraStyle instanceof LabelIconSettingStyle) {
LabelIconSettingStyle style = (LabelIconSettingStyle) extraStyle;
if (style.getBorderColor() != null) {
borderColorSelectBox.setSelectObject(style.getBorderColor());
}
}
}
@Override
public MobileStyle updateBean() {
mobileStyle = Reflect.on(mobileStyleClazz).create().get();
LabelIconSettingStyle extraStyle = new LabelIconSettingStyle();
extraStyle.setCustom(customCombo.getSelectedIndex() == 1);
extraStyle.setWidgetBackground(ColorBackground.getInstance(widgetBackgroundSelectBox.getSelectObject()));
extraStyle.setBorderType(borderType.getSelectedLineStyle());
extraStyle.setBorderColor(borderColorSelectBox.getSelectObject());
extraStyle.setBorderRadius(borderRadius.getValue());
extraStyle.setNewFont(fontConfigPane.updateBean());
mobileStyle.setMobileCommonExtraStyle(extraStyle);
this.widget.setMobileStyle(mobileStyle);
this.customBeanPane.updateBean();
return mobileStyle;
}
@Override
protected void createUniversalPane() {
createBackgroundPane();
createBorderLinePane();
initBorderColor();
createBorderRadiusPane();
createFontPane(WidgetThemeDisplayConstants.DEFAULT_FONT_COLOR_BLACK);
}
private void initBorderColor() {
borderColorSelectBox = new NewColorSelectBox(NORMAL_COMBO_WIDTH);
borderColorSelectBox.setSelectObject(WidgetThemeDisplayConstants.DEFAULT_TRANSPARENT_COLOR);
settingPane.add(createLeftRightComponentsPane(createConfigLabel(Toolkit.i18nText("Fine-Design_Mobile_Widget_BorderColor")), borderColorSelectBox));
}
@Override
protected void initDefaultLineType() {
borderType.setSelectedLineStyle(com.fr.stable.Constants.LINE_NONE);
}
}

151
designer-base/src/main/java/com/fr/widgettheme/widget/mobile/pane/MobileStyleFontConfigPane.java

@ -0,0 +1,151 @@
package com.fr.widgettheme.widget.mobile.pane;
import com.fr.base.BaseUtils;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UIToggleButton;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.FRFont;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.util.Vector;
/**
* 移动端字体面板
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/5/22
*/
public class MobileStyleFontConfigPane extends JPanel {
public static final int FONT_NONE = 0;
private static final int MAX_FONT_SIZE = 18;
private static final int MIN_FONT_SIZE = 12;
private static final Dimension BUTTON_SIZE = new Dimension(20, 18);
/**
* 获取字体大小集合
*
* @return 字体大小集合
*/
public static Vector<Integer> getFontSizes() {
Vector<Integer> fontSizes = new Vector<Integer>();
for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++) {
fontSizes.add(i);
}
return fontSizes;
}
private UIComboBox fontSizeComboBox;
private UIColorButton color;
private UIToggleButton italic;
private UIToggleButton bold;
public MobileStyleFontConfigPane() {
this.initComponent(new Color(0, 0, 0));
}
public MobileStyleFontConfigPane(Color defaultFontColor) {
this.initComponent(defaultFontColor);
}
private void initComponent(Color defaultFontColor) {
fontSizeComboBox = new UIComboBox();
fontSizeComboBox.setModel(new DefaultComboBoxModel(getFontSizes()));
fontSizeComboBox.setSelectedItem(16);
fontSizeComboBox.setPreferredSize(new Dimension(60, 20));
fontSizeComboBox.setRenderer(new LineCellRenderer());
color = new UIColorButton();
color.setColor(defaultFontColor);
italic = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png"));
bold = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png"));
this.setButtonsTips();
this.setButtonsSize(BUTTON_SIZE);
Component[] componentFont = new Component[]{
fontSizeComboBox, color, italic, bold
};
JPanel buttonPane = new JPanel(new BorderLayout());
JPanel flowPane = GUICoreUtils.createFlowPane(componentFont, FlowLayout.LEFT, LayoutConstants.HGAP_LARGE);
// 4是flowPane的默认横向gap,但会导致最左边的控件和边上也有4的间隙,调整一下
flowPane.setBorder(new EmptyBorder(0, -LayoutConstants.HGAP_LARGE, 0, 0));
buttonPane.add(flowPane);
this.setLayout(new BorderLayout(0, 0));
this.add(buttonPane, BorderLayout.CENTER);
}
private void setButtonsTips() {
color.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Foreground"));
italic.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Italic"));
bold.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Bold"));
}
private void setButtonsSize(Dimension size) {
color.setPreferredSize(size);
italic.setPreferredSize(size);
bold.setPreferredSize(size);
}
/**
* 填充字体
*
* @param frFont 字体
*/
public void populateBean(FRFont frFont) {
fontSizeComboBox.setSelectedItem(frFont.getSize());
color.setColor(frFont.getForeground());
bold.setSelected(frFont.isBold());
italic.setSelected(frFont.isItalic());
}
/**
* 更新字体
*/
public FRFont updateBean() {
int style = Font.PLAIN;
style += this.bold.isSelected() ? Font.BOLD : Font.PLAIN;
style += this.italic.isSelected() ? Font.ITALIC : Font.PLAIN;
return FRFont.getInstance(
FRFont.DEFAULT_FONTNAME,
style,
Float.parseFloat(fontSizeComboBox.getSelectedItem().toString()),
color.getColor(),
Constants.LINE_NONE
);
}
private class LineCellRenderer extends UIComboBoxRenderer {
public LineCellRenderer() {
super();
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel renderer = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
int currentValue = ((Integer) value).intValue();
if (currentValue == com.fr.design.mainframe.mobile.ui.MobileStyleFontConfigPane.FONT_NONE) {
renderer.setText(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_None"));
}
return renderer;
}
}
}

65
designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/DisplayEnhanceMobileStyleFactory.java

@ -0,0 +1,65 @@
package com.fr.widgettheme.widget.mobile.provider;
import com.fr.widgettheme.widget.mobile.pane.FileEditorMobileStyleDefinePane;
import com.fr.widgettheme.widget.mobile.pane.FreeButtonMobileStyleDefinePane;
import com.fr.widgettheme.widget.mobile.pane.LabelMobileStyleDefinePane;
import com.fr.widgettheme.theme.widget.mobile.style.FileEditorStyle;
import com.fr.widgettheme.theme.widget.mobile.style.FreeButtonStyle;
import com.fr.widgettheme.theme.widget.mobile.style.LabelIconSettingStyle;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane;
import com.fr.form.ui.FreeButton;
import com.fr.form.ui.Label;
import com.fr.form.ui.MultiFileEditor;
import com.fr.form.ui.Widget;
import com.fr.form.ui.mobile.MobileCommonExtraStyle;
import com.fr.form.ui.mobile.MobileStyle;
/**
* 样式创建工厂
*
* @author Coral.Chen
* @since 11.0
* Created on 2023/5/15
*/
public class DisplayEnhanceMobileStyleFactory {
/**
* 先写个简单工厂处理一下特殊的控件
*
* @param widget
* @return 特殊控件的通用属性面板
*/
public static BasicBeanPane<MobileStyle> createWidgetMobileStyleDefinePane(Widget widget, Class<? extends MobileStyleCustomDefinePane> customDefinePane, Class<? extends MobileStyle> mobileStyle) {
if (widget instanceof Label) {
return new LabelMobileStyleDefinePane(widget, customDefinePane, mobileStyle);
}
if (widget instanceof MultiFileEditor) {
return new FileEditorMobileStyleDefinePane(widget, customDefinePane, mobileStyle);
}
if (widget instanceof FreeButton) {
return new FreeButtonMobileStyleDefinePane(widget, customDefinePane, mobileStyle);
}
return null;
}
/**
* 生成控件移动端通用属性
*
* @param widget
* @return
*/
public static Class<? extends MobileCommonExtraStyle> classForWidgetCommonExtraStyle(Widget widget) {
if (widget instanceof Label) {
return LabelIconSettingStyle.class;
}
if (widget instanceof MultiFileEditor) {
return FileEditorStyle.class;
}
if (widget instanceof FreeButton) {
return FreeButtonStyle.class;
}
return null;
}
}

84
designer-base/src/main/java/com/fr/widgettheme/widget/mobile/provider/WidgetThemeMobileStyleDefinePaneCreator.java

@ -0,0 +1,84 @@
package com.fr.widgettheme.widget.mobile.provider;
import com.fr.base.io.IOFile;
import com.fr.widgettheme.widget.mobile.pane.DisplayEnhanceMobileStyleDefinePane;
import com.fr.widgettheme.theme.widget.mobile.style.WidgetThemeMobileCommonExtraStyle;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane;
import com.fr.form.ui.FreeButton;
import com.fr.form.ui.Label;
import com.fr.form.ui.MultiFileEditor;
import com.fr.form.ui.Widget;
import com.fr.form.ui.mobile.MobileCommonExtraStyle;
import com.fr.form.ui.mobile.MobileStyle;
import com.fr.log.FineLoggerFactory;
import com.fr.widgettheme.control.attr.WidgetDisplayEnhanceMarkAttr;
import org.jetbrains.annotations.NotNull;
/**
* 控件主题移动端样式窗口创建类
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public class WidgetThemeMobileStyleDefinePaneCreator {
private WidgetThemeMobileStyleDefinePaneCreator() {
}
/**
* 创建移动端控件样式属性窗口
*
* @param widget 控件
* @param customDefinePane 窗口类
* @param mobileStyle 样式类
* @return 窗口
*/
public static BasicBeanPane<MobileStyle> createBaseBeanPane(Widget widget, Class<? extends MobileStyleCustomDefinePane> customDefinePane, Class<? extends MobileStyle> mobileStyle) {
try {
JTemplate<?, ?> jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (JTemplate.isValid(jTemplate)) {
IOFile ioFile = (IOFile) jTemplate.getTarget();
WidgetDisplayEnhanceMarkAttr mark = ioFile.getAttrMark(WidgetDisplayEnhanceMarkAttr.XML_TAG);
if (mark != null && mark.isWidgetEnhance()) {
if (commonWidget(widget)) {
return new DisplayEnhanceMobileStyleDefinePane(widget, customDefinePane, mobileStyle);
} else {
return DisplayEnhanceMobileStyleFactory.createWidgetMobileStyleDefinePane(widget, customDefinePane, mobileStyle);
}
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error("[Strongest-Control]: create base bean pane failed.", e);
}
return null;
}
/**
* 根据控件获取通用扩展属性类
*
* @param widget 控件
* @return class
*/
public static @NotNull Class<? extends MobileCommonExtraStyle> classForCommonExtraStyle(Widget widget) {
if (commonWidget(widget)) {
return WidgetThemeMobileCommonExtraStyle.class;
} else {
return DisplayEnhanceMobileStyleFactory.classForWidgetCommonExtraStyle(widget);
}
}
/**
* 是否为普通控件
* 按钮控件标签控件文件控件需要特殊处理
*
* @param widget 控件
* @return /
*/
private static boolean commonWidget(Widget widget) {
return !((widget instanceof FreeButton) || (widget instanceof Label) || (widget instanceof MultiFileEditor));
}
}

BIN
designer-base/src/main/resources/com/fr/widgettheme/combobox.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

3
designer-base/src/main/resources/com/fr/widgettheme/menu.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 1V14H8.5V13H2V2H14V7H15V1H1ZM11 8H11.7L10.9 9H7V10H10.1L9.3 11H7H6V10V9V8H7H11ZM3 4H5V6H3V4ZM5 8H3V10H5V8ZM12 5V4H11H7H6V5V6V7H7H11H12V6V5ZM11 6H7V5H11V6ZM10.0404 12.239L13.1594 8.08039C13.2747 7.92663 13.5194 8.00819 13.5194 8.20039V11.3194H15.5987C15.7635 11.3194 15.8576 11.5075 15.7587 11.6394L12.6397 15.798C12.5244 15.9518 12.2797 15.8702 12.2797 15.678V12.559H10.2004C10.0356 12.559 9.94148 12.3709 10.0404 12.239Z" fill="#333334"/>
</svg>

After

Width:  |  Height:  |  Size: 595 B

41
designer-base/src/test/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPaneTest.java

@ -0,0 +1,41 @@
package com.fr.design.data.tabledata.tabledatapane;
import com.fr.base.Parameter;
import com.fr.design.data.datapane.sqlpane.SQLEditPane;
import com.fr.invoke.Reflect;
import junit.framework.TestCase;
import org.junit.Assert;
/**
* @author Yuan.Wang
* @since 11.0
* Created on 2023/12/22
*/
public class DBTableDataPaneTest extends TestCase {
public void testGetParameters() {
DBTableDataPane pane = new DBTableDataPane();
SQLEditPane editPane = new SQLEditPane();
String sql = "select distinct 类别ID from S产品\n" +
"where 1=1\n" +
"order by 类别ID\n" +
"--${ if(len(comboBox0) = 0,\"\",\"AND 类别00ID = '\" + comboBox0 + \"'\")}";
String sql1 = "select distinct 类别ID from S产品\n" +
"where 1=1\n" +
"order by 类别ID\n" +
"${ if(len(comboBox0) = 0,\"\",\"AND 类别00ID = '\" + comboBox0 + \"'\")}";
editPane.setText(sql);
Reflect.on(pane).set("sqlTextPane", editPane);
Reflect.on(pane).set("pageQuery", sql);
Parameter[] parameters = Reflect.on(pane).call("getParameters").get();
Assert.assertEquals(0, parameters.length);
editPane.setText(sql1);
parameters = Reflect.on(pane).call("getParameters").get();
Assert.assertEquals(1, parameters.length);
Assert.assertEquals(parameters[0].getName(), "comboBox0");
}
}

2
designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java

@ -28,6 +28,7 @@ import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormSelection;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.widget.accessibles.AccessibleBackgroundEditor;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.design.widget.ui.designer.AbstractDataModify;
@ -203,6 +204,7 @@ public class RootDesignDefinePane extends AbstractDataModify<WParameterLayout> {
private void refreshExtraAdvancedPane() {
extraPaneList.clear();
backgroundPane.removeAll();
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
Set<WidgetAdvancedPaneProvider<WParameterLayout>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<WParameterLayout> provider : providers) {
if (!provider.accept(creator)) {

5
designer-form/src/main/java/com/fr/design/widget/ui/btn/AbstractExtraButtonPane.java

@ -8,11 +8,13 @@ import com.fr.design.gui.icombobox.DictionaryComboBox;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widgettheme.processor.WidgetThemeCreatorPaneAdder;
import com.fr.design.widget.btn.ButtonWithHotkeysDetailPane;
import com.fr.form.ui.Button;
import com.fr.general.GeneralContext;
import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.collections.CollectionUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.JPanel;
@ -45,7 +47,8 @@ public abstract class AbstractExtraButtonPane<T extends Button> extends ButtonWi
*/
protected void refreshExtraAdvancedPane(Class cls) {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeCreatorPaneAdder.add(cls, extraPaneList);
boolean containsExtraPane = !CollectionUtils.isEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<T>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<T> provider : providers) {
if (!provider.accept(cls)) {

5
designer-form/src/main/java/com/fr/design/widget/ui/designer/ButtonDefinePane.java

@ -1,5 +1,6 @@
package com.fr.design.widget.ui.designer;
import com.finebi.cbb.utils.CollectionUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
@ -12,6 +13,7 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.widget.accessibles.AccessibleIconEditor;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.widget.btn.ButtonConstants;
import com.fr.form.ui.Button;
import com.fr.general.GeneralContext;
@ -64,7 +66,8 @@ public abstract class ButtonDefinePane<T extends Button> extends AbstractDataMod
private void refreshAdvancedPane() {
extraPaneList.clear();
containsExtraPane = false;
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
containsExtraPane = CollectionUtils.isNotEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<T>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<T> provider : providers) {
if (!provider.accept(creator)) {

7
designer-form/src/main/java/com/fr/design/widget/ui/designer/CheckBoxDefinePane.java

@ -1,5 +1,6 @@
package com.fr.design.widget.ui.designer;
import com.finebi.cbb.utils.CollectionUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
@ -11,7 +12,8 @@ import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widget.ui.designer.component.FontSizeComboPane;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.design.widget.ui.designer.component.FormWidgetValuePane;
import com.fr.form.ui.CheckBox;
import com.fr.general.GeneralContext;
@ -76,7 +78,8 @@ public class CheckBoxDefinePane extends AbstractDataModify<CheckBox> {
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
boolean containsExtraPane = CollectionUtils.isNotEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<CheckBox>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<CheckBox> provider : providers) {
if (!provider.accept(creator)) {

5
designer-form/src/main/java/com/fr/design/widget/ui/designer/DateEditorDefinePane.java

@ -1,5 +1,6 @@
package com.fr.design.widget.ui.designer;
import com.finebi.cbb.utils.CollectionUtils;
import com.fr.base.FRContext;
import com.fr.data.core.FormatField;
import com.fr.design.ExtraDesignClassManager;
@ -14,6 +15,7 @@ import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.widget.component.DateValuePane;
import com.fr.design.widget.component.UIComboBoxNoArrow;
import com.fr.design.widget.ui.designer.component.FormWidgetValuePane;
@ -98,7 +100,8 @@ public class DateEditorDefinePane extends DirectWriteEditorDefinePane<DateEditor
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
boolean containsExtraPane = CollectionUtils.isNotEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<DateEditor>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<DateEditor> provider : providers) {
if (!provider.accept(creator)) {

5
designer-form/src/main/java/com/fr/design/widget/ui/designer/DirectWriteEditorDefinePane.java

@ -1,5 +1,6 @@
package com.fr.design.widget.ui.designer;
import com.finebi.cbb.utils.CollectionUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
@ -9,6 +10,7 @@ import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.widget.ui.designer.component.FormWidgetValuePane;
import com.fr.form.ui.DirectWriteEditor;
@ -66,7 +68,8 @@ public abstract class DirectWriteEditorDefinePane<T extends DirectWriteEditor> e
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
boolean containsExtraPane = CollectionUtils.isNotEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<T>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<T> provider : providers) {
if (!provider.accept(creator)) {

2
designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java

@ -20,7 +20,7 @@ import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widget.ui.designer.component.FontSizeComboPane;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.form.ui.FieldEditor;
import com.fr.general.GeneralContext;
import com.fr.log.FineLoggerFactory;

11
designer-form/src/main/java/com/fr/design/widget/ui/designer/LabelDefinePane.java

@ -1,5 +1,6 @@
package com.fr.design.widget.ui.designer;
import com.finebi.cbb.utils.CollectionUtils;
import com.fr.base.BaseUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
@ -15,6 +16,7 @@ import com.fr.design.gui.style.FRFontPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.design.widget.ui.designer.component.FormWidgetValuePane;
import com.fr.form.ui.Label;
@ -35,7 +37,11 @@ import java.util.Set;
/**
* Created by ibm on 2017/8/3.
* 标签控件pane
*
* @author obo
* @version 11.0
* Created on 2023/11/13
*/
public class LabelDefinePane extends AbstractDataModify<Label> {
private static final int WIDGET_VALUE_PANE_WIDTH = 150;
@ -105,7 +111,8 @@ public class LabelDefinePane extends AbstractDataModify<Label> {
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
boolean containsExtraPane = CollectionUtils.isNotEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<Label>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<Label> provider : providers) {
if (!provider.accept(creator)) {

2
designer-form/src/main/java/com/fr/design/widget/ui/designer/MultiFileEditorPane.java

@ -10,7 +10,7 @@ import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widget.ui.designer.component.FontSizeComboPane;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.form.ui.MultiFileEditor;

12
designer-form/src/main/java/com/fr/design/widget/ui/designer/NumberEditorDefinePane.java

@ -1,5 +1,6 @@
package com.fr.design.widget.ui.designer;
import com.finebi.cbb.utils.CollectionUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
@ -10,6 +11,7 @@ import com.fr.design.gui.ispinner.UIBasicSpinner;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.widget.component.NumberEditorValidatePane;
import com.fr.design.widget.ui.designer.component.FormWidgetValuePane;
import com.fr.form.ui.NumberEditor;
@ -21,6 +23,13 @@ import javax.swing.SwingConstants;
import java.awt.Component;
import java.util.Set;
/**
* 数字编辑控件pane
*
* @author obo
* @version 11.0
* Created on 2023/11/13
*/
public class NumberEditorDefinePane extends FieldEditorDefinePane<NumberEditor> {
public NumberEditorDefinePane(XCreator xCreator){
super(xCreator);
@ -67,7 +76,8 @@ public class NumberEditorDefinePane extends FieldEditorDefinePane<NumberEditor>
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
boolean containsExtraPane = CollectionUtils.isNotEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<NumberEditor>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<NumberEditor> provider : providers) {
if (!provider.accept(creator)) {

5
designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java

@ -1,5 +1,6 @@
package com.fr.design.widget.ui.designer;
import com.finebi.cbb.utils.CollectionUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
@ -12,6 +13,7 @@ import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.widget.ui.designer.component.FormWidgetValuePane;
import com.fr.form.ui.TextEditor;
import com.fr.log.FineLoggerFactory;
@ -85,7 +87,8 @@ public class TextFieldEditorDefinePane extends FieldEditorDefinePane<TextEditor>
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
boolean containsExtraPane = CollectionUtils.isNotEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<TextEditor>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<TextEditor> provider : providers) {
if (!provider.accept(creator)) {

5
designer-form/src/main/java/com/fr/design/widget/ui/designer/btn/ButtonGroupDefinePane.java

@ -1,5 +1,6 @@
package com.fr.design.widget.ui.designer.btn;
import com.finebi.cbb.utils.CollectionUtils;
import com.fr.data.Dictionary;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.beans.BasicBeanPane;
@ -11,6 +12,7 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.widget.accessibles.AccessibleDictionaryEditor;
import com.fr.design.widgettheme.processor.WidgetThemeParaCreatorPaneAdder;
import com.fr.design.widget.ui.designer.ButtonGroupDictPane;
import com.fr.design.widget.ui.designer.FieldEditorDefinePane;
import com.fr.design.widget.ui.designer.component.FormWidgetValuePane;
@ -68,7 +70,8 @@ public abstract class ButtonGroupDefinePane<T extends ButtonGroup> extends Field
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeParaCreatorPaneAdder.add(creator, extraPaneList);
boolean containsExtraPane = CollectionUtils.isNotEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<T>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<T> provider : providers) {
if (!provider.accept(creator)) {

317
designer-form/src/main/java/com/fr/design/widgettheme/BaseStyleSettingPane.java

@ -0,0 +1,317 @@
package com.fr.design.widgettheme;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.gui.frpane.FontSizeComboPane;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.widgettheme.theme.widget.style.BorderStyle;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.style.ThemedWidgetStyle;
import com.fr.widgettheme.theme.bean.ButtonBackground;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.icombobox.LineComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.style.FRFontPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.design.widget.ui.designer.component.UIBoundSpinner;
import com.fr.form.ui.Widget;
import com.fr.general.FRFont;
import com.fr.widgettheme.theme.panel.ButtonStyleDefinedPane;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.widgettheme.util.ThemeTextStylePaneCreator;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 样式设置pane抽象类
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public abstract class BaseStyleSettingPane<T extends Widget> extends BasicBeanPane<T> {
protected List<StyleSetting> styleSettingList;
//样式切换标题头部
protected UIButtonGroup<String> styleSettingHead;
// 自定义样式
protected JPanel customPane;
// 主题色
protected NewColorSelectBox colorSelectBox;
// 风格1
protected UIRadioButton style1;
// 风格2
protected UIRadioButton style2;
// 边框线型
protected LineComboBox lineComboBox;
// 圆角边框
protected UIBoundSpinner borderRadiusSpinner;
// 字体详细设置
protected FRFontPane frFontPane;
// 按钮背景设置
protected ButtonStyleDefinedPane buttonStyleDefinedPane;
protected NewColorSelectBox selectBgColorBox;
/**
* 主题文本样式的字体大小
*/
protected FontSizeComboPane fontSizePane;
/**
* 主题文本样式的字体颜色
*/
protected UIColorButton fontColorButton;
private final Map<StyleSetting, UILabel> labelMap = new HashMap<>();
private final Map<StyleSetting, Component> paneMap = new HashMap<>();
public BaseStyleSettingPane(List<StyleSetting> styleSettingList) {
this.styleSettingList = styleSettingList;
initLabelMap();
initStyleEditor();
initPane();
initDefaultValue();
}
protected void initPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(createHeadPane(), BorderLayout.NORTH);
this.add(createCustomPane(), BorderLayout.CENTER);
}
protected void initStyleEditor() {
initStyle();
colorSelectBox = new NewColorSelectBox(160, true);
lineComboBox = new LineComboBox(WidgetThemeDisplayConstants.BORDER_LINE_STYLE_ARRAY);
borderRadiusSpinner = new UIBoundSpinner(0, Integer.MAX_VALUE, 1);
frFontPane = new FRFontPane();
buttonStyleDefinedPane = new ButtonStyleDefinedPane();
selectBgColorBox = new NewColorSelectBox(160, true);
fontSizePane = new FontSizeComboPane();
fontColorButton = new UIColorButton();
paneMap.put(StyleSetting.STYLE_TYPE, createStyleTypePane());
paneMap.put(StyleSetting.THEME_COLOR, colorSelectBox);
paneMap.put(StyleSetting.LINE_TYPE, lineComboBox);
paneMap.put(StyleSetting.TEXT_STYLE, ThemeTextStylePaneCreator.create(fontSizePane, fontColorButton));
paneMap.put(StyleSetting.BORDER_RADIUS, borderRadiusSpinner);
paneMap.put(StyleSetting.FONT, frFontPane);
paneMap.put(StyleSetting.BTN_BACKGROUND, buttonStyleDefinedPane);
paneMap.put(StyleSetting.SELECT_COLOR, selectBgColorBox);
}
/**
* 初始化style1和style2
*/
private void initStyle() {
style1 = new UIRadioButton(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_1"));
style2 = new UIRadioButton(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_2"));
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(style1);
buttonGroup.add(style2);
}
protected JPanel createHeadPane() {
UILabel headLabel = new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Style_Setting"));
String[] titles = new String[]{Toolkit.i18nText("Fine-Design_Widget_Follow_Theme"), Toolkit.i18nText("Fine-Design_Widget_Theme_Custom")};
styleSettingHead = new UIButtonGroup(titles) {
@Override
public void setSelectedIndex(int newSelectedIndex, boolean fireChanged) {
super.setSelectedIndex(newSelectedIndex, fireChanged);
switchCard();
}
};
JPanel headPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{
new Component[]{headLabel, styleSettingHead}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1);
headPane.setBorder(BorderFactory.createEmptyBorder(0, 0, IntervalConstants.INTERVAL_L1, 0));
return headPane;
}
protected JPanel createStyleTypePane() {
// 容纳风格1和风格2的panel
JPanel stylePane = new JPanel(FRGUIPaneFactory.createBoxFlowLayout());
stylePane.add(style1);
stylePane.add(style2);
return stylePane;
}
protected JPanel createCustomPane() {
int size = styleSettingList.size();
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
int columnCount = 2;
double[] rowSize = new double[size];
for (int i = 0; i < size; i++) {
rowSize[i] = p;
}
double[] columnSize = {p, f};
int[][] rowCount = new int[size][columnCount];
for (int i = 0; i < size; i++) {
for (int j = 0; j < columnCount; j++) {
rowCount[i][j] = 1;
}
}
customPane = TableLayoutHelper.createGapTableLayoutPane(createComponents(size), rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1);
customPane.setBorder(BorderFactory.createEmptyBorder(0, 0, IntervalConstants.INTERVAL_L1, 0));
return customPane;
}
protected Component[][] createComponents(int size) {
Component[][] result = new Component[size][2];
for (int i = 0; i < size; i++) {
result[i] = createComponentByStyleSetting(styleSettingList.get(i));
}
return result;
}
protected Component[] createComponentByStyleSetting(StyleSetting styleSetting) {
Component[] components = new Component[2];
components[0] = labelMap.get(styleSetting);
components[1] = paneMap.get(styleSetting);
return components;
}
protected void switchCard() {
customPane.setVisible(styleSettingHead.getSelectedIndex() == 1);
}
protected void initDefaultValue() {
// 读取当前模板的主题
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (JTemplate.isValid(template)) {
TemplateTheme theme = template.getTemplateTheme();
ThemedWidgetStyle widgetStyle = (ThemedWidgetStyle) theme.getWidgetStyle();
if (widgetStyle != null) {
setThemedStyle(widgetStyle);
return;
}
}
setDefaultStyle();
}
private void setThemedStyle(ThemedWidgetStyle widgetStyle) {
setColorSelectBox(widgetStyle);
setStyle(widgetStyle);
setLineComboBox(widgetStyle);
setBorderRadiusSpinner(widgetStyle);
setTextStylePane(widgetStyle);
setFrFontPane(widgetStyle);
setButtonStyleDefinedPane(widgetStyle);
setSelectBgColor(widgetStyle);
}
private void setColorSelectBox(ThemedWidgetStyle widgetStyle) {
if (colorSelectBox != null) {
colorSelectBox.setSelectObject(widgetStyle.getThemeColor());
}
}
private void setStyle(ThemedWidgetStyle widgetStyle) {
if (widgetStyle.getStyleType() == ThemedWidgetStyle.DEFAULT_STYLE) {
if (style1 != null) {
style1.setSelected(true);
}
} else {
if (style2 != null) {
style2.setSelected(true);
}
}
}
private void setLineComboBox(ThemedWidgetStyle widgetStyle) {
if (lineComboBox != null) {
lineComboBox.setSelectedLineStyle(widgetStyle.getBorderStyle().getLineType());
}
}
private void setBorderRadiusSpinner(ThemedWidgetStyle widgetStyle) {
if (borderRadiusSpinner != null) {
borderRadiusSpinner.setValue(widgetStyle.getBorderStyle().getRadius());
}
}
private void setTextStylePane(ThemedWidgetStyle widgetStyle) {
ThemeTextStyle textStyle = widgetStyle.getTextStyle();
this.fontSizePane.setValue(textStyle.getFontSize());
this.fontColorButton.setColor(textStyle.getFontColor());
}
private void setFrFontPane(ThemedWidgetStyle widgetStyle) {
if (frFontPane != null) {
frFontPane.populateBean(widgetStyle.getFontStyle().getFont());
}
}
private void setButtonStyleDefinedPane(ThemedWidgetStyle widgetStyle) {
if (buttonStyleDefinedPane != null) {
buttonStyleDefinedPane.populate(ButtonBackground.create(widgetStyle.getButtonBackgroundStyle()));
}
}
private void setDefaultStyle() {
if (colorSelectBox != null) {
colorSelectBox.setSelectObject(ThemedWidgetStyle.DEFAULT_COLOR);
}
if (style1 != null) {
style1.setSelected(true);
}
if (lineComboBox != null) {
lineComboBox.setSelectedLineStyle(BorderStyle.DEFAULT_LINE_TYPE);
}
if (borderRadiusSpinner != null) {
borderRadiusSpinner.setValue(BorderStyle.DEFAULT_BORDER_RADIUS);
}
if (fontSizePane != null) {
fontSizePane.setValue(ThemeTextStyle.DEFAULT_FONT_SIZE);
}
if (fontColorButton != null) {
fontColorButton.setColor(Color.BLACK);
}
if (frFontPane != null) {
frFontPane.populateBean(FRFont.getInstance());
}
if (selectBgColorBox != null) {
selectBgColorBox.setSelectObject(null);
}
}
private void setSelectBgColor(ThemedWidgetStyle widgetStyle) {
if(selectBgColorBox != null) {
selectBgColorBox.setSelectObject(widgetStyle.getSelectBackgroundColor());
}
}
/**
* 初始化枚举和UILabel对应的map
*/
private void initLabelMap() {
labelMap.put(StyleSetting.THEME_COLOR, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Color")));
labelMap.put(StyleSetting.TEXT_STYLE, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Text_Style")));
labelMap.put(StyleSetting.FONT, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Font")));
labelMap.put(StyleSetting.STYLE_TYPE, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Style")));
labelMap.put(StyleSetting.LINE_TYPE, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Line")));
labelMap.put(StyleSetting.BORDER_RADIUS, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Theme_Border_Radius")));
labelMap.put(StyleSetting.BTN_BACKGROUND, new UILabel(Toolkit.i18nText("Fine-Design_Theme_Widget_Background")));
labelMap.put(StyleSetting.SELECT_COLOR, new UILabel(Toolkit.i18nText("Fine-Design_Widget_Background_Select_Box")));
}
}

83
designer-form/src/main/java/com/fr/design/widgettheme/LabelSettingPane.java

@ -0,0 +1,83 @@
package com.fr.design.widgettheme;
import com.fr.widgettheme.theme.widget.style.FontStyle;
import com.fr.form.ui.Label;
import com.fr.form.ui.Widget;
import com.fr.general.FRFont;
import com.fr.widgettheme.theme.widget.theme.LabelTheme;
import java.util.Collections;
/**
* 设计器控件属性的高级设置增加主题样式设置项用于标签控件
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public class LabelSettingPane<T extends Widget> extends BaseStyleSettingPane<T> {
public LabelSettingPane() {
super(Collections.singletonList(StyleSetting.FONT));
}
@Override
public void populateBean(T t) {
LabelTheme widgetTheme = initLabelTheme(t);
if (widgetTheme.isFollowTheme()) {
styleSettingHead.setSelectedIndex(0);
} else {
styleSettingHead.setSelectedIndex(1);
FRFont font = ((Label) t).getFont();
frFontPane.populateBean(font);
}
switchCard();
}
private LabelTheme initLabelTheme(T t) {
LabelTheme widgetTheme = (LabelTheme) t.getWidgetTheme();
if (widgetTheme == null) {
widgetTheme = new LabelTheme();
Label label = (Label) t;
if (!label.getDefaultFont().equals(label.getFont())) {
widgetTheme.setFollowTheme(false);
widgetTheme.setFontStyle(new FontStyle((label.getFont())));
}
t.setWidgetTheme(widgetTheme);
}
return widgetTheme;
}
@Override
public void updateBean(T t) {
LabelTheme widgetTheme = initLabelTheme(t);
updateLabelBean(widgetTheme);
((Label) t).setFont(widgetTheme.getFontStyle().getFont());
}
private void updateLabelBean(LabelTheme widgetTheme) {
int selectIndex = styleSettingHead.getSelectedIndex();
widgetTheme.setFollowTheme(selectIndex == 0);
updateLabelStyleBean(widgetTheme);
}
private void updateLabelStyleBean(LabelTheme widgetTheme) {
if (widgetTheme.isFollowTheme()) {
widgetTheme.setFontStyle(new FontStyle());
frFontPane.populateBean(widgetTheme.getFontStyle().getFont());
} else {
widgetTheme.setFontStyle(new FontStyle(frFontPane.update(widgetTheme.getFontStyle().getFont())));
}
switchCard();
}
@Override
public T updateBean() {
return null;
}
@Override
protected String title4PopupWindow() {
return "labelSetting";
}
}

50
designer-form/src/main/java/com/fr/design/widgettheme/ParaButtonSettingPane.java

@ -0,0 +1,50 @@
package com.fr.design.widgettheme;
import com.fr.design.widgettheme.common.ButtonSettingPane;
import com.fr.form.ui.Widget;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.theme.ParaButtonTheme;
import com.fr.widgettheme.theme.widget.theme.cell.ButtonTheme;
import java.util.Arrays;
/**
* 参数面板:设计器控件属性的高级设置增加主题样式设置项包括
* 单选按钮组控件/复选按钮组控件/复选按钮控件
*
* @author Bruce.Deng
* @since 11.0
* Created on 2023/2/27
*/
public class ParaButtonSettingPane<T extends Widget> extends ButtonSettingPane<T> {
public ParaButtonSettingPane() {
super(Arrays.asList(
StyleSetting.THEME_COLOR,
StyleSetting.STYLE_TYPE,
StyleSetting.TEXT_STYLE
));
}
@Override
protected ButtonTheme getButtonTheme() {
return new ParaButtonTheme();
}
@Override
protected void assignFontSizePane(ButtonTheme buttonTheme) {
ThemeTextStyle textStyle = ((ParaButtonTheme) buttonTheme).getTextStyle();
fontSizePane.setValue(textStyle.getFontSize());
fontColorButton.setColor(textStyle.getFontColor());
}
@Override
protected void assignFontSizeStyle(ButtonTheme buttonTheme) {
ParaButtonTheme paraButtonTheme = (ParaButtonTheme) buttonTheme;
ThemeTextStyle textStyle = new ThemeTextStyle();
textStyle.setFontSize(fontSizePane.getValue());
textStyle.setFontColor(fontColorButton.getColor());
paraButtonTheme.setTextStyle(textStyle);
}
}

57
designer-form/src/main/java/com/fr/design/widgettheme/ParaEditorSettingPane.java

@ -0,0 +1,57 @@
package com.fr.design.widgettheme;
import com.fr.design.widgettheme.common.EditorSettingPane;
import com.fr.form.ui.Widget;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.theme.ParaEditorTheme;
import com.fr.widgettheme.theme.widget.theme.cell.EditorTheme;
import java.util.Arrays;
import java.util.List;
/**
* 设计器控件属性的高级设置增加主题样式设置项包括
* 文本控件/数字控件/密码控件/文本域控件/下拉框控件/下拉复选框控件/下拉树控件/日期控件
*
* @author Bruce.Deng
* @since 11.0
* Created on 2023/2/2
*/
public class ParaEditorSettingPane<T extends Widget> extends EditorSettingPane<T> {
public ParaEditorSettingPane() {
super(Arrays.asList(
StyleSetting.THEME_COLOR,
StyleSetting.STYLE_TYPE,
StyleSetting.LINE_TYPE,
StyleSetting.BORDER_RADIUS,
StyleSetting.TEXT_STYLE
));
}
public ParaEditorSettingPane(List<StyleSetting> styleSettingList) {
super(styleSettingList);
}
@Override
protected void assignFontSizePane(EditorTheme widgetTheme) {
ThemeTextStyle textStyle = ((ParaEditorTheme) widgetTheme).getTextStyle();
fontSizePane.setValue(textStyle.getFontSize());
fontColorButton.setColor(textStyle.getFontColor());
}
@Override
protected void assignFontSizeStyle(EditorTheme widgetTheme) {
ParaEditorTheme paraEditorTheme= (ParaEditorTheme) widgetTheme;
ThemeTextStyle textStyle = new ThemeTextStyle();
textStyle.setFontSize(fontSizePane.getValue());
textStyle.setFontColor(fontColorButton.getColor());
paraEditorTheme.setTextStyle(textStyle);
}
@Override
protected EditorTheme getEditorTheme() {
return new ParaEditorTheme();
}
}

68
designer-form/src/main/java/com/fr/design/widgettheme/ParaNormalButtonSettingPane.java

@ -0,0 +1,68 @@
package com.fr.design.widgettheme;
import com.fr.widgettheme.theme.widget.style.FontStyle;
import com.fr.design.widgettheme.common.NormalButtonSettingPane;
import com.fr.form.ui.FreeButton;
import com.fr.form.ui.Widget;
import com.fr.general.FRFont;
import com.fr.widgettheme.theme.widget.theme.ParaNormalButtonTheme;
import com.fr.widgettheme.theme.widget.theme.cell.NormalButtonTheme;
import java.util.Arrays;
/**
* 参数面板常规按钮设置窗口
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public class ParaNormalButtonSettingPane<T extends Widget> extends NormalButtonSettingPane<T> {
public ParaNormalButtonSettingPane() {
super(Arrays.asList(
StyleSetting.BTN_BACKGROUND,
StyleSetting.LINE_TYPE,
StyleSetting.BORDER_RADIUS,
StyleSetting.FONT
));
}
@Override
protected void assignFontPane(NormalButtonTheme normalButtonTheme) {
ParaNormalButtonTheme paraNormalButtonTheme = (ParaNormalButtonTheme) normalButtonTheme;
frFontPane.populateBean(paraNormalButtonTheme.getFontStyle().getFont());
}
@Override
protected void initCustomStyle(FreeButton freeButton, NormalButtonTheme widgetTheme) {
super.initCustomStyle(freeButton, widgetTheme);
FRFont font = freeButton.getFont();
((ParaNormalButtonTheme) widgetTheme).setFontStyle(new FontStyle(font));
}
@Override
protected void updateCustomStyle(FreeButton freeButton, NormalButtonTheme widgetTheme) {
super.updateCustomStyle(freeButton, widgetTheme);
FontStyle fontStyle = ((ParaNormalButtonTheme) widgetTheme).getFontStyle();
freeButton.setFont(fontStyle.getFont());
}
@Override
protected void assignFontStyle(NormalButtonTheme normalButtonTheme) {
ParaNormalButtonTheme paraNormalButtonTheme = (ParaNormalButtonTheme) normalButtonTheme;
if (paraNormalButtonTheme.isFollowTheme()) {
paraNormalButtonTheme.setFontStyle(new FontStyle());
assignFontPane(normalButtonTheme);
} else {
paraNormalButtonTheme.setFontStyle(new FontStyle(frFontPane.update(paraNormalButtonTheme.getFontStyle().getFont())));
}
}
@Override
protected NormalButtonTheme getDefaultNormalButtonTheme() {
return new ParaNormalButtonTheme();
}
}

31
designer-form/src/main/java/com/fr/design/widgettheme/ParaSelectEditorSettingPane.java

@ -0,0 +1,31 @@
package com.fr.design.widgettheme;
import com.fr.form.ui.Widget;
import java.util.Arrays;
/**
* 参数面板下拉框编辑控件配置面板
* 继承自编辑控件配置面板添加一个下拉框背景色
*
* @author obo
* @since 11.0
* Created on 2023/12/13
*/
public class ParaSelectEditorSettingPane<T extends Widget> extends ParaEditorSettingPane<T> {
public ParaSelectEditorSettingPane() {
super(Arrays.asList(
StyleSetting.THEME_COLOR,
StyleSetting.SELECT_COLOR,
StyleSetting.STYLE_TYPE,
StyleSetting.LINE_TYPE,
StyleSetting.BORDER_RADIUS,
StyleSetting.TEXT_STYLE
));
}
@Override
protected String title4PopupWindow() {
return "paraSelectEditorSetting";
}
}

48
designer-form/src/main/java/com/fr/design/widgettheme/ParaTreeEditorSettingPane.java

@ -0,0 +1,48 @@
package com.fr.design.widgettheme;
import com.fr.design.widgettheme.common.TreeEditorSettingPane;
import com.fr.form.ui.TreeEditor;
import com.fr.widgettheme.theme.widget.style.ThemeTextStyle;
import com.fr.widgettheme.theme.widget.theme.ParaTreeTheme;
import com.fr.widgettheme.theme.widget.theme.cell.TreeTheme;
import java.util.Arrays;
/**
* 参数面板设计器控件属性的高级设置增加主题样式设置项包括
* 视图树
*
* @author Bruce.Deng
* @since 11.0
* Created on 2023/2/28
*/
public class ParaTreeEditorSettingPane<T extends TreeEditor> extends TreeEditorSettingPane<T> {
public ParaTreeEditorSettingPane() {
super(Arrays.asList(
StyleSetting.THEME_COLOR,
StyleSetting.STYLE_TYPE,
StyleSetting.TEXT_STYLE
));
}
@Override
protected TreeTheme getTreeTheme() {
return new ParaTreeTheme();
}
@Override
protected void assignFontSizePane(TreeTheme widgetTheme) {
ThemeTextStyle textStyle = widgetTheme.getTextStyle();
fontSizePane.setValue(textStyle.getFontSize());
fontColorButton.setColor(textStyle.getFontColor());
}
@Override
protected void assignFontSizeStyle(TreeTheme widgetTheme) {
ThemeTextStyle textStyle = new ThemeTextStyle();
textStyle.setFontSize(fontSizePane.getValue());
textStyle.setFontColor(fontColorButton.getColor());
widgetTheme.setTextStyle(textStyle);
}
}

45
designer-form/src/main/java/com/fr/design/widgettheme/StyleSetting.java

@ -0,0 +1,45 @@
package com.fr.design.widgettheme;
/**
* 控件样式附加选项类型
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public enum StyleSetting {
/**
* 主题颜色
*/
THEME_COLOR,
/**
* 风格
*/
STYLE_TYPE,
/**
* 线型
*/
LINE_TYPE,
/**
* 边框圆角
*/
BORDER_RADIUS,
/**
* 文本样式
*/
TEXT_STYLE,
/**
* 字体
*/
FONT,
/**
* 按钮背景
*/
BTN_BACKGROUND,
/**
* 自定义下拉框颜色
*/
SELECT_COLOR
}

108
designer-form/src/main/java/com/fr/design/widgettheme/common/ButtonSettingPane.java

@ -0,0 +1,108 @@
package com.fr.design.widgettheme.common;
import com.fr.design.widgettheme.StyleSetting;
import com.fr.design.widgettheme.BaseStyleSettingPane;
import com.fr.form.ui.Widget;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.widgettheme.theme.widget.theme.cell.ButtonTheme;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* 设计器控件属性的高级设置增加主题样式设置项包括
* 单选按钮组控件/复选按钮组控件/复选按钮控件
*
* @author John.Ying
* @since 11.0
* Created on 2023/4/18
*/
public class ButtonSettingPane<T extends Widget> extends BaseStyleSettingPane<T> {
public ButtonSettingPane() {
super(Arrays.asList(
StyleSetting.THEME_COLOR,
StyleSetting.STYLE_TYPE
));
}
public ButtonSettingPane(List<StyleSetting> styleSettingList) {
super(styleSettingList);
}
@Override
public void populateBean(T t) {
ButtonTheme widgetTheme = initButtonTheme(t);
populateButtonBean(widgetTheme);
}
protected ButtonTheme initButtonTheme(T t) {
ButtonTheme widgetTheme = (ButtonTheme) t.getWidgetTheme();
if (widgetTheme == null) {
widgetTheme = getButtonTheme();
updateButtonStyleBean(widgetTheme);
t.setWidgetTheme(widgetTheme);
}
return widgetTheme;
}
protected ButtonTheme getButtonTheme() {
return new ButtonTheme();
}
protected void assignFontSizePane(ButtonTheme buttonTheme) {
}
protected void assignFontSizeStyle(ButtonTheme buttonTheme) {
}
protected void populateButtonBean(ButtonTheme buttonTheme) {
if (buttonTheme.isFollowTheme()) {
styleSettingHead.setSelectedIndex(0);
} else {
styleSettingHead.setSelectedIndex(1);
colorSelectBox.setSelectObject(buttonTheme.getThemeColor());
if (buttonTheme.getStyleType() == WidgetThemeDisplayConstants.STYLE_1) {
style1.setSelected(true);
} else {
style2.setSelected(true);
}
assignFontSizePane(buttonTheme);
}
switchCard();
}
@Override
public void updateBean(T t) {
ButtonTheme widgetTheme = initButtonTheme(t);
updateCellButtonBean(widgetTheme);
}
protected void updateCellButtonBean(ButtonTheme buttonTheme) {
int selectIndex = styleSettingHead.getSelectedIndex();
buttonTheme.setFollowTheme(selectIndex == 0);
updateButtonStyleBean(buttonTheme);
}
protected void updateButtonStyleBean(ButtonTheme buttonTheme) {
buttonTheme.setThemeColor(colorSelectBox.getSelectObject());
buttonTheme.setStyleType(style1.isSelected() ? WidgetThemeDisplayConstants.STYLE_1 : WidgetThemeDisplayConstants.STYLE_2);
assignFontSizeStyle(buttonTheme);
switchCard();
}
@Override
@Nullable
public T updateBean() {
return null;
}
@Override
protected String title4PopupWindow() {
return "buttonSetting";
}
}

117
designer-form/src/main/java/com/fr/design/widgettheme/common/EditorSettingPane.java

@ -0,0 +1,117 @@
package com.fr.design.widgettheme.common;
import com.fr.widgettheme.theme.widget.style.BorderStyle;
import com.fr.design.widgettheme.BaseStyleSettingPane;
import com.fr.form.ui.Widget;
import com.fr.design.widgettheme.StyleSetting;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.widgettheme.theme.widget.theme.cell.EditorTheme;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* 设计器控件属性的高级设置增加主题样式设置项包括
* 文本控件/数字控件/密码控件/文本域控件/下拉框控件/下拉复选框控件/下拉树控件/日期控件
*
* @author John.Ying
* @since 11.0
* Created on 2023/4/18
*/
public class EditorSettingPane<T extends Widget> extends BaseStyleSettingPane<T> {
public EditorSettingPane() {
super(Arrays.asList(
StyleSetting.THEME_COLOR,
StyleSetting.STYLE_TYPE,
StyleSetting.LINE_TYPE,
StyleSetting.BORDER_RADIUS
));
}
public EditorSettingPane(List<StyleSetting> styleSettingList) {
super(styleSettingList);
}
@Override
protected String title4PopupWindow() {
return "fieldEditorSetting";
}
protected void assignFontSizePane(EditorTheme widgetTheme) {
}
protected void assignFontSizeStyle(EditorTheme widgetTheme) {
}
@Override
public void populateBean(T t) {
EditorTheme widgetTheme = initEditorTheme(t);
populateEditorBean(widgetTheme);
}
protected EditorTheme initEditorTheme(T t) {
EditorTheme widgetTheme = (EditorTheme) t.getWidgetTheme();
if (widgetTheme == null) {
widgetTheme = getEditorTheme();
updateEditorStyleBean(widgetTheme);
t.setWidgetTheme(widgetTheme);
}
return widgetTheme;
}
protected EditorTheme getEditorTheme() {
return new EditorTheme();
}
protected void populateEditorBean(EditorTheme editorTheme) {
if (editorTheme.isFollowTheme()) {
styleSettingHead.setSelectedIndex(0);
} else {
styleSettingHead.setSelectedIndex(1);
colorSelectBox.setSelectObject(editorTheme.getThemeColor());
if (editorTheme.getStyleType() == WidgetThemeDisplayConstants.STYLE_1) {
style1.setSelected(true);
} else {
style2.setSelected(true);
}
lineComboBox.setSelectedLineStyle(editorTheme.getBorderStyle().getLineType());
borderRadiusSpinner.setValue(editorTheme.getBorderStyle().getRadius());
selectBgColorBox.setSelectObject(editorTheme.getSelectBoxBgColor());
assignFontSizePane(editorTheme);
}
switchCard();
}
@Override
@Nullable
public T updateBean() {
return null;
}
@Override
public void updateBean(T t) {
EditorTheme widgetTheme = initEditorTheme(t);
updateEditorBean(widgetTheme);
}
protected void updateEditorBean(EditorTheme editorTheme) {
int selectIndex = styleSettingHead.getSelectedIndex();
editorTheme.setFollowTheme(selectIndex == 0);
updateEditorStyleBean(editorTheme);
}
protected void updateEditorStyleBean(EditorTheme editorTheme) {
editorTheme.setThemeColor(colorSelectBox.getSelectObject());
editorTheme.setSelectBoxBgColor(selectBgColorBox.getSelectObject());
editorTheme.setStyleType(style1.isSelected() ? WidgetThemeDisplayConstants.STYLE_1 : WidgetThemeDisplayConstants.STYLE_2);
editorTheme.setBorderStyle(new BorderStyle((int) borderRadiusSpinner.getValue(), lineComboBox.getSelectedLineStyle()));
assignFontSizeStyle(editorTheme);
switchCard();
}
}

136
designer-form/src/main/java/com/fr/design/widgettheme/common/NormalButtonSettingPane.java

@ -0,0 +1,136 @@
package com.fr.design.widgettheme.common;
import com.fr.widgettheme.theme.widget.style.BorderStyle;
import com.fr.widgettheme.theme.widget.style.ButtonBackgroundStyle;
import com.fr.widgettheme.theme.bean.ButtonBackground;
import com.fr.design.widgettheme.BaseStyleSettingPane;
import com.fr.form.ui.FreeButton;
import com.fr.form.ui.Widget;
import com.fr.design.widgettheme.StyleSetting;
import com.fr.widgettheme.theme.widget.theme.cell.NormalButtonTheme;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* 设计器控件属性的高级设置增加主题样式设置项包括
* 按钮组件
*
* @author John.Ying
* @since 11.0
* Created on 2023/4/27
*/
public class NormalButtonSettingPane<T extends Widget> extends BaseStyleSettingPane<T> {
public NormalButtonSettingPane() {
super(Arrays.asList(
StyleSetting.BTN_BACKGROUND,
StyleSetting.LINE_TYPE,
StyleSetting.BORDER_RADIUS
));
}
public NormalButtonSettingPane(List<StyleSetting> styleSettingList) {
super(styleSettingList);
}
@Override
public void populateBean(T t) {
NormalButtonTheme widgetTheme = initNormalButtonTheme(t);
if (t instanceof FreeButton && ((FreeButton) t).isCustomStyle()) {
initCustomStyle((FreeButton) t, widgetTheme);
}
populateNormalButtonBean(widgetTheme);
}
/**
* 根据freeButton自定义样式初始化widgetTheme
*/
protected void initCustomStyle(FreeButton freeButton, NormalButtonTheme widgetTheme) {
ButtonBackgroundStyle buttonBackgroundStyle = new ButtonBackgroundStyle(freeButton.getInitialBackground(), freeButton.getOverBackground(), freeButton.getClickBackground());
widgetTheme.setButtonBackgroundStyle(buttonBackgroundStyle);
widgetTheme.setFollowTheme(false);
}
protected void populateNormalButtonBean(NormalButtonTheme widgetTheme) {
if (widgetTheme.isFollowTheme()) {
styleSettingHead.setSelectedIndex(0);
} else {
styleSettingHead.setSelectedIndex(1);
lineComboBox.setSelectedLineStyle(widgetTheme.getBorderStyle().getLineType());
borderRadiusSpinner.setValue(widgetTheme.getBorderStyle().getRadius());
assignFontPane(widgetTheme);
buttonStyleDefinedPane.populate(ButtonBackground.create(widgetTheme.getButtonBackgroundStyle()));
}
switchCard();
}
protected void assignFontPane(NormalButtonTheme normalButtonTheme) {
}
protected void assignFontStyle(NormalButtonTheme normalButtonTheme) {
}
protected NormalButtonTheme initNormalButtonTheme(T t) {
NormalButtonTheme widgetTheme = (NormalButtonTheme) t.getWidgetTheme();
if (widgetTheme == null) {
widgetTheme = getDefaultNormalButtonTheme();
t.setWidgetTheme(widgetTheme);
}
return widgetTheme;
}
protected NormalButtonTheme getDefaultNormalButtonTheme() {
return new NormalButtonTheme();
}
@Override
public void updateBean(T t) {
NormalButtonTheme widgetTheme = initNormalButtonTheme(t);
int selectIndex = styleSettingHead.getSelectedIndex();
widgetTheme.setFollowTheme(selectIndex == 0);
updateNormalButtonStyleBean(widgetTheme);
if (t instanceof FreeButton) {
FreeButton freeButton = (FreeButton) t;
freeButton.setCustomStyle(!widgetTheme.isFollowTheme());
updateCustomStyle(freeButton, widgetTheme);
}
}
/**
* 更新freeButton的自定义样式
*/
protected void updateCustomStyle(FreeButton freeButton, NormalButtonTheme widgetTheme) {
ButtonBackgroundStyle backgroundStyle = widgetTheme.getButtonBackgroundStyle();
freeButton.setInitialBackground(backgroundStyle.getInitialBackground());
freeButton.setOverBackground(backgroundStyle.getOverBackground());
freeButton.setClickBackground(backgroundStyle.getClickBackground());
}
protected void updateNormalButtonStyleBean(NormalButtonTheme normalButtonTheme) {
assignFontStyle(normalButtonTheme);
normalButtonTheme.setButtonBackgroundStyle(buttonStyleDefinedPane.update());
normalButtonTheme.setBorderStyle(new BorderStyle((int) borderRadiusSpinner.getValue(), lineComboBox.getSelectedLineStyle()));
switchCard();
}
@Override
@Nullable
public T updateBean() {
return null;
}
@Override
protected String title4PopupWindow() {
return "normalButtonSetting";
}
}

32
designer-form/src/main/java/com/fr/design/widgettheme/common/SelectEditorSettingPane.java

@ -0,0 +1,32 @@
package com.fr.design.widgettheme.common;
import com.fr.design.widgettheme.StyleSetting;
import com.fr.form.ui.Widget;
import java.util.Arrays;
/**
* 单元格下拉框编辑控件配置面板
* 继承自编辑控件配置面板添加一个下拉框背景色
*
* @author obo
* @since 11.0
* Created on 2023/12/13
*/
public class SelectEditorSettingPane <T extends Widget> extends EditorSettingPane<T> {
public SelectEditorSettingPane() {
super(Arrays.asList(
StyleSetting.THEME_COLOR,
StyleSetting.SELECT_COLOR,
StyleSetting.STYLE_TYPE,
StyleSetting.LINE_TYPE,
StyleSetting.BORDER_RADIUS
));
}
@Override
protected String title4PopupWindow() {
return "selectEditorSetting";
}
}

107
designer-form/src/main/java/com/fr/design/widgettheme/common/TreeEditorSettingPane.java

@ -0,0 +1,107 @@
package com.fr.design.widgettheme.common;
import com.fr.design.widgettheme.StyleSetting;
import com.fr.design.widgettheme.BaseStyleSettingPane;
import com.fr.form.ui.TreeEditor;
import com.fr.widgettheme.theme.widget.theme.WidgetThemeDisplayConstants;
import com.fr.widgettheme.theme.widget.theme.cell.TreeTheme;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* 设计器控件属性的高级设置增加主题样式设置项包括
* 视图树
*
* @author John.Ying
* @since 11.0
* Created on 2023/4/18
*/
public class TreeEditorSettingPane<T extends TreeEditor> extends BaseStyleSettingPane<T> {
public TreeEditorSettingPane() {
super(Arrays.asList(
StyleSetting.THEME_COLOR,
StyleSetting.STYLE_TYPE
));
}
public TreeEditorSettingPane(List<StyleSetting> styleSettingList) {
super(styleSettingList);
}
@Override
public void populateBean(T t) {
TreeTheme treeTheme = initEditorTheme(t);
populateTreeBean(treeTheme);
}
protected TreeTheme initEditorTheme(T t) {
TreeTheme widgetTheme = (TreeTheme) t.getWidgetTheme();
if (widgetTheme == null) {
widgetTheme = getTreeTheme();
updateTreeStyleBean(widgetTheme);
t.setWidgetTheme(widgetTheme);
}
return widgetTheme;
}
protected TreeTheme getTreeTheme() {
return new TreeTheme();
}
protected void populateTreeBean(TreeTheme treeTheme) {
if (treeTheme.isFollowTheme()) {
styleSettingHead.setSelectedIndex(0);
} else {
styleSettingHead.setSelectedIndex(1);
colorSelectBox.setSelectObject(treeTheme.getThemeColor());
if (treeTheme.getStyleType() == WidgetThemeDisplayConstants.STYLE_1) {
style1.setSelected(true);
} else {
style2.setSelected(true);
}
assignFontSizePane(treeTheme);
}
switchCard();
}
protected void assignFontSizePane(TreeTheme widgetTheme) {
}
protected void assignFontSizeStyle(TreeTheme widgetTheme) {
}
@Override
public void updateBean(T t) {
TreeTheme treeTheme = initEditorTheme(t);
updateTreeBean(treeTheme);
}
protected void updateTreeBean(TreeTheme treeTheme) {
int selectIndex = styleSettingHead.getSelectedIndex();
treeTheme.setFollowTheme(selectIndex == 0);
updateTreeStyleBean(treeTheme);
}
protected void updateTreeStyleBean(TreeTheme treeTheme) {
treeTheme.setThemeColor(colorSelectBox.getSelectObject());
treeTheme.setStyleType(style1.isSelected() ? WidgetThemeDisplayConstants.STYLE_1 : WidgetThemeDisplayConstants.STYLE_2);
assignFontSizeStyle(treeTheme);
switchCard();
}
@Override
@Nullable
public T updateBean() {
return null;
}
@Override
protected String title4PopupWindow() {
return "treeEditorSetting";
}
}

134
designer-form/src/main/java/com/fr/design/widgettheme/processor/WidgetThemeCreatorPaneAdder.java

@ -0,0 +1,134 @@
package com.fr.design.widgettheme.processor;
import com.fr.design.widgettheme.common.SelectEditorSettingPane;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import com.fr.design.beans.BasicBeanPane;
import com.fr.form.parameter.FormSubmitButton;
import com.fr.form.ui.Button;
import com.fr.form.ui.CheckBox;
import com.fr.form.ui.CheckBoxGroup;
import com.fr.form.ui.ComboBox;
import com.fr.form.ui.ComboCheckBox;
import com.fr.form.ui.DateEditor;
import com.fr.form.ui.FreeButton;
import com.fr.form.ui.NumberEditor;
import com.fr.form.ui.Password;
import com.fr.form.ui.RadioGroup;
import com.fr.form.ui.TextArea;
import com.fr.form.ui.TextEditor;
import com.fr.form.ui.TreeComboBoxEditor;
import com.fr.form.ui.TreeEditor;
import com.fr.report.web.button.form.TreeNodeToggleButton;
import com.fr.report.web.button.write.AppendRowButton;
import com.fr.report.web.button.write.DeleteRowButton;
import com.fr.design.widgettheme.common.ButtonSettingPane;
import com.fr.design.widgettheme.common.EditorSettingPane;
import com.fr.design.widgettheme.common.NormalButtonSettingPane;
import com.fr.design.widgettheme.common.TreeEditorSettingPane;
import com.fr.widgettheme.utils.WidgetThemeServerUtils;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 控件主题窗口创建处理类
* 当前类型被接受时添加对应pane到extraPaneList
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public class WidgetThemeCreatorPaneAdder {
private WidgetThemeCreatorPaneAdder() {}
/**
* editor相关处理类
*/
private static final Set<Class<?>> EDITOR_SET = new HashSet<>(Arrays.asList(
TextArea.class,
TextEditor.class,
NumberEditor.class,
Password.class
));
/**
* normal相关处理类
*/
private static final Set<Class<?>> NORMAL_SET = new HashSet<>(Arrays.asList(
AppendRowButton.class,
FreeButton.class,
DeleteRowButton.class,
FormSubmitButton.class,
TreeNodeToggleButton.class,
Button.class
));
/**
* 下拉框相关控件类
*/
private static final Set<Class<?>> SELECT_SET = new HashSet<>(Arrays.asList(
DateEditor.class,
TreeComboBoxEditor.class,
ComboBox.class,
ComboCheckBox.class
));
/**
* 遍历判断当前控件creator类型将符合条件的窗口添加到extraPaneList中
*
* @param creator 控件creator
* @param extraPaneList 列表
*/
public static <T> void add(Class<T> creator, List<BasicBeanPane<T>> extraPaneList) {
if(WidgetThemeDesignerUtils.enableWidgetEnhance()) {
acceptEditor(creator, extraPaneList);
acceptTree(creator, extraPaneList);
acceptNormal(creator, extraPaneList);
acceptButton(creator, extraPaneList);
acceptSelect(creator, extraPaneList);
}
}
private static <T> void insertShortCut(List<BasicBeanPane<T>> extraPaneList, BasicBeanPane pane) {
extraPaneList.add(0, pane);
}
private static <T> void acceptEditor(Class<?> creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = WidgetThemeServerUtils.isNewComboBoxTreeEditor(creator) || EDITOR_SET.contains(creator);
if (accept) {
insertShortCut(extraPaneList, new EditorSettingPane<>());
}
}
private static <T> void acceptTree(Class<?> creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator == TreeEditor.class;
if (accept) {
insertShortCut(extraPaneList, new TreeEditorSettingPane<>());
}
}
private static <T> void acceptNormal(Class<?> creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = NORMAL_SET.contains(creator);
if (accept) {
insertShortCut(extraPaneList, new NormalButtonSettingPane<>());
}
}
private static <T> void acceptButton(Class<?> creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator == CheckBox.class || creator == RadioGroup.class || creator == CheckBoxGroup.class;
if (accept) {
insertShortCut(extraPaneList, new ButtonSettingPane<>());
}
}
private static <T> void acceptSelect(Class<?> creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = SELECT_SET.contains(creator);
if (accept) {
insertShortCut(extraPaneList, new SelectEditorSettingPane<>());
}
}
}

115
designer-form/src/main/java/com/fr/design/widgettheme/processor/WidgetThemeParaCreatorPaneAdder.java

@ -0,0 +1,115 @@
package com.fr.design.widgettheme.processor;
import com.fr.design.widgettheme.ParaNormalButtonSettingPane;
import com.fr.design.widgettheme.ParaSelectEditorSettingPane;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.creator.XButton;
import com.fr.design.designer.creator.XCheckBox;
import com.fr.design.designer.creator.XCheckBoxGroup;
import com.fr.design.designer.creator.XComboBox;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XDateEditor;
import com.fr.design.designer.creator.XLabel;
import com.fr.design.designer.creator.XRadioGroup;
import com.fr.design.designer.creator.XTextArea;
import com.fr.design.designer.creator.XTreeComboBoxEditor;
import com.fr.design.designer.creator.XTreeEditor;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.designer.creator.XWrapperedFieldEditor;
import com.fr.design.widgettheme.LabelSettingPane;
import com.fr.design.widgettheme.ParaButtonSettingPane;
import com.fr.design.widgettheme.ParaEditorSettingPane;
import com.fr.design.widgettheme.ParaTreeEditorSettingPane;
import com.fr.widgettheme.ParameterBackgroundStyleSettingPane;
import com.fr.widgettheme.utils.WidgetThemeServerUtils;
import java.util.List;
/**
* 参数面板控件主题窗口创建处理类
* 当前类型被接受时添加对应pane到extraPaneList
*
* @author obo
* @since 11.0
* Created on 2023/11/13
*/
public class WidgetThemeParaCreatorPaneAdder {
private WidgetThemeParaCreatorPaneAdder() {}
/**
* 处理对应的参数面板控件creator
* 当类型判断符合时,将扩展的pane添加到list
*
* @param creator 控件creator
* @param extraPaneList 扩展paneList
*/
public static <T> void add(XCreator creator, List<BasicBeanPane<T>> extraPaneList) {
if (WidgetThemeDesignerUtils.enableWidgetEnhance()) {
acceptEditor(creator, extraPaneList);
acceptSelect(creator, extraPaneList);
acceptRoot(creator, extraPaneList);
acceptTree(creator, extraPaneList);
acceptLabel(creator, extraPaneList);
acceptNormal(creator, extraPaneList);
acceptButton(creator, extraPaneList);
}
}
private static <T> void insertShortCut(List<BasicBeanPane<T>> extraPaneList, BasicBeanPane pane) {
extraPaneList.add(0, pane);
}
private static <T> void acceptEditor(XCreator creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator instanceof XWrapperedFieldEditor || creator instanceof XTextArea;
if (accept) {
insertShortCut(extraPaneList, new ParaEditorSettingPane<>());
}
}
private static <T> void acceptSelect(XCreator creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator instanceof XComboBox
|| creator instanceof XDateEditor
|| creator instanceof XTreeComboBoxEditor
|| WidgetThemeServerUtils.isNewComboBoxTreeEditor(creator);
if (accept) {
insertShortCut(extraPaneList, new ParaSelectEditorSettingPane<>());
}
}
private static <T> void acceptRoot(XCreator creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator instanceof XWParameterLayout;
if (accept) {
insertShortCut(extraPaneList, new ParameterBackgroundStyleSettingPane());
}
}
private static <T> void acceptTree(XCreator creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator instanceof XTreeEditor && !(creator instanceof XTreeComboBoxEditor);
if (accept) {
insertShortCut(extraPaneList, new ParaTreeEditorSettingPane<>());
}
}
private static <T> void acceptLabel(XCreator creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator instanceof XLabel;
if (accept) {
insertShortCut(extraPaneList, new LabelSettingPane<>());
}
}
private static <T> void acceptNormal(XCreator creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator instanceof XButton;
if (accept) {
insertShortCut(extraPaneList, new ParaNormalButtonSettingPane<>());
}
}
private static <T> void acceptButton(XCreator creator, List<BasicBeanPane<T>> extraPaneList) {
boolean accept = creator instanceof XRadioGroup || creator instanceof XCheckBoxGroup || creator instanceof XCheckBox;
if (accept) {
insertShortCut(extraPaneList, new ParaButtonSettingPane<>());
}
}
}

15
designer-realize/src/main/java/com/fr/design/actions/replace/action/content/js/SearchChartJSAction.java

@ -63,12 +63,15 @@ public class SearchChartJSAction {
//图表-特效-交互属性-监控刷新
dealMonitorRefreshJS(conditionContent, chartCollection, jsInfos);
for (int i = 0; i < chartCollection.getChartCount(); i++) {
ITContent chartContent = ITContent.copy(content);
chartContent.addOtherPos(chartCollection.getChart(i).getChartName());
//坐标轴
searchAxisJS(jsInfos, chartContent, chartCollection.getChart(i));
//组合图表-条件属性-超链特判
dealCustomPlot(jsInfos, conditionContent, chartCollection.getChart(i));
Chart chart = chartCollection.getChart(i);
if (chart != null) {
ITContent chartContent = ITContent.copy(content);
chartContent.addOtherPos(chart.getChartName());
//坐标轴
searchAxisJS(jsInfos, chartContent, chart);
//组合图表-条件属性-超链特判
dealCustomPlot(jsInfos, conditionContent, chart);
}
}
}

74
designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java

@ -2,15 +2,13 @@ package com.fr.design.mainframe.socketio;
import com.fr.config.RemoteConfigEvent;
import com.fr.design.DesignerEnvManager;
import com.fr.design.EnvChangeEntrance;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.RPCConnectHandlerCenter;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.DesignerWorkspaceInfoContext;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.LocaleLinkProvider;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.loghandler.DesignerLogger;
import com.fr.design.mainframe.share.ui.base.MouseClickListener;
import com.fr.design.mainframe.toast.DesignerToastMsgUtil;
@ -21,18 +19,11 @@ import com.fr.event.EventDispatcher;
import com.fr.log.FineLoggerFactory;
import com.fr.serialization.SerializerHelper;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StableUtils;
import com.fr.third.apache.logging.log4j.core.LogEvent;
import com.fr.third.org.apache.http.client.config.RequestConfig;
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
import com.fr.third.org.apache.http.client.methods.HttpGet;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.base.WorkspaceConstants;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.engine.exception.WorkspaceConnectionException;
import com.fr.workspace.server.socket.CustomLogEvent;
import com.fr.workspace.server.socket.LogEventConverter;
import io.socket.client.IO;
@ -40,9 +31,7 @@ import io.socket.client.Socket;
import io.socket.emitter.Emitter;
import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
@ -76,7 +65,6 @@ public class DesignerSocketIO {
private static Status status = Status.Disconnected;
private static Timer disConnectHintTimer = null;
private static long disConnectHintTimerDelay = 3000;
private static final int TIMEOUT = 5000;
//维护一个当前工作环境的websocket连接信息列表
private static ConnectionInfo[] connectionInfos;
//维护一个关于uri列表的计数器
@ -205,10 +193,10 @@ public class DesignerSocketIO {
};
private static void dealWithSocketDisconnect() {
if (checkRPCConnect()) {
if (RPCConnectHandlerCenter.checkRPCConnect(getConnectionInfo())) {
showSocketDisconnectToast();
} else {
showRPCDisconnectDialog();
RPCConnectHandlerCenter.showRPCDisconnectDialog();
}
}
@ -245,62 +233,6 @@ public class DesignerSocketIO {
return jPanel;
}
private static void showRPCDisconnectDialog() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(
DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"),
UIManager.getString("OptionPane.messageDialogTitle"),
JOptionPane.ERROR_MESSAGE,
UIManager.getIcon("OptionPane.errorIcon"));
EnvChangeEntrance.getInstance().chooseEnv();
}
});
}
private static boolean checkRPCConnect() {
CloseableHttpClient httpclient = HttpClients.createDefault();
WorkspaceConnectionInfo info = getConnectionInfo();
HttpGet httpGet = new HttpGet(StableUtils.pathJoin(info.getUrl(), WorkspaceConstants.CONTROLLER_PREFIX, WorkspaceConstants.VT));
RequestConfig requestConfig = RequestConfig
.custom()
.setConnectTimeout(TIMEOUT)
.setConnectionRequestTimeout(TIMEOUT)
.build();
httpGet.setConfig(requestConfig);
try {
CloseableHttpResponse response = httpclient.execute(httpGet);
if (isErrorStatus(response.getStatusLine().getStatusCode())) {
//这边nginx做负载,服务器被kill掉,返回的是502,不会抛错,导致checkRPCConnect通过
//针对500-600的错误码加个判断,其他类型的状态码暂不考虑,如果有遇到再处理,不然怕影响范围大
throw new WorkspaceConnectionException("Response " + response.getStatusLine().toString());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
return false;
}
return true;
}
/**
* 错误状态码
* 5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误 这些错误可能是服务器本身的错误而不是请求出错代码 说明
* 500 (服务器内部错误) 服务器遇到错误无法完成请求
* 501 (尚未实施) 服务器不具备完成请求的功能 例如服务器无法识别请求方法时可能会返回此代码
* 502 (错误网关) 服务器作为网关或代理从上游服务器收到无效响应
* 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护) 通常这只是暂时状态
* 504 (网关超时) 服务器作为网关或代理但是没有及时从上游服务器收到请求
* 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本
*
* @param status 错误状态码
* @return 是否是错误状态码
*/
private static boolean isErrorStatus(int status) {
return status >= 500 && status <= 600;
}
//配置变更监听器
private static final Emitter.Listener modifyConfig = new Emitter.Listener() {
@Override

11
designer-realize/src/main/java/com/fr/design/share/SharableManager.java

@ -8,6 +8,7 @@ import com.fr.design.mainframe.JForm;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.share.collect.ComponentCollector;
import com.fr.design.mainframe.share.collect.SharableCollectorManager;
import com.fr.design.mainframe.share.config.ComponentReuseConfigManager;
import com.fr.design.mainframe.share.encrypt.clipboard.impl.EncryptSelectionClipboardHandler;
import com.fr.design.mainframe.share.encrypt.clipboard.impl.EncryptTransferableClipboardHandler;
import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane;
@ -30,11 +31,13 @@ import java.util.List;
public class SharableManager {
public static void start() {
SharableCollectorManager.getInstance().execute();
if (ComponentReuseConfigManager.getInstance().supportUploadReu()) {
SharableCollectorManager.getInstance().execute();
ClipboardFilter.registerClipboardHandler(EncryptSelectionClipboardHandler.getInstance());
ClipboardFilter.registerClipboardHandler(EncryptTransferableClipboardHandler.getInstance());
registerSharableEncryptDefinePanes();
}
listenEnv();
ClipboardFilter.registerClipboardHandler(EncryptSelectionClipboardHandler.getInstance());
ClipboardFilter.registerClipboardHandler(EncryptTransferableClipboardHandler.getInstance());
registerSharableEncryptDefinePanes();
}
public static void saveTemplate(JTemplate jt) {

42
designer-realize/src/main/java/com/fr/design/webattr/EditToolBar.java

@ -3,6 +3,7 @@ package com.fr.design.webattr;
import com.fr.base.BaseUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.UpdateAction;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
@ -10,11 +11,13 @@ import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.fun.ExportToolBarProvider;
import com.fr.design.fun.ExtraButtonToolBarProvider;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UIBasicSpinner;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.javascript.JavaScriptActionPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
@ -27,6 +30,7 @@ import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.widget.IconDefinePane;
import com.fr.form.ui.Button;
import com.fr.form.ui.CustomToolBarButton;
import com.fr.general.ColorMode;
import com.fr.form.ui.Widget;
import com.fr.form.ui.WidgetInfoConfig;
import com.fr.general.Background;
@ -38,6 +42,7 @@ import com.fr.report.web.button.write.AppendColumnRow;
import com.fr.report.web.button.write.Submit;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
import com.fr.write.JavaScriptResourceInfo;
import javax.swing.BorderFactory;
@ -86,6 +91,8 @@ public class EditToolBar extends BasicPane {
private Background background = null;
private UICheckBox defaultCheckBox;
private UIButtonGroup<String> bgColorButtonGroup;
private ListSelectionListener listSelectionListener = new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
if (lastButton != null) {
@ -163,13 +170,20 @@ public class EditToolBar extends BasicPane {
splitPane.setDividerLocation(120);
this.add(splitPane);
list.addListSelectionListener(listSelectionListener);
JPanel backgroundPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
JPanel backgroundPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, 0, 0, 0);
UIButton bgButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set_Background"));
defaultCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Default_Background"));
bgButton.addActionListener(actioner);
backgroundPane.add(defaultCheckBox);
backgroundPane.add(bgButton);
backgroundPane.setBorder(BorderFactory.createTitledBorder(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set_Background")));
JPanel bgPanel = new JPanel();
bgPanel.add(defaultCheckBox);
bgPanel.add(bgButton);
backgroundPane.add(bgPanel);
if(WidgetThemeDesignerUtils.enableWidgetEnhance()) {
backgroundPane.add(createButtonColorGroup());
}
backgroundPane.setBorder(BorderFactory.createTitledBorder(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_ToolBar_Style_Setting")));
this.add(backgroundPane, BorderLayout.SOUTH);
}
@ -213,6 +227,9 @@ public class EditToolBar extends BasicPane {
this.background = ftoolbar.getBackground();
this.defaultCheckBox.setSelected(ftoolbar.isDefault() ? true : false);
if (bgColorButtonGroup != null) {
this.bgColorButtonGroup.setSelectedIndex(ftoolbar.getButtonBgColorMode().getCode());
}
}
public FToolBar update() {
@ -246,6 +263,9 @@ public class EditToolBar extends BasicPane {
if (!ftoolBar.isDefault()) {
ftoolBar.setBackground(this.background);
}
if (bgColorButtonGroup != null) {
ftoolBar.setButtonBgColorMode(ColorMode.getModeByCode(bgColorButtonGroup.getSelectedIndex()));
}
return ftoolBar;
}
@ -708,4 +728,22 @@ public class EditToolBar extends BasicPane {
}
}
private JPanel createButtonColorGroup() {
UILabel headLabel = new UILabel(Toolkit.i18nText("Fine-Design_ToolBar_Button_Color"));
String[] titles = new String[]{ Toolkit.i18nText("Fine-Design_ToolBar_Button_Color_Auto"),
Toolkit.i18nText("Fine-Design_ToolBar_Button_Color_Light"),
Toolkit.i18nText("Fine-Design_ToolBar_Button_Color_Dark")};
bgColorButtonGroup = new UIButtonGroup<String>(titles) {
@Override
public void setSelectedIndex(int newSelectedIndex, boolean fireChanged) {
super.setSelectedIndex(newSelectedIndex, fireChanged);
}
};
bgColorButtonGroup.setPreferredSize(new Dimension(135, bgColorButtonGroup.getPreferredSize().height));
JPanel headPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(IntervalConstants.INTERVAL_L5, 0);
headPane.add(headLabel);
headPane.add(bgColorButtonGroup);
headPane.setBorder(BorderFactory.createEmptyBorder(0, IntervalConstants.INTERVAL_L2, 0, 0));
return headPane;
}
}

11
designer-realize/src/main/java/com/fr/design/webattr/FToolBar.java

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import com.fr.form.ui.ToolBar;
import com.fr.general.ColorMode;
import com.fr.form.ui.Widget;
import com.fr.general.Background;
@ -12,6 +13,7 @@ public class FToolBar {
private Background background = null;
private boolean isDefault = true;
private ColorMode buttonBgColorMode = ColorMode.AUTO;
public List<ToolBarButton> getButtonlist() {
return buttonlist;
}
@ -52,6 +54,14 @@ public class FToolBar {
this.isDefault = isDefault;
}
public ColorMode getButtonBgColorMode() {
return buttonBgColorMode;
}
public void setButtonBgColorMode(ColorMode buttonBgColorMode) {
this.buttonBgColorMode = buttonBgColorMode;
}
public ToolBar getToolBar() {
Widget[] n = new Widget[this.getButtonlist().size()];
for (int j = 0; j < this.getButtonlist().size(); j++) {
@ -60,6 +70,7 @@ public class FToolBar {
ToolBar toolBar = new ToolBar(n);
toolBar.setBackground(this.background);
toolBar.setDefault(this.isDefault);
toolBar.setButtonBgColorMode(this.buttonBgColorMode);
return toolBar;
}
}

2
designer-realize/src/main/java/com/fr/design/webattr/ToolBarPane.java

@ -12,7 +12,6 @@ import com.fr.form.ui.Widget;
import com.fr.report.web.annotation.OldPrintMethod;
import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import java.awt.Component;
@ -158,6 +157,7 @@ public class ToolBarPane extends BasicBeanPane<ToolBar> {
}
this.getFToolBar().setBackground(toolbar.getBackground());
this.getFToolBar().setDefault(toolbar.isDefault());
this.getFToolBar().setButtonBgColorMode(toolbar.getButtonBgColorMode());
setPopulateFinished(true);
}

13
designer-realize/src/main/java/com/fr/design/widget/ui/CheckBoxDefinePane.java

@ -10,11 +10,12 @@ import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widgettheme.processor.WidgetThemeCreatorPaneAdder;
import com.fr.form.ui.CheckBox;
import com.fr.general.GeneralContext;
import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.collections.CollectionUtils;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.Component;
@ -22,6 +23,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 复选框pane
*
* @author obo
* @version 11.0
* Created on 2023/11/13
*/
public class CheckBoxDefinePane extends AbstractDataModify<CheckBox> {
private UITextField text;
protected final List<BasicBeanPane<CheckBox>> extraPaneList = new ArrayList<>();
@ -60,7 +68,8 @@ public class CheckBoxDefinePane extends AbstractDataModify<CheckBox> {
protected void refreshExtraAdvancedPane() {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeCreatorPaneAdder.add(CheckBox.class, extraPaneList);
boolean containsExtraPane = !CollectionUtils.isEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<CheckBox>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<CheckBox> provider : providers) {
if (!provider.accept(CheckBox.class)) {

12
designer-realize/src/main/java/com/fr/design/widget/ui/FieldEditorDefinePane.java

@ -14,11 +14,13 @@ import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.widgettheme.processor.WidgetThemeCreatorPaneAdder;
import com.fr.form.ui.FieldEditor;
import com.fr.general.GeneralContext;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.collections.CollectionUtils;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
@ -30,6 +32,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 字段编辑pane
*
* @author obo
* @version 11.0
* Created on 2023/11/13
*/
public abstract class FieldEditorDefinePane<T extends FieldEditor> extends AbstractDataModify<T> {
protected UICheckBox allowBlankCheckBox;
// richer:错误信息,是所有控件共有的属性,所以放到这里来
@ -85,7 +94,8 @@ public abstract class FieldEditorDefinePane<T extends FieldEditor> extends Abstr
protected void refreshExtraAdvancedPane(Class cls) {
extraPaneList.clear();
boolean containsExtraPane = false;
WidgetThemeCreatorPaneAdder.add(cls, extraPaneList);
boolean containsExtraPane = !CollectionUtils.isEmpty(extraPaneList);
Set<WidgetAdvancedPaneProvider<T>> providers = ExtraDesignClassManager.getInstance().getArray(WidgetAdvancedPaneProvider.XML_TAG);
for (WidgetAdvancedPaneProvider<T> provider : providers) {
if (!provider.accept(cls)) {

61
designer-realize/src/main/java/com/fr/design/widget/ui/btn/FreeButtonDetailPane.java

@ -3,6 +3,7 @@ package com.fr.design.widget.ui.btn;
import java.awt.Component;
import com.fr.form.ui.FreeButton;
import com.fr.widgettheme.util.WidgetThemeDesignerUtils;
/**
* 自定义按钮
@ -12,33 +13,49 @@ import com.fr.form.ui.FreeButton;
* Created on 2023/4/19
*/
public class FreeButtonDetailPane extends AbstractExtraButtonPane<FreeButton> {
private ButtonSytleDefinedPane buttonSytleDefinedPane;
@Override
protected Component createCenterPane() {
buttonSytleDefinedPane = new ButtonSytleDefinedPane();
return createExtraPane(buttonSytleDefinedPane);
}
@Override
public FreeButton createButton() {
return new FreeButton();
}
public void populate(FreeButton button) {
super.populate(button);
buttonSytleDefinedPane.populate(button);
}
private ButtonSytleDefinedPane buttonSytleDefinedPane;
@Override
protected Component createCenterPane() {
buttonSytleDefinedPane = creatButtonSytleDefinedPane();
return createExtraPane(buttonSytleDefinedPane);
}
@Override
public FreeButton createButton() {
return new FreeButton();
}
/**
* 填充button配置面板
*/
public void populate(FreeButton button) {
super.populate(button);
if (buttonSytleDefinedPane != null) {
buttonSytleDefinedPane.populate(button);
}
}
@Override
public FreeButton update() {
FreeButton button = super.update();
buttonSytleDefinedPane.update(button);
if (buttonSytleDefinedPane != null) {
buttonSytleDefinedPane.update(button);
}
return button;
}
@Override
public Class classType() {
return FreeButton.class;
}
@Override
public Class classType() {
return FreeButton.class;
}
/**
* 自定义按钮控件开启控件显示增强时原有的buttonSytleDefinedPane会被保留
* 内容和控件增强的pane重复且不生效其他控件目前不存在这种情况因此要在实现这里做个判断
* 如果开启控件增强原有的ButtonSytleDefinedPane不展示创建时返回null
*/
private ButtonSytleDefinedPane creatButtonSytleDefinedPane() {
return WidgetThemeDesignerUtils.enableWidgetEnhance() ? null : new ButtonSytleDefinedPane();
}
}

2
designer-realize/src/main/java/com/fr/start/DesignerInitial.java

@ -35,7 +35,7 @@ public class DesignerInitial {
SplashContext.getInstance().hide();
}
});
DesignerLaunchStatus.setStatus(DesignerLaunchStatus.STARTUP_COMPLETE);
DesignerLaunchStatus.setStatusAndAsyncFire(DesignerLaunchStatus.STARTUP_COMPLETE);
}
});
});

8
designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java

@ -11,6 +11,7 @@ import com.fr.event.Event;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.process.FineProcess;
import com.fr.process.ProcessEventPipe;
import com.fr.process.engine.core.FineProcessContext;
@ -37,7 +38,7 @@ public class DesignerSuperListener {
private final ScheduledExecutorService service = Executors.newScheduledThreadPool(2, new NamedThreadFactory("DesignerListener"));
private final ExecutorService helpService = Executors.newSingleThreadExecutor( new NamedThreadFactory("DesignerSuperListener-Help"));
private final ScheduledExecutorService EXIT_SERVICE = Executors.newSingleThreadScheduledExecutor( new NamedThreadFactory("DesignerSuperListener-Exit"));
private FineProcess process;
private ScheduledFuture fixedFuture;
private ScheduledFuture onceFuture;
@ -141,6 +142,11 @@ public class DesignerSuperListener {
}
private void fallBackReport() {
// 60S都没退出去就强制关闭
EXIT_SERVICE.schedule(() -> {
FineLoggerFactory.getLogger().error("[DesignerSuperListener] The designer failed to exit gracefully, attempting a forced shutdown.");
System.exit(1);
}, 60, TimeUnit.SECONDS);
DesignUtils.initLookAndFeel();
StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.UNEXCEPTED_FALL_BACK.getId(),
DesignerErrorMessage.UNEXCEPTED_FALL_BACK.getMessage(),

10
designer-realize/src/main/java/com/fr/start/MainDesigner.java

@ -12,6 +12,7 @@ import com.fr.design.actions.server.TemplateThemeManagerAction;
import com.fr.design.actions.server.WidgetManagerAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.carton.SwitchForSwingChecker;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.constants.UIConstants;
import com.fr.design.deeplink.DeepLinkManager;
import com.fr.design.file.HistoryTemplateListCache;
@ -58,6 +59,7 @@ import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.log.SystemOutLoggerProvider;
import com.fr.module.Module;
import com.fr.module.ModuleContext;
import com.fr.module.engine.event.LifecycleErrorEvent;
@ -117,8 +119,11 @@ public class MainDesigner extends BaseDesigner {
* @param args 参数
*/
public static void main(String[] args) {
DesignerStartupContext.getRecorder().start();
// 设置一下默认的logger,启动后再Reset
FineLoggerFactory.setLogger(SystemOutLoggerProvider.getInstance());
showSplash();
DesignerEnvManager.getEnvManager();
@ -166,8 +171,7 @@ public class MainDesigner extends BaseDesigner {
CompletableFuture<Void> initLookAndFeel = CompletableFuture.runAsync(DesignUtils::initLookAndFeel);
PreLoadService.getInstance().addUIFuture(initLookAndFeel);
showSplash();
DesignerLaunchStatus.setStatusAndAsyncFire(DesignerLaunchStatus.UI_PRE_INIT_COMPLETE);
}
/**

17
designer-realize/src/main/java/com/fr/start/SplashContext.java

@ -1,11 +1,13 @@
package com.fr.start;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.bbs.BBSConstants;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.general.GeneralContext;
import com.fr.general.locale.image.I18nImage;
import com.fr.module.ModuleEvent;
@ -28,13 +30,13 @@ public class SplashContext {
public static final String SPLASH_PATH = getSplashPath();
public static final String SPLASH_CACHE_NAME = SPLASH_PATH.substring(SPLASH_PATH.lastIndexOf("/") + 1);
private static final int FETCH_ONLINE_MAX_TIMES = 50;
private static final String THANKS = Toolkit.i18nText("Fine-Design_Report_Thanks_To");
private String thanks = StringUtils.EMPTY;
private static final SplashContext SPLASH_CONTEXT = new SplashContext();
private SplashStrategy splashStrategy;
private String moduleId = Toolkit.i18nText("Fine-Design_Basic_Initializing");
private String moduleId = StringUtils.EMPTY;
private int loadingIndex = 0;
private String[] loading = new String[]{"..", "....", "......"};
@ -73,7 +75,12 @@ public class SplashContext {
public void show() {
splashStrategy.show();
//监听
initListener();
EventDispatcher.listen(DesignerLaunchStatus.UI_PRE_INIT_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
initListener();
}
});
}
/**
@ -91,6 +98,8 @@ public class SplashContext {
}
private void initListener() {
thanks = Toolkit.i18nText("Fine-Design_Report_Thanks_To");
moduleId = Toolkit.i18nText("Fine-Design_Basic_Initializing");
scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
@ -157,7 +166,7 @@ public class SplashContext {
if (shouldShowThanks() && !hasShowThanks) {
tryFetchOnline();
if (StringUtils.isNotEmpty(guest)) {
updateThanksLog(THANKS + guest);
updateThanksLog(thanks + guest);
hasShowThanks = true;
}
}

14
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -17,6 +17,7 @@ import com.fr.decision.webservice.v10.plugin.helper.category.impl.PluginResource
import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.RPCConnectHandlerCenter;
import com.fr.design.actions.NewFormAction;
import com.fr.design.actions.core.ActionFactory;
import com.fr.design.actions.insert.cell.BiasCellAction;
@ -51,6 +52,7 @@ import com.fr.design.javascript.EmailPane;
import com.fr.design.javascript.JavaScriptImplPane;
import com.fr.design.javascript.ParameterJavaScriptPane;
import com.fr.design.javascript.ProcessTransitionAdapter;
import com.fr.design.lock.TemplateLockInfoReSave;
import com.fr.design.login.DesignerLoginType;
import com.fr.design.login.guide.DesignerGuideHelper;
import com.fr.design.login.message.DesignerMessageHelper;
@ -143,6 +145,7 @@ import com.fr.stable.xml.ObjectXMLWriterFinder;
import com.fr.start.BBSGuestPaneProvider;
import com.fr.start.common.DesignerStartupExecutor;
import com.fr.start.common.DesignerStartupPool;
import com.fr.strongest.WidgetThemeListenerStarter;
import com.fr.task.Once;
import com.fr.workspace.WorkContext;
import com.fr.xml.ReportXMLUtils;
@ -187,8 +190,10 @@ public class DesignerActivator extends Activator implements Prepare {
}
CompletableFuture<Void> themeConfigPrepare = CompletableFuture.runAsync(() -> {
FormThemeConfigMigrator.getInstance().upgrade();
ReportThemeConfigMigrator.getInstance().upgrade();
if (WorkContext.getCurrent().isLocal()) {
FormThemeConfigMigrator.getInstance().upgrade();
ReportThemeConfigMigrator.getInstance().upgrade();
}
}, DesignerStartupPool.common());
CompletableFuture<Void> mainDesignerPrepare = CompletableFuture.runAsync(this::designerModuleStart, DesignerStartupPool.common());
@ -210,6 +215,9 @@ public class DesignerActivator extends Activator implements Prepare {
storePassport();
AlphaFineHelper.switchConfig4Locale();
RecoverManager.register(new RecoverForDesigner());
WidgetThemeListenerStarter.start();
TemplateLockInfoReSave.startListener();
RPCConnectHandlerCenter.startListener();
}, DesignerStartupPool.common());
CompletableFuture<Void> resourcePrepare = CompletableFuture.runAsync(() -> {
@ -533,6 +541,8 @@ public class DesignerActivator extends Activator implements Prepare {
public void stop() {
unloadLogAppender();
DesignerSocketIO.close();
TemplateLockInfoReSave.stopListener();
RPCConnectHandlerCenter.stopListener();
}
@Override

9
designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java

@ -2,12 +2,18 @@ package com.fr.start.module;
import com.fr.design.DesignerEnvManager;
import com.fr.design.RestartHelper;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.file.TemplateResourceManager;
import com.fr.design.utils.DesignUtils;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.file.TmpFileUtils;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.module.Activator;
import com.fr.start.common.DesignerStartupPool;
/**
* Created by juhaoyu on 2018/1/8.
@ -17,7 +23,8 @@ public class PreStartActivator extends Activator {
@Override
public void start() {
//清空临时文件
TmpFileUtils.cleanUpInnerTmpFiles();
Runtime.getRuntime().addShutdownHook(new Thread(TmpFileUtils::cleanUpInnerTmpFiles));
RestartHelper.deleteRecordFilesWhenStart();
//初始化起始画面放到 SplashContext 里面
//EventDispatcher.fire(ModuleEvent.MajorModuleStarting, Toolkit.i18nText("Fine-Design_Basic_Initializing"));

20
designer-realize/src/main/java/com/fr/start/module/optimized/DesignerPluginActivator.java

@ -3,7 +3,11 @@ package com.fr.start.module.optimized;
import com.fr.module.Activator;
import com.fr.module.ModuleContext;
import com.fr.plugin.PluginActivator;
import com.fr.plugin.manage.PluginManager;
import com.fr.start.common.DesignerStartupExecutor;
import com.fr.workspace.WorkContext;
import com.fr.workspace.WorkspaceSwitchHelper;
import com.fr.workspace.WorkspaceSwitchProcess;
/**
* created by Harrison on 2022/06/22
@ -12,13 +16,21 @@ public class DesignerPluginActivator extends Activator {
@Override
public void start() {
DesignerStartupExecutor.getInstance().execute(() -> ModuleContext.getModule(PluginActivator.class).start());
WorkspaceSwitchProcess process = WorkContext.getSwitcher().getProcess();
if (WorkspaceSwitchHelper.supportHotSwitch(process)) {
PluginManager.getHotModule().start();
} else {
DesignerStartupExecutor.getInstance().execute(() -> ModuleContext.getModule(PluginActivator.class).start());
}
}
@Override
public void stop() {
ModuleContext.getModule(PluginActivator.class).stop();
WorkspaceSwitchProcess process = WorkContext.getSwitcher().getProcess();
if (WorkspaceSwitchHelper.supportHotSwitch(process)) {
PluginManager.getHotModule().stop();
} else {
ModuleContext.getModule(PluginActivator.class).stop();
}
}
}

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

Loading…
Cancel
Save