Browse Source

Merging in latest from upstream (DESIGN/design:refs/heads/release/11.0)

* commit '2d6e2f9b260e5ae23a070d61532e9dba6d82626f': (143 commits)
  REPORT-58390 【主题切换】细节定制-决策报表的模板背景-不透明度降低后,缩略图会变暗
  REPORT-58367 【回归测试】聚合报表全选报表块内容,修改跟随主题,配置不生效
  REPORT-58383 【回归测试】聚合报表纸张背景-跟随主题,设计器内配置预览效果不正确
  REPORT-58353 【主题切换】悬浮元素-样式设置为自定义时,不同选项的切换显示
  CHART-20374 && REPORT-57978 【主题切换】细节定制-模板背景-设置图片适应,左上角有奇怪的显示;【11.0】仪表盘标签、轴标签颜色自动控件截断显示
  REPORT-58366 【主题切换】主题编辑界面-细节定制-组件样式、配色编辑 修改提示文字内容/字体/大小/颜色
  REPORT-58344 主题样式frm下的图表标题增加提示
  REPORT-55986 决策报表tap块 移动端属性国际化显示不全
  REPORT-57171 AF打不开
  无jira 加个切换时处理 防止工具栏残留
  REPORT-58296 调整参数面板高度消失问题
  CHART-20385【11.0】图例主题颜色控件展示异常
  REPORT-58159 组件编辑按钮-表单组件选中-设计器日志框无法置于设计器上方
  无jira 调整下日志等级
  REPORT-58212 【主题切换】远程10.0升上来的工程,特定操作下新建的模板预览500
  REPORT-58064 【主题切换】悬浮元素-样式的显示同交互稿不符
  REPORT-58276 【主题切换】细节定制-FRM组件样式-主体填充修改后,联动显示异常
  REPORT-58301 【决策报表】布局切换以后,body背景样式不保留
  代码修改
  REPORT-58225【主题切换】除图表外所有渐变色设置,打开颜色控件显示不正确
  ...
fix-lag
Hoky.He 3 years ago
parent
commit
11772c3dc4
  1. 21
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 8
      designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
  3. 5
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  4. 12
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  5. 8
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataComboBox.java
  6. 24
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java
  7. 452
      designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java
  8. 16
      designer-base/src/main/java/com/fr/design/data/datapane/preview/CopyableJTable.java
  9. 2
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  10. 47
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/db/DBTableDataSavedHook.java
  11. 20
      designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceInfoContext.java
  12. 28
      designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java
  13. 2
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  14. 5
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java
  15. 11
      designer-base/src/main/java/com/fr/design/gui/frpane/JTreeAutoBuildPane.java
  16. 11
      designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java
  17. 12
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIColorButton.java
  18. 36
      designer-base/src/main/java/com/fr/design/gui/ibutton/UINoThemeColorButton.java
  19. 20
      designer-base/src/main/java/com/fr/design/gui/icombobox/ColorSchemeComboBox.java
  20. 34
      designer-base/src/main/java/com/fr/design/gui/icombobox/UIComboBoxUI.java
  21. 13
      designer-base/src/main/java/com/fr/design/gui/icontainer/UIScrollPane.java
  22. 104
      designer-base/src/main/java/com/fr/design/gui/ifilechooser/AbstractFileChooser.java
  23. 10
      designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java
  24. 155
      designer-base/src/main/java/com/fr/design/gui/ifilechooser/UINativeFileChooser.java
  25. 20
      designer-base/src/main/java/com/fr/design/gui/style/AbstractBorderPackerPane.java
  26. 99
      designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java
  27. 8
      designer-base/src/main/java/com/fr/design/gui/style/BorderPane.java
  28. 33
      designer-base/src/main/java/com/fr/design/gui/style/ComponentBodyStylePane.java
  29. 109
      designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java
  30. 348
      designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java
  31. 138
      designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java
  32. 102
      designer-base/src/main/java/com/fr/design/gui/style/ReportBackgroundSpecialPane.java
  33. 24
      designer-base/src/main/java/com/fr/design/gui/style/TextInsetImageBackgroundSpecialPane.java
  34. 27
      designer-base/src/main/java/com/fr/design/gui/style/TitleTranslucentBackgroundSpecialPane.java
  35. 45
      designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java
  36. 9
      designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java
  37. 13
      designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java
  38. 20
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  39. 102
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  40. 3
      designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java
  41. 23
      designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ColorBackgroundQuickPane.java
  42. 5
      designer-base/src/main/java/com/fr/design/mainframe/loghandler/LogMessageBar.java
  43. 8
      designer-base/src/main/java/com/fr/design/mainframe/predefined/ui/detail/ColorFillStylePane.java
  44. 53
      designer-base/src/main/java/com/fr/design/mainframe/predefined/ui/detail/background/ColorDetailPane.java
  45. 13
      designer-base/src/main/java/com/fr/design/mainframe/predefined/ui/preview/ChartPreStylePreView.java
  46. 81
      designer-base/src/main/java/com/fr/design/mainframe/theme/AsyncThemeFetcher.java
  47. 105
      designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java
  48. 74
      designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java
  49. 259
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java
  50. 242
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java
  51. 325
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java
  52. 93
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java
  53. 609
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java
  54. 101
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java
  55. 93
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java
  56. 145
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java
  57. 162
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java
  58. 294
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/CellStyleListEditPane.java
  59. 104
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleEditPane.java
  60. 16
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleFormEditPane.java
  61. 136
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java
  62. 44
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/FormBodyStyleEditPane.java
  63. 65
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ReportBodyStyleEditPane.java
  64. 51
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/AbstractBackgroundDetailPane.java
  65. 136
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/BackgroundSettingPane.java
  66. 105
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ColorDetailPane.java
  67. 35
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/EmptyBackgroundPane.java
  68. 160
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/GradientDetailPane.java
  69. 216
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ImageDetailPane.java
  70. 120
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/PatternDetailPane.java
  71. 98
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/TextureDetailObservePane.java
  72. 198
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java
  73. 19
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java
  74. 50
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/AbstractChartStylePane.java
  75. 69
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartAxisStylePane.java
  76. 58
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartDataSheetStylePane.java
  77. 161
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java
  78. 78
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLabelStylePane.java
  79. 49
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLegendStylePane.java
  80. 88
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartSeriesStylePane.java
  81. 36
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleAndBackgroundStyleFormPane.java
  82. 127
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleAndBackgroundStylePane.java
  83. 101
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/component/ComponentMarginStylePane.java
  84. 147
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListExtendedPane.java
  85. 203
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java
  86. 29
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java
  87. 73
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java
  88. 34
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartComponentPreviewPane.java
  89. 80
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartPreviewPane.java
  90. 163
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java
  91. 198
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java
  92. 126
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ReportThemePreviewPane.java
  93. 10
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ThemePreviewed.java
  94. 19
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/UINoOpaquePanel.java
  95. 47
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/AbstractECPreviewPane.java
  96. 27
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECComponentPreviewPane.java
  97. 104
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java
  98. 126
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java
  99. 32
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/cell/AbstractPreviewCell.java
  100. 33
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/cell/CornerPreviewCell.java
  101. Some files were not shown because too many files have changed in this diff Show More

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

@ -87,6 +87,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private static final int MAX_SHOW_NUM = 10;
private static final String VERSION_80 = "80";
private static final String VERSION_90 = "90";
private static final String VERSION100 = "100";
private static final int CACHINGTEMPLATE_LIMIT = 5;
private static final String WEB_NAME = "webapps";
/**
@ -354,14 +356,21 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
try {
fileWriter = new FileWriter(envFile);
File oldEnvFile = new File(ProductConstants.getEnvHome() + File.separator + ProductConstants.APP_NAME + "6-1" + "Env.xml");
File envFile80 = new File(getEnvHome(VERSION_80) + File.separator + getEnvFile().getName());
if (oldEnvFile.exists()) {
File envFile80 = getOldEnvFile(VERSION_80);
File envFile90 = getOldEnvFile(VERSION_90);
File envFile100 = getOldEnvFile(VERSION100);
// 从10.0往前递进是否存在更老版本的配置文件
if (envFile100.exists()) {
compatibilityPrevVersion(envFile100);
} else if (envFile90.exists()) {
compatibilityPrevVersion(envFile90);
} else if (envFile80.exists()) {
compatibilityPrevVersion(envFile80);
} else if (oldEnvFile.exists()) {
// marks:兼容DesignerEnv6-1.xml
FileReader fileReader = new FileReader(oldEnvFile);
Utils.copyCharTo(fileReader, fileWriter);
fileReader.close();
} else if (envFile80.exists()) {
compatibilityPrevVersion(envFile80);
} else {
// marks:生成一个新的xml文件
StringReader stringReader = new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Env></Env>");
@ -383,6 +392,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
}
}
private File getOldEnvFile(String version) {
return new File(getEnvHome(version) + File.separator + getEnvFile().getName());
}
private static String getEnvHome(String version) {
String userHome = System.getProperty("user.home");
if (userHome == null) {

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

@ -8,6 +8,7 @@ import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.env.DesignerWorkspaceGenerator;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.DesignerWorkspaceInfoContext;
import com.fr.design.env.DesignerWorkspaceType;
import com.fr.design.env.RemoteDesignerWorkspaceInfo;
import com.fr.design.env.RemoteWorkspace;
@ -20,7 +21,7 @@ import com.fr.design.notification.NotificationCenter;
import com.fr.design.utils.DesignUtils;
import com.fr.design.versioncheck.VersionCheckUtils;
import com.fr.env.EnvListPane;
import com.fr.env.handler.RemoteDesignExceptionHandler;
import com.fr.env.handler.WorkspaceExceptionHandler;
import com.fr.exit.DesignerExiter;
import com.fr.general.GeneralUtils;
import com.fr.invoke.Reflect;
@ -105,6 +106,7 @@ public class EnvChangeEntrance {
private boolean switch2Env(final String envName, PopTipStrategy strategy) {
DesignerEnvManager envManager = DesignerEnvManager.getEnvManager();
DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName);
DesignerWorkspaceInfoContext.setWorkspaceInfo(selectedEnv);
WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection();
try {
@ -139,7 +141,7 @@ public class EnvChangeEntrance {
pluginErrorRemind();
} catch (Exception exception) {
// 失败的处理
RemoteDesignExceptionHandler.getInstance().handleInSwitch(exception, selectedEnv);
WorkspaceExceptionHandler.getInstance().handleInSwitch(exception, selectedEnv);
return false;
}
TemplateTreePane.getInstance().refreshDockingView();
@ -436,7 +438,7 @@ public class EnvChangeEntrance {
}
});
if (e != null) {
RemoteDesignExceptionHandler.getInstance().handleInStart(e, workspaceInfo);
WorkspaceExceptionHandler.getInstance().handleInStart(e, workspaceInfo);
}
envListDialog.setVisible(true);
}

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

@ -12,6 +12,7 @@ import com.fr.design.editor.editor.IntegerEditor;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UINoThemeColorButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIDictionaryComboBox;
@ -474,10 +475,10 @@ public class PreferencePane extends BasicPane {
JPanel colorSettingPane = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Basic_Preference_Setting_Colors"));
generalPane.add(colorSettingPane);
gridLineColorTBButton = new UIColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
gridLineColorTBButton = new UINoThemeColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
gridLineColorTBButton.setEnabled(this.isEnabled());
paginationLineColorTBButton = new UIColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
paginationLineColorTBButton = new UINoThemeColorButton(IOUtils.readIcon("/com/fr/design/images/gui/color/foreground.png"));
paginationLineColorTBButton.setEnabled(this.isEnabled());
JPanel leftPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();

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

@ -161,10 +161,18 @@ public abstract class DesignTableDataManager {
}
public static String getChangedDsNameByOldDsName(String oldDsName) {
String changeName;
if (isDsNameChanged(oldDsName)) {
return dsNameChangedMap.get(oldDsName);
changeName = dsNameChangedMap.get(oldDsName);
} else {
changeName = StringUtils.EMPTY;
}
if (StringUtils.isNotEmpty(changeName)) {
return getChangedDsNameByOldDsName(changeName);
} else {
return StringUtils.EMPTY;
return oldDsName;
}
}

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

@ -9,6 +9,7 @@ import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.file.TableDataConfig;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
@ -80,12 +81,13 @@ public class TreeTableDataComboBox extends UIComboBox {
}
public void setSelectedTableDataByName(String name) {
refresh();
TableDataWrapper tableDataWrapper;
if (res_map.get(name) != null) {
tableDataWrapper = res_map.get(name);
} else {
String changeName = DesignTableDataManager.getChangedDsNameByOldDsName(name);
if (StringUtils.isNotEmpty(changeName)) {
tableDataWrapper = res_map.get(changeName);
} else {
tableDataWrapper = res_map.get(name);
}
this.getModel().setSelectedItem(tableDataWrapper);
}

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

@ -64,7 +64,7 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
tableFlowPane.add(tableDataNameComboBox);
tableDataNameComboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
tdChange();
tdChange(true);
}
});
tableFlowPane.add(new PreviewLabel(this));
@ -73,19 +73,21 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
this.add(centerPane, BorderLayout.CENTER);
parentMarkRadio = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Build_Tree_Accord_Parent_Marked_Filed"), true);
lengthMarkRadio = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Build_Tree_Accord_Marked_Filed_Length"));
parentMarkRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
parentMarkRadio.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (isBuildByParentFiled()) {
makeParentEnable();
tdChange();
tdChange(false);
}
}
});
lengthMarkRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
lengthMarkRadio.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (!isBuildByParentFiled()) {
makeLengthEnable();
tdChange();
tdChange(false);
}
}
});
@ -169,7 +171,7 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
}
private void tdChange() {
private void tdChange(boolean isChangeDS) {
TableDataWrapper tableDataWrappe = this.tableDataNameComboBox.getSelectedItem();
if (tableDataWrappe == null) {
return;
@ -186,8 +188,10 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
String[] columnNames = new String[len];
namelist.toArray(columnNames);
for (int i = 0; i < valueEditorPanes.length; i++) {
if (isChangeDS || isNoSelectedColumnName(valueEditorPanes[i])) {
valueEditorPanes[i].setEditors(new Editor[]{new ColumnNameEditor(columnNames), new ColumnIndexEditor(len)}, columnNames[0]);
}
}
} catch (Exception e) {
for (int i = 0; i < valueEditorPanes.length; i++) {
valueEditorPanes[i].setEditors(new Editor[]{new ColumnNameEditor(), new ColumnIndexEditor()}, 1);
@ -197,6 +201,10 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable {
}
}
private boolean isNoSelectedColumnName(ValueEditorPane valueEditorPane) {
return (Integer) valueEditorPane.update() == -1;
}
@Override
protected String title4PopupWindow() {
return "TreeTableDataDictionay";

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

@ -1,8 +1,6 @@
package com.fr.design.data.datapane.connect;
import com.fr.base.GraphHelper;
import com.fr.data.driver.DriverLoader;
import com.fr.data.driver.config.DriverLoaderConfig;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.design.border.UITitledBorder;
import com.fr.design.gui.ibutton.UIButton;
@ -23,8 +21,6 @@ import com.fr.general.ComparatorUtils;
import com.fr.stable.ArrayUtils;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.third.guava.collect.HashBiMap;
import com.fr.workspace.WorkContext;
import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
@ -49,7 +45,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -102,167 +97,12 @@ public class JDBCDefPane extends JPanel {
private Component[][] partComponents;
// 请不要改动dbtype,只应该最后添加
private final String[] dbtype = {"Oracle", "DB2", "SQL Server", "MySQL", "Sybase", "Access", "Derby", "Postgre", "SQLite", "Inceptor", OTHER_DB};
private JDBCDatabaseConnection jdbcDatabase;
private boolean needRefresh = true;
private UIComboBox driverManageBox;
private ActionLabel driverManageLabel;
private UIComboBox driverLoaderBox;
private HashBiMap<String, String> nameAndRepresent;
ActionListener driverListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (driverComboBox.getSelectedItem() == null || ComparatorUtils.equals(driverComboBox.getSelectedItem(), StringUtils.EMPTY)) {
return;
}
odbcTipsLink.setVisible(ComparatorUtils.equals("sun.jdbc.odbc.JdbcOdbcDriver", driverComboBox.getSelectedItem())); // 选择的如果是ODBC就显示提示
Iterator<Entry<String, DriverURLName[]>> jdbc = jdbcMap.entrySet().iterator();
while (jdbc.hasNext()) {
Entry<String, DriverURLName[]> entry = jdbc.next();
DriverURLName[] dus = entry.getValue();
for (int i = 0, len = dus.length; i < len; i++) {
if (ComparatorUtils.equals(dus[i].getDriver(), (driverComboBox.getSelectedItem()))) {
urlTextField.setText(dus[i].getURL());
return;
}
}
}
}
};
ActionListener dbtypeButtonActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if (ComparatorUtils.equals(dbtypeComboBox.getSelectedItem(), StringUtils.EMPTY)) {
return;
}
DriverURLName[] dus = jdbcMap.get(dbtypeComboBox.getSelectedItem());
for (int i = 0, len = dus.length; i < len; i++) {
if (ComparatorUtils.equals(driverComboBox.getSelectedItem(), (dus[i].getDriver()))) {
urlTextField.setText(dus[i].getURL());
if (ComparatorUtils.equals(dbtypeComboBox.getSelectedItem(), ("Access"))) {
// ben:这个能不能换种处理方案- -
JFileChooser filechooser = new JFileChooser();
filechooser.setDialogTitle(Toolkit.i18nText("Fine-Design_Basic_Open"));
filechooser.setMultiSelectionEnabled(false);
filechooser.addChoosableFileFilter(new ChooseFileFilter(new String[]{"accdb", "mdb"}, "Microsoft Office Access"));
int result = filechooser.showOpenDialog(DesignerContext.getDesignerFrame());
File selectedfile = null;
if (result == JFileChooser.APPROVE_OPTION) {
selectedfile = filechooser.getSelectedFile();
if (selectedfile != null) {
String selectedName = selectedfile.getPath().substring(selectedfile.getPath().lastIndexOf('.') + 1);
if (selectedName.equalsIgnoreCase("mdb") || selectedName.equalsIgnoreCase("accdb")) {
urlTextField.setText(urlTextField.getText() + selectedfile.getPath());
}
}
}
}
break;
}
}
}
};
KeyListener portKeyListener = new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
String port = portTextField.getText();
if (isPortValid(port)) {
updateURL();
} else {
portTextField.setText(port.replaceAll(getCharNeedReplace(e.getKeyChar()), ""));
if (!isPortValid(portTextField.getText())) {
portTextField.setText(StringUtils.EMPTY);
updateURL();
}
}
}
};
ActionListener driverManageListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean selectSelfDefine = isSelfDefine();
driverManageLabel.setVisible(selectSelfDefine);
driverLoaderBox.setVisible(selectSelfDefine);
driverComboBox.setVisible(!selectSelfDefine);
// 选中自定义的话,将odbc的屏蔽,选中默认的话,重新触发一次driverComboBox的事件
if (selectSelfDefine) {
odbcTipsLink.setVisible(false);
} else {
driverComboBox.setSelectedItem(driverComboBox.getSelectedItem());
}
}
};
ActionListener dbtypeActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
urlTextField.setText(StringUtils.EMPTY);
driverComboBox.removeAllItems();
driverManageBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Default"));
if (driverLoaderBox.getItemCount() > 0) {
driverLoaderBox.setSelectedIndex(0);
}
if (ComparatorUtils.equals(dbtypeComboBox.getSelectedItem(), StringUtils.EMPTY)) {
driverComboBox.setSelectedItem(StringUtils.EMPTY);
return;
}
DriverURLName[] dus = jdbcMap.get(dbtypeComboBox.getSelectedItem());
for (int i = 0, len = dus.length; i < len; i++) {
driverComboBox.addItem(dus[i].getDriver());
if (i == 0) {
driverComboBox.setSelectedItem(dus[i].getDriver());
urlTextField.setText(dus[i].getURL());
}
}
// 更改数据库类型后 数据库名称置空和之前逻辑保持一致
if (needRefresh) {
jdbcDatabase.setDatabase(StringUtils.EMPTY);
}
changePane(dbtypeComboBox.getSelectedItem());
JDBCConnectionDef.getInstance().setConnection((String) dbtypeComboBox.getSelectedItem(), jdbcDatabase);
DatabaseConnectionPane.JDBC.getAdvancedAttrPane().populate(jdbcDatabase);
}
};
InputMethodListener portInputMethodListener = new InputMethodListener() {
@Override
public void inputMethodTextChanged(InputMethodEvent event) {
if (null == event.getText()) {
return;
}
char ch = event.getText().current();
if (!(ch >= '0' && ch <= '9')) {
event.consume();
}
}
@Override
public void caretPositionChanged(InputMethodEvent event) {
}
};
DocumentListener updateParaListener = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
updatePara();
}
@Override
public void removeUpdate(DocumentEvent e) {
updatePara();
}
@Override
public void changedUpdate(DocumentEvent e) {
updatePara();
}
};
private JDBCDatabaseConnection jdbcDatabase;
private boolean needRefresh = true;
public JDBCDefPane() {
initMap();
this.setBorder(UITitledBorder.createBorderWithTitle("JDBC" + ":"));
this.setLayout(FRGUIPaneFactory.createLabelFlowLayout());
JPanel innerthis = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
@ -275,14 +115,7 @@ public class JDBCDefPane extends JPanel {
}
dbtypeComboBox.addActionListener(dbtypeActionListener);
dbtypeComboBox.setMaximumRowCount(10);
driverLoaderBox = new UIComboBox();
refreshDriverLoader();
driverLoaderBox.setEditable(false);
driverManageBox = new UIComboBox();
refreshDriverManage(true);
driverManageBox.setEditable(false);
driverManageBox.addActionListener(driverManageListener);
driverLoaderBox.setVisible(isSelfDefine());
driverComboBox = new UIComboBox();
driverComboBox.setEditable(true);
driverComboBox.addActionListener(driverListener);
@ -322,39 +155,17 @@ public class JDBCDefPane extends JPanel {
_gfx.drawLine(0, this.getHeight() - 1, GraphHelper.getWidth(this.getText()), this.getHeight() - 1);
}
};
odbcTipsPane.add(odbcTipsLink);
odbcTipsLink.setPreferredSize(new Dimension(GraphHelper.getWidth(Toolkit.i18nText("Fine-Design_Basic_Odbc_Tips")), odbcTipsLink.getPreferredSize().height));
odbcTipsLink.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
String url = CloudCenter.getInstance().acquireUrlByKind("odbc.help");
BrowseUtils.browser(url);
}
});
driverManageLabel = new ActionLabel(Toolkit.i18nText("Fine-Design_Driver_Manage_Add_Driver")) {
@Override
public void paintComponent(Graphics _gfx) {
super.paintComponent(_gfx);
_gfx.setColor(Color.blue);
_gfx.drawLine(0, this.getHeight() - 1, GraphHelper.getWidth(this.getText()), this.getHeight() - 1);
}
};
driverManageLabel.setPreferredSize(new Dimension(GraphHelper.getWidth(Toolkit.i18nText("Fine-Design_Driver_Manage_Add_Driver")), driverManageLabel.getPreferredSize().height));
driverManageLabel.setVisible(isSelfDefine());
driverManageLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
String url = CloudCenter.getInstance().acquireUrlByKind("driver.add.help");
BrowseUtils.browser(url);
}
});
odbcTipsPane.add(driverManageLabel);
odbcTipsPane.add(odbcTipsLink);
JPanel driverComboBoxAndTips = new JPanel(new BorderLayout());
JPanel normalFlowInnerContainer_s_pane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
normalFlowInnerContainer_s_pane.add(driverManageBox);
normalFlowInnerContainer_s_pane.add(driverComboBox);
normalFlowInnerContainer_s_pane.add(driverLoaderBox);
driverComboBoxAndTips.add(normalFlowInnerContainer_s_pane, BorderLayout.WEST);
driverComboBoxAndTips.add(driverComboBox, BorderLayout.WEST);
driverComboBoxAndTips.add(odbcTipsPane, BorderLayout.CENTER);
JPanel hostPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane();
@ -414,70 +225,7 @@ public class JDBCDefPane extends JPanel {
innerthis.add(centerPanel);
}
private void initMap() {
Map<String, DriverLoader> driverLoaders = DriverLoaderConfig.getInstance().getDriverLoaders();
nameAndRepresent = getDriverLoaderAndRepresent(driverLoaders);
}
private HashBiMap<String, String> getDriverLoaderAndRepresent(Map<String, DriverLoader> driverLoaders) {
HashBiMap<String, String> driverHashBiMap = HashBiMap.create();
if (WorkContext.getCurrent().isWarDeploy()) {
return driverHashBiMap;
}
// name 是唯一的,name+driver自然也是唯一的
for (DriverLoader driverLoader : driverLoaders.values()) {
driverHashBiMap.put(driverLoader.getName(), getRepresent(driverLoader.getDriverClass(), driverLoader.getName()));
}
return driverHashBiMap;
}
protected JDBCDatabaseConnection getJDBCDatabase() {
return this.jdbcDatabase;
}
private void changePane(Object dbType) {
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = {p, f, 22};
if (ComparatorUtils.equals(dbType, OTHER_DB) || ComparatorUtils.equals(dbType, "Access") || ComparatorUtils.equals(dbType, "SQLite")) {
if (this.centerPanel.getComponentCount() != partComponents.length * 2) {
centerPanel.removeAll();
TableLayoutHelper.addComponent2ResultPane(partComponents, new double[]{p, p, p, p, p}, columnSize, centerPanel);
}
} else if (this.centerPanel.getComponentCount() != allComponents.length * 2) {
centerPanel.removeAll();
TableLayoutHelper.addComponent2ResultPane(allComponents, new double[]{p, p, p, p, p, p, p, p}, columnSize, centerPanel);
}
}
private String getRepresent(String driverClass, String driverName) {
return driverClass + "(" + driverName + ")";
}
private boolean isSelfDefine() {
return ComparatorUtils.equals(Toolkit.i18nText("Fine-Design_Driver_Manage_Self_Define"), driverManageBox.getSelectedItem());
}
private void refreshDriverLoader() {
Set<String> representSet = nameAndRepresent.values();
driverLoaderBox.clearBoxItems();
for (String represent : representSet) {
driverLoaderBox.addItem(represent);
}
}
private void refreshDriverManage(boolean addSelfDefine) {
driverManageBox.clearBoxItems();
driverManageBox.addItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Default"));
if (addSelfDefine) {
driverManageBox.addItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Self_Define"));
}
}
public void populate(JDBCDatabaseConnection jdbcDatabase) {
// 单例对象,重新打开的时候并不会新建,但是由于driverloaderbox里面需要是动态内容,因此需要进行刷新动作
initMap();
refreshDriverLoader();
needRefresh = false;
if (jdbcDatabase == null) {
jdbcDatabase = new JDBCDatabaseConnection();
@ -507,25 +255,7 @@ public class JDBCDefPane extends JPanel {
this.dbtypeComboBox.setSelectedItem(OTHER_DB);
}
}
this.jdbcDatabase.setIdentity(jdbcDatabase.getIdentity());
// jdbcDatabase.getDriverSource() 只会是空或者是有值,但是为了保险起见,还是应该做个处理
String driverSource = jdbcDatabase.getDriverSource();
if (driverSource == null) {
driverSource = StringUtils.EMPTY;
}
if (driverSource.isEmpty()) {
refreshDriverManage(!nameAndRepresent.isEmpty());
this.driverManageBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Default"));
this.driverComboBox.setSelectedItem(jdbcDatabase.getDriver());
} else {
refreshDriverManage(true);
this.driverManageBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Driver_Manage_Self_Define"));
String represent = getRepresent(jdbcDatabase.getDriver(), jdbcDatabase.getDriverSource());
if (!nameAndRepresent.containsValue(represent)) {
this.driverLoaderBox.addItem(represent);
}
this.driverLoaderBox.setSelectedItem(represent);
}
this.urlTextField.setText(jdbcDatabase.getURL());
this.userNameTextField.setText(jdbcDatabase.getUser());
this.passwordTextField.setText(jdbcDatabase.getPassword());
@ -538,10 +268,31 @@ public class JDBCDefPane extends JPanel {
needRefresh = false;
}
protected JDBCDatabaseConnection getJDBCDatabase() {
return this.jdbcDatabase;
}
private void changePane(Object dbType) {
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = {p, f, 22};
if (ComparatorUtils.equals(dbType, OTHER_DB) || ComparatorUtils.equals(dbType, "Access") || ComparatorUtils.equals(dbType, "SQLite")) {
if (this.centerPanel.getComponentCount() != partComponents.length * 2) {
centerPanel.removeAll();
TableLayoutHelper.addComponent2ResultPane(partComponents, new double[]{p, p, p, p, p}, columnSize, centerPanel);
}
} else if (this.centerPanel.getComponentCount() != allComponents.length * 2) {
centerPanel.removeAll();
TableLayoutHelper.addComponent2ResultPane(allComponents, new double[]{p, p, p, p, p, p, p, p}, columnSize, centerPanel);
}
}
public JDBCDatabaseConnection update() {
if (jdbcDatabase == null) {
jdbcDatabase = new JDBCDatabaseConnection();
}
Object driveItem = this.driverComboBox.getSelectedItem();
jdbcDatabase.setDriver(driveItem == null ? null : driveItem.toString().trim());
jdbcDatabase.setURL(this.urlTextField.getText().trim());
jdbcDatabase.setUser(this.userNameTextField.getText().trim());
jdbcDatabase.setPassword(new String(this.passwordTextField.getPassword()).trim());
@ -553,30 +304,126 @@ public class JDBCDefPane extends JPanel {
jdbcDatabase.setNewCharsetName(EncodeConstants.ENCODING_GBK);
jdbcDatabase.setOriginalCharsetName(((String) this.charSetComboBox.getSelectedItem()));
}
String driverLoader = (String) this.driverLoaderBox.getSelectedItem();
if (driverLoader == null) {
driverLoader = StringUtils.EMPTY;
return jdbcDatabase;
}
if (isSelfDefine()) {
String[] split = driverLoader.split("\\(");
if (split.length > 1) {
String name = split[1];
if (name.length() > 0) {
jdbcDatabase.setDriverSource(name.substring(0, name.length() - 1));
} else {
jdbcDatabase.setDriverSource(StringUtils.EMPTY);
ActionListener dbtypeActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
urlTextField.setText(StringUtils.EMPTY);
driverComboBox.removeAllItems();
if (ComparatorUtils.equals(dbtypeComboBox.getSelectedItem(), StringUtils.EMPTY)) {
driverComboBox.setSelectedItem(StringUtils.EMPTY);
return;
}
} else {
jdbcDatabase.setDriverSource(StringUtils.EMPTY);
DriverURLName[] dus = jdbcMap.get(dbtypeComboBox.getSelectedItem());
for (int i = 0, len = dus.length; i < len; i++) {
driverComboBox.addItem(dus[i].getDriver());
if (i == 0) {
driverComboBox.setSelectedItem(dus[i].getDriver());
urlTextField.setText(dus[i].getURL());
}
jdbcDatabase.setDriver(split[0]);
} else {
Object driveItem = this.driverComboBox.getSelectedItem();
jdbcDatabase.setDriver(driveItem == null ? null : driveItem.toString().trim());
jdbcDatabase.setDriverSource(StringUtils.EMPTY);
}
return jdbcDatabase;
// 更改数据库类型后 数据库名称置空和之前逻辑保持一致
if (needRefresh) {
jdbcDatabase.setDatabase(StringUtils.EMPTY);
}
changePane(dbtypeComboBox.getSelectedItem());
JDBCConnectionDef.getInstance().setConnection((String) dbtypeComboBox.getSelectedItem(), jdbcDatabase);
DatabaseConnectionPane.JDBC.getAdvancedAttrPane().populate(jdbcDatabase);
}
};
ActionListener driverListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (driverComboBox.getSelectedItem() == null || ComparatorUtils.equals(driverComboBox.getSelectedItem(), StringUtils.EMPTY)) {
return;
}
odbcTipsLink.setVisible(ComparatorUtils.equals("sun.jdbc.odbc.JdbcOdbcDriver", driverComboBox.getSelectedItem())); // 选择的如果是ODBC就显示提示
Iterator<Entry<String, DriverURLName[]>> jdbc = jdbcMap.entrySet().iterator();
while (jdbc.hasNext()) {
Entry<String, DriverURLName[]> entry = jdbc.next();
DriverURLName[] dus = entry.getValue();
for (int i = 0, len = dus.length; i < len; i++) {
if (ComparatorUtils.equals(dus[i].getDriver(), (driverComboBox.getSelectedItem()))) {
urlTextField.setText(dus[i].getURL());
return;
}
}
}
}
};
ActionListener dbtypeButtonActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (ComparatorUtils.equals(dbtypeComboBox.getSelectedItem(), StringUtils.EMPTY)) {
return;
}
DriverURLName[] dus = jdbcMap.get(dbtypeComboBox.getSelectedItem());
for (int i = 0, len = dus.length; i < len; i++) {
if (ComparatorUtils.equals(driverComboBox.getSelectedItem(), (dus[i].getDriver()))) {
urlTextField.setText(dus[i].getURL());
if (ComparatorUtils.equals(dbtypeComboBox.getSelectedItem(), ("Access"))) {
// ben:这个能不能换种处理方案- -
JFileChooser filechooser = new JFileChooser();
filechooser.setDialogTitle(Toolkit.i18nText("Fine-Design_Basic_Open"));
filechooser.setMultiSelectionEnabled(false);
filechooser.addChoosableFileFilter(new ChooseFileFilter(new String[]{"accdb", "mdb"}, "Microsoft Office Access"));
int result = filechooser.showOpenDialog(DesignerContext.getDesignerFrame());
File selectedfile = null;
if (result == JFileChooser.APPROVE_OPTION) {
selectedfile = filechooser.getSelectedFile();
if (selectedfile != null) {
String selectedName = selectedfile.getPath().substring(selectedfile.getPath().lastIndexOf('.') + 1);
if (selectedName.equalsIgnoreCase("mdb") || selectedName.equalsIgnoreCase("accdb")) {
urlTextField.setText(urlTextField.getText() + selectedfile.getPath());
}
}
}
}
break;
}
}
}
};
InputMethodListener portInputMethodListener = new InputMethodListener() {
@Override
public void inputMethodTextChanged(InputMethodEvent event) {
if (null == event.getText()) {
return;
}
char ch = event.getText().current();
if (!(ch >= '0' && ch <= '9')) {
event.consume();
}
}
@Override
public void caretPositionChanged(InputMethodEvent event) {
}
};
DocumentListener updateParaListener = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
updatePara();
}
@Override
public void removeUpdate(DocumentEvent e) {
updatePara();
}
@Override
public void changedUpdate(DocumentEvent e) {
updatePara();
}
};
private void updatePara() {
String dbType = dbtypeComboBox.getSelectedItem().toString();
@ -641,6 +488,21 @@ public class JDBCDefPane extends JPanel {
this.hostTextField.getDocument().removeDocumentListener(updateURLListener);
}
KeyListener portKeyListener = new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
String port = portTextField.getText();
if (isPortValid(port)) {
updateURL();
} else {
portTextField.setText(port.replaceAll(getCharNeedReplace(e.getKeyChar()), ""));
if (!isPortValid(portTextField.getText())) {
portTextField.setText(StringUtils.EMPTY);
updateURL();
}
}
}
};
private boolean isPortValid(String port) {
return PORT.matcher(port).find();

16
designer-base/src/main/java/com/fr/design/data/datapane/preview/CopyableJTable.java

@ -48,9 +48,17 @@ public class CopyableJTable extends SortableJTable {
boolean mouseDrag = false;
boolean headerSelect = false;
DefaultTableCellRenderer tableHeaderCellRenderer = new DefaultTableCellRenderer() {
class CopyableTableHeaderCellRenderer implements TableCellRenderer {
TableCellRenderer tableCellRenderer;
CopyableTableHeaderCellRenderer(TableCellRenderer tableCellRenderer) {
this.tableCellRenderer = tableCellRenderer;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
JComponent comp = (JComponent) this.tableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (isChoose(row, column)) {
comp.setBackground(selectBackGround);
} else {
@ -58,13 +66,13 @@ public class CopyableJTable extends SortableJTable {
}
return comp;
}
};
}
public CopyableJTable(TableSorter tableModel) {
super(tableModel);
initListener();
this.getTableHeader().setDefaultRenderer(tableHeaderCellRenderer);
this.getTableHeader().setDefaultRenderer(new CopyableTableHeaderCellRenderer(this.getTableHeader().getDefaultRenderer()));
}
private void initListener() {

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

@ -19,7 +19,6 @@ import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.data.datapane.preview.sql.PreviewPerformedSqlPane;
import com.fr.design.data.datapane.sqlpane.SQLEditPane;
import com.fr.design.data.tabledata.strategy.StrategyConfigHandler;
import com.fr.design.data.tabledata.tabledatapane.db.DBTableDataSavedHook;
import com.fr.design.data.tabledata.tabledatapane.db.StrategyConfigFrom;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
@ -45,6 +44,7 @@ import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.esd.core.strategy.config.StrategyConfig;
import com.fr.esd.core.strategy.config.StrategyConfigHelper;
import com.fr.esd.core.strategy.config.service.StrategyConfigService;
import com.fr.esd.data.db.DBTableDataSavedHook;
import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;

47
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/db/DBTableDataSavedHook.java

@ -1,47 +0,0 @@
package com.fr.design.data.tabledata.tabledatapane.db;
import com.fr.data.impl.DBTableData;
import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.esd.event.xml.XMLSavedHook;
import com.fr.stable.StringUtils;
public class DBTableDataSavedHook implements XMLSavedHook<DBTableData> {
private static final long serialVersionUID = 4925391747683335372L;
private final String tplPath;
private String origName;
private String origConnection;
private String origQuery;
public DBTableDataSavedHook(String tplPath, DBTableData origDBTableData) {
this.tplPath = tplPath;
this.origName = origDBTableData.getDsName();
this.origConnection = origDBTableData.getDatabase().toString();
this.origQuery = origDBTableData.getQuery();
}
@Override
public void doAfterSaved(DBTableData saved) {
String dsName = saved.getDsName();
String conn = saved.getDatabase().toString();
String query = saved.getQuery();
//检查数据集名称、数据链接和sql是否修改,如果修改需要触发缓存监听事件
if (!dsName.equals(origName) || !conn.equals(origConnection) || !query.equals(origQuery)) {
if (StringUtils.isNotEmpty(tplPath) && StringUtils.isNotEmpty(origName)) {
//新建数据集的origName为null,不用触发
StrategyEventsNotifier.modifyDataSet(new DSMapping(tplPath, new DsNameTarget(origName)));
}
}
this.origName = dsName;
this.origConnection = conn;
this.origQuery = query;
}
}

20
designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceInfoContext.java vendored

@ -0,0 +1,20 @@
package com.fr.design.env;
/**
*
* @author hades
* @version 10.0
* Created by hades on 2021/8/24
*/
public class DesignerWorkspaceInfoContext {
private static DesignerWorkspaceInfo workspaceInfo;
public static DesignerWorkspaceInfo getWorkspaceInfo() {
return workspaceInfo;
}
public static void setWorkspaceInfo(DesignerWorkspaceInfo workspaceInfo) {
DesignerWorkspaceInfoContext.workspaceInfo = workspaceInfo;
}
}

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

@ -1,18 +1,38 @@
package com.fr.design.env;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.engine.exception.MainVersionNotMatchException;
import java.io.File;
import java.util.Properties;
/**
* Created by juhaoyu on 2018/6/15.
*/
public class LocalDesignerWorkspaceInfo implements DesignerWorkspaceInfo {
private static final String REPORT_ENGINE_KEY = "report-engine-key";
private static final String REPORT_ENGINE_JAR;
private static final String PROP_PATH = "/com/fr/env/jarVersion.properties";
static {
Properties properties = new Properties();
try {
properties.load(LocalDesignerWorkspaceInfo.class.getResourceAsStream(PROP_PATH));
} catch (Exception ignored) {
}
REPORT_ENGINE_JAR = properties.getProperty(REPORT_ENGINE_KEY, "default.jar");
}
private String name;
private String path;
@ -86,6 +106,14 @@ public class LocalDesignerWorkspaceInfo implements DesignerWorkspaceInfo {
return false;
}
File engineLib = new File(StableUtils.pathJoin(this.path, ProjectConstants.LIB_NAME, REPORT_ENGINE_JAR));
// 非安装版本允许自由切换
boolean notExistLib = !CoreConstants.DOT.equals(StableUtils.getInstallHome())
&& !engineLib.exists();
if (notExistLib) {
throw new MainVersionNotMatchException();
}
return true;
}
}

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

@ -93,7 +93,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
@Override
public void mousePressed(MouseEvent evt) {
if (evt.getClickCount() == 2) {
if (reportletsTree.getPathForLocation(evt.getX(), evt.getY()) != null && evt.getClickCount() == 2) {
openFile();
}
}

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

@ -3,6 +3,7 @@ package com.fr.design.gui.controlpane;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.controlpane.shortcutfactory.ShortCutFactory;
import com.fr.design.gui.ifilechooser.JavaFxNativeFileChooser;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itoolbar.UIToolBarUI;
import com.fr.design.gui.itoolbar.UIToolbar;
@ -277,6 +278,10 @@ public abstract class UIControlPane extends JControlPane {
this.requestFocus();
return;
}
if (JavaFxNativeFileChooser.isShowDialogState()) {
JavaFxNativeFileChooser.setShowDialogState(false);
return;
}
saveSettings();
setVisible(false);
PopupDialogSaveAction saveAction = OSSupportCenter.getAction(PopupDialogSaveAction.class);

11
designer-base/src/main/java/com/fr/design/gui/frpane/JTreeAutoBuildPane.java

@ -27,13 +27,16 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.stable.StringUtils;
import java.awt.*;
import javax.swing.JPanel;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.List;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class JTreeAutoBuildPane extends BasicPane implements PreviewLabel.Previewable, EditOrNewLabel.Editable {
private TreeTableDataComboBox treeTableDataComboBox;

11
designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java

@ -10,6 +10,7 @@ import com.fr.design.gui.ispinner.UIBasicSpinner;
import com.fr.design.gui.itextfield.UINumberField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.GeneralUtils;
import com.fr.stable.AssistUtils;
import com.fr.stable.StringUtils;
@ -27,6 +28,7 @@ import java.math.BigDecimal;
* For input Number.
*/
public abstract class UnitInputPane extends BasicPane {
private static final double MAX_NUM = 3000.0D;
private static final double NUM_POINT = 0.000001;
private int scale = -1;
String title;
@ -46,7 +48,7 @@ public abstract class UnitInputPane extends BasicPane {
centerPane.add(titleLabel);
// Denny:在对话框中加入JSpinner对象
numberFieldSpinner = new UIBasicSpinner(new SpinnerNumberModel(0, 0, 999, 1));
numberFieldSpinner = new UIBasicSpinner(new SpinnerNumberModel(0, 0, MAX_NUM, 1));
GUICoreUtils.setColumnForSpinner(numberFieldSpinner, 24);
numberFieldSpinner.setPreferredSize(new Dimension(60, 20));
numberFieldSpinner.setMinimumSize(new Dimension(60, 20));
@ -71,11 +73,11 @@ public abstract class UnitInputPane extends BasicPane {
public void populate(float floatValue) {
popValue = floatValue;
numberFieldSpinner.setModel(new SpinnerNumberModel(0.00, 0.00, 999.00, 0.01));
numberFieldSpinner.setModel(new SpinnerNumberModel(0.00, 0.00, MAX_NUM, 0.01));
JFormattedTextField temp = GUICoreUtils.getSpinnerTextField(numberFieldSpinner);
addChangeListener(temp);
BigDecimal de = new BigDecimal(floatValue + "");
BigDecimal de = new BigDecimal(GeneralUtils.objectToString(floatValue));
if (scale > 0) {
floatValue = de.setScale(scale, BigDecimal.ROUND_DOWN).floatValue();
} else {
@ -108,7 +110,8 @@ public abstract class UnitInputPane extends BasicPane {
if (temp.getText().length() == 0) {
return 0;
}
BigDecimal de = new BigDecimal(temp.getText());
BigDecimal de = new BigDecimal(GeneralUtils.objectToString(temp.getValue()));
if (scale > 0) {
return de.setScale(scale, BigDecimal.ROUND_DOWN).floatValue();
} else {

12
designer-base/src/main/java/com/fr/design/gui/ibutton/UIColorButton.java

@ -154,7 +154,14 @@ public class UIColorButton extends UIButton implements PopupHider, UIObserver, G
protected ColorControlWindow getColorControlWindow() {
//find parant.
if (this.popupWin == null) {
this.popupWin = new ColorControlWindow(UIColorButton.this) {
this.popupWin = initColorControlWindow();
}
return popupWin;
}
protected ColorControlWindow initColorControlWindow(){
return new ColorControlWindow(UIColorButton.this) {
@Override
protected void colorChanged() {
UIColorButton.this.setColor(this.getColor());
@ -163,9 +170,6 @@ public class UIColorButton extends UIButton implements PopupHider, UIObserver, G
};
}
return popupWin;
}
/**
* 添加监听
*

36
designer-base/src/main/java/com/fr/design/gui/ibutton/UINoThemeColorButton.java

@ -0,0 +1,36 @@
package com.fr.design.gui.ibutton;
import com.fr.design.gui.ipoppane.PopupHider;
import com.fr.design.style.color.ColorControlWindow;
import javax.swing.Icon;
public class UINoThemeColorButton extends UIColorButton{
public UINoThemeColorButton(Icon icon) {
super(icon);
}
protected ColorControlWindow initColorControlWindow(){
return new NoThemeColorControlWindow(this);
}
private class NoThemeColorControlWindow extends ColorControlWindow{
public NoThemeColorControlWindow(PopupHider popupHider) {
super(popupHider);
}
protected boolean supportThemeColor(){
return false;
}
@Override
protected void colorChanged() {
UINoThemeColorButton.this.setColor(this.getColor());
}
}
}

20
designer-base/src/main/java/com/fr/design/gui/icombobox/ColorSchemeComboBox.java

@ -2,14 +2,18 @@ package com.fr.design.gui.icombobox;
import com.fr.base.ChartColorMatching;
import com.fr.base.ChartPreStyleConfig;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.chart.ThemedChartSeriesColor;
import com.fr.cert.token.lang.Collections;
import com.fr.chart.base.ChartConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.i18n.Toolkit;
import com.fr.general.GeneralUtils;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
@ -65,7 +69,21 @@ public class ColorSchemeComboBox extends UIComboBox {
Iterator names = config.names();
if (preDefined) {
colorSchemes.put(Toolkit.i18nText("Fine-Design_Chart_Predefined"), null);
ColorInfo colorInfo = new ColorInfo();
List<Color> list = new ArrayList<>();
colorInfo.setColors(list);
TemplateTheme templateTheme = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getTemplateTheme();
ThemedChartSeriesColor themedChartSeriesColor = templateTheme.getChartStyle().getThemedChartSeriesColor();
if (themedChartSeriesColor.isCombineColor()) {
colorInfo.setGradient(false);
list.addAll(templateTheme.getColorScheme().getColors());
} else {
colorInfo.setGradient(true);
list.add(themedChartSeriesColor.getBeginColor());
list.add(themedChartSeriesColor.getEndColor());
}
colorSchemes.put(Toolkit.i18nText("Fine-Design_Chart_Follow_Theme"), colorInfo);
} else {
//添加默认的方案和第一个方案
String defaultName = config.getCurrentStyle();

34
designer-base/src/main/java/com/fr/design/gui/icombobox/UIComboBoxUI.java

@ -10,12 +10,26 @@ import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import sun.swing.DefaultLookup;
import javax.swing.*;
import javax.swing.AbstractButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import java.awt.*;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
@ -159,6 +173,10 @@ public class UIComboBoxUI extends BasicComboBoxUI implements MouseListener {
return new UIComboPopup(comboBox);
}
protected ComboPopup createHorizontalNeverUIComboPopUp() {
return new HorizontalNeverUIComboPopup(comboBox);
}
private void setRollover(boolean isRollover) {
if (this.isRollover != isRollover) {
this.isRollover = isRollover;
@ -270,4 +288,16 @@ public class UIComboBoxUI extends BasicComboBoxUI implements MouseListener {
}
}
private class HorizontalNeverUIComboPopup extends UIComboPopup {
public HorizontalNeverUIComboPopup(JComboBox comboBox) {
super(comboBox);
}
@Override
protected JScrollPane createScroller() {
return new UIScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
}
}

13
designer-base/src/main/java/com/fr/design/gui/icontainer/UIScrollPane.java

@ -3,8 +3,11 @@ package com.fr.design.gui.icontainer;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.iscrollbar.UIScrollBar;
import javax.swing.*;
import java.awt.*;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import java.awt.Color;
import java.awt.Component;
/**
* @author zhou
@ -16,7 +19,11 @@ public class UIScrollPane extends JScrollPane {
private static final int INCREAMENT = 30;
public UIScrollPane(Component c) {
super(c, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
this(c, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
public UIScrollPane(Component c, int vertical, int horizontal) {
super(c, vertical, horizontal);
this.setHorizontalScrollBar(createHorizontalScrollBar());
this.getVerticalScrollBar().setUnitIncrement(INCREAMENT);
this.getVerticalScrollBar().setBlockIncrement(INCREAMENT);

104
designer-base/src/main/java/com/fr/design/gui/ifilechooser/AbstractFileChooser.java

@ -0,0 +1,104 @@
package com.fr.design.gui.ifilechooser;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.io.File;
/**
* @author hades
* @version 10.0
* Created by hades on 2020/3/31
*/
@Deprecated
public abstract class AbstractFileChooser<T,E> {
/**
* 返回当前目录
*
*/
public abstract File getCurrentDirectory();
/**
* 返回当前的文件选择过滤器
*
*/
public abstract FileFilter getFileFilter();
/**
* 返回选择的文件
*
*/
public abstract File getSelectedFile();
/**
* 多文件选择模式下 返回选择的多个文件
*
*/
public abstract File[] getSelectedFiles();
/**
* 是否可以选择多个文件
*
*/
public abstract boolean isMultiSelectionEnabled();
/**
* 设置当前选择的目录
*
*/
public abstract void setCurrentDirectory(File dir);
/**
* 设置左上角标题
*
*/
public abstract void setDialogTitle(String title);
/**
* 设置当前的文件过滤器
*
*/
public abstract void setFileFilter(final T filter);
/**
* 设置文件选择器模式
*
* JFileChooser.FILES_ONLY
* JFileChooser.DIRECTORIES_ONLY
* JFileChooser.FILES_AND_DIRECTORIES
*/
public abstract void setFileSelectionMode(E selectionMode);
/**
* 设置是否允许选择多个文件
*
*/
public abstract void setMultiSelectionEnabled(boolean multiple);
/**
* 设置选择的文件 用于showSaveDialog
*
*/
public abstract void setSelectedFile(File file);
/**
* 弹出文件选择器 打开文件
*
*/
public abstract int showOpenDialog(Component parent);
/**
* 弹出文件选择器 保存文件
*
*/
public abstract int showSaveDialog(Component parent);
/**
* https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4031440
*
* 设置文件名后缀 起到文件过滤的作用 形如 "*.jpg;*.jpeg"
*
*/
public abstract void setExtensionFilter(String file);
}

10
designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java

@ -24,6 +24,7 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
public class JavaFxNativeFileChooser implements FileChooserProvider {
private static boolean showDialogState = false;
private File[] selectedFiles = new File[0];
private FileSelectionMode fileSelectionMode = FileSelectionMode.FILE;
private String title = Toolkit.i18nText("Fine-Design_Basic_Open");
@ -43,8 +44,17 @@ public class JavaFxNativeFileChooser implements FileChooserProvider {
return null;
}
public static boolean isShowDialogState() {
return showDialogState;
}
public static void setShowDialogState(boolean showDialogState) {
JavaFxNativeFileChooser.showDialogState = showDialogState;
}
@Override
public int showDialog(Component parent) {
setShowDialogState(true);
final CountDownLatch latch = new CountDownLatch(1);
PlatformImpl.startup(() -> {
});

155
designer-base/src/main/java/com/fr/design/gui/ifilechooser/UINativeFileChooser.java

@ -0,0 +1,155 @@
package com.fr.design.gui.ifilechooser;
import com.fr.design.gui.ifilechooser.AbstractFileChooser;
import com.fr.design.mainframe.DesignerContext;
import com.fr.stable.os.OperatingSystem;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.io.File;
import java.io.FilenameFilter;
/**
* 系统原生风格的文件选择器
*
* jdk问题
* https://bugs.openjdk.java.net/browse/JDK-4811090 不支持文件扩展选择
* https://stackoverflow.com/questions/40713398/filter-not-working-in-filedialog windows下 setFilenameFilter不work
*
* @author hades
* @version 10.0
* Created by hades on 2020/3/31
*/
@Deprecated
public class UINativeFileChooser extends AbstractFileChooser<FileFilter, Integer> {
private final FileDialog fileDialog;
private FileFilter fileFilter;
private int selectionMode;
public UINativeFileChooser(File file) {
fileDialog = new FileDialog(DesignerContext.getDesignerFrame());
if (file != null) {
fileDialog.setDirectory(file.getAbsolutePath());
fileDialog.setFile(file.toString());
}
}
public UINativeFileChooser() {
this(null);
}
@Override
public File getCurrentDirectory() {
return new File(fileDialog.getDirectory());
}
@Override
public FileFilter getFileFilter() {
return fileFilter;
}
@Override
public File getSelectedFile() {
return new File(fileDialog.getDirectory() + fileDialog.getFile());
}
@Override
public File[] getSelectedFiles() {
return fileDialog.getFiles();
}
@Override
public boolean isMultiSelectionEnabled() {
return fileDialog.isMultipleMode();
}
@Override
public void setCurrentDirectory(File f) {
fileDialog.setDirectory(f.toString());
}
@Override
public void setDialogTitle(String title) {
fileDialog.setTitle(title);
}
@Override
public void setFileFilter(final FileFilter cff) {
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File Directory, String fileName) {
return cff.accept(new File(Directory.getAbsolutePath() + fileName));
}
};
fileDialog.setFilenameFilter(filter);
fileFilter = cff;
}
@Override
public void setFileSelectionMode(Integer selectionMode) {
this.selectionMode = selectionMode;
}
@Override
public void setMultiSelectionEnabled(boolean multiple) {
fileDialog.setMultipleMode(multiple);
}
@Override
public void setSelectedFile(File file) {
fileDialog.setDirectory(file.getAbsolutePath());
fileDialog.setFile(file.getName());
}
@Override
public int showOpenDialog(Component parent) {
boolean appleProperty = OperatingSystem.isMacos() && selectionMode == JFileChooser.DIRECTORIES_ONLY;
if (appleProperty) {
System.setProperty("apple.awt.fileDialogForDirectories", "true");
}
try {
fileDialog.setLocale(JComponent.getDefaultLocale());
fileDialog.setMode(FileDialog.LOAD);
fileDialog.setVisible(true);
return fileDialog.getFile() == null ? JFileChooser.CANCEL_OPTION : JFileChooser.APPROVE_OPTION;
} finally {
if (appleProperty) {
System.setProperty("apple.awt.fileDialogForDirectories", "false");
}
}
}
@Override
public int showSaveDialog(Component parent) {
fileDialog.setLocale(JComponent.getDefaultLocale());
fileDialog.setMode(FileDialog.SAVE);
fileDialog.setVisible(true);
return fileDialog.getFile() == null ? JFileChooser.CANCEL_OPTION : JFileChooser.APPROVE_OPTION;
}
@Override
public void setExtensionFilter(String file) {
fileDialog.setFile(file);
}
/**
* 确认本地文件选择器是否支持选择模式
* @param selectionMode 选择模式
* @return 是否支持选择模式
*/
public static boolean supportsSelectionMode(int selectionMode) {
switch (selectionMode) {
case JFileChooser.FILES_AND_DIRECTORIES:
return false;
case JFileChooser.DIRECTORIES_ONLY:
return OperatingSystem.isMacos();
case JFileChooser.FILES_ONLY:
default:
return true;
}
}
}

20
designer-base/src/main/java/com/fr/design/gui/style/AbstractBorderPackerPane.java

@ -0,0 +1,20 @@
package com.fr.design.gui.style;
import com.fr.design.dialog.BasicPane;
import com.fr.general.act.BorderPacker;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/11
*/
public abstract class AbstractBorderPackerPane extends BasicPane {
public abstract void populateBean(BorderPacker style);
public abstract void updateBean(BorderPacker style);
@Override
protected String title4PopupWindow() {
return null;
}
}

99
designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java

@ -0,0 +1,99 @@
package com.fr.design.gui.style;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.BasicScrollPane;
import com.fr.design.gui.frpane.UIPercentDragPane;
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.mainframe.backgroundpane.GradientBackgroundQuickPane;
import com.fr.general.Background;
import com.fr.general.act.BackgroundPacker;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/11
*/
public abstract class AbstractTranslucentBackgroundSpecialPane<T extends BackgroundPacker> extends BasicPane {
private final int uiLabelWidth;
private final int uiSettingWidth;
// 背景名称:如主题背景 或 标题背景
private final String backgroundName;
// 背景
protected BackgroundSpecialPane backgroundPane = new LayoutBackgroundSpecialPane();
// 背景透明度
protected UIPercentDragPane opacityPane = new UIPercentDragPane();
public AbstractTranslucentBackgroundSpecialPane(int uiLabelWidth, int uiSettingWidth, String backgroundName) {
this.uiLabelWidth = uiLabelWidth;
this.uiSettingWidth = uiSettingWidth;
this.backgroundName = backgroundName;
this.initializePane();
}
private void initializePane() {
setLayout(new BorderLayout(0, 0));
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f};
// 确保BackgroundSpecialPane高度变化时,Label依然保持与其顶部对齐
JPanel backgroundLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
backgroundLabelPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0));
backgroundLabelPane.add(new UILabel(backgroundName), BorderLayout.NORTH);
JPanel backgroundComposedPane = TableLayoutHelper.createGapTableLayoutPane(
new JComponent[][]{
{backgroundLabelPane, backgroundPane}
},
new double[]{p}, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1);
JPanel opacityComposedPane = TableLayoutHelper.createGapTableLayoutPane(
new JComponent[][]{
{new UILabel(""), new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Alpha"))},
{new UILabel(""), opacityPane}
},
new double[]{p, p}, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1);
opacityComposedPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0));
opacityComposedPane.setVisible(false);
backgroundPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
Background background = backgroundPane.update();
opacityComposedPane.setVisible(background != null);
}
});
add(backgroundComposedPane, BorderLayout.NORTH, 0);
add(opacityComposedPane, BorderLayout.CENTER, 1);
}
@Override
protected String title4PopupWindow() {
return null;
}
public abstract void populateBean(T style);
public abstract void updateBean(T style);
protected static class LayoutBackgroundSpecialPane extends BackgroundSpecialPane {
@Override
protected GradientBackgroundQuickPane createGradientBackgroundQuickPane() {
return new GradientBackgroundQuickPane(140);
}
}
}

8
designer-base/src/main/java/com/fr/design/gui/style/BorderPane.java

@ -95,8 +95,14 @@ public class BorderPane extends AbstractBasicStylePane implements GlobalNameObse
borderPanel = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Border"), 280, 24, panel);
this.add(borderPanel, BorderLayout.NORTH);
UILabel backgroundFillLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Background_Fill"));
backgroundFillLabel.setPreferredSize(new Dimension(60, 20));
backgroundPane = new BackgroundPane();
backgroundPanel = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background"), 280, 24, backgroundPane);
JPanel backgroundContainPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{backgroundFillLabel, backgroundPane}},
TableLayoutHelper.FILL_LASTCOLUMN, LayoutConstants.VGAP_SMALL, LayoutConstants.VGAP_MEDIUM);
backgroundPanel = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background"), 280, 24, backgroundContainPane);
this.add(backgroundPanel, BorderLayout.CENTER);
initAllNames();
outerToggleButton.addChangeListener(outerToggleButtonChangeListener);

33
designer-base/src/main/java/com/fr/design/gui/style/ComponentBodyStylePane.java

@ -0,0 +1,33 @@
package com.fr.design.gui.style;
import com.fr.general.act.BorderPacker;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/11
*/
public class ComponentBodyStylePane extends AbstractTranslucentBackgroundSpecialPane<BorderPacker> {
public ComponentBodyStylePane(int uiLabelWidth) {
this(uiLabelWidth, -1);
}
public ComponentBodyStylePane(int uiLabelWidth, int uiSettingWidth) {
super(uiLabelWidth, uiSettingWidth, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Fill"));
}
@Override
public void populateBean(BorderPacker style) {
this.backgroundPane.populateBean(style.getBackground());
if (this.opacityPane != null) {
this.opacityPane.populateBean(style.getAlpha());
}
}
@Override
public void updateBean(BorderPacker style) {
style.setBackground(backgroundPane.update());
style.setAlpha((float)opacityPane.updateBean());
}
}

109
designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java

@ -0,0 +1,109 @@
package com.fr.design.gui.style;
import com.fr.design.designer.IntervalConstants;
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.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.general.act.BorderPacker;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.BorderLayout;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/11
*/
public class ComponentIntegralStylePane extends AbstractBorderPackerPane {
public static final String[] BORDER_STYLE = new String[]{
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Common"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Shadow")
};
//渲染风格:有无阴影
protected UIComboBox borderStyleCombo;
// 含图片类型边框的边框配置面板(图片类型边框 + 阴影时存在默认的阴影颜色)
protected TranslucentBorderSpecialPane borderPane;
//边框圆角或圆角裁剪
protected UISpinner cornerSpinner;
private final int uiLabelWidth;
private final int uiSettingWidth;
private final boolean supportBorderImage;
private final boolean supportCornerRadius;
public ComponentIntegralStylePane(int uiLabelWidth,
boolean supportBorderImage, boolean supportCornerRadius) {
this(uiLabelWidth, -1, supportBorderImage, supportCornerRadius);
}
public ComponentIntegralStylePane(int uiLabelWidth, int uiSettingWidth) {
this(uiLabelWidth, uiSettingWidth, true, true);
}
public ComponentIntegralStylePane(
int uiLabelWidth, int uiSettingWidth,
boolean supportBorderImage, boolean supportCornerRadius) {
this.uiLabelWidth = uiLabelWidth;
this.uiSettingWidth = uiSettingWidth;
this.supportBorderImage = supportBorderImage;
this.supportCornerRadius = supportCornerRadius;
this.initializePane();
}
private void initializeComponents() {
borderStyleCombo = new UIComboBox(BORDER_STYLE);
borderPane = new TranslucentBorderSpecialPane(this.supportBorderImage);
cornerSpinner = new UISpinner(0,1000,1,0);
}
protected void initializePane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
this.initializeComponents();
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = supportCornerRadius ? new double[] {p, p, p} : new double[]{p, p};
double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f};
JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Render_Style")), borderStyleCombo},
{this.borderPane, null},
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Radius")), cornerSpinner},
},
rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1);
this.add(content, BorderLayout.NORTH);
}
@Override
public void populateBean(BorderPacker style) {
if (this.borderStyleCombo != null) {
this.borderStyleCombo.setSelectedIndex(style.getBorderStyle());
}
if (cornerSpinner != null) {
this.cornerSpinner.setValue(style.getBorderRadius());
}
if (this.borderPane != null) {
this.borderPane.populateBean(style);
}
}
@Override
public void updateBean(BorderPacker style) {
if (borderStyleCombo != null) {
style.setBorderStyle(borderStyleCombo.getSelectedIndex());
}
if (cornerSpinner != null) {
style.setBorderRadius((int) cornerSpinner.getValue());
}
if (borderPane != null) {
borderPane.updateBean(style);
}
}
}

348
designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java

@ -0,0 +1,348 @@
package com.fr.design.gui.style;
import com.fr.base.Utils;
import com.fr.base.svg.IconUtils;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.formula.TinyFormulaPane;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UIToggleButton;
import com.fr.design.gui.icheckbox.UICheckBox;
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.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.WidgetTitle;
import com.fr.general.FRFont;
import com.fr.general.IOUtils;
import com.fr.general.act.BorderPacker;
import com.fr.general.act.TitlePacker;
import com.fr.stable.Constants;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/11
*/
public class ComponentTitleStylePane extends AbstractBorderPackerPane {
private static final Dimension BUTTON_SIZE = new Dimension(20, 20);
public static final TitlePacker DEFAULT_TITLE_PACKER = new WidgetTitle();
// 标题可见
protected UICheckBox visibleCheckbox;
//标题文字内容
protected TinyFormulaPane textContentPane;
//标题字体格式
protected UIComboBox fontFamilyComboBox;
//标题字体大小
protected UIComboBox fontSizeComboBox;
//标题字体颜色
protected UIColorButton fontColorSelectPane;
//标题字体特殊效果:粗体、斜体、下划线
private UIToggleButton fontBoldButton;
private UIToggleButton fontItalicButton;
private UIToggleButton fontUnderlineButton;
// 标题图文混排
protected TextInsetImageBackgroundSpecialPane insetImagePane;
//对齐方式
protected UIButtonGroup alignPane;
//标题整体背景
protected TitleTranslucentBackgroundSpecialPane backgroundPane;
// 是否支持用户编辑这些属性(不支持时: 设置面板总是不可见)
private boolean isSupportTitleVisible = true;
private boolean isSupportTitleContent = true;
private boolean isSupportTitleOtherSetting = true;
// 用于控制各部分设置的可见性
private JPanel titleVisiblePane;
private JPanel titleContentPane;
private JPanel titleOtherSettingPane;
private final int uiLabelWidth;
private final int uiSettingWidth;
public ComponentTitleStylePane(int uiLabelWidth) {
this(uiLabelWidth, -1);
}
public ComponentTitleStylePane(
int uiLabelWidth, int uiSettingWidth) {
this.uiLabelWidth = uiLabelWidth;
this.uiSettingWidth = uiSettingWidth;
this.initializePane();
}
private void initializeComponents() {
visibleCheckbox = new UICheckBox();
textContentPane = new TinyFormulaPane();
fontFamilyComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
FRFont frFont = DEFAULT_TITLE_PACKER.getFrFont();
if (frFont != null) {
String fontFamily = frFont.getFamily();
// 使用style中默认的字体初始化titleFontFamilyComboBox,保证UI和数据的一致性
this.fontFamilyComboBox.setSelectedItem(fontFamily);
}
fontFamilyComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Family"));
fontSizeComboBox = new UIComboBox(FRFontPane.FONT_SIZES);
fontSizeComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Size"));
fontColorSelectPane = new UIColorButton();
fontColorSelectPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Foreground"));
fontColorSelectPane.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Foreground"));
fontBoldButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png"));
fontBoldButton.setPreferredSize(BUTTON_SIZE);
fontBoldButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Bold"));
fontBoldButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Bold"));
fontItalicButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png"));
fontItalicButton.setPreferredSize(BUTTON_SIZE);
fontItalicButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Italic"));
fontItalicButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Italic"));
fontUnderlineButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/underline.png"));
fontUnderlineButton.setPreferredSize(BUTTON_SIZE);
fontUnderlineButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline"));
fontUnderlineButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline"));
insetImagePane = new TextInsetImageBackgroundSpecialPane();
alignPane = new UIButtonGroup<>(
new Icon[]{
IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_left_normal.png"),
IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_center_normal.png"),
IconUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_right_normal.png")
},
new Integer[]{Constants.LEFT, Constants.CENTER, Constants.RIGHT});
alignPane.setAllToolTips(
new String[] {
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Left"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Center"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Right")
});
alignPane.setSelectedItem(DEFAULT_TITLE_PACKER.getPosition());
backgroundPane = new TitleTranslucentBackgroundSpecialPane(this.uiLabelWidth, this.uiSettingWidth);
}
private void initializePane() {
this.setLayout(new BorderLayout(0, 0));
this.initializeComponents();
titleVisiblePane = this.createTitleVisiblePane();
titleContentPane = this.createTitleContentPane();
titleOtherSettingPane = this.createTitleOtherSettingPane();
if (isSupportTitleVisible) {
titleVisiblePane.setVisible(true);
}
if (isSupportTitleVisible) {
titleContentPane.setVisible(false);
}
if (isSupportTitleVisible) {
titleOtherSettingPane.setVisible(false);
}
addComponents(titleVisiblePane, titleContentPane, titleOtherSettingPane);
}
private JPanel createTitleVisiblePane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
visibleCheckbox.setSelected(false);
container.add(visibleCheckbox, BorderLayout.WEST);
container.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Visible")), BorderLayout.CENTER);
visibleCheckbox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
boolean visible = visibleCheckbox.isSelected();
if (titleContentPane != null) {
titleContentPane.setVisible(visible && isSupportTitleContent);
}
if (titleOtherSettingPane != null) {
titleOtherSettingPane.setVisible(visible && isSupportTitleOtherSetting);
}
}
});
return container;
}
private JPanel createTitleContentPane() {
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p};
double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f};
return TableLayoutHelper.createCommonTableLayoutPane(
new JComponent[][]{{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Content")), textContentPane}},
rowSize, columnSize, IntervalConstants.INTERVAL_L1);
}
private JPanel createTitleOtherSettingPane() {
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p, p, p, p, p};
double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f};
JComponent[][] components = new JComponent[][]{
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Format")), fontFamilyComboBox},
{null, createTitleFontButtonPane()},
{insetImagePane, null},
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Text_Align")), alignPane},
{backgroundPane, null}
};
return TableLayoutHelper.createCommonTableLayoutPane(components, rowSize, columnSize, IntervalConstants.INTERVAL_L1);
}
protected JPanel createTitleFontButtonPane(){
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p};
double[] columnSize = {f, p, p, p, p};
JPanel buttonPane = TableLayoutHelper.createCommonTableLayoutPane( new JComponent[][] {
{fontSizeComboBox, fontColorSelectPane, fontItalicButton, fontBoldButton, fontUnderlineButton},
}, rowSize, columnSize, IntervalConstants.INTERVAL_W0);
JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
containerPane.add(buttonPane, BorderLayout.NORTH);
return containerPane;
}
@Override
public void populateBean(BorderPacker style) {
TitlePacker widgetTitle = style == null ? new WidgetTitle() : style.getTitle();
widgetTitle = widgetTitle == null ? new WidgetTitle() : widgetTitle;
boolean titleVisible = style != null && style.getType() != LayoutBorderStyle.STANDARD;
visibleCheckbox.setSelected(isSupportTitleVisible && titleVisible);
titleContentPane.setVisible(isSupportTitleContent && titleVisible);
titleOtherSettingPane.setVisible(isSupportTitleOtherSetting && titleVisible);
this.textContentPane.populateBean(widgetTitle.getTextObject().toString());
FRFont frFont = widgetTitle.getFrFont();
this.fontSizeComboBox.setSelectedItem(frFont.getSize());
this.fontFamilyComboBox.setSelectedItem(frFont.getFamily());
this.fontColorSelectPane.setColor(frFont.getForeground());
this.fontColorSelectPane.repaint();
fontBoldButton.setSelected(frFont.isBold());
fontItalicButton.setSelected(frFont.isItalic());
int line = frFont.getUnderline();
if (line == Constants.LINE_NONE) {
fontUnderlineButton.setSelected(false);
} else {
fontUnderlineButton.setSelected(true);
}
alignPane.setSelectedItem(widgetTitle.getPosition());
insetImagePane.populateBean(widgetTitle);
backgroundPane.populateBean(widgetTitle);
}
@Override
public void updateBean(BorderPacker style) {
style.setType(visibleCheckbox != null && visibleCheckbox.isSelected() ? LayoutBorderStyle.TITLE : LayoutBorderStyle.STANDARD);
TitlePacker title = style.getTitle() == null ? new WidgetTitle() : style.getTitle();
title.setTextObject(textContentPane.updateBean());
FRFont frFont = title.getFrFont();
frFont = frFont.applySize((Integer) fontSizeComboBox.getSelectedItem());
frFont = frFont.applyName(fontFamilyComboBox.getSelectedItem().toString());
frFont = frFont.applyForeground(fontColorSelectPane.getColor());
frFont = updateTitleFontItalicBold(frFont);
int line = fontUnderlineButton.isSelected() ? Constants.LINE_THIN : Constants.LINE_NONE;
frFont = frFont.applyUnderline(line);
title.setFrFont(frFont);
title.setPosition((Integer) alignPane.getSelectedItem());
insetImagePane.updateBean(title);
backgroundPane.updateBean(title);
style.setTitle(title);
}
private FRFont updateTitleFontItalicBold(FRFont frFont) {
int italic_bold = frFont.getStyle();
boolean isItalic = italic_bold == Font.ITALIC || italic_bold == (Font.BOLD + Font.ITALIC);
boolean isBold = italic_bold == Font.BOLD || italic_bold == (Font.BOLD + Font.ITALIC);
if (fontItalicButton.isSelected() && !isItalic) {
italic_bold += Font.ITALIC;
} else if (!fontItalicButton.isSelected() && isItalic) {
italic_bold -= Font.ITALIC;
}
frFont = frFont.applyStyle(italic_bold);
if (fontBoldButton.isSelected() && !isBold) {
italic_bold += Font.BOLD;
} else if (!fontBoldButton.isSelected() && isBold) {
italic_bold -= Font.BOLD;
}
frFont = frFont.applyStyle(italic_bold);
return frFont;
}
private void addComponents(JComponent... components) {
if (components == null) {
return;
}
JPanel container = this;
for (JComponent component: components) {
if (component != null) {
container.add(component, BorderLayout.NORTH);
JPanel nextContainer = new JPanel(FRGUIPaneFactory.createBorderLayout());
component.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0));
container.add(nextContainer, BorderLayout.CENTER);
container = nextContainer;
}
}
}
public void setSupportTitleVisible(boolean supporting) {
isSupportTitleVisible = supporting;
if (titleVisiblePane != null) {
titleVisiblePane.setVisible(supporting);
}
}
public void setSupportTitleContent(boolean supporting) {
isSupportTitleContent = supporting;
if (titleContentPane != null) {
boolean titleVisible = visibleCheckbox.isSelected();
if (isSupportTitleContent) {
titleContentPane.setVisible(titleVisible);
} else {
titleContentPane.setVisible(false);
}
}
}
public void setSupportOtherSetting(boolean supporting) {
isSupportTitleOtherSetting = supporting;
if (titleOtherSettingPane != null) {
boolean titleVisible = visibleCheckbox.isSelected();
if (isSupportTitleOtherSetting) {
titleOtherSettingPane.setVisible(titleVisible);
} else {
titleOtherSettingPane.setVisible(false);
}
}
}
}

138
designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java

@ -0,0 +1,138 @@
package com.fr.design.gui.style;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.dialog.BasicPane;
import com.fr.design.event.GlobalNameListener;
import com.fr.design.event.GlobalNameObserver;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ibutton.UIButtonGroup;
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 com.fr.design.mainframe.JTemplate;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/19
*/
public class FollowingThemePane extends BasicPane implements UIObserver {
public static final int SETTING_LABEL_WIDTH = 60;
public static final String[] FOLLOWING_THEME_STRING_ARRAYS = new String[]{
Toolkit.i18nText("Fine-Design_Style_Follow_Theme"),
Toolkit.i18nText("Fine-Design_Style_Not_Follow_Theme"),
};
private final UIButtonGroup<String> followingThemeButtonGroup;
private final List<FollowingThemeActionChangeListener> changeListeners = new ArrayList<>();
private UIObserverListener uiObserverListener;
private JPanel container;
public FollowingThemePane(String name) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
followingThemeButtonGroup = new UIButtonGroup<>(FOLLOWING_THEME_STRING_ARRAYS);
followingThemeButtonGroup.setSelectedIndex(1);
followingThemeButtonGroup.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (FollowingThemeActionChangeListener changeListener : changeListeners) {
changeListener.onFollowingTheme(isFollowingTheme());
}
invalidate();
// 与主题相关的属性面板更新完毕后,再通知外层更新数据
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
}
});
UILabel followingThemeLabel = new UILabel(name);
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
JPanel followingThemePane =
TableLayoutHelper.createGapTableLayoutPane( new Component[][]{new Component[] { followingThemeLabel, followingThemeButtonGroup}},
new double[] { p }, new double[] { SETTING_LABEL_WIDTH, f }, 10, 0);
followingThemePane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
followingThemePane.setVisible(false);
add(followingThemePane, BorderLayout.NORTH);
container = FRGUIPaneFactory.createBorderLayout_S_Pane();
add(container, BorderLayout.CENTER);
}
public void addFollowThemePane(JPanel content, FollowingThemeActionChangeListener changeListener) {
if (content != null) {
container.add(content, BorderLayout.NORTH);
changeListeners.add(changeListener);
JPanel nextContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(nextContainer, BorderLayout.CENTER);
container = nextContainer;
}
}
@Override
protected String title4PopupWindow() {
return null;
}
@Override
public void registerChangeListener(UIObserverListener uiObserverListener) {
this.uiObserverListener = uiObserverListener;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
public interface FollowingThemeActionChangeListener {
void onFollowingTheme(boolean following);
}
public TemplateTheme getUsingTheme() {
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (template != null) {
return template.getTemplateTheme();
}
return null;
}
public void supportFollowingTheme(boolean supporting) {
getComponent(0).setVisible(supporting);
if (!supporting) {
setFollowingTheme(false);
}
}
public void setFollowingTheme(boolean following) {
followingThemeButtonGroup.setSelectedIndex(following ? 0 : 1);
for (FollowingThemeActionChangeListener changeListener : changeListeners) {
changeListener.onFollowingTheme(isFollowingTheme());
}
}
public boolean isFollowingTheme() {
return followingThemeButtonGroup.getSelectedIndex() == 0;
}
}

102
designer-base/src/main/java/com/fr/design/gui/style/ReportBackgroundSpecialPane.java

@ -0,0 +1,102 @@
package com.fr.design.gui.style;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.event.UIObserverListener;
import com.fr.design.fun.BackgroundQuickUIProvider;
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 Starryi
* @version 1.0
* Created by Starryi on 2021/8/19
*/
public class ReportBackgroundSpecialPane extends BackgroundPane {
public ReportBackgroundSpecialPane(){
super();
}
@Override
protected BackgroundQuickPane[] supportKindsOfBackgroundUI() {
NullBackgroundQuickPane nullBackgroundPane = new NullBackgroundQuickPane();
ColorBackgroundQuickPane colorBackgroundPane = new ColorBackgroundQuickPane();
colorBackgroundPane.registerChangeListener(new UIObserverListener() {
@Override
public void doChange() {
fireStateChanged();
}
});
ImageBackgroundQuickPane imageBackgroundPane = new ImageBackgroundQuickPane();
imageBackgroundPane.registerChangeListener(new UIObserverListener() {
@Override
public void doChange() {
fireStateChanged();
}
});
GradientBackgroundQuickPane gradientBackgroundPane = createGradientBackgroundQuickPane();
gradientBackgroundPane.registerChangeListener(new UIObserverListener() {
@Override
public void doChange() {
fireStateChanged();
}
});
TextureBackgroundQuickPane textureBackgroundPane = new TextureBackgroundQuickPane();
textureBackgroundPane.registerChangeListener(new UIObserverListener() {
@Override
public void doChange() {
fireStateChanged();
}
});
PatternBackgroundQuickPane patternBackgroundPane = new PatternBackgroundQuickPane();
patternBackgroundPane.registerChangeListener(new UIObserverListener() {
@Override
public void doChange() {
fireStateChanged();
}
});
List<BackgroundQuickPane> kinds = new ArrayList<BackgroundQuickPane>();
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(new UIObserverListener() {
@Override
public void doChange() {
fireStateChanged();
}
});
kinds.add(newTypePane);
}
return kinds.toArray(new BackgroundQuickPane[kinds.size()]);
}
protected GradientBackgroundQuickPane createGradientBackgroundQuickPane() {
// 使用默认的150宽度构建渐变条
return new GradientBackgroundQuickPane();
}
}

24
designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java → designer-base/src/main/java/com/fr/design/gui/style/TextInsetImageBackgroundSpecialPane.java

@ -1,4 +1,4 @@
package com.fr.design.gui.xpane;
package com.fr.design.gui.style;
import com.fr.base.Style;
import com.fr.base.background.ImageBackground;
@ -18,7 +18,6 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.backgroundpane.ImagePreviewPane;
import com.fr.design.style.background.image.ImageFileChooser;
import com.fr.design.widget.ui.designer.component.UIBoundSpinner;
import com.fr.form.ui.WidgetTitle;
import com.fr.general.Background;
import com.fr.general.IOUtils;
@ -26,11 +25,20 @@ import com.fr.general.ImageWithSuffix;
import com.fr.general.act.TitlePacker;
import com.fr.stable.Constants;
import javax.swing.*;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
@ -42,8 +50,8 @@ import java.awt.geom.RoundRectangle2D;
* @version 10.0.18
* Created by Starryi on 2021/7/3
*/
public class TitleInsetImagePane extends JPanel implements UIObserver {
private final int SETTING_LABEL_WIDTH = LayoutStylePane.SETTING_LABEL_WIDTH;
public class TextInsetImageBackgroundSpecialPane extends JPanel implements UIObserver {
private final int SETTING_LABEL_WIDTH = 60;
private final int DELETE_BUTTON_SIZE = 24;
private final int IMAGE_PREVIEW_SIZE = 145;
private final Color IMAGE_PREVIEW_OVERLAY_COLOR = new Color(255, 255, 255, 51);
@ -62,7 +70,7 @@ public class TitleInsetImagePane extends JPanel implements UIObserver {
private ImageFileChooser imageFileChooser;
public TitleInsetImagePane() {
public TextInsetImageBackgroundSpecialPane() {
this.initComponents();
this.initLayout();
}
@ -198,7 +206,7 @@ public class TitleInsetImagePane extends JPanel implements UIObserver {
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Inset_Relative_Right_Tooltip"),
});
imagePaddingPane = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, WidgetTitle.DEFAULT_INSET_PADDING);
imagePaddingPane = new UISpinner(0, Integer.MAX_VALUE, 1, WidgetTitle.DEFAULT_INSET_PADDING);
imagePaddingPane.setValue(DEFAULT_INSET_PADDING);
}

27
designer-base/src/main/java/com/fr/design/gui/style/TitleTranslucentBackgroundSpecialPane.java

@ -0,0 +1,27 @@
package com.fr.design.gui.style;
import com.fr.general.act.TitlePacker;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/11
*/
public class TitleTranslucentBackgroundSpecialPane extends AbstractTranslucentBackgroundSpecialPane<TitlePacker> {
public TitleTranslucentBackgroundSpecialPane(int uiLabelWidth, int uiSettingWidth) {
super(uiLabelWidth, uiSettingWidth, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Background"));
}
@Override
public void populateBean(TitlePacker style) {
backgroundPane.populateBean(style.getBackground());
opacityPane.populateBean(style.getBackgroundOpacity());
}
@Override
public void updateBean(TitlePacker style) {
style.setBackground(backgroundPane.update());
style.setBackgroundOpacity((float)opacityPane.updateBean());
}
}

45
designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java → designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java

@ -1,8 +1,6 @@
package com.fr.design.gui.xpane;
package com.fr.design.gui.style;
import com.fr.base.GraphHelper;
import com.fr.base.Style;
import com.fr.base.Utils;
import com.fr.base.background.ImageBackground;
import com.fr.base.background.ImageFileBackground;
import com.fr.design.border.UIRoundedBorder;
@ -16,8 +14,6 @@ import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.frpane.ImgChooseWrapper;
import com.fr.design.gui.frpane.UIPercentDragPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIButtonUI;
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.layout.FRGUIPaneFactory;
@ -28,9 +24,9 @@ import com.fr.design.mainframe.backgroundpane.ImagePreviewPane;
import com.fr.design.style.background.image.ImageFileChooser;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.env.utils.DesignerInteractionHistory;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.general.Background;
import com.fr.general.IOUtils;
import com.fr.general.act.BorderPacker;
import com.fr.stable.Constants;
import com.fr.stable.GraphDrawHelper;
import com.fr.stable.ProjectLibrary;
@ -78,8 +74,8 @@ import java.util.Arrays;
*
* 可配置图片类型边框的样式设置面板
*/
public class BorderLineAndImagePane extends JPanel implements UIObserver {
private final int SETTING_LABEL_WIDTH = LayoutStylePane.SETTING_LABEL_WIDTH;
public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane implements UIObserver {
private final int SETTING_LABEL_WIDTH = 60;
private final Style DEFAULT_IMAGE_LAYOUT_STYLE = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_DEFAULT);
private final String TWEAK_NINE_POINT_HELP_URL = "https://help.fanruan.com/finereport/doc-view-4135.html";
@ -98,7 +94,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver {
private int[] ninePoint = new int[] {-1, -1, -1, -1};
public BorderLineAndImagePane(boolean supportBorderImage) {
public TranslucentBorderSpecialPane(boolean supportBorderImage) {
this.initComponents(supportBorderImage);
this.initLayout();
}
@ -273,7 +269,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver {
if (imagePreviewPane.getImage() != null) {
tweakPane.previewPane.setNinePoint(ninePoint);
BasicDialog dialog = tweakPane.showWindow(SwingUtilities.getWindowAncestor(BorderLineAndImagePane.this));
BasicDialog dialog = tweakPane.showWindow(SwingUtilities.getWindowAncestor(TranslucentBorderSpecialPane.this));
dialog.addDialogActionListener(new DialogActionAdapter() {
@Override
public void doOk() {
@ -287,7 +283,13 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver {
});
}
public void populateBean(LayoutBorderStyle style) {
@Override
protected String title4PopupWindow() {
return null;
}
@Override
public void populateBean(BorderPacker style) {
int borderLine = style.getBorder();
Color borderColor = style.getColor();
@ -333,7 +335,8 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver {
this.borderColorPane.setSelectObject(style.getColor());
}
public void updateBean(LayoutBorderStyle style) {
@Override
public void updateBean(BorderPacker style) {
style.setBorder(this.borderLineCombo.getSelectedLineStyle());
style.setColor(this.borderColorPane.getSelectObject());
@ -366,24 +369,6 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver {
return true;
}
protected UIButtonUI createButtonUI(final UIColorButton uiColorButton) {
return new UIButtonUI() {
public void paint(Graphics g, JComponent c) {
UIButton b = (UIButton) c;
g.setColor(Color.black);
GraphHelper.draw(g, new RoundRectangle2D.Double(1, 1, b.getWidth() - 2, b.getHeight() - 2, 0, 0), 1);
if (b.getModel().isEnabled()) {
g.setColor(uiColorButton.getColor());
} else {
g.setColor(new Color(Utils.filterRGB(uiColorButton.getColor().getRGB(), 50)));
}
g.fillRect(2, 2, b.getWidth() - 3, b.getHeight() - 3);
}
};
}
protected static class BorderLineAndImageComboBox extends LineComboBox {
public static final int LINE_PICTURE = -1;
public final static int[] BORDER_LINE_AND_IMAGE_STYLE_ARRAY = new int[] {

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

@ -117,7 +117,9 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
private JPanel initParamsPane() {
extendParametersCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Hyperlink_Extends_Report_Parameters"));
extendParametersCheckBox.setSelected(true);
parameterViewPane = new ReportletParameterViewPane(getChartParaType(), getValueEditorPane(), getValueEditorPane());
parameterViewPane.setVisible(false);
parameterViewPane.addTableEditorListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
List<ParameterProvider> list = parameterViewPane.update();
@ -158,6 +160,7 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
customNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Custom"));
addRadioToGroup(fileNameRadioGroup, defaultNameRadio, customNameRadio);
fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula"));
fileNameFormulaEditor.setEnabled(false);
fileNameRadioGroup.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -220,10 +223,8 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
@Override
public void actionPerformed(ActionEvent e) {
if (currentTemplateRadio.isSelected()) {
reportPathTextField.setEnabled(false);
browserButton.setEnabled(false);
} else {
reportPathTextField.setEnabled(true);
browserButton.setEnabled(true);
}
}
@ -234,11 +235,13 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
JPanel reportletNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
// 路径输入框
reportPathTextField = new UITextField(20);
reportPathTextField.setEnabled(false);
reportletNamePane.add(reportPathTextField, BorderLayout.CENTER);
// 选择路径按钮
browserButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Select"));
browserButton.setPreferredSize(new Dimension(browserButton.getPreferredSize().width, 20));
browserButton.setEnabled(false);
reportletNamePane.add(browserButton, BorderLayout.EAST);
browserButton.addActionListener(new ActionListener() {
@Override
@ -272,10 +275,8 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane<ExportJavaScript
}
this.templateRadioGroup.selectIndexButton(ob.isCurrentTemplate() ? 0 : 1);
if (ob.isCurrentTemplate()) {
this.reportPathTextField.setEnabled(false);
this.browserButton.setEnabled(false);
} else {
this.reportPathTextField.setEnabled(true);
this.browserButton.setEnabled(true);
this.reportPathTextField.setText(ob.getTemplatePath());
}

13
designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java

@ -47,12 +47,12 @@ public class FRGUIPaneFactory {
}
/**
* 创建一个靠左的布局上下间隔为0左右间隔为常量
* 创建一个靠左的布局上下间隔为0左右间隔为常量首间隔为0
*
* @return FlowLayout对象
*/
public static LayoutManager createLeftZeroVgapNormalHgapLayout() {
return new FlowLayout(FlowLayout.LEFT, 5, 0);
return new FRLeftFlowLayout(0, 5, 0);
}
@ -591,6 +591,15 @@ public class FRGUIPaneFactory {
return jp;
}
public static JPanel createBorderLayout_NO_Opaque_Pane() {
JPanel jp = new JPanel();
jp.setOpaque(false);
jp.setBackground(null);
jp.setLayout(FRGUIPaneFactory.createBorderLayout());
return jp;
}
/**
* 创建卡片式布局
*

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

@ -135,6 +135,8 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
//用于判断设计器是否打开了
private boolean designerOpened = false;
private boolean serverConfig = false;
private int contentWidth = (int) (java.awt.Toolkit.getDefaultToolkit().getScreenSize().getWidth());
private int contentHeight = (int) (java.awt.Toolkit.getDefaultToolkit().getScreenSize().getHeight());
@ -879,8 +881,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
basePane.add(east, BorderLayout.EAST);
}
layeredPane.repaint();
layeredPane.revalidate();
jTemplate.setComposite();
}
/**
@ -1176,4 +1177,19 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
return designerOpened;
}
/**
* 判断是否正在进行服务器配置
* @return boolean
*/
public boolean isServerConfig() {
return serverConfig;
}
/**
* 设置是否正在进行服务器配置
* @param serverConfig
*/
public void setServerConfig(boolean serverConfig) {
this.serverConfig = serverConfig;
}
}

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

@ -6,7 +6,12 @@ import com.fr.base.extension.FileExtension;
import com.fr.base.io.BaseBook;
import com.fr.base.iofile.attr.DesignBanCopyAttrMark;
import com.fr.base.iofile.attr.TemplateIdAttrMark;
import com.fr.base.iofile.attr.TemplateThemeAttrMark;
import com.fr.base.theme.TemplateThemeCompatible;
import com.fr.base.theme.ThemedTemplate;
import com.fr.base.vcs.DesignerMode;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignState;
import com.fr.design.DesignerEnvManager;
@ -60,6 +65,7 @@ import com.fr.file.MemFILE;
import com.fr.form.ui.NoneWidget;
import com.fr.form.ui.Widget;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContext;
import com.fr.plugin.context.PluginRuntime;
@ -85,22 +91,27 @@ import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
import javax.swing.undo.UndoManager;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.util.Set;
import java.util.concurrent.Callable;
/**
* 报表设计和表单设计的编辑区域(设计器编辑的IO文件)
*/
public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>> extends TargetComponent<T> implements ToolBarMenuDockPlus, DesignerProxy, JTemplateSave, TabChangeListener {
public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>> extends TargetComponent<T> implements ToolBarMenuDockPlus, DesignerProxy, JTemplateSave, TabChangeListener, ThemedTemplate {
// TODO ALEX_SEP editingFILE这个属性一定要吗?如果非要不可,有没有可能保证不为null
private static final int PREDEFINED_ICON_WIDTH = 27;
private static final int PREFIX_NUM = 3000;
protected FILE editingFILE = null;
// alex:初始状态为saved,这样不管是新建模板,还是打开模板,如果未做任何操作直接关闭,不提示保存
private boolean saved = true;
private boolean authoritySaved = true;
private UIButton templateThemeButton;
private UndoManager undoMananger;
private UndoManager authorityUndoManager;
protected U undoState;
@ -134,9 +145,12 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
private final String runtimeId = UUID.randomUUID().toString();
private PluginEventListener pluginListener;
// 监听全局主题数据更新
private TemplateThemeConfig.ThemeConfigChangeListener themeConfigChangeListener;
public JTemplate() {
initAndStartPlugin();
startListenThemeConfig();
}
public JTemplate(T t, String defaultFileName) {
@ -178,6 +192,11 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
this.undoState = createUndoState();
initAndStartPlugin();
if (isNewFile) {
setUpTheme4NewTemplate();
}
startListenThemeConfig();
}
private void initAndStartPlugin() {
@ -207,6 +226,35 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
PluginListenerRegistration.getInstance().listen(PluginEventType.AfterRun, this.pluginListener, filter);
}
private void startListenThemeConfig() {
if (themeConfigChangeListener == null) {
themeConfigChangeListener = new TemplateThemeConfig.ThemeConfigChangeListener() {
@Override
public void onThemeConfigChanged(TemplateThemeConfig.ThemeConfigEvent event) {
TemplateTheme usingTheme = getTemplateTheme();
boolean isUsingThemeChanged = StringUtils.equals(event.themName, usingTheme.getName());
if (isUsingThemeChanged && (event.action == TemplateThemeConfig.ThemeConfigAction.REMOVE ||
event.action == TemplateThemeConfig.ThemeConfigAction.UPDATE)) {
checkAndResetTheme();
}
}
};
TemplateThemeConfig<? extends TemplateTheme> config = getUsingTemplateThemeConfig();
if (config != null) {
config.addThemeConfigChangeListener(themeConfigChangeListener);
}
}
}
private void stopListenThemeConfig() {
if (themeConfigChangeListener != null) {
TemplateThemeConfig<? extends TemplateTheme> config = getUsingTemplateThemeConfig();
if (config != null) {
config.addThemeConfigChangeListener(themeConfigChangeListener);
}
}
}
private void initPluginPane() {
ExtraDesignClassManager classManager = PluginModule.getAgent(PluginModule.ExtraDesign);
@ -370,6 +418,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public void whenClose() {
// stop的时候 pluginListener 和 PluginFilter 都会移除
PluginListenerRegistration.getInstance().stopListen(this.pluginListener);
stopListenThemeConfig();
}
@ -565,6 +614,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
*/
public void undo() {
this.getUndoManager().undo();
// 撤销前模版使用主题可能已经被删除或修改,需要重置模版样式
checkAndResetTheme();
fireSuperTargetModified();
}
@ -573,7 +624,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
*/
public void redo() {
this.getUndoManager().redo();
// 重做前模版使用主题可能已经被删除或修改,需要重置模版样式
checkAndResetTheme();
fireSuperTargetModified();
}
@ -625,6 +677,14 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
super.fireTargetModified();
}
public void fireTargetModified(boolean shouldCreateNewUndoState) {
if (shouldCreateNewUndoState) {
fireTargetModified();
} else {
super.fireTargetModified();
}
}
protected abstract U createUndoState();
protected abstract void applyUndoState(U u);
@ -1352,6 +1412,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
for (DesignerFrameUpButtonProvider provider : providers) {
uiButtons = ArrayUtils.addAll(uiButtons, provider.getUpButtons(getMenuState()));
}
templateThemeButton = createTemplateThemeButton();
uiButtons = ArrayUtils.addAll(uiButtons, templateThemeButton);
return uiButtons;
}
@ -1360,6 +1422,23 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
return new UIButton[]{new CheckButton()};
}
protected UIButton createTemplateThemeButton() {
UIButton button = new UIButton(IOUtils.readIcon("/com/fr/design/icon/icon_predefined_style.png")) {
@Override
public Dimension getPreferredSize() {
FontMetrics metrics = getFontMetrics(getFont());
int width = Math.min(metrics.stringWidth(getText()) + PREDEFINED_ICON_WIDTH, 100);
return new Dimension(width, 20);
}
};
button.setToolTipText(getTemplateTheme().getName());
button.setText(getTemplateTheme().getName());
button.setAlignmentX(SwingConstants.LEFT);
button.set4ToolbarButton();
button.setEnabled(true);
return button;
}
/**
* 由于老版本的模板没有模板ID当勾选使用参数模板时候就加一个模板ID attr
*
@ -1643,4 +1722,23 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public String getRuntimeId() {
return runtimeId;
}
protected void setUpTheme4NewTemplate() {
TemplateTheme theme = getUsingTemplateThemeConfig().cachedFetchTheme4NewTemplate();
TemplateThemeAttrMark themeAttrMark = template.getAttrMark(TemplateThemeAttrMark.XML_TAG);
if (themeAttrMark == null) {
themeAttrMark = new TemplateThemeAttrMark();
template.addAttrMark(themeAttrMark);
}
themeAttrMark.setName(theme.getName());
themeAttrMark.setDark(theme.isDark());
}
@Override
public void setTemplateTheme(TemplateTheme newTheme, TemplateThemeCompatible compatible) {
ThemedTemplate.super.setTemplateTheme(newTheme, compatible);
String name = newTheme.getName();
templateThemeButton.setText(name);
templateThemeButton.setToolTipText(name);
}
}

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

@ -53,6 +53,9 @@ public class JTemplateNameHelper {
* @Date 2021/4/9 11:13
**/
private static Integer getFileNameIndex(String prefix, String fileName) {
if (fileName.length() <= prefix.length()) {
return null;
}
char[] chars = new char[fileName.length()];
int i = 0;
for (; i < fileName.length(); i++) {

23
designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ColorBackgroundQuickPane.java

@ -3,12 +3,8 @@ package com.fr.design.mainframe.backgroundpane;
import com.fr.base.background.ColorBackground;
import com.fr.design.event.UIObserverListener;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.style.color.NewColorSelectPane;
import com.fr.design.style.color.NewColorSelectBox;
import com.fr.general.Background;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Color;
@ -18,13 +14,13 @@ import java.awt.Color;
*/
public class ColorBackgroundQuickPane extends BackgroundQuickPane {
private NewColorSelectPane detailColorSelectPane;
private NewColorSelectBox colorSelectBox;
public ColorBackgroundQuickPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
detailColorSelectPane = new NewColorSelectPane();
this.add(detailColorSelectPane, BorderLayout.NORTH);
colorSelectBox = new NewColorSelectBox(100);
this.add(colorSelectBox, BorderLayout.NORTH);
}
public void populateBean(Background background) {
@ -37,12 +33,11 @@ public class ColorBackgroundQuickPane extends BackgroundQuickPane {
}
public void populateColor(Color color) {
this.detailColorSelectPane.setColor(color);
this.colorSelectBox.setSelectObject(color);
}
public Color updateColor() {
this.detailColorSelectPane.updateUsedColor();
return this.detailColorSelectPane.getNotNoneColor();
return this.colorSelectBox.getSelectObject();
}
/**
@ -52,7 +47,7 @@ public class ColorBackgroundQuickPane extends BackgroundQuickPane {
*/
@Override
public void registerChangeListener(final UIObserverListener listener) {
detailColorSelectPane.addChangeListener(new ChangeListenerImpl(listener));
this.colorSelectBox.addSelectChangeListener(new ChangeListenerImpl(listener));
}
@Override
@ -78,6 +73,6 @@ public class ColorBackgroundQuickPane extends BackgroundQuickPane {
@Override
public void reset() {
this.detailColorSelectPane.setColor(null);
this.colorSelectBox.setSelectObject(null);
}
}

5
designer-base/src/main/java/com/fr/design/mainframe/loghandler/LogMessageBar.java

@ -48,6 +48,7 @@ public class LogMessageBar extends JPanel {
public void mouseClicked(MouseEvent e) {
if (dlg != null && dlg.isVisible()) {
dlg.setExtendedState(JFrame.NORMAL);
dlg.requestFocus();
return;
}
dlg = new LogDetailPane().showDialog();
@ -87,4 +88,8 @@ public class LogMessageBar extends JPanel {
}
THIS = null;
}
public JFrame getLogFrame() {
return dlg;
}
}

8
designer-base/src/main/java/com/fr/design/mainframe/predefined/ui/detail/ColorFillStylePane.java

@ -15,7 +15,7 @@ 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.background.gradient.FixedGradientBar;
import com.fr.design.style.background.gradient.FixedGradientBarNoTheme;
import com.fr.design.style.color.ColorAdjustPane;
import com.fr.stable.StringUtils;
@ -40,7 +40,7 @@ public class ColorFillStylePane extends BasicBeanPane<ColorFillStyle> {
private ColorSchemeComboBox styleSelectBox;
private JPanel customPane;
private JPanel changeColorSetPane;
private FixedGradientBar colorGradient;
private FixedGradientBarNoTheme colorGradient;
private CardLayout cardLayout;
@ -69,8 +69,8 @@ public class ColorFillStylePane extends BasicBeanPane<ColorFillStyle> {
};
changeColorSetPane = new JPanel(cardLayout = new CardLayout());
changeColorSetPane.add(colorGradient = new FixedGradientBar(4, 130), "gradient");
gradientColors = new Color[]{Color.WHITE, FixedGradientBar.NEW_CHARACTER};
changeColorSetPane.add(colorGradient = new FixedGradientBarNoTheme(4, 130), "gradient");
gradientColors = new Color[]{Color.WHITE, FixedGradientBarNoTheme.NEW_CHARACTER};
changeColorSetPane.add(colorAdjustPane = new ColorAdjustPane(), "acc");
accColors = ColorAdjustPane.DEFAULT_COLORS;
cardLayout.show(changeColorSetPane, "acc");

53
designer-base/src/main/java/com/fr/design/mainframe/predefined/ui/detail/background/ColorDetailPane.java

@ -3,20 +3,10 @@ package com.fr.design.mainframe.predefined.ui.detail.background;
import com.fr.base.background.ColorBackground;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.style.color.ColorSelectPane;
import com.fr.design.style.color.NewColorSelectPane;
import com.fr.general.Background;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
/**
* Created by kerry on 2020-08-31
@ -50,48 +40,9 @@ public class ColorDetailPane extends AbstractBackgroundDetailPane<ColorBackgroun
return background instanceof ColorBackground;
}
class ColorBackgroundSelectPane extends ColorSelectPane implements UIObserver {
class ColorBackgroundSelectPane extends NewColorSelectPane implements UIObserver {
protected UIObserverListener uiObserverListener;
protected void initialCompents(boolean isSupportTransparent) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createEmptyBorder());
if (isSupportTransparent) {
this.add(createNorthPane(), BorderLayout.NORTH);
}
JPanel centerPane = createCenterPane();
this.add(centerPane, BorderLayout.CENTER);
this.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
}
});
}
private JPanel createNorthPane() {
// UIButton transpanrentBtn = createTranspanrentButton();
UIButton transpanrentBtn = new UIButton();
transpanrentBtn.setPreferredSize(new Dimension(160, 20));
JPanel jPanel = TableLayoutHelper.createGapTableLayoutPane(
new Component[][]{new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background_Color")),
transpanrentBtn}}, TableLayoutHelper.FILL_NONE, 33, 5);
jPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 10));
return jPanel;
}
protected JPanel createCenterPane() {
// JPanel centerPane = super.createCenterPane();
JPanel centerPane = new JPanel();
JPanel jPanel = TableLayoutHelper.createGapTableLayoutPane(
new Component[][]{new Component[]{new UILabel(" "), centerPane}}, TableLayoutHelper.FILL_NONE, 33, 5);
jPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 10));
return jPanel;
}
@Override
public void registerChangeListener(UIObserverListener listener) {
this.uiObserverListener = listener;

13
designer-base/src/main/java/com/fr/design/mainframe/predefined/ui/preview/ChartPreStylePreView.java

@ -4,17 +4,14 @@ import com.fr.base.chart.BaseChartCollection;
import com.fr.base.chart.BaseChartPainter;
import com.fr.base.chart.chartdata.CallbackEvent;
import com.fr.base.chart.result.WebChartIDInfo;
import com.fr.chart.base.ChartPreStyleProvider;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.config.predefined.PredefinedStyle;
import com.fr.design.gui.chart.MiddleChartComponent;
import com.fr.general.Background;
import com.fr.plugin.chart.vanchart.VanChart;
import com.fr.script.Calculator;
import com.fr.stable.core.PropertyChangeListener;
import javax.swing.BorderFactory;
import java.util.List;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
@ -79,13 +76,13 @@ public class ChartPreStylePreView extends MiddleChartComponent {
}
public void refresh(PredefinedStyle style) {
VanChart vanChart = chartCollection.getSelectedChartProvider(VanChart.class);
List<ChartPreStyleProvider> chartPreStyleProviders = vanChart.getChartPreStyleProvider();
for (ChartPreStyleProvider chartPreStyleProvider : chartPreStyleProviders) {
chartPreStyleProvider.updatePreDefinedStyle(style);
/*VanChart vanChart = chartCollection.getSelectedChartProvider(VanChart.class);
List<ChartThemeStyleProvider> chartThemeStyleProviders = vanChart.getChartPreStyleProvider();
for (ChartThemeStyleProvider chartThemeStyleProvider : chartThemeStyleProviders) {
chartThemeStyleProvider.updateThemeStyle(style);
}
componentBackground = style.getComponentStyle().getBorderStyle().getBackground();
vanChart.attrChange();
vanChart.attrChange();*/
}
@Override

81
designer-base/src/main/java/com/fr/design/mainframe/theme/AsyncThemeFetcher.java

@ -0,0 +1,81 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.module.ModuleContext;
import javax.swing.SwingUtilities;
import java.util.concurrent.ExecutorService;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/24
*/
public class AsyncThemeFetcher<T extends TemplateTheme> {
private final ExecutorService executorService;
private final TemplateThemeConfig<T> config;
public AsyncThemeFetcher(int threads, TemplateThemeConfig<T> config) {
this.executorService = ModuleContext.getExecutor().newFixedThreadPool(
threads,
new NamedThreadFactory(this.getClass().getName())
);
this.config = config;
}
public void shutdown() {
executorService.shutdown();
}
public boolean isShutdown() {
return executorService.isShutdown();
}
public void submit(String themeName, AsyncThemeFetchCallback<T> callback) {
if (callback != null) {
callback.beforeCachedFetch();
}
executorService.submit(new Runnable() {
@Override
public void run() {
if (executorService.isShutdown()) {
return;
}
T theme = config.cachedFetch(themeName);
if (executorService.isShutdown()) {
return;
}
if (callback != null) {
// 后续任务不要在工作线程中执行,从而确保只在EDT线程操作UI
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
callback.afterCachedFetch(theme);
}
});
}
}
});
}
public interface AsyncThemeFetchCallback<T extends TemplateTheme> {
void beforeCachedFetch();
void afterCachedFetch(T theme);
}
public static class AsyncThemeFetchCallbackAdapter<T extends TemplateTheme> implements AsyncThemeFetchCallback<T> {
@Override
public void beforeCachedFetch() {
}
@Override
public void afterCachedFetch(T theme) {
}
}
}

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

@ -0,0 +1,105 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.FineColorManager;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemedComponentStyle;
import com.fr.base.theme.settings.ThemedFormBodyStyle;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
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 javax.swing.JPanel;
import java.util.List;
import java.awt.Color;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class FormThemeProfilePane extends TemplateThemeProfilePane<FormTheme> {
public static final int LABEL_WIDTH = 60;
private FormBodyStyleEditPane formBodyStyleSettingPane;
private ComponentStyleEditPane componentStyleSettingPane;
public FormThemeProfilePane(TemplateThemeConfig<FormTheme> config) {
super(config);
}
@Override
public FormThemePreviewPane createThemePreviewPane() {
return new FormThemePreviewPane();
}
@Override
protected JPanel createCustomEditorsPane() {
JPanel container = super.createCustomEditorsPane();
formBodyStyleSettingPane = new FormBodyStyleEditPane();
addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane);
addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane());
addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane());
componentStyleSettingPane = new ComponentStyleEditPane();
addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane);
return container;
}
@Override
protected JPanel createChartStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
chartStyleSettingPane = new ChartStyleFormEditPane();
container.add(chartStyleSettingPane);
return container;
}
@Override
public void onColorSchemeChanged(List<Color> colors) {
super.onColorSchemeChanged(colors);
FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors);
ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean();
FineColorManager.traverse(formBodyStyle, replaceByColorScheme);
formBodyStyleSettingPane.populateBean(formBodyStyle);
ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean();
FineColorManager.traverse(componentStyle, replaceByColorScheme);
componentStyleSettingPane.populateBean(componentStyle);
}
@Override
public void populateBean(FormTheme theme) {
super.populateBean(theme);
isPopulating = true;
formBodyStyleSettingPane.populateBean(theme.getBodyStyle());
componentStyleSettingPane.populateBean(theme.getComponentStyle());
themePreviewPane.refresh(theme);
isPopulating = false;
}
@Override
public void updateBean(FormTheme theme) {
ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean();
theme.setBodyStyle(formBodyStyle);
ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean();
theme.setComponentStyle(componentStyle);
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title");
}
}

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

@ -0,0 +1,74 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.FineColorManager;
import com.fr.base.theme.ReportTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemedReportBodyStyle;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.theme.edit.ReportBodyStyleEditPane;
import com.fr.design.mainframe.theme.preview.ReportThemePreviewPane;
import javax.swing.JPanel;
import java.awt.Color;
import java.util.List;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class ReportThemeProfilePane extends TemplateThemeProfilePane<ReportTheme> {
private ReportBodyStyleEditPane reportBodyStyleSettingPane;
public ReportThemeProfilePane(TemplateThemeConfig<ReportTheme> config) {
super(config);
}
@Override
public ReportThemePreviewPane createThemePreviewPane() {
return new ReportThemePreviewPane();
}
@Override
protected JPanel createCustomEditorsPane() {
JPanel container = super.createCustomEditorsPane();
this.reportBodyStyleSettingPane = new ReportBodyStyleEditPane();
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Template_Background"), reportBodyStyleSettingPane);
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane());
addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane());
return container;
}
@Override
public void onColorSchemeChanged(List<Color> colors) {
super.onColorSchemeChanged(colors);
FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors);
ThemedReportBodyStyle bodyStyle = reportBodyStyleSettingPane.updateBean();
FineColorManager.traverse(bodyStyle, replaceByColorScheme);
reportBodyStyleSettingPane.populateBean(bodyStyle);
}
@Override
public void populateBean(ReportTheme theme) {
super.populateBean(theme);
isPopulating = true;
reportBodyStyleSettingPane.populateBean(theme.getBodyStyle());
themePreviewPane.refresh(theme);
isPopulating = false;
}
@Override
public void updateBean(ReportTheme theme) {
theme.setBodyStyle(this.reportBodyStyleSettingPane.updateBean());
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Report_Theme_Profile_Dialog_Title");
}
}

259
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java

@ -0,0 +1,259 @@
package com.fr.design.mainframe.theme;
import com.fr.base.GraphHelper;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemeThumbnail;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog;
import com.fr.general.IOUtils;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeBlock<T extends TemplateTheme> extends JPanel {
public static final int HEIGHT = 150;
public static final int THUMBNAIL_HEIGHT = 125;
private static final Color HOVERING_BORDER_COLOR = new Color(65, 155, 249);
private final String name;
private final TemplateThemeConfig<T> config;
private T theme;
private final TemplateThemeProfilePane<T> profilePane;
private final Icon theme4currentTemplateMarkIcon = IOUtils.readIcon("/com/fr/design/form/images/theme4currentTemplate.png");
private final Icon theme4NewTemplateMarkIcon= IOUtils.readIcon("/com/fr/design/form/images/theme4newTemplate.png");
private final Icon profileIcon = IOUtils.readIcon("/com/fr/design/icon/icon_edit.png");
private final boolean displayTheme4NewTemplateMarker;
private final ThumbnailPane thumbnailPane;
// UIButton会影响Block的手势监听,这里使用UILabel代替,点击事件也有Block代为处理
private UILabel profileButton;
private boolean selected = false;
private boolean hovering = false;
private MouseAdapter clickListener;
public TemplateThemeBlock(String name,
boolean displayTheme4NewTemplateMarker,
TemplateThemeConfig<T> config,
TemplateThemeProfilePane<T> profilePane) {
this.name = name;
this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker;
this.config = config;
this.profilePane = profilePane;
this.thumbnailPane = new ThumbnailPane();
initializePane();
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (clickListener != null) {
clickListener.mouseClicked(e);
}
if (profileButton != null && profilePane != null) {
delegateProfileButtonClick(e);
}
}
@Override
public void mouseEntered(MouseEvent e) {
hovering = true;
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
hovering = false;
repaint();
}
});
}
private void initializePane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
setPreferredSize(new Dimension(getPreferredSize().width, HEIGHT));
setBackground(Color.WHITE);
thumbnailPane.setBackground(Color.WHITE);
thumbnailPane.setPreferredSize(new Dimension(getPreferredSize().width, THUMBNAIL_HEIGHT));
JPanel infoPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
infoPane.setBackground(Color.WHITE);
infoPane.setBorder(BorderFactory.createEmptyBorder(0, IntervalConstants.INTERVAL_L7,0,IntervalConstants.INTERVAL_L7));
UILabel titleLabel = new UILabel(name);
titleLabel.setToolTipText(name);
infoPane.add(titleLabel, BorderLayout.CENTER);
if (profilePane != null) {
addProfileButton(infoPane);
}
add(thumbnailPane, BorderLayout.CENTER);
add(infoPane, BorderLayout.SOUTH);
}
public void setTheme(T theme) {
this.theme = theme;
Image image = null;
if (theme != null) {
ThemeThumbnail thumbnail = theme.getThumbnail();
if (thumbnail != null) {
image = thumbnail.getImage();
}
}
thumbnailPane.setThumbnail(image);
}
public T getTheme() {
return this.theme;
}
public void setSelected(boolean selected) {
this.selected = selected;
repaint();
}
public void addClickListener(MouseAdapter clickListener) {
this.clickListener = clickListener;
}
private void addProfileButton(JPanel panel) {
profileButton = new UILabel(profileIcon);
profileButton.setPreferredSize(new Dimension(24, 24));
panel.add(profileButton, BorderLayout.EAST);
}
private void delegateProfileButtonClick(MouseEvent e) {
int x = e.getX();
int y = e.getY();
int profileButtonX = profileButton.getX();
int profileButtonY = thumbnailPane.getHeight() + profileButton.getY();
boolean inX = profileButtonX <= x && x <= profileButtonX + profileButton.getWidth();
boolean inY = profileButtonY <= y && y <= profileButtonY + profileButton.getHeight();
if (inX && inY) {
openProfileDialog();
}
}
private void openProfileDialog() {
if (theme == null) {
return;
}
Window parent = SwingUtilities.getWindowAncestor(TemplateThemeBlock.this);
TemplateThemeProfileDialog<T> profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane);
try {
profilePane.populateBean((T) theme.clone());
} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
profileDialog.setVisible(true);
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (template != null) {
TemplateThemeConfig<? extends TemplateTheme> templateUsingConfig = template.getUsingTemplateThemeConfig();
TemplateTheme templateTheme = template.getTemplateTheme();
if (templateUsingConfig == this.config && StringUtils.equals(templateTheme.getName(), name)) {
theme4currentTemplateMarkIcon.paintIcon(this, g, getWidth() - 25, 0);
}
}
if (displayTheme4NewTemplateMarker && StringUtils.equals(config.getThemeName4NewTemplate(), name)) {
theme4NewTemplateMarkIcon.paintIcon(this, g, 0, 0);
}
if (selected || this.hovering) {
g.setColor(HOVERING_BORDER_COLOR);
Rectangle rectangle = new Rectangle(1, 1, this.getWidth() - 2, this.getHeight() - 2);
GraphHelper.draw(g, rectangle, Constants.LINE_MEDIUM);
}
}
private static class ThumbnailPane extends JPanel {
private static final Image LOADING_IMAGE = Toolkit.getDefaultToolkit().createImage(ThumbnailPane.class.getResource("/com/fr/design/images/mainframe/loading.gif"));
private Image thumbnail = null;
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
Color oldColor = g2d.getColor();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(oldColor);
paintCenterImage(g2d, thumbnail != null ? thumbnail : LOADING_IMAGE);
}
private void paintCenterImage(Graphics2D g2d, Image image) {
if (image == null) {
return;
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int width = getWidth();
int height = getHeight();
int imgWidth = image.getWidth(null);
int imgHeight = image.getHeight(null);
if (width <= 0 || height <= 0 || imgWidth <= 0 || imgHeight <= 0) {
return;
}
float imgAspect = 1.0F * imgWidth / imgHeight;
if (1.0F * width / height > 1.0F * imgWidth / imgHeight) {
imgHeight = height;
imgWidth = (int) (1.0F * imgHeight * imgAspect);
} else {
imgWidth = width;
imgHeight = (int) (1.0F * imgWidth / imgAspect);
}
int x = (width - imgWidth) / 2;
int y = (height - imgHeight) / 2;
g2d.drawImage(image, x, y, imgWidth, imgHeight, null);
}
public void setThumbnail(Image thumbnail) {
this.thumbnail = thumbnail;
invalidate();
repaint();
}
}
}

242
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java

@ -0,0 +1,242 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.event.ChangeEvent;
import com.fr.design.event.ChangeListener;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeListPane<T extends TemplateTheme> extends BasicPane {
public static final int BLOCK_COUNT_ROW_LINE = 3;
public static final int BLOCK_GAP = IntervalConstants.INTERVAL_L1;
public static final int CONTENT_WIDTH = 630;
public static final int ASYNC_FETCH_THEME_THREAD_COUNT = 10;
private final AsyncThemeFetcher<T> asyncThemeFetcher;
private final boolean displayTheme4NewTemplateMarker;
protected final TemplateThemeConfig<T> config;
private final TemplateThemeProfilePane<T> profilePane;
private final JPanel contentListPane;
private final Map<String, TemplateThemeBlock<T>> blockCache = new HashMap<>();
private TemplateThemeBlock<T> selectedBlock;
private TemplateThemeBlock<T> block4newTemplate;
private TemplateThemeConfig.ThemeConfigChangeListener themeConfigChangeListener;
private ChangeListener changeListener;
public TemplateThemeListPane(boolean displayTheme4NewTemplateMarker, TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) {
this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker;
this.config = config;
this.profilePane = profilePane;
this.contentListPane = new JPanel();
this.asyncThemeFetcher = new AsyncThemeFetcher<>(ASYNC_FETCH_THEME_THREAD_COUNT, config);
initializePane();
}
private void initializePane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
setPreferredSize(new Dimension(CONTENT_WIDTH, getPreferredSize().height));
contentListPane.setBorder(BorderFactory.createEmptyBorder(BLOCK_GAP, 0, BLOCK_GAP, 0));
contentListPane.setLayout(new GridLayout(0, BLOCK_COUNT_ROW_LINE, BLOCK_GAP, BLOCK_GAP));
fillContentListPane();
JPanel wrapper = FRGUIPaneFactory.createBorderLayout_S_Pane();
wrapper.add(contentListPane, BorderLayout.NORTH);
UIScrollPane scrollPane = new UIScrollPane(wrapper);
scrollPane.setBorder(BorderFactory.createEmptyBorder());
add(scrollPane, BorderLayout.CENTER);
}
public void fillContentListPane() {
contentListPane.removeAll();
List<String> names = config.getThemeNames();
for (String name: names) {
if (config.contains(name)) {
TemplateThemeBlock<T> block = createCachedTemplateThemeBlock(name);
contentListPane.add(block);
if (StringUtils.equals(name, config.getThemeName4NewTemplate())) {
block4newTemplate = block;
}
}
}
}
private TemplateThemeBlock<T> createCachedTemplateThemeBlock(String name) {
TemplateThemeBlock<T> block = blockCache.get(name);
if (block == null) {
block = createNewTemplateThemeBlock(name);
blockCache.put(name, block);
}
return block;
}
private TemplateThemeBlock<T> createNewTemplateThemeBlock(String name) {
final TemplateThemeBlock<T> block = new TemplateThemeBlock<>(name, displayTheme4NewTemplateMarker, config, profilePane);
block.addClickListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
setSelectedBlock(block);
}
});
asyncThemeFetcher.submit(name, new AsyncThemeFetcher.AsyncThemeFetchCallbackAdapter<T>() {
@Override
public void beforeCachedFetch() {
super.beforeCachedFetch();
block.setTheme(null);
}
@Override
public void afterCachedFetch(T theme) {
super.afterCachedFetch(theme);
block.setTheme(theme);
}
});
return block;
}
public void setSelectedChangeListener(ChangeListener changeListener) {
this.changeListener = changeListener;
}
private void setSelectedBlock(TemplateThemeBlock<T> block) {
if (selectedBlock != null) {
selectedBlock.setSelected(false);
}
selectedBlock = block;
if (selectedBlock != null) {
selectedBlock.setSelected(true);
}
if (changeListener != null) {
changeListener.fireChanged(new ChangeEvent(this));
}
}
private void asyncFetchTheme(String themeName) {
asyncThemeFetcher.submit(themeName, new AsyncThemeListItemFetchCallback(themeName));
}
@Override
protected String title4PopupWindow() {
return null;
}
public T getSelectedTheme() {
return selectedBlock != null ? selectedBlock.getTheme() : null;
}
public void startListenThemeConfig() {
if (themeConfigChangeListener == null) {
themeConfigChangeListener = new TemplateThemeConfig.ThemeConfigChangeListener() {
@Override
public void onThemeConfigChanged(TemplateThemeConfig.ThemeConfigEvent event) {
String themeName = event.themName;
TemplateThemeBlock<T> existingBlock = blockCache.get(event.themName);
switch (event.action) {
case DEFAULT_THEME_4_NEW_TEMPLATE_UPDATE: {
if (block4newTemplate != null) {
block4newTemplate.repaint();
}
if (existingBlock != null) {
existingBlock.repaint();
}
block4newTemplate = existingBlock;
break;
}
case UPDATE: {
if (existingBlock != null) {
asyncFetchTheme(themeName);
}
break;
}
case REMOVE: {
if (existingBlock != null) {
contentListPane.remove(existingBlock);
if (existingBlock == selectedBlock) {
setSelectedBlock(null);
}
validate();
repaint();
blockCache.remove(event.themName);
}
break;
}
case ADD: {
if (existingBlock == null) {
// TODO 这里是否还能继续优化?
fillContentListPane();
asyncFetchTheme(themeName);
validate();
repaint();
}
break;
}
}
}
};
config.addThemeConfigChangeListener(themeConfigChangeListener);
}
}
public void stopListenThemeConfig() {
if (themeConfigChangeListener != null) {
config.removeThemeConfigChangeListener(themeConfigChangeListener);
themeConfigChangeListener = null;
}
}
public void stopAsyncFetchTheme() {
asyncThemeFetcher.shutdown();
}
private class AsyncThemeListItemFetchCallback extends AsyncThemeFetcher.AsyncThemeFetchCallbackAdapter<T> {
private final String themeName;
public AsyncThemeListItemFetchCallback(String themeName) {
this.themeName = themeName;
}
@Override
public void beforeCachedFetch() {
super.beforeCachedFetch();
TemplateThemeBlock<T> block = blockCache.get(themeName);
if (block != null) {
block.setTheme(null);
}
}
@Override
public void afterCachedFetch(T theme) {
super.afterCachedFetch(theme);
TemplateThemeBlock<T> block = blockCache.get(themeName);
if (block != null) {
block.setTheme(theme);
}
}
}
}

325
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java

@ -0,0 +1,325 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.FormThemeConfig;
import com.fr.base.theme.ReportTheme;
import com.fr.base.theme.ReportThemeConfig;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.event.ChangeEvent;
import com.fr.design.event.ChangeListener;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.icon.IconPathConstants;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog;
import com.fr.design.mainframe.theme.edit.CellStyleListEditPane;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.ToolBarDef;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeManagePane<T extends TemplateTheme> extends BasicPane {
private final RemoveThemeAction removeAction;
private final UIButton setTheme4NewTemplateButton;
private final TemplateThemeConfig<T> config;
private final TemplateThemeListPane<T> themeListPane;
private final TemplateThemeProfilePane<T> profilePane;
private final AsyncThemeFetcher<T> asyncThemeFetcher;
public static TemplateThemeManagePane<FormTheme> createFormThemesManagerPane() {
FormThemeConfig config = FormThemeConfig.getInstance();
FormThemeProfilePane editPane = new FormThemeProfilePane(config);
return new TemplateThemeManagePane<>(config, editPane);
}
public static TemplateThemeManagePane<ReportTheme> createReportThemesManagerPane() {
ReportThemeConfig config = ReportThemeConfig.getInstance();
ReportThemeProfilePane editPane = new ReportThemeProfilePane(config);
return new TemplateThemeManagePane<>(config, editPane);
}
public TemplateThemeManagePane(TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) {
this.config = config;
this.profilePane = profilePane;
this.themeListPane = new TemplateThemeListPane<>(true, config, profilePane);
this.removeAction = new RemoveThemeAction(false);
this.setTheme4NewTemplateButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Default_Setting"));
this.asyncThemeFetcher = new AsyncThemeFetcher<>(1, config);
initializePane();
}
public TemplateThemeConfig<T> getConfig() {
return config;
}
private void initializePane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
add(createActionsContainer(), BorderLayout.NORTH);
JPanel nextContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
add(nextContainer, BorderLayout.CENTER);
nextContainer.add(new JSeparator(), BorderLayout.NORTH);
themeListPane.setPreferredSize(new Dimension(themeListPane.getPreferredSize().width, 490));
themeListPane.setSelectedChangeListener(new ChangeListener() {
@Override
public void fireChanged(ChangeEvent event) {
resetEnableRemoveAction(themeListPane.getSelectedTheme(), removeAction);
resetEnableSetTheme4NewTemplateButton(themeListPane.getSelectedTheme(), setTheme4NewTemplateButton);
}
});
nextContainer.add(themeListPane, BorderLayout.CENTER);
resetEnableRemoveAction(themeListPane.getSelectedTheme(), removeAction);
resetEnableSetTheme4NewTemplateButton(themeListPane.getSelectedTheme(), setTheme4NewTemplateButton);
repaint();
}
private void resetEnableRemoveAction(T selectedTheme, RemoveThemeAction removeAction) {
if (selectedTheme == null) {
removeAction.setEnabled(false);
return;
}
String selectedThemeName = selectedTheme.getName();
if (StringUtils.isEmpty(selectedThemeName)) {
removeAction.setEnabled(false);
return;
}
removeAction.setEnabled(selectedTheme.isRemovable());
}
private void resetEnableSetTheme4NewTemplateButton(T selectedTheme, UIButton setTheme4NewTemplateButton) {
if (selectedTheme == null) {
setTheme4NewTemplateButton.setEnabled(false);
return;
}
String selectedThemeName = selectedTheme.getName();
if (StringUtils.isEmpty(selectedThemeName)) {
setTheme4NewTemplateButton.setEnabled(false);
return;
}
T currentTheme4NewTemplate = config.cachedFetchTheme4NewTemplate();
if (currentTheme4NewTemplate == null) {
setTheme4NewTemplateButton.setEnabled(true);
return;
}
String currentThemeName4NewTemplate = currentTheme4NewTemplate.getName();
if (StringUtils.isEmpty(currentThemeName4NewTemplate)) {
setTheme4NewTemplateButton.setEnabled(true);
return;
}
setTheme4NewTemplateButton.setEnabled(!StringUtils.equals(currentThemeName4NewTemplate, selectedTheme.getName()));
}
private JPanel createActionsContainer() {
JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane();
content.setPreferredSize(new Dimension(content.getPreferredSize().width, 20));
UIToolbar toolBar = ToolBarDef.createJToolBar();
toolBar.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
content.add(toolBar, BorderLayout.CENTER);
MenuDef addMenuDef = createAddMenuDef();
ToolBarDef toolbarDef = new ToolBarDef();
toolbarDef.addShortCut(addMenuDef, removeAction);
toolbarDef.updateToolBar(toolBar);
setTheme4NewTemplateButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
T theme = themeListPane.getSelectedTheme();
if (theme != null) {
config.setThemeName4NewTemplate(theme.getName(), new CallBackAdaptor() {
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
}
});
}
}
});
content.add(setTheme4NewTemplateButton, BorderLayout.EAST);
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
container.add(content, BorderLayout.CENTER);
container.setPreferredSize(new Dimension(container.getPreferredSize().width, 30));
return container;
}
private MenuDef createAddMenuDef() {
MenuDef menuDef = new MenuDef(Toolkit.i18nText("Fine-Design_Basic_Action_Add"));
menuDef.setIconPath(IconPathConstants.ADD_POPMENU_ICON_PATH);
menuDef.setRePaint(true);
menuDef.addShortCut(new AddThemeAction(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Create_Light_Theme"), config.getDefaultLightThemeName()));
menuDef.addShortCut(new AddThemeAction(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Create_Dark_Theme"), config.getDefaultDarkThemeName()));
return menuDef;
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title");
}
private class RemoveThemeAction extends UpdateAction {
public RemoveThemeAction(boolean initialEnabled) {
setEnabled(initialEnabled);
setName(Toolkit.i18nText("Fine-Design_Basic_Remove"));
setMnemonic('R');
setSmallIcon(IOUtils.readIcon(IconPathConstants.TD_REMOVE_ICON_PATH));
}
@Override
public void actionPerformed(ActionEvent e) {
T theme = TemplateThemeManagePane.this.themeListPane.getSelectedTheme();
if (theme == null) {
return;
}
int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this),
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Delete_Tip", theme.getName()),
Toolkit.i18nText("Fine-Design_Basic_Delete"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
config.removeTheme(theme.getName(), new CallBackAdaptor() {
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
}
});
}
}
}
private class AddThemeAction extends UpdateAction {
private final String prototypeThemeName;
public AddThemeAction(String name, String prototypeThemeName) {
setName(name);
setMnemonic('R');
this.prototypeThemeName = prototypeThemeName;
asyncThemeFetcher.submit(prototypeThemeName, null);
}
@Override
public void actionPerformed(ActionEvent e) {
asyncThemeFetcher.submit(prototypeThemeName, new AsyncThemeFetcher.AsyncThemeFetchCallbackAdapter<T>() {
@Override
public void afterCachedFetch(T theme) {
super.afterCachedFetch(theme);
createNewTheme(theme);
}
});
}
private void createNewTheme(T prototypeTheme) {
Window parent = SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this);
TemplateThemeProfileDialog<T> profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane);
try {
T theme = (T) prototypeTheme.clone();
theme.setName(StringUtils.EMPTY);
theme.setMutable(true);
theme.setRemovable(true);
profilePane.populateBean(theme);
profileDialog.setVisible(true);
} catch (CloneNotSupportedException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
}
}
public static class BottomLineBorder extends LineBorder {
private BottomLineBorder(Color color, int thickness) {
super(color, thickness);
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2d = (Graphics2D)g;
Color oldColor = g2d.getColor();
Stroke oldStroke = g2d.getStroke();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getLineColor());
g2d.setStroke(new BasicStroke(getThickness() * 2));
g2d.drawLine(0, height, width, height + getThickness() * 2);
g2d.setStroke(oldStroke);
g2d.setColor(oldColor);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
}
}
public void startListenThemeConfig() {
themeListPane.startListenThemeConfig();
}
public void stopListenThemeConfig() {
themeListPane.stopListenThemeConfig();
}
public void stopAsyncFetchTheme() {
asyncThemeFetcher.shutdown();
themeListPane.stopAsyncFetchTheme();
}
}

93
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java

@ -0,0 +1,93 @@
package com.fr.design.mainframe.theme;
import com.fr.base.chart.chartdata.CallbackEvent;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemeThumbnail;
import com.fr.design.mainframe.theme.preview.ThemePreviewed;
import com.fr.log.FineLoggerFactory;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public abstract class TemplateThemePreviewPane<T extends TemplateTheme> extends JPanel implements CallbackEvent, ThemePreviewed<T> {
private JPanel parent;
public void setParent(JPanel parent) {
this.parent = parent;
}
@Override
public void callback() {
if (parent != null) {
parent.repaint();
} else {
this.repaint();
}
}
protected Image createThumbnailImage() {
BufferedImage image = null;
int thumbnailWidth = ThemeThumbnail.WIDTH;
int thumbnailHeight = ThemeThumbnail.HEIGHT;
float thumbnailAspect = 1.0F * thumbnailWidth / thumbnailHeight;
int width = getWidth();
int height = getHeight();
float aspect = 1.0F * width / height;
if (thumbnailAspect > aspect) {
height = (int) (width / thumbnailAspect);
} else {
width = (int) (height * thumbnailAspect);
}
try {
// 使用TYPE_INT_RGB和new Color(255, 255, 255, 1)设置有透明背景buffer image,
// 使得创建出来的透明像素是(255, 255, 255, 1),而不是(0, 0, 0, 0)
// 这样不支持透明通道缩略图的旧设计器打开新设计器创建的模版时,就不会创建出拥有黑色背景的缩略图
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// 创建一个支持透明背景的buffer image
image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
g2d.dispose();
g2d = image.createGraphics();
g2d.fillRect(0, 0, width, height);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.clipRect(0, 0, width, height);
paint(g2d);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
if (image != null) {
return image.getScaledInstance(thumbnailWidth, thumbnailHeight, BufferedImage.SCALE_SMOOTH);
}
return null;
}
@Override
public void paintComponent(Graphics g) {
g.clearRect(0, 0, 517, 532);
paintBackground((Graphics2D) g);
}
protected abstract void paintBackground(Graphics2D g);
}

609
designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java

@ -0,0 +1,609 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.FineColorManager;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.settings.ThemeThumbnail;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.base.theme.settings.ThemedColorScheme;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane;
import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
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.theme.dialog.TemplateThemeProfileDialog;
import com.fr.design.mainframe.theme.edit.CellStyleListEditPane;
import com.fr.design.mainframe.theme.edit.ChartStyleEditPane;
import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane;
import com.fr.design.mainframe.theme.edit.ui.ColorListPane;
import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import com.fr.design.mainframe.theme.ui.BorderUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.transaction.CallBackAdaptor;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerFacade;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public abstract class TemplateThemeProfilePane<T extends TemplateTheme> extends AbstractAttrNoScrollPane {
public static final int TITLE_BORDER_FONT = 12;
public static final int LEFT_TITLE_PANE_WIDTH = 397;
public static final int LEFT_TITLE_PANE_HEIGHT = 532 + TITLE_BORDER_FONT / 2 + 10;
public static final int PREVIEW_PANE_WIDTH = LEFT_TITLE_PANE_WIDTH - 10;
public static final int PREVIEW_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT - TITLE_BORDER_FONT - 16;
public static final int RIGHT_PANE_WIDTH = 362;
public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT;
public static final int COLOR_SCHEME_TITLE_PANE_WIDTH = 298;
public static final int COLOR_SCHEME_TITLE_PANE_HEIGHT = 174 + TITLE_BORDER_FONT / 2;
protected TemplateThemePreviewPane<T> themePreviewPane;
protected UITextField nameTextField;
private UILabel nameErrorLabel;
protected ColorListPane colorListPane;
private ColorListExtendedPane colorListExtendedPane;
protected CellStyleListEditPane cellStyleSettingPane;
protected ChartStyleEditPane chartStyleSettingPane;
protected boolean isPopulating = false;
protected UITabbedPane uiTabbedPane;
private final TemplateThemeConfig<T> config;
private UIButton saveButton = new UIButton();
private UIButton saveAsButton = new UIButton();
private boolean currentIsNewTheme;
private T theme;
public TemplateThemeProfilePane(TemplateThemeConfig<T> config) {
this.config = config;
theme = config.createNewTheme();
}
@Override
protected JPanel createContentPane() {
JPanel container = new JPanel(new BorderLayout(5, 0));
container.add(createLeftPane(), BorderLayout.CENTER);
container.add(createRightPane(), BorderLayout.EAST);
addAttributeChangeListener(new AttributeChangeListener() {
@Override
public void attributeChange() {
if (!isPopulating) {
valueChangeAction();
}
}
});
return container;
}
@Override
protected void initContentPane() {
super.initContentPane();
if (leftContentPane != null) {
// 修正 AbstractAttrNoScrollPane 的默认行为
leftContentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6));
}
}
public void valueChangeAction() {
themePreviewPane.refresh(updateBean());
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Dialog_Title");
}
private JPanel createLeftPane() {
JPanel titleContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
titleContainer.setPreferredSize(new Dimension(LEFT_TITLE_PANE_WIDTH, LEFT_TITLE_PANE_HEIGHT));
titleContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Preview_Pane_Title"), TITLE_BORDER_FONT));
JPanel previewContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
previewContainer.setBorder(BorderFactory.createEmptyBorder(5, 4, 10, 4));
titleContainer.add(previewContainer, BorderLayout.CENTER);
themePreviewPane = createThemePreviewPane();
themePreviewPane.setPreferredSize(new Dimension(PREVIEW_PANE_WIDTH, PREVIEW_PANE_HEIGHT));
themePreviewPane.setPreferredSize(new Dimension(PREVIEW_PANE_WIDTH, PREVIEW_PANE_HEIGHT));
previewContainer.add(themePreviewPane, BorderLayout.CENTER);
return titleContainer;
}
private JPanel createRightPane() {
JPanel container = new JPanel(new BorderLayout(0, 12));
container.setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT));
JPanel nameEditPane = createNameEditPane();
container.add(nameEditPane, BorderLayout.NORTH);
JPanel settingPane = new JPanel(new BorderLayout(0, 10));
container.add(settingPane, BorderLayout.CENTER);
settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH);
settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER);
uiTabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
valueChangeAction();
}
});
return container;
}
private JPanel createNameEditPane() {
JPanel container = new JPanel(new BorderLayout(30, 0));
container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
container.add(LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), BorderLayout.WEST);
JPanel settingContainer = new JPanel(new BorderLayout(10, 0));
container.add(settingContainer, BorderLayout.CENTER);
nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED);
nameErrorLabel.setVisible(false);
nameTextField = new UITextField();
nameTextField.setEnabled(false);
nameTextField.setPreferredSize(new Dimension(165, 20));
nameTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, nameTextField, nameErrorLabel, saveButton);
}
}
@Override
public void removeUpdate(DocumentEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, nameTextField, nameErrorLabel, saveButton);
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
nameTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, nameTextField, nameErrorLabel, saveButton);
}
}
@Override
public void focusLost(FocusEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, nameTextField, nameErrorLabel, saveButton);
}
}
});
settingContainer.add(nameTextField, BorderLayout.WEST);
settingContainer.add(nameErrorLabel, BorderLayout.CENTER);
return container;
}
private JPanel createColorSchemeEditPane() {
colorListPane = new ColorListPane();
colorListExtendedPane = new ColorListExtendedPane();
JPanel extendedContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
colorListExtendedPane.setBackground(null);
colorListExtendedPane.setOpaque(false);
extendedContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
extendedContainer.setBackground(Color.WHITE);
extendedContainer.add(colorListExtendedPane);
double p = TableLayout.PREFERRED;
double[] rowSize = new double[]{p, p, p};
double[] columnSize = {p, p};
JPanel previewLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
previewLabelPane.add(LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Preview_Label")), BorderLayout.NORTH);
UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153));
tipLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListPane},
{null, tipLabel},
{previewLabelPane, extendedContainer},
},
rowSize, columnSize, 18, 7);
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel borderContainer = new JPanel(new BorderLayout());
borderContainer.setPreferredSize(new Dimension(COLOR_SCHEME_TITLE_PANE_WIDTH, COLOR_SCHEME_TITLE_PANE_HEIGHT));
borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title")));
borderContainer.add(content);
JPanel container = new JPanel(new BorderLayout());
container.add(borderContainer, BorderLayout.WEST);
colorListPane.addColorChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
List<Color> colors = colorListPane.update();
onColorSchemeChanged(colors);
}
});
return container;
}
protected JPanel createCustomEditorsPane() {
JPanel container = new JPanel(new BorderLayout());
container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title")));
uiTabbedPane = new UITabbedPane();
uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1));
container.add(uiTabbedPane, BorderLayout.NORTH);
return container;
}
public void addCustomEditorPane(String title, JComponent component) {
component.setPreferredSize(new Dimension(360, 260));
uiTabbedPane.addTab(title, component);
}
protected JPanel createCellStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
cellStyleSettingPane = new CellStyleListEditPane();
cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() {
@Override
public void attributeChange() {
valueChangeAction();
}
});
container.add(cellStyleSettingPane);
return container;
}
protected JPanel createChartStyleSettingPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
chartStyleSettingPane = new ChartStyleEditPane();
container.add(chartStyleSettingPane);
return container;
}
public abstract TemplateThemePreviewPane<T> createThemePreviewPane();
public void onColorSchemeChanged(List<Color> colors) {
colorListExtendedPane.populate(colors);
FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors);
ThemedCellStyleList cellStyle = cellStyleSettingPane.updateBean();
FineColorManager.traverse(cellStyle, replaceByColorScheme);
ThemedChartStyle themedChartStyle = chartStyleSettingPane.updateBean();
FineColorManager.traverse(themedChartStyle, replaceByColorScheme);
chartStyleSettingPane.populateBean(themedChartStyle);
chartStyleSettingPane.populateGradientBar(colors);
}
public void populateBean(T theme) {
try {
this.theme = (T) theme.clone();
} catch (CloneNotSupportedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
isPopulating = true;
String name = theme.getName();
currentIsNewTheme = config.cachedFetch(name) == null;
nameTextField.setText(name);
nameTextField.setEnabled(StringUtils.isEmpty(name));
if (saveButton != null) {
saveButton.setEnabled(theme.isMutable() && !currentIsNewTheme);
}
if (saveAsButton != null) {
saveAsButton.setEnabled(!currentIsNewTheme);
}
cellStyleSettingPane.populateBean(theme.getCellStyleList());
colorListPane.populate(theme.getColorScheme().getColors());
colorListExtendedPane.populate(colorListPane.update());
chartStyleSettingPane.populateBean(theme.getChartStyle());
themePreviewPane.refresh(theme);
isPopulating = false;
}
public T updateBean() {
if (theme == null) {
theme = config.createNewTheme();
}
theme.setName(this.nameTextField.getText());
Image thumbnailImage = themePreviewPane.createThumbnailImage();
if (thumbnailImage != null) {
ThemeThumbnail thumbnail = new ThemeThumbnail();
thumbnail.setImage(thumbnailImage);
theme.setThumbnail(thumbnail);
}
ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean();
theme.setCellStyleList(cellStyleConfig);
ThemedColorScheme colorScheme = theme.getColorScheme();
colorScheme.setColors(this.colorListPane.update());
theme.setColorScheme(colorScheme);
theme.setChartStyle(this.chartStyleSettingPane.updateBean());
updateBean(theme);
return theme;
}
public List<Color> getCurrentColorScheme() {
return colorListPane.update();
}
protected abstract void updateBean(T theme);
public UIButton createSaveButton() {
saveButton = new UIButton();
saveButton.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Save"));
saveButton.setEnabled(false);
saveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
T theme = updateBean();
boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, nameTextField, nameErrorLabel, saveButton);
if (canBeSaved && theme != null) {
theme.setName(nameTextField.getText());
config.addTheme(theme, true, new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
currentIsNewTheme = false;
nameTextField.setEnabled(false);
saveAsButton.setEnabled(true);
}
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
}
});
}
}
});
return saveButton;
}
public UIButton createSaveAsButton(final TemplateThemeProfileDialog<T> profileDialog) {
saveAsButton = new UIButton();
saveAsButton.removeAll();
saveAsButton.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Save_As"));
saveAsButton.setEnabled(false);
saveAsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new SaveAsDialog(profileDialog).setVisible(true);
}
});
return saveAsButton;
}
private class SaveAsDialog extends JDialog {
private final TemplateThemeProfileDialog<T> parent;
private UITextField nameTextField;
private UILabel nameErrorLabel;
private UIButton confirmButton;
public SaveAsDialog(TemplateThemeProfileDialog<T> dialog) {
super(dialog, ModalityType.APPLICATION_MODAL);
setTitle(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Save_As_Dialog_Title"));
setResizable(false);
setSize(new Dimension(300, 140));
GUICoreUtils.centerWindow(this);
parent = dialog;
initializeComponents();
add(createContentPane(), BorderLayout.CENTER);
add(createActionsContainer(), BorderLayout.SOUTH);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
exit();
}
});
}
private void initializeComponents() {
nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED);
nameErrorLabel.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 0));
confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm"));
confirmButton.setEnabled(false);
confirmButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
saveAsNew(nameTextField.getText());
}
});
nameTextField = new UITextField();
nameTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(true, nameTextField, nameErrorLabel, confirmButton);
}
}
@Override
public void removeUpdate(DocumentEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(true, nameTextField, nameErrorLabel, confirmButton);
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
nameTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(true, nameTextField, nameErrorLabel, confirmButton);
}
}
@Override
public void focusLost(FocusEvent e) {
if (isEnabled()) {
checkThemeCanBeSavedAndUpdateUI(true, nameTextField, nameErrorLabel, confirmButton);
}
}
});
nameTextField.setPreferredSize(new Dimension(180, 20));
}
private JPanel createActionsContainer() {
UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel"));
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exit();
}
});
JPanel container = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane();
container.add(confirmButton);
container.add(cancelButton);
return container;
}
private JPanel createContentPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel nameTextPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(20, 5);
nameTextPane.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
nameTextPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Save_As_Pane_Name_Label")));
nameTextPane.add(nameTextField);
container.add(nameTextPane, BorderLayout.CENTER);
container.add(nameErrorLabel, BorderLayout.SOUTH);
return container;
}
private void saveAsNew(String name) {
T newThemeObject = null;
try {
newThemeObject = (T) updateBean().clone();
} catch (CloneNotSupportedException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
return;
}
boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(true, nameTextField, nameErrorLabel, confirmButton);
if (canBeSaved && newThemeObject != null) {
newThemeObject.setName(name);
newThemeObject.setRemovable(true);
newThemeObject.setMutable(true);
config.addTheme(newThemeObject, true, new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
exit();
parent.exit();
}
@Override
public void afterRollback() {
super.afterRollback();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this),
i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"),
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
}
});
}
}
public void exit() {
this.dispose();
}
}
private boolean isThemeNameEmpty(String name) {
return StringUtils.isEmpty(name);
}
private boolean isThemeNameDuplicated(String name) {
return config.cachedFetch(name) != null;
}
private boolean checkThemeCanBeSavedAndUpdateUI(boolean checkDuplicated, UITextField textField, UILabel errorLabel, UIButton... actionButtons) {
String error = StringUtils.EMPTY;
String name = textField.getText();
if (isThemeNameEmpty(name)) {
error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip");
} else if (checkDuplicated && isThemeNameDuplicated(name)) {
error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip");
}
errorLabel.setText(error);
boolean valid = StringUtils.isEmpty(error);
errorLabel.setVisible(!valid);
if (actionButtons != null && actionButtons.length > 0) {
for (UIButton button : actionButtons) {
if (button != null) {
button.setEnabled(valid);
}
}
}
return valid;
}
}

101
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java

@ -0,0 +1,101 @@
package com.fr.design.mainframe.theme.dialog;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/16
*/
public abstract class TemplateThemeDialog extends JDialog {
public static final int DIALOG_TITLE_HEIGHT = 28;
public static final int DIALOG_BOTTOM_ACTION_BAR_HEIGHT = 30;
public static final int DIALOG_BOTTOM_ACTION_BUTTON_GAP = 10;
public static final int DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT = 20;
public TemplateThemeDialog(Window parent, String title, int contentWidth, int contentHeight) {
super(parent, ModalityType.APPLICATION_MODAL);
setTitle(title);
setResizable(false);
setLayout(FRGUIPaneFactory.createBorderLayout());
int dialogContentHeight = contentHeight + DIALOG_BOTTOM_ACTION_BAR_HEIGHT;
int dialogWindowHeight = dialogContentHeight + DIALOG_TITLE_HEIGHT;
setSize(new Dimension(contentWidth, dialogWindowHeight));
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
exit();
}
});
GUICoreUtils.centerWindow(this);
}
protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] rightButtons) {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(contentPane, BorderLayout.CENTER);
container.add(createActionsContainer(rightButtons), BorderLayout.SOUTH);
return container;
}
protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] leftButtons, UIButton[] rightButtons) {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(contentPane, BorderLayout.CENTER);
container.add(createActionsContainer(leftButtons, rightButtons), BorderLayout.SOUTH);
return container;
}
private JPanel createActionsContainer(UIButton... buttons) {
return this.createActionsContainer(FlowLayout.RIGHT, buttons);
}
private JPanel createActionsContainer(int align, UIButton... buttons) {
JPanel container = new JPanel(new FlowLayout(align, DIALOG_BOTTOM_ACTION_BUTTON_GAP, 0));
int paddingVertical = (DIALOG_BOTTOM_ACTION_BAR_HEIGHT - DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT) / 2;
container.setBorder(BorderFactory.createEmptyBorder(paddingVertical, 0, paddingVertical, 0));
if (buttons == null || buttons.length == 0) {
return container;
}
for (UIButton button: buttons) {
if (button != null) {
button.setPreferredSize(new Dimension(button.getPreferredSize().width, DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT));
container.add(button);
}
}
return container;
}
private JPanel createActionsContainer(UIButton[] leftButtons, UIButton[] rightButtons) {
JPanel leftPane = createActionsContainer(FlowLayout.LEFT, leftButtons);
JPanel rightPane = createActionsContainer(FlowLayout.RIGHT, rightButtons);
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(leftPane, BorderLayout.WEST);
container.add(rightPane, BorderLayout.EAST);
return container;
}
public void exit() {
this.dispose();
}
}

93
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java

@ -0,0 +1,93 @@
package com.fr.design.mainframe.theme.dialog;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.ReportTheme;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.theme.TemplateThemeManagePane;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeManageDialog extends TemplateThemeDialog {
public static final int CONTENT_WIDTH = 660;
public static final int CONTENT_HEIGHT = 570;
private final TemplateThemeManageDialogContentPane contentPane;
public TemplateThemeManageDialog(Window parent) {
super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT);
contentPane = new TemplateThemeManageDialogContentPane();
setContentPane(createDialogContentPane(contentPane, new UIButton[]{ createCompleteButton() }));
}
private UIButton createCompleteButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Complete"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exit();
}
});
return button;
}
@Override
public void exit(){
contentPane.exit();
super.exit();
}
public static class TemplateThemeManageDialogContentPane extends JPanel {
private final TemplateThemeManagePane<FormTheme> formThemesManagerPane;
private final TemplateThemeManagePane<ReportTheme> reportThemesManagerPane;
public TemplateThemeManageDialogContentPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
UITabbedPane tabbedPane = new UITabbedPane();
add(tabbedPane, BorderLayout.NORTH);
formThemesManagerPane = TemplateThemeManagePane.createFormThemesManagerPane();
formThemesManagerPane.startListenThemeConfig();
reportThemesManagerPane = TemplateThemeManagePane.createReportThemesManagerPane();
reportThemesManagerPane.startListenThemeConfig();
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_FORM_TAB"), formThemesManagerPane);
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_REPORT_TAB"), reportThemesManagerPane);
tabbedPane.setSelectedIndex(0);
JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (template != null) {
TemplateThemeConfig<? extends TemplateTheme> config = template.getUsingTemplateThemeConfig();
if (config == reportThemesManagerPane.getConfig()) {
tabbedPane.setSelectedIndex(1);
}
}
}
public void exit() {
formThemesManagerPane.stopListenThemeConfig();
formThemesManagerPane.stopAsyncFetchTheme();
reportThemesManagerPane.stopListenThemeConfig();
reportThemesManagerPane.stopAsyncFetchTheme();
}
}
}

145
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java

@ -0,0 +1,145 @@
package com.fr.design.mainframe.theme.dialog;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.theme.TemplateThemeProfilePane;
import com.fr.file.FILE;
import com.fr.file.FILEChooserPane;
import com.fr.file.FileFILE;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ListSet;
import com.fr.stable.xml.XMLPrintWriter;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class TemplateThemeProfileDialog<T extends TemplateTheme> extends TemplateThemeDialog {
public static TemplateThemeProfilePane<? extends TemplateTheme> currentVisibleProfilePane;
public static final int CONTENT_WIDTH = 910;
public static final int CONTENT_HEIGHT = 570;
public TemplateThemeProfileDialog(Window parent, TemplateThemeProfilePane<T> profilePane) {
super(parent, profilePane.getTitle(), CONTENT_WIDTH, CONTENT_HEIGHT);
JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane();
content.setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT));
content.add(profilePane, BorderLayout.CENTER);
setContentPane(createDialogContentPane(content, new UIButton[]{
// 用于视觉设计师导出内置主题文件,发布前关闭
// 后续由产品经理决定是否开启此功能
createExportButton(profilePane),
profilePane.createSaveButton(),
profilePane.createSaveAsButton(this),
createCancelButton()
}));
currentVisibleProfilePane = profilePane;
}
private void exportTheme(T theme) {
FILEChooserPane fileChooser = FILEChooserPane.getInstance(true, true, new ChooseFileFilter() {
@Override
public boolean accept(FILE f) {
return f.isDirectory();
}
@Override
public String getDescription() {
return "export theme to xml";
}
@Override
public boolean containsExtension(String extension) {
return true;
}
@Override
public String toString() {
return getDescription();
}
});
fileChooser.setCurrentDirectory(new FileFILE(new File("~/")));
fileChooser.setFileNameTextField(theme.getName(), ".xml");
FILE exportedFile = null;
int result = fileChooser.showSaveDialog(DesignerContext.getDesignerFrame(), ".xml");
if (result == FILEChooserPane.JOPTIONPANE_OK_OPTION || result == FILEChooserPane.OK_OPTION) {
exportedFile = fileChooser.getSelectedFILE();
}
if (exportedFile == null) {
return;
}
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(exportedFile.getPath()))) {
XMLPrintWriter writer = XMLPrintWriter.create(bos);
theme.writeXML(writer);
writer.flush();
writer.close();
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
public UIButton createExportButton(TemplateThemeProfilePane<T> profilePane) {
UIButton exportButton = new UIButton();
exportButton.setText(Toolkit.i18nText("Fine-Design_Basic_Export"));
exportButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
T theme = profilePane.updateBean();
theme.getImageIdList().setIdList(new ListSet<>());
exportTheme(theme);
}
});
return exportButton;
}
private UIButton createCancelButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exit();
}
});
return button;
}
@Override
public void exit() {
currentVisibleProfilePane = null;
super.exit();
}
public static List<Color> getEditingColorScheme() {
if (currentVisibleProfilePane != null) {
return currentVisibleProfilePane.getCurrentColorScheme();
}
return null;
}
public static boolean isEditingTheme() {
return currentVisibleProfilePane != null;
}
}

162
designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java

@ -0,0 +1,162 @@
package com.fr.design.mainframe.theme.dialog;
import com.fr.base.theme.ThemedTemplate;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.event.ChangeEvent;
import com.fr.design.event.ChangeListener;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.TemplateThemeListPane;
import com.fr.design.mainframe.theme.ui.BorderUtils;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.CompoundBorder;
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class
TemplateThemeUsingDialog<T extends TemplateTheme> extends TemplateThemeDialog {
public static final int CONTENT_WIDTH = 660;
public static final int CONTENT_HEIGHT = 515;
private final TemplateThemeListPane<T> themeListPane;
private final ThemedTemplate currentTemplate;
public TemplateThemeUsingDialog(Window parent, ThemedTemplate template, TemplateThemeConfig<T> config) {
super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT);
this.currentTemplate = template;
this.themeListPane = new TemplateThemeListPane<>(false, config, null);
JPanel content = createContent();
UIButton openThemeManagerButton = createOpenThemeManagerButton();
UIButton usingCurrentThemeButton = createUsingCurrentThemeButton();
UIButton completeButton = createCompleteButton();
setContentPane(createDialogContentPane(content,
new UIButton[]{ openThemeManagerButton },
new UIButton[]{ usingCurrentThemeButton, completeButton }
));
themeListPane.startListenThemeConfig();
resetEnableCurrentThemeButton(themeListPane.getSelectedTheme(), usingCurrentThemeButton);
themeListPane.setSelectedChangeListener(new ChangeListener() {
@Override
public void fireChanged(ChangeEvent event) {
resetEnableCurrentThemeButton(themeListPane.getSelectedTheme(), usingCurrentThemeButton);
}
});
}
private void resetEnableCurrentThemeButton(T selectedTheme, UIButton usingCurrentThemeButton) {
if (selectedTheme == null) {
usingCurrentThemeButton.setEnabled(false);
return;
}
String selectedThemeName = selectedTheme.getName();
if (StringUtils.isEmpty(selectedThemeName)) {
usingCurrentThemeButton.setEnabled(false);
return;
}
if (currentTemplate == null) {
usingCurrentThemeButton.setEnabled(false);
return;
}
TemplateTheme templateUsingTheme = currentTemplate.getTemplateTheme();
if (templateUsingTheme == null) {
usingCurrentThemeButton.setEnabled(true);
return;
}
String templateUsingThemeName = templateUsingTheme.getName();
if (StringUtils.isEmpty(templateUsingThemeName)) {
usingCurrentThemeButton.setEnabled(true);
return;
}
usingCurrentThemeButton.setEnabled(!StringUtils.equals(templateUsingThemeName, selectedTheme.getName()));
}
private JPanel createContent() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
JPanel themeListPaneContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
themeListPaneContainer.setBorder(new CompoundBorder(
BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Select"), 12),
BorderFactory.createEmptyBorder(0, 10, 0, 10)
));
themeListPaneContainer.add(themeListPane, BorderLayout.CENTER);
container.add(themeListPaneContainer, BorderLayout.CENTER);
return container;
}
private UIButton createOpenThemeManagerButton() {
if (WorkContext.getCurrent().isRoot()) {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TemplateThemeManageDialog dialog = new TemplateThemeManageDialog(TemplateThemeUsingDialog.this);
dialog.setVisible(true);
}
});
return button;
}
return null;
}
private UIButton createUsingCurrentThemeButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Use"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
apply2CurrentTemplate(button);
}
});
return button;
}
private UIButton createCompleteButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Complete"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exit();
}
});
return button;
}
public void exit() {
themeListPane.stopListenThemeConfig();
themeListPane.stopAsyncFetchTheme();
super.exit();
}
private void apply2CurrentTemplate(UIButton usingCurrentThemeButton) {
TemplateTheme theme = themeListPane.getSelectedTheme();
if (theme != null) {
currentTemplate.setTemplateTheme(theme);
themeListPane.repaint();
usingCurrentThemeButton.setEnabled(false);
}
}
}

294
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/CellStyleListEditPane.java

@ -0,0 +1,294 @@
package com.fr.design.mainframe.theme.edit;
import com.fr.base.Style;
import com.fr.base.theme.settings.ThemedCellStyle;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.config.predefined.PredefinedCellStyle;
import com.fr.design.actions.UpdateAction;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.NameInspector;
import com.fr.design.gui.controlpane.JListControlPane;
import com.fr.design.gui.controlpane.NameObjectCreator;
import com.fr.design.gui.controlpane.NameableCreator;
import com.fr.design.gui.controlpane.ShortCut4JControlPane;
import com.fr.design.gui.controlpane.UnrepeatedNameHelper;
import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.gui.ilist.DefaultListCellEditor;
import com.fr.design.gui.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.ModNameActionListener;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.icon.IconPathConstants;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.edit.cell.CellStyleEditPane;
import com.fr.design.mainframe.theme.edit.cell.NoBorderPaneCellStyleEditPane;
import com.fr.design.menu.ShortCut;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.general.NameObject;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* Created by kerry on 2020-09-27
*/
public class CellStyleListEditPane extends JListControlPane {
private boolean namePermitted = true;
private AttributeChangeListener attributeChangeListener;
public CellStyleListEditPane() {
super();
setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
addModNameActionListener(new ModNameActionListener() {
public void nameModed(int index, String oldName, String newName) {
if (ComparatorUtils.equals(oldName, newName) || ComparatorUtils.equals(newName, NameInspector.ILLEGAL_NAME_HOLDER)) {
return;
}
namePermitted = true;
String[] allNames = nameableList.getAllNames();
allNames[index] = StringUtils.EMPTY;
if (StringUtils.isEmpty(newName)) {
showTipDialogAndReset(i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Cell_Style_Empty_Name_Tip"), index);
nameableList.setNameAt(oldName, index);
return;
}
if (isNameRepeated(new List[]{Arrays.asList(allNames)}, newName)) {
showTipDialogAndReset(i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Cell_Style_Duplicated_Name_Tip", newName), index);
nameableList.setNameAt(oldName, index);
return;
}
populateSelectedValue();
}
});
}
public void registerAttrChangeListener(AttributeChangeListener listener){
this.attributeChangeListener = listener;
}
private void showTipDialogAndReset(String content, int index) {
nameableList.stopEditing();
FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(CellStyleListEditPane.this),
content,
i18nText("Fine-Design_Basic_Alert"),
JOptionPane.WARNING_MESSAGE);
setIllegalIndex(index);
namePermitted = false;
}
@Override
public NameableCreator[] createNameableCreators() {
return new NameableCreator[]{ new DefaultCellStyleNameObjectCreator(), new CellStyleNameObjectCreator() };
}
@Override
protected JNameEdList createJNameList() {
JNameEdList nameEdList = super.createJNameList();
nameEdList.setCellEditor(new DefaultListCellEditor(new UITextField()) {
@Override
public Component getListCellEditorComponent(JList list, Object value, boolean isSelected, int index) {
ListModelElement element = (ListModelElement) getModel().getElementAt(index);
if (element != null) {
NameObject selectNameObject = (NameObject) element.wrapper;
ThemedCellStyle cellStyle = (ThemedCellStyle) (selectNameObject.getObject());
if (!cellStyle.isRemovable()) {
return null;
}
}
return super.getListCellEditorComponent(list, value, isSelected, index);
}
});
return nameEdList;
}
@Override
public BasicBeanPane createPaneByCreators(NameableCreator creator) {
CellStyleEditPane stylePane = (CellStyleEditPane) super.createPaneByCreators(creator);
stylePane.registerAttrChangeListener(attributeChangeListener);
return stylePane;
}
@Override
protected String title4PopupWindow() {
return StringUtils.EMPTY;
}
protected void initComponentPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setCreators(this.createNameableCreators());
initCardPane();
JPanel leftPane = getLeftPane();
leftPane.setPreferredSize(new Dimension(90, 0));
cardPane.setPreferredSize(new Dimension(270, 0));
JPanel mainSplitPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
mainSplitPane.add(leftPane, BorderLayout.WEST);
mainSplitPane.add(cardPane, BorderLayout.CENTER);
this.add(mainSplitPane, BorderLayout.CENTER);
this.checkButtonEnabled();
}
@Override
protected void initToolBar() {
super.initToolBar();
UIToolbar toolbar = getToolBar();
toolbar.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
}
@Override
protected ShortCut4JControlPane[] createShortcuts() {
return new ShortCut4JControlPane[]{
createAddItemShortCut4JControlPane(),
new RemoveItemShortCut4JControlPane(new RemoveItemAction())
};
}
private ShortCut4JControlPane createAddItemShortCut4JControlPane (){
ShortCut shortCut = shortCutFactory.createAddItemUpdateAction(new NameableCreator[]{new CellStyleNameObjectCreator()});
return new AddItemShortCut4JControlPane(shortCut);
}
public void populateBean(ThemedCellStyleList ob) {
if (ob == null) {
return;
}
List<NameObject> nameObjectList = new ArrayList<>();
List<ThemedCellStyle> cellStyleList = ob.getCellStyleList();
for (ThemedCellStyle cellStyle: cellStyleList) {
nameObjectList.add(new NameObject(cellStyle.getName(), cellStyle));
}
NameObject[] nameObjectArray = new NameObject[nameObjectList.size()];
nameObjectList.toArray(nameObjectArray);
populate(nameObjectArray);
}
public ThemedCellStyleList updateBean() {
Nameable[] nameables = this.update();
ThemedCellStyleList styleConfig = new ThemedCellStyleList();
for (Nameable nameable : nameables) {
ThemedCellStyle tmpStyle = (ThemedCellStyle) ((NameObject) nameable).getObject();
tmpStyle.setName(nameable.getName());
styleConfig.addThemedCellStyle(tmpStyle);
}
return styleConfig;
}
private static class AddItemShortCut4JControlPane extends ShortCut4JControlPane{
AddItemShortCut4JControlPane(ShortCut shortCut) {
this.shortCut = shortCut;
}
@Override
public void checkEnable() {
this.shortCut.setEnabled(true);
}
}
private class RemoveItemShortCut4JControlPane extends ShortCut4JControlPane {
RemoveItemShortCut4JControlPane(ShortCut shortCut) {
this.shortCut = shortCut;
}
@Override
public void checkEnable() {
ListModelElement selectModel = CellStyleListEditPane.this.getSelectedValue();
if (selectModel != null) {
NameObject selectNameObject = (NameObject) selectModel.wrapper;
ThemedCellStyle cellStyle = (ThemedCellStyle) (selectNameObject.getObject());
this.shortCut.setEnabled(cellStyle.isRemovable() && !cellStyle.isDefault4New());
} else {
this.shortCut.setEnabled(false);
}
}
}
private class RemoveItemAction extends UpdateAction {
RemoveItemAction() {
setName(i18nText(("Fine-Design_Basic_Action_Remove")));
setMnemonic('R');
setSmallIcon(IOUtils.readIcon(IconPathConstants.TD_REMOVE_ICON_PATH));
}
@Override
public void actionPerformed(ActionEvent evt) {
CellStyleListEditPane.this.onRemoveItem();
}
}
private static class CellStyleNameObjectCreator extends NameObjectCreator {
public CellStyleNameObjectCreator() {
this(CellStyleEditPane.class);
}
public CellStyleNameObjectCreator(Class<? extends BasicBeanPane> updatePane) {
super(i18nText("Fine-Design_Predefined_Cell_New_Style"), ThemedCellStyle.class, updatePane);
}
@Override
public Nameable createNameable(UnrepeatedNameHelper helper) {
ThemedCellStyle cellStyle = new ThemedCellStyle();
cellStyle.setName(menuName);
cellStyle.setStyle(Style.getInstance());
cellStyle.setRemovable(true);
cellStyle.setImmutable(true);
cellStyle.setDefault4Absent(false);
cellStyle.setDefault4New(false);
return new NameObject(helper.createUnrepeatedName(this.menuName()), cellStyle);
}
@Override
public Object acceptObject2Populate(Object ob) {
if (ob instanceof NameObject) {
ob = ((NameObject) ob).getObject();
}
if (clazzOfObject != null && clazzOfObject.isInstance(ob) && acceptNameObject(ob)) {
doSthChanged4Icon(ob);
return ob;
}
return null;
}
public boolean acceptNameObject(Object ob) {
return !((ThemedCellStyle) ob).isDefault4New();
}
}
private static class DefaultCellStyleNameObjectCreator extends CellStyleNameObjectCreator {
public DefaultCellStyleNameObjectCreator() {
super(NoBorderPaneCellStyleEditPane.class);
}
@Override
public boolean acceptNameObject(Object ob) {
return ((ThemedCellStyle) ob).isDefault4New();
}
}
}

104
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleEditPane.java

@ -0,0 +1,104 @@
package com.fr.design.mainframe.theme.edit;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.MultiTabPane;
import com.fr.design.mainframe.theme.edit.chart.ChartAxisStylePane;
import com.fr.design.mainframe.theme.edit.chart.ChartDataSheetStylePane;
import com.fr.design.mainframe.theme.edit.chart.ChartLabelStylePane;
import com.fr.design.mainframe.theme.edit.chart.ChartLegendStylePane;
import com.fr.design.mainframe.theme.edit.chart.ChartSeriesStylePane;
import com.fr.design.mainframe.theme.edit.chart.ChartTitleAndBackgroundStylePane;
import javax.swing.BorderFactory;
import java.util.ArrayList;
import java.util.List;
import java.awt.Color;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-16
*/
public class ChartStyleEditPane extends MultiTabPane<ThemedChartStyle> {
private ChartSeriesStylePane chartSeriesStylePane;
private ChartLegendStylePane chartLegendStylePane;
private ChartLabelStylePane chartLabelPane;
private ChartAxisStylePane chartAxisStylePane;
private ChartDataSheetStylePane chartDataSheetStylePane;
private ChartTitleAndBackgroundStylePane chartTitleAndBackgroundStylePane;
public ChartStyleEditPane() {
}
@Override
protected void initLayout() {
super.initLayout();
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
@Override
protected List<BasicPane> initPaneList() {
this.chartSeriesStylePane = new ChartSeriesStylePane();
this.chartLegendStylePane = new ChartLegendStylePane();
this.chartLabelPane = new ChartLabelStylePane();
this.chartAxisStylePane = new ChartAxisStylePane();
this.chartDataSheetStylePane = new ChartDataSheetStylePane();
this.chartTitleAndBackgroundStylePane = createChartTitleAndBackgroundStylePane();
paneList = new ArrayList<>();
paneList.add(this.chartSeriesStylePane);
paneList.add(this.chartLegendStylePane);
paneList.add(this.chartLabelPane);
paneList.add(this.chartAxisStylePane);
paneList.add(this.chartDataSheetStylePane);
paneList.add(this.chartTitleAndBackgroundStylePane);
return paneList;
}
protected ChartTitleAndBackgroundStylePane createChartTitleAndBackgroundStylePane() {
return new ChartTitleAndBackgroundStylePane();
}
@Override
public void populateBean(ThemedChartStyle ob) {
chartSeriesStylePane.populate(ob);
chartLegendStylePane.populate(ob);
chartLabelPane.populate(ob);
chartAxisStylePane.populate(ob);
chartDataSheetStylePane.populate(ob);
chartTitleAndBackgroundStylePane.populate(ob);
}
@Override
public void updateBean(ThemedChartStyle ob) {
}
@Override
public ThemedChartStyle updateBean() {
ThemedChartStyle chartStyle = new ThemedChartStyle();
chartSeriesStylePane.update(chartStyle);
chartLegendStylePane.update(chartStyle);
chartLabelPane.update(chartStyle);
chartAxisStylePane.update(chartStyle);
chartDataSheetStylePane.update(chartStyle);
chartTitleAndBackgroundStylePane.update(chartStyle);
return chartStyle;
}
public void populateGradientBar(List<Color> colors) {
chartSeriesStylePane.populateGradientBar(colors);
}
@Override
public boolean accept(Object ob) {
return false;
}
@Override
public void reset() {
}
}

16
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleFormEditPane.java

@ -0,0 +1,16 @@
package com.fr.design.mainframe.theme.edit;
import com.fr.design.mainframe.theme.edit.chart.ChartTitleAndBackgroundStyleFormPane;
import com.fr.design.mainframe.theme.edit.chart.ChartTitleAndBackgroundStylePane;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2021-08-30
*/
public class ChartStyleFormEditPane extends ChartStyleEditPane {
protected ChartTitleAndBackgroundStylePane createChartTitleAndBackgroundStylePane() {
return new ChartTitleAndBackgroundStyleFormPane();
}
}

136
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java

@ -0,0 +1,136 @@
package com.fr.design.mainframe.theme.edit;
import com.fr.base.theme.settings.ThemedComponentStyle;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.style.ComponentBodyStylePane;
import com.fr.design.gui.style.ComponentIntegralStylePane;
import com.fr.design.gui.style.ComponentTitleStylePane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.edit.component.ComponentMarginStylePane;
import com.fr.design.mainframe.theme.edit.ui.LabelUtils;
import com.fr.design.mainframe.theme.edit.ui.TabbedPane;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.general.act.BorderPacker;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/12
*/
public class ComponentStyleEditPane extends JPanel {
public static final int LABEL_WIDTH = 60;
public static final int SETTING_WIDTH = 193;
private final ComponentTitleStylePane componentTitleStylePane;
private final ComponentBodyStylePane componentBodyStylePane;
private final ExtendedComponentIntegralStylePane componentIntegralStylePane;
public ComponentStyleEditPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
componentTitleStylePane = new ThemedComponentTitleStylePane(LABEL_WIDTH, SETTING_WIDTH);
componentBodyStylePane = new ComponentBodyStylePane(LABEL_WIDTH, SETTING_WIDTH);
componentIntegralStylePane = new ExtendedComponentIntegralStylePane();
JPanel content = new TabbedPane(
new String[] {
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Title"),
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Body"),
Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Integral")
},
new JComponent[] { createTabContainer(componentTitleStylePane), createTabContainer(componentBodyStylePane), createTabContainer(componentIntegralStylePane) }
);
add(content, BorderLayout.NORTH);
}
public void populateBean(ThemedComponentStyle style) {
componentTitleStylePane.populateBean(style.getStyle());
componentBodyStylePane.populateBean(style.getStyle());
componentIntegralStylePane.populateBean(style);
}
public ThemedComponentStyle updateBean() {
ThemedComponentStyle style = new ThemedComponentStyle();
componentTitleStylePane.updateBean(style.getStyle());
componentBodyStylePane.updateBean(style.getStyle());
componentIntegralStylePane.updateBean(style);
return style;
}
private static class ExtendedComponentIntegralStylePane extends JPanel {
private final ComponentIntegralStylePane integralStylePane;
private final ComponentMarginStylePane marginStylePane;
public ExtendedComponentIntegralStylePane() {
setLayout(new BorderLayout(0, IntervalConstants.INTERVAL_L1));
integralStylePane = new ComponentIntegralStylePane(LABEL_WIDTH, SETTING_WIDTH);
marginStylePane = new ComponentMarginStylePane(LABEL_WIDTH, SETTING_WIDTH);
add(integralStylePane, BorderLayout.NORTH);
add(marginStylePane, BorderLayout.CENTER);
}
public void populateBean(ThemedComponentStyle style) {
integralStylePane.populateBean(style.getStyle());
marginStylePane.populate(style);
}
public void updateBean(ThemedComponentStyle style) {
integralStylePane.updateBean(style.getStyle());
marginStylePane.update(style);
}
}
private static class ThemedComponentTitleStylePane extends ComponentTitleStylePane {
public ThemedComponentTitleStylePane(int uiLabelWidth, int uiSettingWidth) {
super(uiLabelWidth, uiSettingWidth);
setSupportTitleVisible(false);
setSupportTitleContent(false);
setSupportOtherSetting(true);
}
@Override
public void populateBean(BorderPacker style) {
style.setType(LayoutBorderStyle.TITLE);
super.populateBean(style);
}
@Override
public void updateBean(BorderPacker style) {
super.updateBean(style);
style.setType(LayoutBorderStyle.TITLE);
}
}
private JComponent createTabContainer(final JComponent component) {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setPreferredSize(new Dimension(container.getPreferredSize().width, 220));
JPanel tipLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
tipLabelPane.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153));
tipLabelPane.add(tipLabel);
container.add(tipLabelPane, BorderLayout.NORTH);
JScrollPane scrollPane = new JScrollPane(component);
scrollPane.setPreferredSize(new Dimension(container.getPreferredSize().width, 220));
scrollPane.setBorder(BorderFactory.createEmptyBorder());
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
container.add(scrollPane, BorderLayout.CENTER);
return container;
}
}

44
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/FormBodyStyleEditPane.java

@ -0,0 +1,44 @@
package com.fr.design.mainframe.theme.edit;
import com.fr.base.theme.settings.ThemedFormBodyStyle;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.style.ComponentBodyStylePane;
import javax.swing.BorderFactory;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/12
*/
public class FormBodyStyleEditPane extends JScrollPane {
public static final int LABEL_WIDTH = 60;
public static final int SETTING_WIDTH = 193;
private final ComponentBodyStylePane bodyStylePane;
public FormBodyStyleEditPane() {
bodyStylePane = new ComponentBodyStylePane(LABEL_WIDTH, SETTING_WIDTH);
bodyStylePane.setBorder(BorderFactory.createEmptyBorder(
IntervalConstants.INTERVAL_L1,
IntervalConstants.INTERVAL_L1,
IntervalConstants.INTERVAL_L1,
IntervalConstants.INTERVAL_L1
));
setViewportView(bodyStylePane);
setBorder(BorderFactory.createEmptyBorder());
setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
}
public void populateBean(ThemedFormBodyStyle style) {
bodyStylePane.populateBean(style.getStyle());
}
public ThemedFormBodyStyle updateBean() {
ThemedFormBodyStyle formBodyStyle = new ThemedFormBodyStyle();
bodyStylePane.updateBean(formBodyStyle.getStyle());
return formBodyStyle;
}
}

65
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ReportBodyStyleEditPane.java

@ -0,0 +1,65 @@
package com.fr.design.mainframe.theme.edit;
import com.fr.base.theme.settings.ThemedReportBodyStyle;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.style.ReportBackgroundSpecialPane;
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.predefined.ui.detail.background.BackgroundSettingPane;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Component;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/12
*/
public class ReportBodyStyleEditPane extends JScrollPane {
public static final int LABEL_WIDTH = 60;
public static final int SETTING_WIDTH = 193;
private final ReportBackgroundSpecialPane backgroundPane;
public ReportBodyStyleEditPane() {
backgroundPane = new ReportBackgroundSpecialPane();
double p = TableLayout.PREFERRED;
JPanel uiLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
uiLabelPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Report_Background_Fill")), 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
));
setViewportView(backgroundLabeledPane);
setBorder(BorderFactory.createEmptyBorder());
setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
}
public void populateBean(ThemedReportBodyStyle style) {
backgroundPane.populateBean(style.getBackground());
}
public ThemedReportBodyStyle updateBean() {
ThemedReportBodyStyle style = new ThemedReportBodyStyle();
style.setBackground(backgroundPane.update());
return style;
}
}

51
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/AbstractBackgroundDetailPane.java

@ -0,0 +1,51 @@
package com.fr.design.mainframe.theme.edit.background;
import com.fr.design.event.UIObserverListener;
import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane;
import com.fr.general.Background;
import javax.swing.event.ChangeListener;
/**
* Created by kerry on 2020-09-14
*/
public abstract class AbstractBackgroundDetailPane<T extends Background> extends BackgroundQuickPane {
@Override
public boolean accept(Background background) {
return false;
}
@Override
public void populateBean(Background background) {
this.populate((T) background);
}
@Override
public Background updateBean() {
return this.update();
}
@Override
public String title4PopupWindow() {
return null;
}
@Override
public void reset() {
}
@Override
public void registerChangeListener(UIObserverListener listener) {
}
public abstract void populate(T background);
public abstract T update();
public void addChangeListener(ChangeListener changeListener) {
}
}

136
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/BackgroundSettingPane.java

@ -0,0 +1,136 @@
package com.fr.design.mainframe.theme.edit.background;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
/**
* Created by kerry on 2020-09-02
*/
public class BackgroundSettingPane extends BasicBeanPane<Background> {
private ChangeListener changeListener = null;
private UIComboBox headCombobox;
private BackgroundQuickPane[] paneList;
public BackgroundSettingPane() {
init();
}
private void init() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(createComboHeadPane(), BorderLayout.NORTH);
CardLayout cardlayout = new CardLayout();
paneList = supportKindsOfBackgroundUI();
final JPanel centerPane = new JPanel(cardlayout) {
@Override
public Dimension getPreferredSize() {// AUGUST:使用当前面板的的高度
int index = headCombobox.getSelectedIndex();
return new Dimension(super.getPreferredSize().width, paneList[index].getPreferredSize().height);
}
};
centerPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
for (BackgroundQuickPane pane : paneList) {
headCombobox.addItem(pane.title4PopupWindow());
centerPane.add(pane, pane.title4PopupWindow());
}
headCombobox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
cardlayout.show(centerPane, (String) headCombobox.getSelectedItem());
}
});
this.add(centerPane, BorderLayout.CENTER);
}
public void addChangeListener(ChangeListener changeListener) {
this.changeListener = changeListener;
}
private JPanel createComboHeadPane() {
headCombobox = new UIComboBox();
JPanel jPanel = TableLayoutHelper.createGapTableLayoutPane(
new Component[][]{new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Report_Fill")), headCombobox}},
TableLayoutHelper.FILL_NONE, 33, 5);
headCombobox.setPreferredSize(new Dimension(160, 20));
jPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
return jPanel;
}
protected BackgroundQuickPane[] supportKindsOfBackgroundUI() {
java.util.List<BackgroundQuickPane> kinds = new ArrayList<>();
kinds.add(new EmptyBackgroundPane());
kinds.add(new ColorDetailPane());
kinds.add(new TextureDetailObservePane());
kinds.add(new PatternDetailPane());
kinds.add(createImageSelectPane());
kinds.add(new GradientDetailPane());
return kinds.toArray(new BackgroundQuickPane[kinds.size()]);
}
protected ImageDetailPane createImageSelectPane() {
ImageDetailPane imageDetailPane = new ImageDetailPane();
imageDetailPane.registerChangeListener(new UIObserverListener() {
@Override
public void doChange() {
fireChangeListener();
}
});
return imageDetailPane;
}
protected void fireChangeListener() {
if (changeListener != null) {
changeListener.stateChanged(null);
}
}
@Override
public void populateBean(Background background) {
for (int i = 0; i < paneList.length; i++) {
BackgroundQuickPane pane = paneList[i];
if (pane.accept(background)) {
pane.populateBean(background);
headCombobox.setSelectedIndex(i);
return;
}
}
}
@Override
public Background updateBean() {
int selectIndex = this.headCombobox.getSelectedIndex();
try {
return paneList[selectIndex].updateBean();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
@Override
protected String title4PopupWindow() {
return null;
}
}

105
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ColorDetailPane.java

@ -0,0 +1,105 @@
package com.fr.design.mainframe.theme.edit.background;
import com.fr.base.background.ColorBackground;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.style.color.ColorSelectPane;
import com.fr.general.Background;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
/**
* Created by kerry on 2020-08-31
*/
public class ColorDetailPane extends AbstractBackgroundDetailPane<ColorBackground> {
public static final String SPACE_4 = " ";
private ColorBackgroundSelectPane selectPane;
public ColorDetailPane() {
this.selectPane = new ColorBackgroundSelectPane();
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(this.selectPane, BorderLayout.CENTER);
}
@Override
public void populate(ColorBackground background) {
this.selectPane.setColor(background.getColor());
}
@Override
public ColorBackground update() {
return ColorBackground.getInstance(selectPane.getColor());
}
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Color");
}
@Override
public boolean accept(Background background) {
return background instanceof ColorBackground;
}
class ColorBackgroundSelectPane extends ColorSelectPane implements UIObserver {
protected UIObserverListener uiObserverListener;
protected void initialCompents(boolean isSupportTransparent) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createEmptyBorder());
if (isSupportTransparent) {
this.add(createNorthPane(), BorderLayout.NORTH);
}
JPanel centerPane = createCenterPane();
this.add(centerPane, BorderLayout.CENTER);
this.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
}
});
}
private JPanel createNorthPane() {
UIButton transpanrentBtn = new UIButton();
transpanrentBtn.setPreferredSize(new Dimension(160, 20));
JPanel jPanel = TableLayoutHelper.createGapTableLayoutPane(
new Component[][]{new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_Color")),
transpanrentBtn}}, TableLayoutHelper.FILL_NONE, 33, 5);
jPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 10));
return jPanel;
}
protected JPanel createCenterPane() {
JPanel centerPane = new JPanel();
JPanel jPanel = TableLayoutHelper.createGapTableLayoutPane(
new Component[][]{new Component[]{new UILabel(SPACE_4), centerPane}}, TableLayoutHelper.FILL_NONE, 33, 5);
jPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 10));
return jPanel;
}
@Override
public void registerChangeListener(UIObserverListener listener) {
this.uiObserverListener = listener;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
}
}

35
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/EmptyBackgroundPane.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.theme.edit.background;
import com.fr.design.i18n.Toolkit;
import com.fr.general.Background;
/**
* Created by kerry on 2020-09-01
*/
public class EmptyBackgroundPane extends AbstractBackgroundDetailPane {
@Override
public void populate(Background background) {
}
@Override
public Background update() {
return null;
}
/**
* 名称
*
* @return 名称
*/
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Background_Null");
}
public boolean accept(Background background) {
return background == null;
}
}

160
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/GradientDetailPane.java

@ -0,0 +1,160 @@
package com.fr.design.mainframe.theme.edit.background;
import com.fr.base.background.GradientBackground;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
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.design.layout.TableLayoutHelper;
import com.fr.design.style.background.gradient.GradientBar;
import com.fr.general.Background;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 渐变色的面板不是很pp面板应用显得繁琐有写可以写成控件类型比如色彩选择的可以做得花哨点
*
* @author ben
*/
public class GradientDetailPane extends AbstractBackgroundDetailPane<GradientBackground> implements UIObserver {
private static final long serialVersionUID = -6854603990673031897L;
private UIObserverListener listener;
private UIRadioButton left2right, top2bottom;
private GradientBar gradientBar;
private ChangeListener changeListener = null;
public GradientDetailPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel gradientPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel blankJp = new JPanel();
gradientBar = new GradientBar(4, 140);
blankJp.add(gradientBar);
gradientPanel.add(gradientBar, BorderLayout.SOUTH);
JPanel jp = new JPanel(new GridLayout(2, 1, 15, 10));
left2right = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Page_Setup_Horizontal"));
jp.add(left2right);
left2right.setSelected(true);
left2right.addActionListener(reviewListener);
top2bottom = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Page_Setup_Vertical"));
jp.add(top2bottom);
top2bottom.addActionListener(reviewListener);
ButtonGroup toggle = new ButtonGroup();
toggle.add(left2right);
toggle.add(top2bottom);
Component[][] components = new Component[][]{
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_Gradient_Setting")), gradientPanel},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_Gradient_Color")), jp}
};
JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN,
IntervalConstants.INTERVAL_W4, IntervalConstants.INTERVAL_L1);
this.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (listener != null) {
listener.doChange();
}
}
});
this.add(contentPane);
}
@Override
public boolean accept(Background background) {
return background instanceof GradientBackground;
}
public void populate(GradientBackground bg) {
this.gradientBar.getSelectColorPointBtnP1().setColorInner(bg.getStartColor());
this.gradientBar.getSelectColorPointBtnP2().setColorInner(bg.getEndColor());
if (bg.getDirection() == GradientBackground.LEFT2RIGHT) {
left2right.setSelected(true);
} else {
top2bottom.setSelected(true);
}
if (bg.isUseCell()) {
return;
}
double startValue = (double) bg.getBeginPlace();
double endValue = (double) bg.getFinishPlace();
gradientBar.setStartValue(startValue);
gradientBar.setEndValue(endValue);
this.gradientBar.repaint();
}
public GradientBackground update() {
GradientBackground gb = new GradientBackground(
gradientBar.getSelectColorPointBtnP1().getColorInner(),
gradientBar.getSelectColorPointBtnP2().getColorInner());
if (left2right.isSelected()) {
gb.setDirection(GradientBackground.LEFT2RIGHT);
} else {
gb.setDirection(GradientBackground.TOP2BOTTOM);
}
if (gradientBar.isOriginalPlace()) {
gb.setUseCell(true);
} else {
gb.setUseCell(false);
gb.setBeginPlace((float) gradientBar.getStartValue());
gb.setFinishPlace((float) gradientBar.getEndValue());
}
return gb;
}
ActionListener reviewListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireChagneListener();
}
};
public void addChangeListener(ChangeListener changeListener) {
this.changeListener = changeListener;
gradientBar.addChangeListener(changeListener);
}
public void fireChagneListener() {
if (this.changeListener != null) {
ChangeEvent evt = new ChangeEvent(this);
this.changeListener.stateChanged(evt);
}
}
@Override
public void registerChangeListener(UIObserverListener listener) {
this.listener = listener;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Gradient_Color");
}
}

216
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ImageDetailPane.java

@ -0,0 +1,216 @@
package com.fr.design.mainframe.theme.edit.background;
import com.fr.base.Style;
import com.fr.base.background.ImageBackground;
import com.fr.base.background.ImageFileBackground;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.frpane.ImgChooseWrapper;
import com.fr.design.gui.ibutton.UIButton;
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.design.layout.TableLayoutHelper;
import com.fr.design.style.background.image.ImageFileChooser;
import com.fr.design.style.background.image.ImagePreviewPane;
import com.fr.general.Background;
import com.fr.stable.Constants;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Image background pane.
*/
public class ImageDetailPane extends AbstractBackgroundDetailPane<ImageBackground> implements UIObserver {
private UIObserverListener listener;
protected ImagePreviewPane previewPane = null;
private Style imageStyle = null;
private ChangeListener changeListener = null;
private ImageFileChooser imageFileChooser = null;
private UIRadioButton defaultRadioButton = null;
private UIRadioButton tiledRadioButton = null;
private UIRadioButton extendRadioButton = null;
private UIRadioButton adjustRadioButton = null;
public ImageDetailPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(initSelectFilePane(), BorderLayout.CENTER);
imageFileChooser = new ImageFileChooser();
imageFileChooser.setMultiSelectionEnabled(false);
previewPane = new ImagePreviewPane();
this.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (listener != null) {
listener.doChange();
}
}
});
}
public JPanel initSelectFilePane() {
JPanel selectFilePane = FRGUIPaneFactory.createBorderLayout_L_Pane();
selectFilePane.setBorder(BorderFactory.createEmptyBorder());
UIButton selectPictureButton = new UIButton(
Toolkit.i18nText("Fine-Design_Basic_Background_Image_Select"));
selectPictureButton.setMnemonic('S');
selectPictureButton.addActionListener(selectPictureActionListener);
selectPictureButton.setPreferredSize(new Dimension(160, 20));
//布局
defaultRadioButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Default"));
tiledRadioButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Titled"));
extendRadioButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Extend"));
adjustRadioButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Layout_Image_Adjust"));
defaultRadioButton.addActionListener(layoutActionListener);
tiledRadioButton.addActionListener(layoutActionListener);
extendRadioButton.addActionListener(layoutActionListener);
adjustRadioButton.addActionListener(layoutActionListener);
JPanel jp = new JPanel(new GridLayout(4, 1, 15, 10));
for (UIRadioButton button : imageLayoutButtons()) {
jp.add(button);
}
ButtonGroup layoutBG = new ButtonGroup();
layoutBG.add(defaultRadioButton);
layoutBG.add(tiledRadioButton);
layoutBG.add(extendRadioButton);
layoutBG.add(adjustRadioButton);
defaultRadioButton.setSelected(true);
Component[][] components = new Component[][]{
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_Image")), selectPictureButton},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_Fill_Mode")), jp}
};
JPanel centerPane = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_NONE,
IntervalConstants.INTERVAL_L4, IntervalConstants.INTERVAL_L1);
selectFilePane.add(centerPane, BorderLayout.CENTER);
return selectFilePane;
}
protected UIRadioButton[] imageLayoutButtons() {
return new UIRadioButton[]{
defaultRadioButton,
tiledRadioButton,
extendRadioButton,
adjustRadioButton
};
}
@Override
public boolean accept(Background background) {
return background instanceof ImageBackground;
}
/**
* Select picture.
*/
ActionListener selectPictureActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
int returnVal = imageFileChooser.showOpenDialog(ImageDetailPane.this);
setImageStyle();
ImgChooseWrapper.getInstance(previewPane, imageFileChooser, imageStyle, changeListener).dealWithImageFile(returnVal);
}
};
protected void setImageStyle() {
if (tiledRadioButton.isSelected()) {
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_TILED);
} else if (adjustRadioButton.isSelected()) {
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_ADJUST);
} else if (extendRadioButton.isSelected()) {
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_EXTEND);
} else {
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_CENTER);
}
}
ActionListener layoutActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
setImageStyle();
changeImageStyle();
}
private void changeImageStyle() {
previewPane.setImageStyle(ImageDetailPane.this.imageStyle);
previewPane.repaint();
}
};
@Override
public void populate(ImageBackground imageBackground) {
if (imageBackground.getLayout() == Constants.IMAGE_CENTER) {
defaultRadioButton.setSelected(true);
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_CENTER);
} else if (imageBackground.getLayout() == Constants.IMAGE_EXTEND) {
extendRadioButton.setSelected(true);
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_EXTEND);
} else if (imageBackground.getLayout() == Constants.IMAGE_ADJUST) {
adjustRadioButton.setSelected(true);
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_ADJUST);
} else {
tiledRadioButton.setSelected(true);
imageStyle = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_TILED);
}
previewPane.setImageStyle(ImageDetailPane.this.imageStyle);
if (imageBackground.getImage() != null) {
previewPane.setImageWithSuffix(imageBackground.getImageWithSuffix());
previewPane.setImage(imageBackground.getImage());
}
fireChagneListener();
}
@Override
public ImageBackground update() {
ImageBackground imageBackground = new ImageFileBackground(previewPane.getImageWithSuffix());
setImageStyle();
imageBackground.setLayout(imageStyle.getImageLayout());
return imageBackground;
}
@Override
public void addChangeListener(ChangeListener changeListener) {
this.changeListener = changeListener;
}
private void fireChagneListener() {
if (this.changeListener != null) {
ChangeEvent evt = new ChangeEvent(this);
this.changeListener.stateChanged(evt);
}
}
@Override
public void registerChangeListener(UIObserverListener listener) {
this.listener = listener;
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Background_Image");
}
}

120
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/PatternDetailPane.java

@ -0,0 +1,120 @@
package com.fr.design.mainframe.theme.edit.background;
import com.fr.base.background.PatternBackground;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.style.background.impl.PatternBackgroundPane;
import com.fr.design.style.color.ColorSelectBox;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.LayoutManager;
/**
* Created by kerry on 2020-08-31
*/
public class PatternDetailPane extends AbstractBackgroundDetailPane<PatternBackground> implements UIObserver {
private UIObserverListener listener;
private PatternNewBackgroundPane patternNewBackgroundPane;
public PatternDetailPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
patternNewBackgroundPane = new PatternNewBackgroundPane(6);
this.add(patternNewBackgroundPane, BorderLayout.CENTER);
}
@Override
public void registerChangeListener(UIObserverListener listener) {
this.listener = listener;
}
@Override
public void populate(PatternBackground background) {
this.patternNewBackgroundPane.populate(background);
}
@Override
public PatternBackground update() {
try {
return (PatternBackground) this.patternNewBackgroundPane.update();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Background_Pattern");
}
@Override
public boolean accept(Background background) {
return background instanceof PatternBackground;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
class PatternNewBackgroundPane extends PatternBackgroundPane {
private PatternNewBackgroundPane(int nColumn) {
super(nColumn);
}
protected LayoutManager layoutOfTypePane(int nColumn) {
return new GridLayout(0, nColumn, 2, 2);
}
protected void initComponents(int nColumn) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createEmptyBorder());
JPanel jPanel = new JPanel();
jPanel.setLayout(layoutOfTypePane(nColumn));
setChildrenOfTypePane(jPanel);
foregroundColorPane = new ColorSelectBox(80);
backgroundColorPane = new ColorSelectBox(80);
foregroundColorPane.setSelectObject(Color.lightGray);
backgroundColorPane.setSelectObject(Color.black);
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_Pattern"));
label.setVerticalAlignment(SwingConstants.TOP);
Component[][] components = new Component[][]{
new Component[]{label, jPanel},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_ForeBackground_Color")), foregroundColorPane},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_Pattern_Color")), backgroundColorPane}
};
JPanel centerPane = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN,
IntervalConstants.INTERVAL_W4, IntervalConstants.INTERVAL_L1);
JPanel jPanel1 = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane();
jPanel1.add(centerPane);
jPanel1.setBorder(BorderFactory.createEmptyBorder());
this.add(jPanel1, BorderLayout.NORTH);
this.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (listener != null) {
listener.doChange();
}
}
});
}
}
}

98
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/TextureDetailObservePane.java

@ -0,0 +1,98 @@
package com.fr.design.mainframe.theme.edit.background;
import com.fr.base.background.TextureBackground;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.style.background.texture.TextureDetailPane;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
/**
* Created by kerry on 2020-09-02
*/
public class TextureDetailObservePane extends AbstractBackgroundDetailPane<TextureBackground> implements UIObserver {
private TextureDetailPane detailPane;
private UIObserverListener listener;
public TextureDetailObservePane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
detailPane = TextureDetailPane.createMiniTextureDetailPane(6);
detailPane.setPreferredSize(new Dimension(160, 108));
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Background_Texture"));
label.setPreferredSize(new Dimension(24, 108));
label.setVerticalAlignment(SwingConstants.TOP);
JPanel jPanel = TableLayoutHelper.createGapTableLayoutPane(
new Component[][]{new Component[]{label, detailPane}}, TableLayoutHelper.FILL_LASTCOLUMN, 33, 5);
jPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 10));
detailPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (listener != null) {
listener.doChange();
}
}
});
this.add(jPanel, BorderLayout.CENTER);
}
@Override
public void registerChangeListener(UIObserverListener listener) {
this.listener = listener;
}
@Override
public boolean shouldResponseChangeListener() {
return true;
}
@Override
public void populate(TextureBackground background) {
this.detailPane.populate(background);
}
@Override
public TextureBackground update() {
try {
return (TextureBackground) this.detailPane.update();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
@Override
public String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Basic_Background_Texture");
}
@Override
public boolean accept(Background background) {
return background instanceof TextureBackground;
}
@Override
public void addChangeListener(ChangeListener changeListener) {
}
}

198
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java

@ -0,0 +1,198 @@
package com.fr.design.mainframe.theme.edit.cell;
import com.fr.base.ScreenResolution;
import com.fr.base.Style;
import com.fr.base.theme.settings.ThemedCellStyle;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.AttrScrollPane;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.BasicScrollPane;
import com.fr.design.dialog.MultiTabPane;
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane;
import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.gui.style.AbstractBasicStylePane;
import com.fr.design.gui.style.AlignmentPane;
import com.fr.design.gui.style.BorderPane;
import com.fr.design.gui.style.FormatPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.ui.BorderUtils;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* 复杂的原型图导致复杂的画法非我所愿也
*
* @author zhou
* @since 2012-5-24上午10:36:10
*/
public class CellStyleEditPane extends MultiTabPane<ThemedCellStyle> {
private ThemedCellStyle cellStyle;
private PreviewArea previewArea;
private boolean populating;
private AttributeChangeListener attributeChangeListener;
public CellStyleEditPane() {
super();
tabPane.setOneLineTab(true);
tabPane.setDrawLine(false);
tabPane.setBorder(BorderFactory.createLineBorder(UIConstants.SHADOW_GREY));
tabPane.setLayout(new GridLayout(1, 3, 0, 0));
}
public void registerAttrChangeListener(AttributeChangeListener listener){
this.attributeChangeListener = listener;
}
private void fireAttrChangeListener() {
if (this.attributeChangeListener != null) {
this.attributeChangeListener.attributeChange();
}
}
public String title4PopupWindow() {
return i18nText("Fine-Design_Report_Custom_Style");
}
public void reset() {
populateBean(null);
}
@Override
public void populateBean(ThemedCellStyle ob) {
this.populating = true;
this.cellStyle = ob;
for (BasicPane basicPane : paneList) {
((AbstractBasicStylePane) basicPane).populateBean(ob.getStyle());
previewArea.preview(ob.getStyle());
}
this.populating = false;
}
@Override
public ThemedCellStyle updateBean() {
AbstractBasicStylePane basicStylePane = (AbstractBasicStylePane) paneList.get(tabPane.getSelectedIndex());
this.cellStyle.setStyle(basicStylePane.update(this.cellStyle.getStyle()));
return this.cellStyle;
}
@Override
public boolean accept(Object ob) {
return ob instanceof ThemedCellStyle;
}
@Override
protected List<BasicPane> initPaneList() {
paneList = new ArrayList<>();
paneList.add(new FormatPane());
paneList.add(new BorderPane());
paneList.add(new AlignmentPane());
return paneList;
}
@Override
protected void initLayout() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel jPanel = new JPanel();
jPanel.setLayout(new BorderLayout(0, 4));
JPanel previewPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
previewArea = new PreviewArea();
previewPane.setBorder(BorderUtils.createTitleBorder(i18nText("Fine-Design_Basic_Preview")));
previewPane.add(previewArea, BorderLayout.CENTER);
this.add(previewPane, BorderLayout.NORTH);
this.add(jPanel, BorderLayout.CENTER);
jPanel.add(tabPane, BorderLayout.NORTH);
JPanel attrListenerPane = new AbstractAttrNoScrollPane() {
@Override
protected void initContentPane() {
leftContentPane = createContentPane();
this.add(leftContentPane, BorderLayout.CENTER);
}
@Override
protected JPanel createContentPane() {
this.addAttributeChangeListener(new AttributeChangeListener() {
@Override
public void attributeChange() {
if (populating) {
return;
}
ThemedCellStyle cellStyle = updateBean();
if (cellStyle != null) {
previewArea.preview(cellStyle.getStyle());
}
fireAttrChangeListener();
}
});
BasicScrollPane basicScrollPane = new AttrScrollPane() {
@Override
protected JPanel createContentPane() {
return centerPane;
}
};
return basicScrollPane;
}
};
jPanel.add(attrListenerPane, BorderLayout.CENTER);
}
@Override
public void updateBean(ThemedCellStyle ob) {}
private static class PreviewArea extends JComponent {
private static final String paintText = "Report";
private Style style = Style.DEFAULT_STYLE;
public PreviewArea() {
setPreferredSize(new Dimension(223, 30));
}
public void preview(Style style) {
this.style = style;
repaint();
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int resolution = ScreenResolution.getScreenResolution();
if (style == Style.DEFAULT_STYLE) {
// 如果是默认的style,就只写"Report"上去
Style.paintContent(g2d, paintText, style, getWidth() - 3, getHeight() - 3, resolution);
return;
}
Style.paintBackground(g2d, style, getWidth() - 3, getHeight() - 3);
Style.paintContent(g2d, paintText, style, getWidth() - 3, getHeight() - 3, resolution);
Style.paintBorder(g2d, style, getWidth() - 3, getHeight() - 3);
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
}
}

19
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java

@ -0,0 +1,19 @@
package com.fr.design.mainframe.theme.edit.cell;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.style.AlignmentPane;
import com.fr.design.gui.style.FormatPane;
import java.util.ArrayList;
import java.util.List;
public class NoBorderPaneCellStyleEditPane extends CellStyleEditPane {
@Override
protected List<BasicPane> initPaneList() {
paneList = new ArrayList<>();
paneList.add(new FormatPane());
paneList.add(new AlignmentPane());
return paneList;
}
}

50
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/AbstractChartStylePane.java

@ -0,0 +1,50 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.icontainer.UIScrollPane;
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;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-17
*/
public abstract class AbstractChartStylePane extends BasicPane {
public AbstractChartStylePane() {
initComponents();
initPane();
}
protected abstract void initComponents();
protected void initPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
double e1 = 75;
double e = 155;
double p = TableLayout.PREFERRED;
double[] columnSize = {e1, e};
JPanel gapTableLayoutPane = TableLayoutHelper.createGapTableLayoutPane(getComponent(), getRows(p), columnSize, 20, LayoutConstants.VGAP_LARGE);
gapTableLayoutPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
UIScrollPane rightTopPane = new UIScrollPane(gapTableLayoutPane);
rightTopPane.setBorder(BorderFactory.createEmptyBorder());
this.add(rightTopPane, BorderLayout.CENTER);
}
protected abstract Component[][] getComponent();
protected abstract double[] getRows(double p);
public abstract void populate(ThemedChartStyle chartStyle);
public abstract void update(ThemedChartStyle chartStyle);
}

69
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartAxisStylePane.java

@ -0,0 +1,69 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.style.color.ColorSelectBox;
import java.awt.Component;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-16
*/
public class ChartAxisStylePane extends AbstractChartStylePane {
//轴标题字体样式
private ChartFontPane titleFontPane;
//轴标签字体样式
private ChartFontPane labelFontPane;
//轴线颜色
private ColorSelectBox axisLineColor;
protected void initComponents() {
titleFontPane = new ChartFontPane() {
public String getUILabelText() {
return Toolkit.i18nText("Fine-Design_Chart_Axis_Title_Character");
}
};
labelFontPane = new ChartFontPane() {
public String getUILabelText() {
return Toolkit.i18nText("Fine-Design_Chart_Axis_Label_Character");
}
};
axisLineColor = new ColorSelectBox(100);
}
protected Component[][] getComponent() {
return new Component[][]{
new Component[]{titleFontPane, null},
new Component[]{labelFontPane, null},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Axis_Line_Color")), axisLineColor}
};
}
protected double[] getRows(double p) {
return new double[]{p, p, p};
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Chart_Axis");
}
public void populate(ThemedChartStyle chartStyle) {
titleFontPane.populate(chartStyle.getAxisTitleFont());
labelFontPane.populate(chartStyle.getAxisLabelFont());
axisLineColor.setSelectObject(chartStyle.getAxisLineColor());
}
public void update(ThemedChartStyle chartStyle) {
chartStyle.setAxisTitleFont(titleFontPane.update());
chartStyle.setAxisLabelFont(labelFontPane.update());
chartStyle.setAxisLineColor(axisLineColor.getSelectObject());
}
}

58
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartDataSheetStylePane.java

@ -0,0 +1,58 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.style.color.ColorSelectBox;
import java.awt.Component;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-17
*/
public class ChartDataSheetStylePane extends AbstractChartStylePane {
//字体样式
private ChartFontPane fontPane;
//边框颜色
private ColorSelectBox borderColor;
protected void initComponents() {
fontPane = new ChartFontPane() {
public String getUILabelText() {
return Toolkit.i18nText("Fine-Design_Chart_DataSheet_Character");
}
};
borderColor = new ColorSelectBox(100);
}
protected Component[][] getComponent() {
return new Component[][]{
new Component[]{fontPane, null},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Border_Color")), borderColor}
};
}
protected double[] getRows(double p) {
return new double[]{p, p, p};
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Chart_Data_Sheet");
}
public void populate(ThemedChartStyle chartStyle) {
fontPane.populate(chartStyle.getDataSheetFont());
borderColor.setSelectObject(chartStyle.getDataSheetBorderColor());
}
public void update(ThemedChartStyle chartStyle) {
chartStyle.setDataSheetFont(fontPane.update());
chartStyle.setDataSheetBorderColor(borderColor.getSelectObject());
}
}

161
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java

@ -0,0 +1,161 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.base.BaseUtils;
import com.fr.base.FRContext;
import com.fr.base.Utils;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.event.UIObserverListener;
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.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.FRFont;
import com.fr.general.GeneralUtils;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-16
*/
public class ChartFontPane extends BasicPane {
public static final int FONT_START = 6;
public static final int FONT_END = 72;
private UIComboBox fontNameComboBox;
private UIComboBox fontSizeComboBox;
private UIToggleButton bold;
private UIToggleButton italic;
private UIColorButton fontColor;
private static Integer[] FONT_SIZES = new Integer[FONT_END - FONT_START + 1];
static {
for (int i = FONT_START; i <= FONT_END; i++) {
FONT_SIZES[i - FONT_START] = i;
}
}
public ChartFontPane() {
initState();
initComponents();
}
private void initState() {
fontNameComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
fontSizeComboBox = new UIComboBox(FONT_SIZES);
bold = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png"));
italic = new UIToggleButton(BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png"));
fontColor = new UIColorButton();
}
protected void initComponents() {
Component[] components = new Component[]{
fontColor, italic, bold
};
JPanel buttonPane = new JPanel(new BorderLayout());
buttonPane.add(fontSizeComboBox, BorderLayout.CENTER);
buttonPane.add(GUICoreUtils.createFlowPane(components, FlowLayout.LEFT, LayoutConstants.HGAP_LARGE), BorderLayout.EAST);
this.setLayout(new BorderLayout());
this.add(getContentPane(buttonPane), BorderLayout.CENTER);
populate(FRContext.getDefaultValues().getFRFont());
}
protected JPanel getContentPane(JPanel buttonPane) {
double e1 = 75;
double e = 155;
double p = TableLayout.PREFERRED;
double[] rows = {p, p, p};
double[] columnSize = {e1, e};
UILabel text = new UILabel(getUILabelText(), SwingConstants.LEFT);
Component[][] components = {
new Component[]{null, null},
new Component[]{text, fontNameComboBox},
new Component[]{null, buttonPane}
};
return TableLayoutHelper.createGapTableLayoutPane(components, rows, columnSize, 20, LayoutConstants.VGAP_LARGE);
}
public String getUILabelText() {
return Toolkit.i18nText("Fine-Design_Chart_Character");
}
public String title4PopupWindow() {
return null;
}
public void populate(FRFont frFont) {
UIObserverListener listener = fontNameComboBox == null ? null : fontNameComboBox.getUiObserverListener();
removeAllComboBoxListener();
if (frFont != null) {
fontNameComboBox.setSelectedItem(frFont.getFamily());
bold.setSelected(frFont.isBold());
italic.setSelected(frFont.isItalic());
populateFontSize(frFont);
if (fontColor != null) {
fontColor.setColor(frFont.getForeground());
}
}
//更新结束后,注册监听器
registerAllComboBoxListener(listener);
}
private void populateFontSize(FRFont frFont) {
if (fontSizeComboBox != null) {
fontSizeComboBox.setSelectedItem(frFont.getSize());
}
}
private void removeAllComboBoxListener() {
fontNameComboBox.removeChangeListener();
fontSizeComboBox.removeChangeListener();
}
private void registerAllComboBoxListener(UIObserverListener listener) {
fontNameComboBox.registerChangeListener(listener);
fontSizeComboBox.registerChangeListener(listener);
}
/**
* 更新字
*
* @return 更新字
*/
public FRFont update() {
String name = GeneralUtils.objectToString(fontNameComboBox.getSelectedItem());
return FRFont.getInstance(name, updateFontStyle(), updateFontSize(), fontColor.getColor());
}
private int updateFontStyle() {
int style = Font.PLAIN;
if (bold.isSelected() && !italic.isSelected()) {
style = Font.BOLD;
} else if (!bold.isSelected() && italic.isSelected()) {
style = Font.ITALIC;
} else if (bold.isSelected() && italic.isSelected()) {
style = 3;
}
return style;
}
private float updateFontSize() {
return Float.parseFloat(GeneralUtils.objectToString(fontSizeComboBox.getSelectedItem()));
}
}

78
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLabelStylePane.java

@ -0,0 +1,78 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-16
*/
public class ChartLabelStylePane extends AbstractChartStylePane {
private UIButtonGroup<Integer> autoButton;
//字体样式
private ChartFontPane chartFontPane;
protected void initComponents() {
autoButton = new UIButtonGroup<>(new String[]{Toolkit.i18nText("Fine-Design_Chart_Auto"),
Toolkit.i18nText("Fine-Design_Chart_Custom")});
chartFontPane = new ChartFontPane() {
public String getUILabelText() {
return Toolkit.i18nText("Fine-Design_Chart_Label_Character");
}
};
initListener();
}
protected Component[][] getComponent() {
return new Component[][]{
new Component[]{null, null},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Style_Setting")), autoButton},
new Component[]{chartFontPane, null}
};
}
protected double[] getRows(double p) {
return new double[]{p, p, p};
}
private void initListener() {
autoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
checkPreButton();
}
});
}
private void checkPreButton() {
chartFontPane.setVisible(autoButton.getSelectedIndex() == 1);
chartFontPane.setPreferredSize(autoButton.getSelectedIndex() == 1 ? new Dimension(0, 60) : new Dimension(0, 0));
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Chart_Label");
}
public void populate(ThemedChartStyle chartStyle) {
autoButton.setSelectedIndex(chartStyle.isAutoLabelFont() ? 0 : 1);
chartFontPane.populate(chartStyle.getLabelFont());
checkPreButton();
}
public void update(ThemedChartStyle chartStyle) {
chartStyle.setAutoLabelFont(autoButton.getSelectedIndex() == 0);
chartStyle.setLabelFont(chartFontPane.update());
}
}

49
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLegendStylePane.java

@ -0,0 +1,49 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.design.i18n.Toolkit;
import java.awt.Component;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-16
*/
public class ChartLegendStylePane extends AbstractChartStylePane {
//字体样式
private ChartFontPane chartFontPane;
protected void initComponents() {
chartFontPane = new ChartFontPane() {
public String getUILabelText() {
return Toolkit.i18nText("Fine-Design_Chart_Legend_Character");
}
};
}
protected Component[][] getComponent() {
return new Component[][]{
new Component[]{chartFontPane, null}
};
}
protected double[] getRows(double p) {
return new double[]{p};
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Chart_Legend");
}
public void populate(ThemedChartStyle chartStyle) {
chartFontPane.populate(chartStyle.getLegendFont());
}
public void update(ThemedChartStyle chartStyle) {
chartStyle.setLegendFont(chartFontPane.update());
}
}

88
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartSeriesStylePane.java

@ -0,0 +1,88 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog;
import com.fr.design.style.background.gradient.FixedGradientBar;
import java.util.List;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-17
*/
public class ChartSeriesStylePane extends AbstractChartStylePane {
private UIButtonGroup<Integer> colorTypeButton;
private FixedGradientBar gradientBar;
protected void initComponents() {
colorTypeButton = new UIButtonGroup<>(new String[]{Toolkit.i18nText("Fine-Design_Chart_Custom_Color"),
Toolkit.i18nText("Fine-Design_Chart_Legend_Gradual")});
gradientBar = new FixedGradientBar(4, 130);
initListener();
}
protected Component[][] getComponent() {
return new Component[][]{
new Component[]{null, null},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Match_Color_Scheme")), colorTypeButton},
new Component[]{null, gradientBar}
};
}
protected double[] getRows(double p) {
return new double[]{p, p, p};
}
private void initListener() {
colorTypeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
checkTypeButton();
}
});
}
private void checkTypeButton() {
gradientBar.setVisible(colorTypeButton.getSelectedIndex() == 1);
gradientBar.setPreferredSize(colorTypeButton.getSelectedIndex() == 1 ? new Dimension(0, 60) : new Dimension(0, 0));
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Chart_Series");
}
public void populate(ThemedChartStyle chartStyle) {
if (chartStyle.getThemedChartSeriesColor().isCombineColor()) {
List<Color> editingColorScheme = TemplateThemeProfileDialog.getEditingColorScheme();
colorTypeButton.setSelectedIndex(0);
gradientBar.updateColor(editingColorScheme.get(0), editingColorScheme.get(1));
} else {
colorTypeButton.setSelectedIndex(1);
gradientBar.updateColor(chartStyle.getThemedChartSeriesColor().getBeginColor(), chartStyle.getThemedChartSeriesColor().getEndColor());
}
checkTypeButton();
}
public void populateGradientBar(List<Color> colors) {
gradientBar.updateColor(colors.get(0), colors.get(1));
this.repaint();
}
public void update(ThemedChartStyle chartStyle) {
chartStyle.getThemedChartSeriesColor().setCombineColor(colorTypeButton.getSelectedIndex() == 0);
chartStyle.getThemedChartSeriesColor().setBeginColor(gradientBar.getSelectColorPointBtnP1().getColorInner());
chartStyle.getThemedChartSeriesColor().setEndColor(gradientBar.getSelectColorPointBtnP2().getColorInner());
}
}

36
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleAndBackgroundStyleFormPane.java

@ -0,0 +1,36 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import java.awt.Color;
import java.awt.Component;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2021-08-30
*/
public class ChartTitleAndBackgroundStyleFormPane extends ChartTitleAndBackgroundStylePane {
private UILabel tooltipLabel;
protected void initComponents() {
super.initComponents();
tooltipLabel = new UILabel("<html>" + Toolkit.i18nText("Fine-Design_Chart_Title_Background_Tooltip") + "</html>");
tooltipLabel.setForeground(new Color(153, 153, 153));
}
protected Component[][] getComponent() {
Component[][] component = super.getComponent();
Component[][] newComponent = new Component[component.length + 2][];
System.arraycopy(component, 0, newComponent, 2, component.length);
newComponent[0] = new Component[]{null, null};
newComponent[1] = new Component[]{tooltipLabel, null};
return newComponent;
}
protected double[] getRows(double p) {
return new double[]{p, p, p, p, p, p, p};
}
}

127
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleAndBackgroundStylePane.java

@ -0,0 +1,127 @@
package com.fr.design.mainframe.theme.edit.chart;
import com.fr.base.background.ImageBackground;
import com.fr.base.theme.settings.ThemedChartStyle;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.backgroundpane.BackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.ColorBackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.ImageBackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.NullBackgroundQuickPane;
import com.fr.design.mainframe.backgroundpane.VanChartGradientPane;
import com.fr.design.style.color.ColorSelectBox;
import com.fr.general.Background;
import com.fr.stable.Constants;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.List;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-16
*/
public class ChartTitleAndBackgroundStylePane extends AbstractChartStylePane {
//字体样式
private ChartFontPane chartFontPane;
private UIComboBox typeComboBox;
private List<BackgroundQuickPane> paneList;
private JPanel centerPane;
//网格线颜色
private ColorSelectBox mainGridColor;
protected void initComponents() {
chartFontPane = new ChartFontPane() {
public String getUILabelText() {
return Toolkit.i18nText("Fine-Design_Chart_Title_Character");
}
};
mainGridColor = new ColorSelectBox(100);
typeComboBox = new UIComboBox();
final CardLayout cardlayout = new CardLayout();
initList();
centerPane = new JPanel(cardlayout) {
@Override
public Dimension getPreferredSize() {// AUGUST:使用当前面板的的高度
int index = typeComboBox.getSelectedIndex();
return new Dimension(super.getPreferredSize().width, paneList.get(index).getPreferredSize().height);
}
};
for (int i = 0; i < paneList.size(); i++) {
BackgroundQuickPane pane = paneList.get(i);
typeComboBox.addItem(pane.title4PopupWindow());
centerPane.add(pane, pane.title4PopupWindow());
}
typeComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
cardlayout.show(centerPane, (String) typeComboBox.getSelectedItem());
}
});
}
private void initList() {
paneList = new ArrayList<>();
paneList.add(new NullBackgroundQuickPane());
paneList.add(new ColorBackgroundQuickPane());
paneList.add(new ImageBackgroundQuickPane(false));
paneList.add(new VanChartGradientPane());
}
protected Component[][] getComponent() {
return new Component[][]{
new Component[]{chartFontPane, null},
new Component[]{null, null},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Area_Background_Color")), typeComboBox},
new Component[]{null, centerPane},
new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Grid_Line_Color")), mainGridColor}
};
}
protected double[] getRows(double p) {
return new double[]{p, p, p, p, p};
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Chart_Title_Background");
}
public void populate(ThemedChartStyle chartStyle) {
chartFontPane.populate(chartStyle.getTitleFont());
Background background = chartStyle.getChartBackground();
for (int i = 0; i < paneList.size(); i++) {
BackgroundQuickPane pane = paneList.get(i);
if (pane.accept(background)) {
pane.populateBean(background);
typeComboBox.setSelectedIndex(i);
break;
}
}
mainGridColor.setSelectObject(chartStyle.getGridMainLineColor());
}
public void update(ThemedChartStyle chartStyle) {
chartStyle.setTitleFont(chartFontPane.update());
chartStyle.setChartBackground(paneList.get(typeComboBox.getSelectedIndex()).updateBean());
if (chartStyle.getChartBackground() instanceof ImageBackground) {
((ImageBackground) chartStyle.getChartBackground()).setLayout(Constants.IMAGE_EXTEND);
}
chartStyle.setGridMainLineColor(mainGridColor.getSelectObject());
}
}

101
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/component/ComponentMarginStylePane.java

@ -0,0 +1,101 @@
package com.fr.design.mainframe.theme.edit.component;
import com.fr.base.theme.settings.ThemedComponentStyle;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.gui.ilable.UILabel;
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 javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.Component;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* Created by kerry on 2020-09-01
*/
public class ComponentMarginStylePane extends JPanel {
private final int uiLabelWidth;
private final int uiSettingWidth;
protected UISpinner top;
protected UISpinner bottom;
protected UISpinner left;
protected UISpinner right;
public ComponentMarginStylePane(int uiLabelWidth, int uiSettingWidth) {
this.uiLabelWidth = uiLabelWidth;
this.uiSettingWidth = uiSettingWidth;
initBoundPane(0, 0, 0, 0);
}
public void initBoundPane(int t, int b, int l, int r) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
top = new UISpinner(0, Integer.MAX_VALUE, 1, t);
bottom = new UISpinner(0, Integer.MAX_VALUE, 1, b);
left = new UISpinner(0, Integer.MAX_VALUE, 1, l);
right = new UISpinner(0, Integer.MAX_VALUE, 1, r);
top.setGlobalName(i18nText("Fine-Design_Form_Layout_Padding_Duplicate"));
bottom.setGlobalName(i18nText("Fine-Design_Form_Layout_Padding_Duplicate"));
left.setGlobalName(i18nText("Fine-Design_Form_Layout_Padding_Duplicate"));
right.setGlobalName(i18nText("Fine-Design_Form_Layout_Padding_Duplicate"));
UILabel uiLabel = new UILabel(i18nText("Fine-Design_Form_Layout_Padding_Duplicate"));
uiLabel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0));
uiLabel.setVerticalAlignment(SwingConstants.TOP);
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
double[] rowSize = { p };
double[] columnSize = { this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f };
JPanel panel = TableLayoutHelper.createGapTableLayoutPane(
new Component[][]{new Component[]{uiLabel, createPaddingPane()}},
rowSize, columnSize,
IntervalConstants.INTERVAL_L1, 0
);
this.add(panel);
}
public JPanel createPaddingPane() {
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
double[] rowSize = {p, p, p, p};
double[] columnSize = {f, f};
Component[][] paddingPane = new Component[][]{
new Component[]{top, bottom},
new Component[]{createLabelByKey("Fine-Design_Report_Top"), createLabelByKey("Fine-Design_Report_Bottom")},
new Component[]{left, right},
new Component[]{createLabelByKey("Fine-Design_Report_Left"), createLabelByKey("Fine-Design_Basic_Right")}
};
return TableLayoutHelper.createGapTableLayoutPane(paddingPane, rowSize, columnSize, IntervalConstants.INTERVAL_L6, IntervalConstants.INTERVAL_L6);
}
public void populate(ThemedComponentStyle componentStyle) {
this.top.setValue(componentStyle.getPaddingTop());
this.bottom.setValue(componentStyle.getPaddingBottom());
this.left.setValue(componentStyle.getPaddingLeft());
this.right.setValue(componentStyle.getPaddingRight());
}
public void update(ThemedComponentStyle componentStyle) {
componentStyle.setPaddingTop((int) this.top.getValue());
componentStyle.setPaddingBottom((int) this.bottom.getValue());
componentStyle.setPaddingLeft((int) this.left.getValue());
componentStyle.setPaddingRight((int) this.right.getValue());
}
private UILabel createLabelByKey(String key) {
return new UILabel(i18nText(key), SwingConstants.CENTER);
}
}

147
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListExtendedPane.java

@ -0,0 +1,147 @@
package com.fr.design.mainframe.theme.edit.ui;
import com.fr.base.theme.FineColorManager;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/7
*/
public class ColorListExtendedPane extends JPanel implements MouseListener {
public static final int DEFAULT_COLOR_COUNT = 8;
public static final int DEFAULT_EXTENDED_COUNT = 5;
public static final int DEFAULT_COLOR_SIZE = 16;
public static final int DEFAULT_COLOR_GAP = 3;
public static final ExtendedColorComputer DEFAULT_EXTENDED_COMPUTER = new ExtendedColorComputer() {
@Override
public Color computeExtendedColor(Color color, int index, int count) {
return FineColorManager.computeExtendedColor(color, index, count);
}
};
private final boolean selectable;
private final int colorCount;
private final int extendedCount;
private final int boxSize;
private final int boxGap;
private final List<Color> colorList = new ArrayList<>();
private ExtendedColorComputer extendedColorComputer = DEFAULT_EXTENDED_COMPUTER;
private int selectedColorIndex = -1;
private int selectedExtendedIndex = -1;
public ColorListExtendedPane() {
this(false, DEFAULT_COLOR_COUNT, DEFAULT_EXTENDED_COUNT, DEFAULT_COLOR_SIZE, DEFAULT_COLOR_GAP);
}
public ColorListExtendedPane(boolean selectable, int colorCount, int extendedCount, int boxSize, int boxGap) {
setLayout(FRGUIPaneFactory.createBorderLayout());
this.selectable = selectable;
this.colorCount = Math.max(1, colorCount);
this.extendedCount = extendedCount;
this.boxSize = boxSize;
this.boxGap = boxGap;
for (int i = 0; i < colorCount; i++) {
colorList.add(Color.WHITE);
}
int width = colorCount * boxSize + (colorCount - 1) * boxGap;
int height = extendedCount * boxSize + (extendedCount - 1) * boxGap;
setPreferredSize(new Dimension(width, height));
}
public void populate(List<Color> colors) {
if (colors.size() > 0) {
colorList.clear();
for (int i = 0; i < colorCount; i++) {
Color color = colors.get(i % colorCount);
colorList.add(color);
}
repaint();
}
}
public List<Color> update() {
return new ArrayList<>(colorList);
}
public void setExtendedColorComputer(ExtendedColorComputer extendedColorComputer) {
this.extendedColorComputer = extendedColorComputer;
}
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
int colorIndex = x / (boxSize + boxGap);
int colorX = colorIndex * (boxSize + boxGap);
int extendedIndex = y / boxSize;
int extendedY = extendedIndex * boxSize;
if (colorX <= x && x <= colorX + boxSize && extendedY <= y && y <= extendedY + boxSize) {
selectedColorIndex = colorIndex;
selectedExtendedIndex = extendedIndex;
} else {
selectedColorIndex = -1;
selectedExtendedIndex = -1;
}
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
public interface ExtendedColorComputer {
Color computeExtendedColor(Color color, int index, int count);
}
@Override
public void paint(Graphics g) {
super.paint(g);
Color oldColor = g.getColor();
for (int i = 0; i < colorList.size(); i++) {
int x = i * (boxSize + boxGap);
for (int j = 0; j < extendedCount; j++) {
Color color = extendedColorComputer.computeExtendedColor(colorList.get(i), j, extendedCount);
g.setColor(color);
int y = j * (boxSize + boxGap);
g.fillRect(x, y, boxSize, boxSize);
}
}
g.setColor(oldColor);
}
}

203
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java

@ -0,0 +1,203 @@
package com.fr.design.mainframe.theme.edit.ui;
import com.fr.base.FineColor;
import com.fr.base.background.ColorBackground;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.style.AbstractSelectBox;
import com.fr.design.style.color.NewColorSelectPane;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/7
*/
public class ColorListPane extends JPanel implements UIObserver {
public static final int DEFAULT_COLOR_COUNT = 8;
public static final int DEFAULT_COLOR_SIZE = 16;
public static final int DEFAULT_COLOR_GAP = 3;
private final int colorCount;
private final List<Color> colorList = new ArrayList<>();
private final List<ColorButton> colorButtons = new ArrayList<>();
private final EventListenerList colorChangeListenerList = new EventListenerList();
private UIObserverListener uiObserverListener;
public ColorListPane() {
this(DEFAULT_COLOR_COUNT, DEFAULT_COLOR_SIZE, DEFAULT_COLOR_GAP);
}
public ColorListPane(int colorCount, int boxSize, int boxGap) {
this.colorCount = Math.max(1, colorCount);
for (int i = 0; i < colorCount; i++) {
colorList.add(Color.WHITE);
}
setLayout(new GridLayout(1, 8, boxGap, 0));
for (int i = 0; i < colorCount; i++) {
ColorButton colorButton = new ColorButton(null);
colorButton.setPreferredSize(new Dimension(boxSize, boxSize));
add(colorButton);
int index = i;
colorButton.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
colorList.set(index, colorButton.getSelectObject());
fireColorStateChanged();
}
});
colorButtons.add(colorButton);
}
setPreferredSize(new Dimension(colorCount * boxSize + (colorCount - 1) * boxGap, boxSize));
iniListener();
}
private void iniListener() {
if (shouldResponseChangeListener()) {
this.addColorChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (uiObserverListener == null) {
return;
}
uiObserverListener.doChange();
}
});
}
}
public void populate(List<Color> colors) {
for (int i = 0; i < colors.size() && i < colorList.size(); i++) {
Color color = colors.get(i % colorCount);
colorList.set(i, color);
colorButtons.get(i).setSelectObject(color);
}
}
public List<Color> update() {
return new ArrayList<>(colorList);
}
public void addColorChangeListener(ChangeListener changeListener) {
colorChangeListenerList.add(ChangeListener.class, changeListener);
}
public void removeColorChangeListener(ChangeListener changeListener) {
colorChangeListenerList.remove(ChangeListener.class, changeListener);
}
public void fireColorStateChanged() {
Object[] listeners = colorChangeListenerList.getListenerList();
ChangeEvent e = null;
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ChangeListener.class) {
if (e == null) {
e = new ChangeEvent(this);
}
((ChangeListener) listeners[i + 1]).stateChanged(e);
}
}
}
public void registerChangeListener(UIObserverListener listener) {
uiObserverListener = listener;
}
public boolean shouldResponseChangeListener() {
return true;
}
private static class ColorButton extends AbstractSelectBox<Color> {
private Color color;
private NewColorSelectPane colorPane;
private ChangeListener changeListener;
public ColorButton(Color color) {
this.color = color;
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
showPopupMenu();
}
});
}
@Override
public JPanel initWindowPane(double preferredWidth) {
colorPane = new NewColorSelectPane(false) {
@Override
public void setVisible(boolean b) {
super.setVisible(b);
}
@Override
protected boolean selectRealTime() {
return false;
}
};
colorPane.setColor(this.getSelectObject());
colorPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
hidePopupMenu();
FineColor fineColor = ((NewColorSelectPane) e.getSource()).getColor();
// 不要直接使用原始的FineColor对象,它的值会变化,这里实际需要的内部的真实颜色
color = fineColor.getColor();
fireDisplayComponent(ColorBackground.getInstance(color));
ColorListPane.ColorButton.this.fireStateChanged();
}
});
return colorPane;
}
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(color);
g2d.fill(new Rectangle2D.Double(0, 0, getWidth(), getHeight()));
}
public void fireStateChanged() {
if (changeListener != null) {
changeListener.stateChanged(null);
}
}
public void addChangeListener(ChangeListener changeListener) {
this.changeListener = changeListener;
}
public Color getSelectObject() {
return this.color;
}
public void setSelectObject(Color color) {
this.color = color;
if (this.colorPane != null) {
this.colorPane.setColor(color);
}
fireDisplayComponent(ColorBackground.getInstance(color));
}
}
}

29
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java

@ -0,0 +1,29 @@
package com.fr.design.mainframe.theme.edit.ui;
import com.fr.design.gui.ilable.UILabel;
import com.fr.general.FRFont;
import java.awt.Color;
import java.awt.Font;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/15
*/
public class LabelUtils {
public static UILabel createLabel(String title) {
return createLabel(title, new Color(51, 51, 52));
}
public static UILabel createLabel(String title, Color color) {
return createLabel(title, color, 12);
}
public static UILabel createLabel(String title, Color color, int size) {
UILabel uiLabel = new UILabel(title);
uiLabel.setForeground(color);
Font newFont = FRFont.getInstance(uiLabel.getFont().getFontName(), Font.PLAIN, size);
uiLabel.setFont(newFont);
return uiLabel;
}
}

73
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java

@ -0,0 +1,73 @@
package com.fr.design.mainframe.theme.edit.ui;
import com.fr.design.gui.ibutton.UITabGroup;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.util.Arrays;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/12
*/
public class TabbedPane extends JPanel {
protected UITabGroup buttonGroup;
public JPanel tabContentPane;
public CardLayout cardLayout;
private String[] names = new String[]{};
private JComponent[] panes = new JComponent[]{};
public TabbedPane(String[] names, JComponent[] panes) {
setLayout(FRGUIPaneFactory.createBorderLayout());
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
for (JComponent pane :panes) {
pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
int count = Math.min(names.length, panes.length);
if (count > 0) {
this.names = names.length > count ? Arrays.copyOf(names, count) : names;
this.panes = panes.length > count ? Arrays.copyOf(panes, count) : panes;
initializeTabPane();
}
}
private void initializeTabPane() {
buttonGroup = new UITabGroup(this.names) {
@Override
public void tabChanged(int index) {
super.tabChanged(index);
cardLayout.show(tabContentPane, names[buttonGroup.getSelectedIndex()]);
}
};
buttonGroup.setDrawLine(true);
cardLayout = new CardLayout();
tabContentPane = new JPanel(cardLayout) {
@Override
public Dimension getPreferredSize() {
int selectedIndex = buttonGroup.getSelectedIndex();
if (selectedIndex < 0) {
return super.getPreferredSize();
} else {
return panes[selectedIndex].getPreferredSize();
}
}
};
for (int i = 0; i < this.names.length; i++) {
tabContentPane.add(panes[i], names[i]);
}
buttonGroup.setSelectedIndex(0);
cardLayout.show(tabContentPane, names[0]);
add(buttonGroup, BorderLayout.NORTH);
add(tabContentPane, BorderLayout.CENTER);
}
}

34
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartComponentPreviewPane.java

@ -0,0 +1,34 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.theme.FormTheme;
import java.awt.Component;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class ChartComponentPreviewPane extends ComponentPreviewPane implements ThemePreviewed<FormTheme> {
private ChartPreviewPane contentPane;
public ChartComponentPreviewPane(boolean showTitle) {
super(showTitle);
}
@Override
protected Component createContentPane() {
contentPane = new ChartPreviewPane();
return contentPane;
}
@Override
public void refresh(FormTheme theme) {
super.refresh(theme);
contentPane.refresh(theme);
}
public ChartPreviewPane getContentPane() {
return contentPane;
}
}

80
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartPreviewPane.java

@ -0,0 +1,80 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.chart.BaseChartCollection;
import com.fr.base.chart.BaseChartPainter;
import com.fr.base.chart.chartdata.CallbackEvent;
import com.fr.base.chart.result.WebChartIDInfo;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.TemplateThemeCompatible;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.design.gui.chart.MiddleChartComponent;
import com.fr.script.Calculator;
import com.fr.stable.core.PropertyChangeListener;
import javax.swing.BorderFactory;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class ChartPreviewPane extends MiddleChartComponent implements ThemePreviewed<TemplateTheme> {
private ChartCollection chartCollection;
private CallbackEvent callbackEvent;
public ChartPreviewPane() {
this.setBorder(BorderFactory.createEmptyBorder(0, 1, 2, 1));
}
public void setCallbackEvent(CallbackEvent callbackEvent) {
this.callbackEvent = callbackEvent;
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g);
if (chartCollection != null) {
drawChart(g2d);
}
drawChart(g2d);
}
private void drawChart(Graphics2D g2d) {
Dimension d = getBounds().getSize();
int chartWidth = d.width;
int chartHeight = d.height;
BaseChartPainter painter = chartCollection.createResultChartPainterWithOutDealFormula(Calculator.createCalculator(),
WebChartIDInfo.createEmptyDesignerInfo(), chartWidth, chartHeight);
painter.paint(g2d, chartWidth, chartHeight, 0, null, callbackEvent);
}
@Override
public void populate(BaseChartCollection cc) {
this.chartCollection = (ChartCollection) cc;
}
@Override
public BaseChartCollection update() {
return this.chartCollection;
}
@Override
public void reset() {
}
@Override
public void addStopEditingListener(PropertyChangeListener list) {
}
@Override
public void refresh(TemplateTheme style) {
chartCollection.onTemplateUsingThemeChange(style, TemplateThemeCompatible.NONE);
}
}

163
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java

@ -0,0 +1,163 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.BaseUtils;
import com.fr.base.Style;
import com.fr.base.background.ImageBackground;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.settings.ThemedComponentStyle;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.form.ui.Label;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.WidgetValue;
import com.fr.general.Background;
import com.fr.general.act.BorderPacker;
import com.fr.general.act.TitlePacker;
import com.fr.stable.Constants;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public abstract class ComponentPreviewPane extends UINoOpaquePanel implements ThemePreviewed<FormTheme> {
public static final int TITLE_HEIGHT = 35;
private final JPanel container;
private TitleDemoPane titlePane;
private BorderPacker style = new LayoutBorderStyle();
public ComponentPreviewPane(){
this(false);
}
public ComponentPreviewPane(boolean showTitle) {
container = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
setLayout(new BorderLayout());
if (showTitle) {
titlePane = new TitleDemoPane();
titlePane.setPreferredSize(new Dimension(517, TITLE_HEIGHT));
container.add(titlePane, BorderLayout.NORTH);
}
container.add(createContentPane(), BorderLayout.CENTER);
add(container, BorderLayout.CENTER);
}
protected abstract Component createContentPane();
@Override
public void refresh(FormTheme theme) {
ThemedComponentStyle componentStyle = theme.getComponentStyle();
style = componentStyle.getStyle();
setBorder(new UIRoundedBorder(style.getBorder(), style.getColor(), style.getBorderRadius()));
int paddingTop = componentStyle.getPaddingTop();
int paddingBottom = componentStyle.getPaddingBottom();
int paddingLeft = componentStyle.getPaddingLeft();
int paddingRight = componentStyle.getPaddingRight();
container.setBorder(BorderFactory.createEmptyBorder(paddingTop, paddingLeft, paddingBottom, paddingRight));
if (titlePane != null) {
titlePane.refresh(componentStyle);
}
}
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Border border = getBorder();
if (border instanceof UIRoundedBorder) {
UIRoundedBorder roundedBorder = (UIRoundedBorder) border;
Utils.clipByRoundBorder(g2d, getWidth(), getHeight(), roundedBorder.getRoundedCorner(), roundedBorder.getThickness());
}
int titleHeight = titlePane == null ? 0 : titlePane.getHeight();
Utils.paintBackground(g2d, style.getBackground(), new Rectangle2D.Double(0, titleHeight, getWidth(), getHeight() - titleHeight), style.getAlpha());
Utils.paintBackground(g2d, style.getBorderImage(), new Rectangle2D.Double(0, 0, getWidth(), getHeight()), style.getBorderImageOpacity());
super.paint(g);
}
private static class TitleDemoPane extends UINoOpaquePanel {
private final Label data = new Label();
public void refresh(ThemedComponentStyle componentStyle) {
BorderPacker borderPacker = componentStyle.getStyle();
TitlePacker titlePacker = componentStyle.getStyle().getTitle();
data.setColor(borderPacker.getColor());
data.setWidgetValue(new WidgetValue(String.valueOf(titlePacker.getTextObject())));
data.setFont(titlePacker.getFrFont());
data.setTextalign(titlePacker.getPosition());
data.setBackground(titlePacker.getBackground());
data.setBackgroundOpacity(titlePacker.getBackgroundOpacity());
data.setInsetImage(titlePacker.getInsetImage());
data.setInsetImagePadding(titlePacker.getInsetImagePadding());
data.setInsetRelativeTextLeft(titlePacker.isInsetRelativeTextLeft());
data.setInsetRelativeTextRight(titlePacker.isInsetRelativeTextRight());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension size = getSize();
Background background = data.getBackground();
float opacity = data.getBackgroundOpacity();
if (background != null) {
Utils.paintBackground((Graphics2D) g, background, new Rectangle2D.Double(0, 0, size.getWidth(), size.getHeight()), opacity);
}
Graphics2D g2d = (Graphics2D) g.create();
Background inset = data.getInsetImage();
Image insetImage = inset instanceof ImageBackground ? ((ImageBackground) inset).getImage() : null;
BaseUtils.drawStringStyleInRotation(g2d,
getWidth(), getHeight(),
data.getWidgetValue().toString(),
Style.getInstance(data.getFont())
.deriveHorizontalAlignment(data.getTextalign())
.deriveVerticalAlignment(data.isVerticalCenter() ? SwingConstants.CENTER : SwingConstants.TOP)
.deriveTextStyle(data.isWrap() ? Style.TEXTSTYLE_WRAPTEXT : Style.TEXTSTYLE_SINGLELINE),
insetImage, data.getInsetImagePadding(), data.isInsetRelativeTextLeft(), data.isInsetRelativeTextRight(),
Constants.FR_PAINT_RESOLUTION);
}
}
private static class Utils {
private static void paintBackground(Graphics2D g2d, Background background, Shape shape, float opacity) {
if (background != null) {
Composite oldComposite = g2d.getComposite();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, opacity));
background.paint(g2d, shape);
g2d.setComposite(oldComposite);
}
}
private static void clipByRoundBorder(Graphics2D g2d, int width, int height, int radius, int borderThickness) {
int currentClipRadius = Math.max(radius - borderThickness, 0);
g2d.clip(new RoundRectangle2D.Double(0, 0, width, height, currentClipRadius, currentClipRadius));
}
}
}

198
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java

@ -0,0 +1,198 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.BaseFormula;
import com.fr.base.background.ColorBackground;
import com.fr.base.theme.FormTheme;
import com.fr.chart.base.ChartConstants;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chart.chartattr.Title;
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.ecpreview.ECComponentPreviewPane;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.chart.PiePlot4VanChart;
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.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.Composite;
import java.awt.Graphics2D;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.geom.Rectangle2D;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class FormThemePreviewPane extends TemplateThemePreviewPane<FormTheme> {
private ECComponentPreviewPane elementCasePane;
private Background background;
private ChartComponentPreviewPane columnChartPreviewPane;
private ChartComponentPreviewPane pieChartPreviewPane;
private float alpha = 1.0F;
public FormThemePreviewPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel content = new UINoOpaquePanel();
content.setLayout(new BorderLayout());
content.add(createChartContent(), BorderLayout.CENTER);
content.add(elementCasePane = new ECComponentPreviewPane(), 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(300, 368);
}
};
columnChartPanel.setLayout(new BorderLayout());
columnChartPreviewPane = createChartPreviewPane(initColumnChart(), 300, 368);
columnChartPanel.add(columnChartPreviewPane, BorderLayout.CENTER);
JPanel pieChartPanel = new UINoOpaquePanel() {
public Dimension getPreferredSize() {
return new Dimension(217, 368);
}
};
pieChartPanel.setLayout(new BorderLayout());
pieChartPreviewPane = createChartPreviewPane(initPieChart(), 217, 368);
pieChartPanel.add(pieChartPreviewPane, BorderLayout.CENTER);
chartContent.add(columnChartPanel, BorderLayout.CENTER);
chartContent.add(pieChartPanel, BorderLayout.EAST);
return chartContent;
}
private ChartComponentPreviewPane createChartPreviewPane(ChartCollection chartCollection, int width, int height) {
ChartComponentPreviewPane chartComponentPreviewPane = new ChartComponentPreviewPane(true);
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);
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, 517, 532));
g2d.setComposite(oldComposite);
}
//柱形图
private ChartCollection initColumnChart() {
try {
VanChart chart = (VanChart) ChartTypeManager.getInstance().getCharts(VanChartColumnPlot.VAN_CHART_COLUMN_PLOT_ID)[0].clone();
chart.getTitle().setTitleVisible(false);
VanChartTools vanChartTools = chart.getVanChartTools();
vanChartTools.setSort(false);
vanChartTools.setExport(false);
vanChartTools.setFullScreen(false);
VanChartColumnPlot plot = chart.getPlot();
AttrLabel defaultAttrLabel = plot.getDefaultAttrLabel();
defaultAttrLabel.setEnable(true);
defaultAttrLabel.getAttrLabelDetail().getBorder().setBorderStyle(0);
defaultAttrLabel.getAttrLabelDetail().getBackground().setBackground(null);
plot.getConditionCollection().getDefaultAttr().addDataSeriesCondition(defaultAttrLabel);
plot.getLegend().setPosition(Constants.TOP);
plot.setPlotStyle(ChartConstants.STYLE_NONE);
plot.setSeriesOverlapPercent(30);
plot.setCategoryIntervalPercent(30);
VanChartAxis defaultYAxis = plot.getDefaultYAxis();
Title title = new Title();
title.setTextObject(Toolkit.i18nText("Fine-Design_Chart_Axis_Title"));
title.getTextAttr().setRotation(-90);
title.getTextAttr().setThemed(true);
defaultYAxis.setTitle(title);
defaultYAxis.setShowAxisTitle(true);
defaultYAxis.setCustomMaxValue(true);
defaultYAxis.setCustomMinValue(true);
defaultYAxis.setCustomMainUnit(true);
defaultYAxis.setMaxValue(BaseFormula.createFormulaBuilder().build("=600"));
defaultYAxis.setMinValue(BaseFormula.createFormulaBuilder().build("=0"));
defaultYAxis.setMainUnit(BaseFormula.createFormulaBuilder().build("=200"));
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 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();
plot.getLegend().setPosition(Constants.BOTTOM);
plot.setPlotStyle(ChartConstants.STYLE_NONE);
plot.setInnerRadiusPercent(75);
plot.getRadius().setRadiusType(RadiusType.FIXED);
plot.getRadius().setRadius(80);
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;
}
}

126
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ReportThemePreviewPane.java

@ -0,0 +1,126 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.BaseFormula;
import com.fr.base.background.ColorBackground;
import com.fr.base.theme.ReportTheme;
import com.fr.chart.base.ChartConstants;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chart.chartattr.Title;
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.ecpreview.ECReportPreviewPane;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
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.vanchart.VanChart;
import java.awt.Graphics2D;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.geom.Rectangle2D;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class ReportThemePreviewPane extends TemplateThemePreviewPane<ReportTheme> {
private Background background;
private final ECReportPreviewPane reportPreviewPane;
private final ChartPreviewPane chartPreviewPane;
public ReportThemePreviewPane(){
setLayout(FRGUIPaneFactory.createBorderLayout());
chartPreviewPane = new ChartPreviewPane();
chartPreviewPane.populate(initColumnChart());
chartPreviewPane.setCallbackEvent(this);
reportPreviewPane = new ECReportPreviewPane();
this.add(chartPreviewPane, BorderLayout.CENTER);
this.add(reportPreviewPane, BorderLayout.SOUTH);
}
@Override
public void refresh(ReportTheme theme) {
background = theme.getBodyStyle().getBackground();
reportPreviewPane.refresh(theme);
chartPreviewPane.refresh(theme);
repaint();
}
protected void paintBackground(Graphics2D g2d) {
if (background == null) {
background = ColorBackground.getInstance(Color.WHITE);
}
background.paint(g2d, new Rectangle2D.Double(0, 0, 517, 532));
}
//柱形图
private ChartCollection initColumnChart() {
try {
VanChart chart = (VanChart) ChartTypeManager.getInstance().getCharts(VanChartColumnPlot.VAN_CHART_COLUMN_PLOT_ID)[0].clone();
VanChartTools vanChartTools = chart.getVanChartTools();
vanChartTools.setSort(false);
vanChartTools.setExport(false);
vanChartTools.setFullScreen(false);
VanChartColumnPlot plot = chart.getPlot();
AttrLabel defaultAttrLabel = plot.getDefaultAttrLabel();
defaultAttrLabel.setEnable(true);
defaultAttrLabel.getAttrLabelDetail().getBorder().setBorderStyle(0);
defaultAttrLabel.getAttrLabelDetail().getBackground().setBackground(null);
plot.getConditionCollection().getDefaultAttr().addDataSeriesCondition(defaultAttrLabel);
plot.setPlotStyle(ChartConstants.STYLE_NONE);
plot.setSeriesOverlapPercent(30);
plot.setCategoryIntervalPercent(30);
VanChartAxis defaultYAxis = plot.getDefaultYAxis();
Title title = new Title();
title.setTextObject(Toolkit.i18nText("Fine-Design_Chart_Axis_Title"));
title.getTextAttr().setRotation(-90);
title.getTextAttr().setThemed(true);
defaultYAxis.setTitle(title);
defaultYAxis.setShowAxisTitle(true);
defaultYAxis.setCustomMaxValue(true);
defaultYAxis.setCustomMinValue(true);
defaultYAxis.setCustomMainUnit(true);
defaultYAxis.setMaxValue(BaseFormula.createFormulaBuilder().build("=600"));
defaultYAxis.setMinValue(BaseFormula.createFormulaBuilder().build("=0"));
defaultYAxis.setMainUnit(BaseFormula.createFormulaBuilder().build("=200"));
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;
}
}

10
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ThemePreviewed.java

@ -0,0 +1,10 @@
package com.fr.design.mainframe.theme.preview;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public interface ThemePreviewed<T> {
void refresh(T style);
}

19
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/UINoOpaquePanel.java

@ -0,0 +1,19 @@
package com.fr.design.mainframe.theme.preview;
import javax.swing.JPanel;
import java.awt.LayoutManager;
public class UINoOpaquePanel extends JPanel {
public UINoOpaquePanel(){
super();
this.setOpaque(false);
this.setBackground(null);
}
public UINoOpaquePanel(LayoutManager layout) {
super(layout, true);
this.setOpaque(false);
this.setBackground(null);
}
}

47
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/AbstractECPreviewPane.java

@ -0,0 +1,47 @@
package com.fr.design.mainframe.theme.preview.ecpreview;
import com.fr.base.Style;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyle;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.theme.preview.ThemePreviewed;
import com.fr.design.mainframe.theme.preview.UINoOpaquePanel;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.AbstractPreviewCell;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.PreviewCell;
import javax.swing.JPanel;
import java.util.List;
public abstract class AbstractECPreviewPane extends UINoOpaquePanel implements ThemePreviewed<TemplateTheme> {
protected Style getReportHeaderStyle(ThemedCellStyleList cellStyleList) {
return getCellStyle(cellStyleList, Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
}
protected Style getMainContentStyle(ThemedCellStyleList cellStyleList) {
return getCellStyle(cellStyleList, Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text"));
}
protected Style getHighLightStyle(ThemedCellStyleList cellStyleList) {
return getCellStyle(cellStyleList, Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text"));
}
protected Style getSmallTitleStyle(ThemedCellStyleList cellStyleList) {
return getCellStyle(cellStyleList, Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title"));
}
private Style getCellStyle(ThemedCellStyleList cellStyleList, String styleName) {
ThemedCellStyle cellStyle = cellStyleList.find(styleName);
if (cellStyle == null) {
return Style.DEFAULT_STYLE;
}
return cellStyle.getStyle();
}
protected void refresh(List<AbstractPreviewCell> list, Style style) {
for (AbstractPreviewCell cell : list) {
cell.refresh(style);
}
}
}

27
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECComponentPreviewPane.java

@ -0,0 +1,27 @@
package com.fr.design.mainframe.theme.preview.ecpreview;
import com.fr.base.theme.FormTheme;
import com.fr.design.mainframe.theme.preview.ComponentPreviewPane;
import java.awt.Component;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class ECComponentPreviewPane extends ComponentPreviewPane {
private ECPreviewPane contentPane;
@Override
protected Component createContentPane() {
contentPane = new ECPreviewPane();
return contentPane;
}
@Override
public void refresh(FormTheme theme) {
super.refresh(theme);
contentPane.refresh(theme);
}
}

104
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java

@ -0,0 +1,104 @@
package com.fr.design.mainframe.theme.preview.ecpreview;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.preview.UINoOpaquePanel;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.AbstractPreviewCell;
import com.fr.design.mainframe.theme.preview.ecpreview.cell.PreviewCell;
import com.fr.log.FineLoggerFactory;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class ECPreviewPane extends AbstractECPreviewPane {
private static String csv =
"城市 当月目标 当月实际完成 月度完成率 全年完成率\n" +
"南通市 324,646 324,646 100% 100%\n" +
"合肥市 248,938 348,938 140% 140%\n" +
"邵阳市 248,938 348,938 140% 140%\n" +
"合计 1,071,460 1,371,460 128% 128%";
private final List<String[]> DATA_LIST = createDataList();
private static final String BLANK_CHAR = " ";
private List<AbstractPreviewCell> headerCellList = new ArrayList<>();
private List<AbstractPreviewCell> contentCellList = new ArrayList<>();
private List<AbstractPreviewCell> hightLightCellList = new ArrayList<>();
private List<String[]> createDataList() {
List<String[]> data = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new StringReader(csv))) {
String textLine;
while ((textLine = reader.readLine()) != null) {
String[] texts = textLine.split(BLANK_CHAR);
data.add(texts);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return data;
}
public ECPreviewPane() {
this.setPreferredSize(new Dimension(517, 170));
this.setBorder(BorderFactory.createEmptyBorder(0, 1, 2, 1));
this.setLayout(FRGUIPaneFactory.createBorderLayout());
String[] titleArr = DATA_LIST.get(0);
String[] endArr = DATA_LIST.get(DATA_LIST.size() - 1);
JPanel titlePane = new UINoOpaquePanel(new GridLayout());
this.add(titlePane, BorderLayout.NORTH);
for (String title : titleArr) {
PreviewCell cell = new PreviewCell(title);
cell.setPreferredSize(new Dimension(103, 36));
titlePane.add(cell);
headerCellList.add(cell);
}
JPanel contentPane = new UINoOpaquePanel(new GridLayout(3, 5, 0, 0));
this.add(contentPane, BorderLayout.CENTER);
for (int i = 1; i < DATA_LIST.size() - 1; i++) {
String[] textLine = DATA_LIST.get(i);
for (int j = 0; j < textLine.length; j++) {
String text = textLine[j];
PreviewCell cell = new PreviewCell(text);
cell.setPreferredSize(new Dimension(103, 33));
contentPane.add(cell);
contentCellList.add(cell);
}
}
JPanel endPane = new UINoOpaquePanel(new GridLayout());
this.add(endPane, BorderLayout.SOUTH);
for (String text : endArr) {
PreviewCell cell = new PreviewCell(text);
cell.setPreferredSize(new Dimension(103, 33));
endPane.add(cell);
hightLightCellList.add(cell);
}
}
@Override
public void refresh(TemplateTheme theme) {
ThemedCellStyleList cellStyleConfig = theme.getCellStyleList();
refresh(headerCellList, getReportHeaderStyle(cellStyleConfig));
refresh(contentCellList, getMainContentStyle(cellStyleConfig));
refresh(hightLightCellList, getHighLightStyle(cellStyleConfig));
}
}

126
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java

@ -0,0 +1,126 @@
package com.fr.design.mainframe.theme.preview.ecpreview;
import com.fr.base.theme.ReportTheme;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyleList;
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.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;
public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreviewed<ReportTheme> {
private List<AbstractPreviewCell> headerCellList = new ArrayList<>();
private List<AbstractPreviewCell> titleCellList = new ArrayList<>();
private List<AbstractPreviewCell> contentCellList = new ArrayList<>();
private List<AbstractPreviewCell> highLightCellList = new ArrayList<>();
private PreviewPane previewPane;
public ECReportPreviewPane() {
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, 270));
this.setBorder(BorderFactory.createEmptyBorder(7, 10, 5, 10));
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel northPane = createNorthPane();
JPanel centerPane = createCenterPane();
this.add(northPane, BorderLayout.NORTH);
this.add(centerPane, BorderLayout.CENTER);
}
private JPanel createNorthPane() {
JPanel northPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{"产品", "数据", "统计维度"}, new Point2D[]{new Point(132, 75), new Point(189, 53)});
cornerCell.setPreferredSize(new Dimension(189, 75));
headerCellList.add(cornerCell);
northPane.add(cornerCell, BorderLayout.WEST);
JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane();
northPane.add(centerPane, BorderLayout.CENTER);
PreviewCell cell = new PreviewCell("按地区统计");
titleCellList.add(cell);
cell.setPreferredSize(new Dimension(308, 38));
centerPane.add(cell, BorderLayout.NORTH);
JPanel eastSouthPane = new UINoOpaquePanel(new GridLayout());
PreviewCell cell1 = new PreviewCell("华东");
PreviewCell cell2 = new PreviewCell("华南");
PreviewCell cell3 = new PreviewCell("小计");
headerCellList.add(cell1);
headerCellList.add(cell2);
headerCellList.add(cell3);
eastSouthPane.add(cell1);
eastSouthPane.add(cell2);
eastSouthPane.add(cell3);
centerPane.add(eastSouthPane, BorderLayout.CENTER);
return northPane;
}
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("饮料");
titleCellList.add(cell1);
cell1.setPreferredSize(new Dimension(94, 183));
westPane.add(cell1, BorderLayout.WEST);
JPanel gridPane = new UINoOpaquePanel(new GridLayout(6, 1));
for (int i = 0; i < 6; i++) {
PreviewCell cell = new PreviewCell("苹果汁");
cell.setPreferredSize(new Dimension(95, 31));
headerCellList.add(cell);
gridPane.add(cell);
}
westPane.add(gridPane, BorderLayout.CENTER);
JPanel innerCenterPane = new UINoOpaquePanel(new GridLayout(6, 3));
centerPane.add(innerCenterPane, BorderLayout.CENTER);
for (int i = 0; i < 18; i++) {
PreviewCell cell = new PreviewCell("35600");
cell.setPreferredSize(new Dimension(102, 31));
if ((i + 1) % 3 == 0) {
highLightCellList.add(cell);
} else {
contentCellList.add(cell);
}
innerCenterPane.add(cell);
}
return centerPane;
}
@Override
public void refresh(TemplateTheme theme) {
ThemedCellStyleList cellStyleConfig = theme.getCellStyleList();
refresh(headerCellList, getReportHeaderStyle(cellStyleConfig));
refresh(contentCellList, getMainContentStyle(cellStyleConfig));
refresh(titleCellList, getSmallTitleStyle(cellStyleConfig));
refresh(highLightCellList, getHighLightStyle(cellStyleConfig));
}
}
}

32
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/cell/AbstractPreviewCell.java

@ -0,0 +1,32 @@
package com.fr.design.mainframe.theme.preview.ecpreview.cell;
import com.fr.base.ScreenResolution;
import com.fr.base.Style;
import javax.swing.JComponent;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
public abstract class AbstractPreviewCell extends JComponent {
protected Style style = Style.DEFAULT_STYLE;
public void refresh(Style style) {
this.style = style;
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int resolution = ScreenResolution.getScreenResolution();
Style.paintBackground(g2d, style, getWidth(), getHeight());
paintContent(g2d, resolution);
Style.paintBorder(g2d, style, getWidth(), getHeight());
}
protected abstract void paintContent(Graphics2D g2d, int resolution);
@Override
public Dimension getMinimumSize() {
return new Dimension(125, 30);
}
}

33
designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/cell/CornerPreviewCell.java

@ -0,0 +1,33 @@
package com.fr.design.mainframe.theme.preview.ecpreview.cell;
import com.fr.general.FRFont;
import com.fr.stable.GraphDrawHelper;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
public class CornerPreviewCell extends AbstractPreviewCell {
private final String[] values;
private final Point2D[] point2DS;
public CornerPreviewCell(String[] values, Point2D[] point2DS) {
this.values = values;
this.point2DS = point2DS;
}
@Override
protected void paintContent(Graphics2D g2d, int resolution) {
FRFont frFont = style.getFRFont();
g2d.setPaint(frFont.getForeground());
g2d.drawString(values[0], 23, 53);
GraphDrawHelper.drawRotatedString(g2d, values[1], 104, 50, 30);
g2d.drawString(values[2], 128, 23);
//画分割线
for (int i = 0; i < point2DS.length; i++) {
g2d.draw(new Line2D.Double(0, 0, point2DS[i].getX(), point2DS[i].getY())); //画线
}
}
}

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

Loading…
Cancel
Save