Browse Source

Merge pull request #5579 in DESIGN/design from feature/x to release/11.0

* commit 'e949220ea20d62889d948e0f91d127da73f21e94': (60 commits)
  REPORT-58211 【主题切换】单元格样式的背景渐变色,右边按钮不好点
  REPORT-57892 公式编辑器优化:实时计算返回结果为日期格式时不正确 1.修改了一些bug; 2.根据产品调整了一些需求。
  REPORT-58209 【主题切换】配色编辑修改一个配色,会同时改变两列模板预览的配色内容
  REPORT-58038 【主题切换】模板打开,模板应用的主题修改后,右侧面板有一个快速切换的效果
  REPORT-58188 【主题切换】tab设置边框色以后,tab标题栏没了
  REPORT-58052 &&REPORT-57959 【主题切换】模板背景设置图片默认,整体预览部分显示有问题 【主题切换】细节定制-组件样式-背景中设置圆角,左侧图示看着会重叠
  REPORT-58073 【主题切换】细节定制-FRM组件样式-标题配置后点击保存,并未联动变化
  REPORT-58038 【主题切换】模板打开,模板应用的主题修改后,右侧面板有一个快速切换的效果
  REPORT-58009 【主题切换】远程设置模板主题页面的,模板主题管理入口没有屏蔽
  REPORT-58123 【主题切换】frm模板第一次打开,选中组件,切换自定义,需要点两下
  REPORT-58119 【主题切换】主题里单元格重名的弹窗里还是提示的预定义样式
  REPORT-58062 【主题切换】细节定制-单元格样式-样式数量较多,菜单栏中选择时没有滚动条
  REPORT-58067 【主题切换】细节定制-FRM组件样式-标题里多了个“文本”的设置
  REPORT-58035 demo部分模板出现报错
  REPORT-57964 【主题切换】纸张背景配置页,字体显示不全
  REPORT-58000 【主题切换】主题名称超长的展示问题 REPORT-58001 【主题切换】主题超长时应用主题工具栏就不显示主题名称及图标(自适应按钮也不显示了)
  REPORT-58089 【主题切换】单元格样式重名以后变成重命名,会导致多个重命名
  REPORT-58034 【主题切换】模板主题页面,不应该显示☆
  REPORT-58048 【主题切换】细节定制-组件样式-生效范围的提示显示不全
  REPORT-57935 【主题切换】单元格右侧设计面板显示不符合交互图
  ...
fix-lag
superman 3 years ago
parent
commit
4f68863f6c
  1. 21
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 5
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  3. 298
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  4. 18
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIColorButton.java
  5. 36
      designer-base/src/main/java/com/fr/design/gui/ibutton/UINoThemeColorButton.java
  6. 20
      designer-base/src/main/java/com/fr/design/gui/icombobox/ColorSchemeComboBox.java
  7. 20
      designer-base/src/main/java/com/fr/design/gui/style/AbstractBorderPackerPane.java
  8. 99
      designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java
  9. 8
      designer-base/src/main/java/com/fr/design/gui/style/BorderPane.java
  10. 33
      designer-base/src/main/java/com/fr/design/gui/style/ComponentBodyStylePane.java
  11. 109
      designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java
  12. 348
      designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java
  13. 141
      designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java
  14. 102
      designer-base/src/main/java/com/fr/design/gui/style/ReportBackgroundSpecialPane.java
  15. 24
      designer-base/src/main/java/com/fr/design/gui/style/TextInsetImageBackgroundSpecialPane.java
  16. 27
      designer-base/src/main/java/com/fr/design/gui/style/TitleTranslucentBackgroundSpecialPane.java
  17. 45
      designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java
  18. 9
      designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java
  19. 17
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  20. 102
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  21. 23
      designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ColorBackgroundQuickPane.java
  22. 53
      designer-base/src/main/java/com/fr/design/mainframe/predefined/ui/detail/background/ColorDetailPane.java
  23. 13
      designer-base/src/main/java/com/fr/design/mainframe/predefined/ui/preview/ChartPreStylePreView.java
  24. 86
      designer-base/src/main/java/com/fr/design/mainframe/theme/AsyncThemeFetcher.java
  25. 96
      designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java
  26. 74
      designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java
  27. 208
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java
  28. 242
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java
  29. 312
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java
  30. 88
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java
  31. 594
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java
  32. 101
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java
  33. 93
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java
  34. 145
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java
  35. 162
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java
  36. 294
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/CellStyleListEditPane.java
  37. 100
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleEditPane.java
  38. 136
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java
  39. 44
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/FormBodyStyleEditPane.java
  40. 65
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ReportBodyStyleEditPane.java
  41. 51
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/AbstractBackgroundDetailPane.java
  42. 136
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/BackgroundSettingPane.java
  43. 105
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ColorDetailPane.java
  44. 35
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/EmptyBackgroundPane.java
  45. 160
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/GradientDetailPane.java
  46. 216
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ImageDetailPane.java
  47. 120
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/PatternDetailPane.java
  48. 98
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/TextureDetailObservePane.java
  49. 198
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java
  50. 19
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java
  51. 50
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/AbstractChartStylePane.java
  52. 69
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartAxisStylePane.java
  53. 58
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartDataSheetStylePane.java
  54. 161
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java
  55. 78
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLabelStylePane.java
  56. 49
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLegendStylePane.java
  57. 88
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartSeriesStylePane.java
  58. 127
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleAndBackgroundStylePane.java
  59. 101
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/component/ComponentMarginStylePane.java
  60. 147
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListExtendedPane.java
  61. 203
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java
  62. 29
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java
  63. 73
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java
  64. 34
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartComponentPreviewPane.java
  65. 80
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartPreviewPane.java
  66. 163
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java
  67. 204
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java
  68. 130
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ReportThemePreviewPane.java
  69. 10
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ThemePreviewed.java
  70. 19
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/UINoOpaquePanel.java
  71. 47
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/AbstractECPreviewPane.java
  72. 27
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECComponentPreviewPane.java
  73. 104
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java
  74. 126
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java
  75. 32
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/cell/AbstractPreviewCell.java
  76. 33
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/cell/CornerPreviewCell.java
  77. 25
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/cell/PreviewCell.java
  78. 30
      designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BorderUtils.java
  79. 320
      designer-base/src/main/java/com/fr/design/mainframe/theme/ui/NoEdgeTitleBorder.java
  80. 36
      designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java
  81. 2
      designer-base/src/main/java/com/fr/design/report/WatermarkPane.java
  82. 6
      designer-base/src/main/java/com/fr/design/style/CustomSelectBox.java
  83. 9
      designer-base/src/main/java/com/fr/design/style/background/BackgroundPane.java
  84. 243
      designer-base/src/main/java/com/fr/design/style/background/gradient/AbstractComponentPopBox.java
  85. 53
      designer-base/src/main/java/com/fr/design/style/background/gradient/FixedGradientBarWithPopMenu.java
  86. 55
      designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java
  87. 6
      designer-base/src/main/java/com/fr/design/style/background/impl/ColorBackgroundPane.java
  88. 10
      designer-base/src/main/java/com/fr/design/style/background/impl/ColorNoThemeBackgroundPane.java
  89. 60
      designer-base/src/main/java/com/fr/design/style/color/ColorAdjustPane.java
  90. 73
      designer-base/src/main/java/com/fr/design/style/color/ColorButton.java
  91. 10
      designer-base/src/main/java/com/fr/design/style/color/ColorCell.java
  92. 12
      designer-base/src/main/java/com/fr/design/style/color/ColorControlWindow.java
  93. 2
      designer-base/src/main/java/com/fr/design/style/color/ColorControlWindowWithAuto.java
  94. 13
      designer-base/src/main/java/com/fr/design/style/color/ColorFactory.java
  95. 14
      designer-base/src/main/java/com/fr/design/style/color/ColorSelectBox.java
  96. 14
      designer-base/src/main/java/com/fr/design/style/color/ColorSelectDetailPane.java
  97. 1
      designer-base/src/main/java/com/fr/design/style/color/ColorSelectDialog.java
  98. 1
      designer-base/src/main/java/com/fr/design/style/color/ColorSelectPane.java
  99. 10
      designer-base/src/main/java/com/fr/design/style/color/DetailColorSelectPane.java
  100. 38
      designer-base/src/main/java/com/fr/design/style/color/FineColorCell.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) {

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();

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

@ -2,32 +2,76 @@ package com.fr.design.formula;
import com.fr.base.BaseFormula;
import com.fr.base.BaseUtils;
import com.fr.base.Parameter;
import com.fr.base.ParameterMapNameSpace;
import com.fr.base.TableDataNameSpace;
import com.fr.base.io.IOFile;
import com.fr.data.TableDataSource;
import com.fr.design.actions.UpdateAction;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.QuickList;
import com.fr.design.gui.itableeditorpane.ParameterTableModel;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea;
import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.parameter.ParameterInputPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.FArray;
import com.fr.log.FineLoggerFactory;
import com.fr.parser.ArrayExpression;
import com.fr.parser.BlockIntervalLiteral;
import com.fr.parser.ColumnRowRangeInPage;
import com.fr.parser.FRLexer;
import com.fr.parser.FRParser;
import com.fr.parser.FunctionCall;
import com.fr.parser.SheetIntervalLiteral;
import com.fr.report.core.namespace.SimpleCellValueNameSpace;
import com.fr.script.Calculator;
import com.fr.script.ScriptConstants;
import com.fr.script.checker.FunctionCheckerDispatcher;
import com.fr.script.checker.exception.ConditionCheckWrongException;
import com.fr.script.checker.exception.FunctionCheckWrongException;
import com.fr.script.rules.FunctionParameterType;
import com.fr.script.rules.FunctionRule;
import com.fr.stable.EncodeConstants;
import com.fr.stable.EssentialUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.stable.UtilEvalError;
import com.fr.stable.script.ColumnRowRange;
import com.fr.stable.script.Expression;
import javax.swing.*;
import com.fr.stable.script.Node;
import com.fr.stable.script.Tiny;
import com.fr.stable.script.TinyHunter;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
@ -37,7 +81,10 @@ import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
@ -53,9 +100,14 @@ import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 公式编辑面板
@ -65,6 +117,10 @@ import java.util.List;
*/
public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula");
public static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula");
public static final int DEFUAL_FOMULA_LENGTH = 103;
public static final String ELLIPSIS = "...";
private VariableTreeAndDescriptionArea variableTreeAndDescriptionArea;
private RSyntaxTextArea formulaTextArea;
private UITextField keyWordTextField = new UITextField(18);
@ -78,6 +134,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private QuickList functionTypeList;
private DefaultListModel functionNameModel;
private JList functionNameList;
private UITableEditorPane<ParameterProvider> editor4CalPane;
public FormulaPane() {
initComponents();
@ -201,6 +258,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void initTextPane() {
// text
JPanel textPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.add(textPane, BorderLayout.CENTER);
JPanel checkBoxandbuttonPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
@ -217,13 +275,19 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
UIButton checkValidButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Check_Valid"));
UIButton calButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Button"));
checkValidButton.addActionListener(checkValidActionListener);
calButton.addActionListener(calculateActionListener);
JPanel checkBoxPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
checkBoxPane.setPreferredSize(new Dimension(450, 30));
checkBoxandbuttonPane.add(checkBoxPane, BorderLayout.WEST);
checkBoxandbuttonPane.add(checkValidButton, BorderLayout.EAST);
checkBoxandbuttonPane.add(calButton, BorderLayout.EAST);
extendCheckBoxPane(checkBoxPane);
ParameterTableModel model = new ParameterTableModel(0);
editor4CalPane = new UITableEditorPane<>(model);
}
@ -585,40 +649,225 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
}
// check valid
private ActionListener checkValidActionListener = new ActionListener() {
private final ActionListener checkValidActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// Execute Formula default cell element.
String formulaText = formulaTextArea.getText().trim();
String formulaValidMessage = getFormulaValidMessage(formulaText);
FineJOptionPane.showMessageDialog(
FormulaPane.this,
formulaValidMessage + ".",
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.INFORMATION_MESSAGE);
}
};
if (formulaText != null && formulaText.length() > 0) {
StringReader in = new StringReader(formulaText);
FRLexer lexer = new FRLexer(in);
FRParser parser = new FRParser(lexer);
Expression expression = null;
try {
expression = parser.parse();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
// alex:继续往下面走,expression为null时告知不合法公式
private static String getFormulaValidMessage(String formulaText) {
StringReader in = new StringReader(formulaText);
FRLexer lexer = new FRLexer(in);
FRParser parser = new FRParser(lexer);
try {
Expression expression = parser.parse();
Node node = expression.getConditionalExpression();
return FunctionCheckerDispatcher.getInstance()
.getFunctionChecker(node)
.checkFunction(node) ? VALID_FORMULA : INVALID_FORMULA;
} catch (ConditionCheckWrongException cce) {
String functionName = cce.getFunctionName();
StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Condition_Tips") + ":");
return errorMsg.toString();
} catch (FunctionCheckWrongException ce) {
List<FunctionRule> rules = ce.getRules();
String functionName = ce.getFunctionName();
StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + ":");
for (int i = 0; i < rules.size(); i++) {
errorMsg.append("(");
if (rules.get(i).getParameterList().isEmpty()) {
errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param"));
}
for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) {
errorMsg.append(getTypeString(functionParameterType)).append(",");
}
if (",".equals(errorMsg.charAt(errorMsg.length() - 1) + "")) {
errorMsg.deleteCharAt(errorMsg.length() - 1);
}
errorMsg.append(")");
if (i != rules.size() - 1) {
errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or"));
}
}
return errorMsg.toString();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return INVALID_FORMULA;
// alex:继续往下面走,expression为null时告知不合法公式
}
}
private static String getTypeString(FunctionParameterType type) {
switch (type) {
case NUMBER:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number");
case STRING:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String");
case ANY:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any");
case DATE:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date");
case BOOLEAN:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean");
case ARRAY:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array");
}
return "";
}
private final ActionListener calculateActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String formulaText = formulaTextArea.getText().trim();
if (containsUnsupportedSimulationFormulas(formulaText)) {
FineJOptionPane.showMessageDialog(
FormulaPane.this,
/*
* alex:仅仅只需要根据expression是否为null作合法性判断
* 不需要eval
* TODO 但有个问题,有些函数的参数个数是有规定的,何以判别之
*/
(expression != null ? com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula") : com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula")) + ".",
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.INFORMATION_MESSAGE);
return;
}
String formulaValidMessage = getFormulaValidMessage(formulaText);
String messageTips;
if (formulaValidMessage.equals(INVALID_FORMULA)) {
messageTips = INVALID_FORMULA;
} else {
messageTips = formulaValidMessage.equals(VALID_FORMULA) ? "" : formulaValidMessage + "\n";
Map<String, Object> paramsMap = setParamsIfExist(formulaText);
Calculator calculator = Calculator.createCalculator();
ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(paramsMap);
calculator.pushNameSpace(parameterMapNameSpace);
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (currentEditingTemplate != null) {
IOFile file = (IOFile) currentEditingTemplate.getTarget();
calculator.setAttribute(TableDataSource.KEY, file);
calculator.pushNameSpace(TableDataNameSpace.getInstance());
calculator.pushNameSpace(SimpleCellValueNameSpace.getInstance());
}
BaseFormula baseFormula = BaseFormula.createFormulaBuilder().build(formulaText);
try {
Object value = calculator.evalValue(baseFormula);
String objectToString = EssentialUtils.objectToString(value);
String result = objectToString.length() > DEFUAL_FOMULA_LENGTH ?
objectToString.substring(0, DEFUAL_FOMULA_LENGTH - ELLIPSIS.length()) + ELLIPSIS : objectToString;
messageTips = messageTips +
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Result") + ":" + result;
FineLoggerFactory.getLogger().info("value:{}", value);
} catch (UtilEvalError utilEvalError) {
FineLoggerFactory.getLogger().error("", utilEvalError);
}
}
FineJOptionPane.showMessageDialog(
FormulaPane.this,
messageTips,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.INFORMATION_MESSAGE);
}
};
private boolean containsUnsupportedSimulationFormulas(String formulaText) {
try {
Expression expression = Calculator.createCalculator().parse(formulaText);
String name = ((FunctionCall) expression.getConditionalExpression()).getName();
if (UnsupportedSimulationFormulaHunter.isUnsupportedFomula(name)) {
return true;
}
UnsupportedSimulationFormulaHunter unsupportedSimulationFormulaHunter = new UnsupportedSimulationFormulaHunter();
expression.traversal4Tiny(unsupportedSimulationFormulaHunter);
return !unsupportedSimulationFormulaHunter.isSupported();
} catch (Exception e) {
FineLoggerFactory.getLogger().error("", e);
}
return true;
}
private Map<String, Object> setParamsIfExist(String formulaText) {
Map<String, Object> parameterMap = new HashMap<>();
try {
Calculator calculator = Calculator.createCalculator();
Expression expression = calculator.parse(formulaText);
ParameterCellHunter parameterCellHunter = new ParameterCellHunter();
expression.traversal4Tiny(parameterCellHunter);
Parameter[] parameters = parameterCellHunter.getParameterBooty();
if (parameters.length < 1 && editor4CalPane.update().size() < 1) {
return parameterMap;
}
ParameterInputPane pPane = new ParameterInputPane(parameters);
pPane.showSmallWindow(new JFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
parameterMap.putAll(pPane.update());
}
}).setVisible(true);
//过滤出数组参数,如:[1,2]
for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
if (entry.getValue().toString().startsWith("[") && entry.getValue().toString().startsWith("]")) {
Expression parse = calculator.parse(entry.getValue());
ArrayExpression arrayExpression = (ArrayExpression) parse.getConditionalExpression();
FArray<Node> fArray = new FArray<>(arrayExpression.getArrays());
parameterMap.put(entry.getKey(), fArray);
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error("", e);
}
return parameterMap;
}
private static class ParameterCellHunter extends TinyHunter {
private final Set<Parameter> parameterList = new HashSet<>();
Parameter[] getParameterBooty() {
return parameterList.toArray(new Parameter[0]);
}
public void hunter4Tiny(Tiny tiny) {
String statement = tiny.getStatement();
if (StringUtils.isNotBlank(statement) && statement.startsWith(ScriptConstants.DETAIL_TAG)) {
parameterList.add(new Parameter(statement.substring(1)));
} else if (tiny.getClass() == ColumnRowRange.class || tiny.getClass() == ColumnRowRangeInPage.class ||
tiny.getClass() == SheetIntervalLiteral.class || tiny.getClass() == BlockIntervalLiteral.class) {
parameterList.add(new Parameter(tiny.toString()));
}
}
}
private static class UnsupportedSimulationFormulaHunter extends TinyHunter {
public final static String[] UNSUPPORTED_FORMULAS = new String[]{"PROPORTION", "TOIMAGE",
"WEBIMAGE", "SORT", "CROSSLAYERTOTAL", "CIRCULAR", "LAYERTOTAL", "MOM", "HIERARCHY"};
private boolean supported = true;
public boolean isSupported() {
return supported;
}
public void hunter4Tiny(Tiny tiny) {
String statement = tiny.getStatement().toUpperCase();
if (Arrays.asList(UNSUPPORTED_FORMULAS).contains(statement)) {
supported = false;
}
}
public static boolean isUnsupportedFomula(String formula) {
return Arrays.asList(UNSUPPORTED_FORMULAS).contains(formula);
}
}
public class VariableTreeAndDescriptionArea extends JPanel {
private JTree variablesTree;
@ -805,13 +1054,13 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) variablesTree.getLastSelectedPathComponent();
Object selectedValue = selectedTreeNode.getUserObject();
Object selectedParentValue = ((DefaultMutableTreeNode)selectedTreeNode.getParent()).getUserObject();
Object selectedParentValue = ((DefaultMutableTreeNode) selectedTreeNode.getParent()).getUserObject();
if (selectedValue == null) {
return;
}
if (selectedValue instanceof TextUserObject) {
if (selectedValue instanceof TextUserObject) {
//有公式说明的条件:1.属于TextUserObject 2.parent是系统参数
if (ComparatorUtils.equals(((TextFolderUserObject) selectedParentValue).getText(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Variables"))) {
@ -1010,6 +1259,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
/**
* 把以关键词开头的和不以关键词开头的分别按照字母表顺序排序
*
* @param o1 待比较对象1
* @param o2 待比较对象2
* @return 比较结果1表示 o1 > o2, -1表示 o1 < o2, 0表示 o1 = o2

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

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

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();

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);
}
}
}
}

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

@ -0,0 +1,141 @@
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) {
TemplateTheme theme = template.getTemplateTheme();
if (theme instanceof FormTheme) {
return theme;
}
}
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/layout/FRGUIPaneFactory.java

@ -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;
}
/**
* 创建卡片式布局
*

17
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());
@ -1175,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);
}
}

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);
}
}

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

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

@ -0,0 +1,86 @@
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 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) {
callback.beforeCachedFetch();
executorService.submit(new Runnable() {
@Override
public void run() {
if (executorService.isShutdown()) {
return;
}
T theme = config.cachedFetch(themeName, new TemplateThemeConfig.CacheCondition<T>() {
@Override
public boolean shouldCacheTheme(T theme) {
return callback.shouldCache(AsyncThemeFetcher.this, theme);
}
});
if (executorService.isShutdown()) {
return;
}
callback.afterCachedFetch(theme);
}
});
}
public interface AsyncThemeFetchCallback<T extends TemplateTheme> {
void beforeCachedFetch();
boolean shouldCache(AsyncThemeFetcher<T> fetcher, T theme);
void afterCachedFetch(T theme);
}
public static class AsyncThemeFetchCallbackAdapter<T extends TemplateTheme> implements AsyncThemeFetchCallback<T> {
@Override
public void beforeCachedFetch() {
}
@Override
public boolean shouldCache(AsyncThemeFetcher<T> fetcher, T theme) {
// 如果Fetcher已经关闭就不放进缓存里了
// 因为可切换工作目录,所以submit时的工作目录环境与最终获取到主题数据时的工作目录环境可能不是同一个,
// 如果仍然放进缓存中,会污染当前工作目录环境的主题缓存.
// TODO: 除了根据asyncThemeFetch的关闭情况来判断是否缓存主题,也可以更加精细的判断前后的工作目录环境是否时同一个
// TODO: 后续看情况再优化吧.
return !fetcher.isShutdown();
}
@Override
public void afterCachedFetch(T theme) {
}
}
}

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

@ -0,0 +1,96 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.FineColorManager;
import com.fr.base.theme.TemplateThemeConfig;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.settings.ThemedComponentStyle;
import com.fr.base.theme.settings.ThemedFormBodyStyle;
import com.fr.design.i18n.Toolkit;
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.awt.Color;
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 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
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");
}
}

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

@ -0,0 +1,208 @@
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.ImageIcon;
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.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.concurrent.ExecutorService;
/**
* @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 UILabel thumbnailLabel;
// 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;
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);
thumbnailLabel = new UILabel();
thumbnailLabel.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(thumbnailLabel, BorderLayout.CENTER);
add(infoPane, BorderLayout.SOUTH);
}
public void setTheme(T theme) {
this.theme = theme;
thumbnailLabel.setIcon(null);
if (theme != null) {
ThemeThumbnail thumbnail = theme.getThumbnail();
if (thumbnail != null) {
Image image = thumbnail.getImage();
if (image != null) {
thumbnailLabel.setIcon(new ImageIcon(image));
}
}
}
repaint();
}
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 = thumbnailLabel.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);
}
}
}

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);
}
}
}
}

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

@ -0,0 +1,312 @@
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.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.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;
/**
* @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());
}
}
});
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.getLightThemeName4New()));
menuDef.addShortCut(new AddThemeAction(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Create_Dark_Theme"), config.getDarkThemeName4New()));
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) {
Configurations.modify(new WorkerFacade(config.getClass()) {
@Override
public void run() {
config.removeTheme(theme.getName());
}
});
}
}
}
private class AddThemeAction extends UpdateAction {
private T prototypeTheme;
public AddThemeAction(String name, String prototypeThemeName) {
setName(name);
setMnemonic('R');
asyncThemeFetcher.submit(prototypeThemeName, new AsyncThemeFetcher.AsyncThemeFetchCallbackAdapter<T>() {
@Override
public void beforeCachedFetch() {
super.beforeCachedFetch();
prototypeTheme = null;
}
@Override
public void afterCachedFetch(T theme) {
super.afterCachedFetch(theme);
prototypeTheme = theme;
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if (prototypeTheme == null) {
return;
}
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();
}
}

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

@ -0,0 +1,88 @@
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.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();
// 使用TYPE_INT_RGB和new Color(255, 255, 255, 1)设置有透明背景buffer image,
// 使得创建出来的透明像素是(255, 255, 255, 1),而不是(0, 0, 0, 0)
// 这样不支持透明通道缩略图的旧设计器打开新设计器创建的模版时,就不会创建出拥有黑色背景的缩略图
g2d.setColor(new Color(255, 255, 255, 1));
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;
}
}

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

@ -0,0 +1,594 @@
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.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.JPanel;
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;
/**
* @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);
JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListPane},
{null, LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(0XC6C6C6), 10)},
{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());
Configurations.modify(new WorkerFacade(config.getClass()) {
@Override
public void run() {
config.addTheme(theme, true);
}
}.addCallBack(new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
currentIsNewTheme = false;
nameTextField.setEnabled(false);
saveAsButton.setEnabled(true);
}
}));
}
}
});
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);
T finalNewThemeObject = newThemeObject;
Configurations.modify(new WorkerFacade(config.getClass()) {
@Override
public void run() {
config.addTheme(finalNewThemeObject, true);
}
}.addCallBack(new CallBackAdaptor() {
@Override
public void afterCommit() {
super.afterCommit();
exit();
parent.exit();
}
}));
}
}
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();
}
}
}

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

@ -0,0 +1,100 @@
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 = new ChartTitleAndBackgroundStylePane();
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;
}
@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() {
}
}

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_Background")
},
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(0XC6C6C6), 10);
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.FixedGradientBarWithPopMenu;
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 FixedGradientBarWithPopMenu 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 FixedGradientBarWithPopMenu(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());
}
}

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));
}
}
}

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

@ -0,0 +1,204 @@
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.Graphics;
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();
}
@Override
public void paintComponent(Graphics g) {
paintBackground((Graphics2D) g);
}
private 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;
}
}

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

@ -0,0 +1,130 @@
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.Graphics;
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();
}
@Override
public void paintComponent(Graphics g) {
paintBackground((Graphics2D) g);
}
private 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())); //画线
}
}
}

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

@ -0,0 +1,25 @@
package com.fr.design.mainframe.theme.preview.ecpreview.cell;
import com.fr.base.Style;
import java.awt.Dimension;
import java.awt.Graphics2D;
public class PreviewCell extends AbstractPreviewCell {
private final String value;
public PreviewCell(String value) {
this.value = value;
}
@Override
protected void paintContent(Graphics2D g2d, int resolution) {
Style.paintContent(g2d, value, style, getWidth() - 3, getHeight() - 3, resolution);
}
@Override
public Dimension getMinimumSize() {
return new Dimension(125, 30);
}
}

30
designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BorderUtils.java

@ -0,0 +1,30 @@
package com.fr.design.mainframe.theme.ui;
import com.fr.design.border.UIRoundedBorder;
import com.fr.general.FRFont;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import java.awt.Color;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/15
*/
public class BorderUtils {
public static Border createTitleBorder(String title) {
return createTitleBorder(title, 12);
}
public static Border createTitleBorder(String title, int size) {
return new NoEdgeTitleBorder(
new UIRoundedBorder(new Color(0XE0E0E1), 1, 1),
title,
TitledBorder.LEADING,
TitledBorder.TOP,
FRFont.getInstance().applySize(size),
new Color(47, 142, 241)
);
}
}

320
designer-base/src/main/java/com/fr/design/mainframe/theme/ui/NoEdgeTitleBorder.java

@ -0,0 +1,320 @@
package com.fr.design.mainframe.theme.ui;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.plaf.basic.BasicHTML;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.geom.Path2D;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/16
* 修正TitleBorder默认的行为使得组件有多大边框就有多大
*/
public class NoEdgeTitleBorder extends TitledBorder {
private final JLabel label;
public NoEdgeTitleBorder(Border border, String title, int titleJustification, int titlePosition, Font titleFont, Color titleColor) {
super(border, title, titleJustification, titlePosition, titleFont, titleColor);
this.label = new JLabel();
this.label.setOpaque(false);
this.label.putClientProperty(BasicHTML.propertyKey, null);
}
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Border border = getBorder();
String title = getTitle();
if ((title != null) && !title.isEmpty()) {
int edge = 0; //(border instanceof TitledBorder) ? 0 : EDGE_SPACING;
JLabel label = getLabel(c);
Dimension size = label.getPreferredSize();
Insets insets = getBorderInsets(border, c, new Insets(0, 0, 0, 0));
int borderX = x + edge;
int borderY = y + edge;
int borderW = width - edge - edge;
int borderH = height - edge - edge;
int labelY = y;
int labelH = size.height;
int position = getPosition();
switch (position) {
case ABOVE_TOP:
insets.left = 0;
insets.right = 0;
borderY += labelH - edge;
borderH -= labelH - edge;
break;
case TOP:
insets.top = edge + insets.top/2 - labelH/2;
if (insets.top < edge) {
borderY -= insets.top;
borderH += insets.top;
}
else {
labelY += insets.top;
}
break;
case BELOW_TOP:
labelY += insets.top + edge;
break;
case ABOVE_BOTTOM:
labelY += height - labelH - insets.bottom - edge;
break;
case BOTTOM:
labelY += height - labelH;
insets.bottom = edge + (insets.bottom - labelH) / 2;
if (insets.bottom < edge) {
borderH += insets.bottom;
}
else {
labelY -= insets.bottom;
}
break;
case BELOW_BOTTOM:
insets.left = 0;
insets.right = 0;
labelY += height - labelH;
borderH -= labelH - edge;
break;
}
insets.left += edge + TEXT_INSET_H;
insets.right += edge + TEXT_INSET_H;
int labelX = x;
int labelW = width - insets.left - insets.right;
if (labelW > size.width) {
labelW = size.width;
}
switch (getJustification(c)) {
case LEFT:
labelX += insets.left;
break;
case RIGHT:
labelX += width - insets.right - labelW;
break;
case CENTER:
labelX += (width - labelW) / 2;
break;
}
if (border != null) {
if ((position != TOP) && (position != BOTTOM)) {
border.paintBorder(c, g, borderX, borderY, borderW, borderH);
}
else {
Graphics g2 = g.create();
if (g2 instanceof Graphics2D) {
Graphics2D g2d = (Graphics2D) g2;
Path2D path = new Path2D.Float();
path.append(new Rectangle(borderX, borderY, borderW, labelY - borderY), false);
path.append(new Rectangle(borderX, labelY, labelX - borderX - TEXT_SPACING, labelH), false);
path.append(new Rectangle(labelX + labelW + TEXT_SPACING, labelY, borderX - labelX + borderW - labelW - TEXT_SPACING, labelH), false);
path.append(new Rectangle(borderX, labelY + labelH, borderW, borderY - labelY + borderH - labelH), false);
g2d.clip(path);
}
border.paintBorder(c, g2, borderX, borderY, borderW, borderH);
g2.dispose();
}
}
g.translate(labelX, labelY);
label.setSize(labelW, labelH);
label.paint(g);
g.translate(-labelX, -labelY);
}
else if (border != null) {
border.paintBorder(c, g, x, y, width, height);
}
}
/**
* Reinitialize the insets parameter with this Border's current Insets.
* @param c the component for which this border insets value applies
* @param insets the object to be reinitialized
*/
public Insets getBorderInsets(Component c, Insets insets) {
Border border = getBorder();
insets = getBorderInsets(border, c, insets);
String title = getTitle();
if ((title != null) && !title.isEmpty()) {
int edge = 0; //(border instanceof TitledBorder) ? 0 : EDGE_SPACING;
JLabel label = getLabel(c);
Dimension size = label.getPreferredSize();
switch (getPosition()) {
case ABOVE_TOP:
insets.top += size.height - edge;
break;
case TOP: {
if (insets.top < size.height) {
insets.top = size.height - edge;
}
break;
}
case BELOW_TOP:
insets.top += size.height;
break;
case ABOVE_BOTTOM:
insets.bottom += size.height;
break;
case BOTTOM: {
if (insets.bottom < size.height) {
insets.bottom = size.height - edge;
}
break;
}
case BELOW_BOTTOM:
insets.bottom += size.height - edge;
break;
}
insets.top += edge; //TEXT_SPACING;
insets.left += edge; //TEXT_SPACING;
insets.right += edge; //TEXT_SPACING;
insets.bottom += edge; //TEXT_SPACING;
}
return insets;
}
public int getBaseline(Component c, int width, int height) {
if (c == null) {
throw new NullPointerException("Must supply non-null component");
}
if (width < 0) {
throw new IllegalArgumentException("Width must be >= 0");
}
if (height < 0) {
throw new IllegalArgumentException("Height must be >= 0");
}
Border border = getBorder();
String title = getTitle();
if ((title != null) && !title.isEmpty()) {
int edge = 0; //(border instanceof TitledBorder) ? 0 : EDGE_SPACING;
JLabel label = getLabel(c);
Dimension size = label.getPreferredSize();
Insets insets = getBorderInsets(border, c, new Insets(0, 0, 0, 0));
int baseline = label.getBaseline(size.width, size.height);
switch (getPosition()) {
case ABOVE_TOP:
return baseline;
case TOP:
insets.top = edge + (insets.top - size.height) / 2;
return (insets.top < edge)
? baseline
: baseline + insets.top;
case BELOW_TOP:
return baseline + insets.top + edge;
case ABOVE_BOTTOM:
return baseline + height - size.height - insets.bottom - edge;
case BOTTOM:
insets.bottom = edge + (insets.bottom - size.height) / 2;
return (insets.bottom < edge)
? baseline + height - size.height
: baseline + height - size.height + insets.bottom;
case BELOW_BOTTOM:
return baseline + height - size.height;
}
}
return -1;
}
private int getPosition() {
int position = getTitlePosition();
if (position != DEFAULT_POSITION) {
return position;
}
Object value = UIManager.get("TitledBorder.position");
if (value instanceof Integer) {
int i = (Integer) value;
if ((0 < i) && (i <= 6)) {
return i;
}
}
else if (value instanceof String) {
String s = (String) value;
if (s.equalsIgnoreCase("ABOVE_TOP")) {
return ABOVE_TOP;
}
if (s.equalsIgnoreCase("TOP")) {
return TOP;
}
if (s.equalsIgnoreCase("BELOW_TOP")) {
return BELOW_TOP;
}
if (s.equalsIgnoreCase("ABOVE_BOTTOM")) {
return ABOVE_BOTTOM;
}
if (s.equalsIgnoreCase("BOTTOM")) {
return BOTTOM;
}
if (s.equalsIgnoreCase("BELOW_BOTTOM")) {
return BELOW_BOTTOM;
}
}
return TOP;
}
private int getJustification(Component c) {
int justification = getTitleJustification();
if ((justification == LEADING) || (justification == DEFAULT_JUSTIFICATION)) {
return c.getComponentOrientation().isLeftToRight() ? LEFT : RIGHT;
}
if (justification == TRAILING) {
return c.getComponentOrientation().isLeftToRight() ? RIGHT : LEFT;
}
return justification;
}
private Color getColor(Component c) {
Color color = getTitleColor();
if (color != null) {
return color;
}
return (c != null)
? c.getForeground()
: null;
}
private JLabel getLabel(Component c) {
this.label.setText(getTitle());
Font font = getFont(c);
this.label.setFont(font);
this.label.setForeground(getColor(c));
this.label.setComponentOrientation(c.getComponentOrientation());
this.label.setEnabled(c.isEnabled());
Dimension dimension = this.label.getPreferredSize();
dimension.height = font.getSize();
this.label.setPreferredSize(dimension);
return this.label;
}
private static Insets getBorderInsets(Border border, Component c, Insets insets) {
if (border == null) {
insets.set(0, 0, 0, 0);
}
else if (border instanceof AbstractBorder) {
AbstractBorder ab = (AbstractBorder) border;
insets = ab.getBorderInsets(c, insets);
}
else {
Insets i = border.getBorderInsets(c);
insets.set(i.top, i.left, i.bottom, i.right);
}
return insets;
}
}

36
designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java

@ -12,7 +12,13 @@ public abstract class SnapChatAllTypes {
/**
* 社区按钮
*/
BBS("BBS");
BBS("BBS"),
/**
* 服务器按钮
*/
SERVER("SERVER");
private static final String SIGN = "0001";
@ -35,4 +41,32 @@ public abstract class SnapChatAllTypes {
}
}
public enum UpdateAction implements SnapChatKey {
/**
* 服务器模版主题管理
*/
TEMPLATE_THEMES_MANAGER("TEMPLATE_THEMES_MANAGER");
private static final String SIGN = "0002";
private String key;
UpdateAction(String key) {
this.key = key;
}
public String getKey() {
return key;
}
@Override
public String calc() {
return CommonUtils.join(
new String[]{SIGN, getKey()}, "-"
);
}
}
}

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

@ -163,7 +163,7 @@ public class WatermarkPane extends BasicPane {
tipsJp.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Direction_Vertical"), SwingConstants.CENTER));
watermarkGapTipsPane.add(tipsJp, BorderLayout.CENTER);
colorPane = new NewColorSelectPane();
colorPane = new NewColorSelectPane(false);
JPanel colorLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
colorLabelPane.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Text_Color")), BorderLayout.NORTH);

6
designer-base/src/main/java/com/fr/design/style/CustomSelectBox.java

@ -11,7 +11,7 @@ import javax.swing.event.ChangeListener;
import com.fr.base.background.ColorBackground;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.style.background.BackgroundCustomJComponent;
import com.fr.design.style.color.ColorSelectPane;
import com.fr.design.style.color.NewColorSelectPane;
/**
@ -40,11 +40,11 @@ public class CustomSelectBox extends AbstractPopBox {
@Override
public JPanel initWindowPane(double preferredWidth) {
ColorSelectPane colorPane = new ColorSelectPane();
NewColorSelectPane colorPane = new NewColorSelectPane();
colorPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
ColorSelectPane source = (ColorSelectPane)e.getSource();
NewColorSelectPane source = (NewColorSelectPane)e.getSource();
setSelectObject(source.getColor());
hidePopupMenu();
}

9
designer-base/src/main/java/com/fr/design/style/background/BackgroundPane.java

@ -8,6 +8,7 @@ import java.awt.Dimension;
import java.util.HashMap;
import java.util.Map;
import com.fr.base.background.ColorBackground;
import com.fr.design.gui.frpane.UITabbedPane;
import javax.swing.event.ChangeEvent;
@ -16,6 +17,9 @@ import javax.swing.event.EventListenerList;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.dialog.BasicPane;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.style.background.impl.ColorBackgroundPane;
import com.fr.design.style.background.impl.ColorNoThemeBackgroundPane;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
@ -27,14 +31,15 @@ public class BackgroundPane extends BasicPane {
private EventListenerList eventChangeList = new EventListenerList();
protected Map<Integer, BackgroundDetailPane> cacheMap = new HashMap<>();
//需求说: 如果是浏览器背景, 隐藏掉几个button
public BackgroundPane() {
BackgroundFactory.getWrapper(ColorBackground.class).setType(
DesignerContext.getDesignerFrame().isServerConfig() ? ColorNoThemeBackgroundPane.class : ColorBackgroundPane.class);
this.initComponents();
this.setPreferredSize(new Dimension(400, 300));
}
protected void initComponents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());

243
designer-base/src/main/java/com/fr/design/style/background/gradient/AbstractComponentPopBox.java

@ -0,0 +1,243 @@
package com.fr.design.style.background.gradient;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.style.background.BackgroundJComponent;
import com.fr.general.Background;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.awt.AWTEvent;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2021-08-24
*/
public abstract class AbstractComponentPopBox extends JComponent {
protected BackgroundJComponent displayComponent;
private JWindow selectPopupWindow;
private boolean isWindowEventInit = false;
private static int GAP = 2;
private static int GAP2 = 20;
private List<ChangeListener> changeListenerList = new ArrayList<ChangeListener>();
MouseAdapter mouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent evt) {
showPopupMenu();
}
};
AWTEventListener awt = new AWTEventListener() {
public void eventDispatched(AWTEvent event) {
if (event instanceof MouseEvent) {
MouseEvent evt = (MouseEvent) event;
if (evt.getClickCount() > 0) {
mouseClick(evt);
}
}
}
};
protected void showPopupMenu() {
if (selectPopupWindow != null && selectPopupWindow.isVisible()) {
hidePopupMenu();
return;
}
if (!this.isEnabled()) {
return;
}
Toolkit.getDefaultToolkit().addAWTEventListener(awt, AWTEvent.MOUSE_EVENT_MASK);
selectPopupWindow = this.getControlWindow();
Point convertPoint = new Point(0, 0);
// e: 将点(0,0)从ColorSelectionPane的坐标系统转换到屏幕坐标.
SwingUtilities.convertPointToScreen(convertPoint, this);
int y = convertPoint.y + this.getSize().height;
int x = convertPoint.x;
int h = y + selectPopupWindow.getHeight();
int width = x + selectPopupWindow.getWidth();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
if (h > screenSize.height) {
y = y - selectPopupWindow.getHeight() - GAP2;// 超过屏幕高度了
}
if (width > screenSize.width) {
x = screenSize.width - selectPopupWindow.getWidth();
}
selectPopupWindow.setLocation(x, y);
selectPopupWindow.setVisible(true);
//wei : 为了点击别的地方下拉颜色窗口消失
MouseAdapter parentMouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent evt) {
mouseClick(evt);
}
};
if (!this.isWindowEventInit && SwingUtilities.getAncestorOfClass(GradientBackgroundPane.class, this) != null) {
SwingUtilities.getAncestorOfClass(GradientBackgroundPane.class, this).addMouseListener(parentMouseListener);
this.isWindowEventInit = true;
}
}
private void mouseClick(MouseEvent evt) {
Point point = new Point((int) (evt.getLocationOnScreen().getX()), (int) evt.getLocationOnScreen().getY());
Dimension popBoxD = AbstractComponentPopBox.this.getSize();
try {
Point popBoxP = AbstractComponentPopBox.this.getLocationOnScreen();
Dimension popMenuD = this.getControlWindow().getSize();
Point popMenuP = this.getControlWindow().getLocation();
Rectangle popBoxRect = new Rectangle(popBoxP, popBoxD);
Rectangle popMenuRect = new Rectangle(popMenuP, popMenuD);
if (!popBoxRect.contains(point) && !popMenuRect.contains(point)) {
this.hidePopupMenu();
}
} catch (Exception ignore) {
this.hidePopupMenu();
}
}
protected void hidePopupMenu() {
if (selectPopupWindow != null) {
selectPopupWindow.setVisible(false);
}
selectPopupWindow = null;
Toolkit.getDefaultToolkit().removeAWTEventListener(awt);
}
protected JWindow getControlWindow() {
//find parent.
if (this.selectPopupWindow == null) {
Window parentWindow = SwingUtilities.windowForComponent(this);
if (parentWindow != null) {
this.selectPopupWindow = new AbstractComponentPopBox.SelectControlWindow(parentWindow);
}
selectPopupWindow.addMouseListener(new MouseAdapter() {
public void mouseExited(MouseEvent evt) {
int x = evt.getLocationOnScreen().x;
int y = evt.getLocationOnScreen().y;
if (selectPopupWindow != null) {
double desValue = 2;
Rectangle rectangle = selectPopupWindow.getBounds();
boolean b1 = x < rectangle.x + desValue || x >= rectangle.x + rectangle.width - desValue;
boolean b2 = y > rectangle.y + rectangle.height - desValue;//避免了鼠标下移刚进入selectPopupWindow的过程中弹出框隐藏,上移移出后由AbstractPopBox的mouseListener处理
if (b1 || b2) {
hidePopupMenu();
}
}
}
});
}
return selectPopupWindow;
}
/**
* 添加事件
*
* @param changeListener 事件
*/
public void addSelectChangeListener(ChangeListener changeListener) {
this.changeListenerList.add(changeListener);
}
/**
* 删除事件
*
* @param changeListener 事件
*/
public void removeSelectChangeListener(ChangeListener changeListener) {
this.changeListenerList.remove(changeListener);
}
/**
* 响应事件
*/
public void fireChangeListener() {
if (!changeListenerList.isEmpty()) {
ChangeEvent evt = new ChangeEvent(this);
for (int i = 0; i < changeListenerList.size(); i++) {
this.changeListenerList.get(i).stateChanged(evt);
}
}
}
/**
* 待说明
*
* @param background 背景
*/
public void fireDisplayComponent(Background background) {
if (displayComponent != null) {
displayComponent.setSelfBackground(background);
}
fireChangeListener();
this.repaint();
}
/**
* 初始化弹出框的面板
*
* @param preWidth 宽度
* @return 弹出面板
*/
public abstract JPanel initWindowPane(double preWidth);
private class SelectControlWindow extends JWindow {
private static final long serialVersionUID = -5776589767069105911L;
public SelectControlWindow(Window paranet) {
super(paranet);
this.initComponents();
}
public void initComponents() {
JPanel defaultPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
this.setContentPane(defaultPane);
// defaultPane.setBorder(UIManager.getBorder("PopupMenu.border"));
if (displayComponent != null) {
defaultPane.add(initWindowPane(displayComponent.getPreferredSize().getWidth()));
} else {
defaultPane.add(initWindowPane(20));
}
this.pack();
}
@Override
public void setVisible(boolean b) {
super.setVisible(b);
AbstractComponentPopBox.this.repaint();
}
}
protected boolean isPopupVisible() {
return selectPopupWindow == null ? false : selectPopupWindow.isVisible();
}
}

53
designer-base/src/main/java/com/fr/design/style/background/gradient/FixedGradientBarWithPopMenu.java

@ -0,0 +1,53 @@
package com.fr.design.style.background.gradient;
import com.fr.base.background.ColorBackground;
import com.fr.design.style.color.NewColorSelectPane;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2021-08-19
*/
public class FixedGradientBarWithPopMenu extends FixedGradientBar {
private NewColorSelectPane colorPane;
public FixedGradientBarWithPopMenu(int minvalue, int maxvalue) {
super(minvalue, maxvalue);
}
protected void clickButton(int select) {
setIndex(select);
showPopupMenu();
}
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.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
hidePopupMenu();
setColor(((NewColorSelectPane) e.getSource()).getColor());
getList().get(getIndex()).setColorInner(getColor());
fireDisplayComponent(ColorBackground.getInstance(getColor()));
FixedGradientBarWithPopMenu.this.stateChanged();
}
});
return colorPane;
}
}

55
designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java

@ -10,9 +10,9 @@ import com.fr.design.style.color.ColorSelectDetailPane;
import com.fr.design.style.color.ColorSelectDialog;
import com.fr.design.style.color.ColorSelectable;
import com.fr.stable.AssistUtils;
import com.fr.stable.os.OperatingSystem;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
@ -33,7 +33,7 @@ import java.awt.geom.Point2D;
/**
* TODO:面板缩放的功能没有考虑就是尾值过大导致超过界面显示的情况原来的那个实现完全是个BUG要缩放的情况也比较少就干脆以后弄吧
*/
public class GradientBar extends JComponent implements UIObserver, ColorSelectable {
public class GradientBar extends AbstractComponentPopBox implements UIObserver, ColorSelectable {
/**
*
@ -88,6 +88,22 @@ public class GradientBar extends JComponent implements UIObserver, ColorSelectab
iniListener();
}
public List<SelectColorPointBtn> getList() {
return list;
}
public void setList(List<SelectColorPointBtn> list) {
this.list = list;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public void updateColor(Color begin, Color end) {
p1.setColorInner(begin);
p2.setColorInner(end);
@ -106,15 +122,7 @@ public class GradientBar extends JComponent implements UIObserver, ColorSelectab
}
if (select >= 0) {
ColorSelectDetailPane pane = new ColorSelectDetailPane(Color.WHITE);
ColorSelectDialog.showDialog(DesignerContext.getDesignerFrame(), pane, Color.WHITE, GradientBar.this);
Color color = GradientBar.this.getColor();
if (color != null) {
DesignerEnvManager.getEnvManager().getColorConfigManager().addToColorQueue(color);
list.get(select).setColorInner(color);
stateChanged();
GradientBar.this.repaint();
}
clickButton(select);
}
GradientBar.this.repaint();
}
@ -122,6 +130,23 @@ public class GradientBar extends JComponent implements UIObserver, ColorSelectab
});
}
protected void clickButton(int select) {
ColorSelectDetailPane pane = new ColorSelectDetailPane(Color.WHITE);
Color selectColor = list.get(select).getColorInner() == null ? Color.WHITE : list.get(select).getColorInner();
ColorSelectDialog.showDialog(DesignerContext.getDesignerFrame(), pane, selectColor, GradientBar.this);
Color color = GradientBar.this.getColor();
if (color != null) {
DesignerEnvManager.getEnvManager().getColorConfigManager().addToColorQueue(color);
list.get(select).setColorInner(color);
stateChanged();
GradientBar.this.repaint();
}
}
public JPanel initWindowPane(double preWidth) {
return null;
}
protected void addMouseDragListener() {
this.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
@ -132,10 +157,10 @@ public class GradientBar extends JComponent implements UIObserver, ColorSelectab
break;
}
}
if(OperatingSystem.isLinux() && AssistUtils.equals(oldIndex,index)){
if(Math.abs(p1.getX() - e.getX()) > Math.abs(p2.getX() - e.getX())){
if (OperatingSystem.isLinux() && AssistUtils.equals(oldIndex, index)) {
if (Math.abs(p1.getX() - e.getX()) > Math.abs(p2.getX() - e.getX())) {
index = 1;
}else{
} else {
index = 0;
}
}

6
designer-base/src/main/java/com/fr/design/style/background/impl/ColorBackgroundPane.java

@ -19,10 +19,14 @@ public class ColorBackgroundPane extends BackgroundDetailPane {
public ColorBackgroundPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
detailColorSelectPane = new DetailColorSelectPane();
detailColorSelectPane = createColorSelectPane();
this.add(detailColorSelectPane, BorderLayout.CENTER);
}
protected DetailColorSelectPane createColorSelectPane(){
return new DetailColorSelectPane();
}
public void populate(Background background) {
if (background instanceof ColorBackground) {
ColorBackground colorBackgroud = (ColorBackground) background;

10
designer-base/src/main/java/com/fr/design/style/background/impl/ColorNoThemeBackgroundPane.java

@ -0,0 +1,10 @@
package com.fr.design.style.background.impl;
import com.fr.design.style.color.DetailColorSelectPane;
public class ColorNoThemeBackgroundPane extends ColorBackgroundPane{
protected DetailColorSelectPane createColorSelectPane(){
return new DetailColorSelectPane(false);
}
}

60
designer-base/src/main/java/com/fr/design/style/color/ColorAdjustPane.java

@ -1,13 +1,14 @@
package com.fr.design.style.color;
import com.fr.base.BaseUtils;
import com.fr.base.background.ColorBackground;
import com.fr.design.DesignerEnvManager;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.style.AbstractSelectBox;
import com.fr.design.mainframe.DesignerContext;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@ -75,7 +76,7 @@ public class ColorAdjustPane extends JPanel implements UIObserver {
int size = colorButtons.size();
Color[] colors = new Color[size];
for (int i = 0; i < size; i++) {
colors[i] = colorButtons.get(i).getSelectObject();
colors[i] = colorButtons.get(i).getColor();
}
return colors;
}
@ -169,7 +170,7 @@ public class ColorAdjustPane extends JPanel implements UIObserver {
}
private class AddColorButton extends AbstractSelectBox<Color> {
private class AddColorButton extends JComponent implements ColorSelectable {
BufferedImage image = BaseUtils.readImageWithCache("/com/fr/design/images/buttonicon/add.png");
@ -195,43 +196,38 @@ public class ColorAdjustPane extends JPanel implements UIObserver {
return new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
showPopupMenu();
//打开颜色选择面板
showDialog();
}
};
}
public JPanel initWindowPane(double preferredWidth) {
// 下拉的时候重新生成面板,刷新最近使用颜色
ColorSelectPane colorPane = new ColorSelectPane(false) {
public void setVisible(boolean b) {
super.setVisible(b);
}
private void showDialog() {
ColorSelectDetailPane pane = new ColorSelectDetailPane(getColor());
ColorSelectDialog.showDialog(DesignerContext.getDesignerFrame(), pane, getColor(), this, true);
Color color = this.getColor();
if (color != null) {
DesignerEnvManager.getEnvManager().getColorConfigManager().addToColorQueue(color);
}
}
protected boolean selectRealTime() {
return false;
}
};
colorPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
hidePopupMenu();
Color color = ((ColorSelectPane) e.getSource()).getColor();
fireDisplayComponent(ColorBackground.getInstance(color));
if(colorButtons.size() < MAX_BUTTON) {
colorButtons.add(createColorButton(color));
}
ColorAdjustPane.this.stateChanged();
relayout();
}
});
return colorPane;
@Override
public void setColor(Color color) {
if (colorButtons.size() < MAX_BUTTON) {
colorButtons.add(createColorButton(color));
}
ColorAdjustPane.this.stateChanged();
relayout();
}
public Color getSelectObject() {
return null;
@Override
public Color getColor() {
return Color.WHITE;
}
public void setSelectObject(Color color) {
@Override
public void colorSetted(ColorCell colorCell) {
}
}
}
}

73
designer-base/src/main/java/com/fr/design/style/color/ColorButton.java

@ -1,11 +1,10 @@
package com.fr.design.style.color;
import com.fr.base.BaseUtils;
import com.fr.base.background.ColorBackground;
import com.fr.design.style.AbstractSelectBox;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.DesignerContext;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.JComponent;
import javax.swing.event.ChangeListener;
import java.awt.Color;
import java.awt.Dimension;
@ -22,7 +21,7 @@ import java.awt.image.BufferedImage;
* @version 10.0
* Created by Bjorn on 2020-03-06
*/
public class ColorButton extends AbstractSelectBox<Color> {
public class ColorButton extends JComponent implements ColorSelectable {
private static final double DEL_WIDTH = 7;
@ -34,8 +33,6 @@ public class ColorButton extends AbstractSelectBox<Color> {
private boolean isMoveOn = false;
private ColorSelectPane colorPane;
private boolean lastButton;
private ChangeListener changeListener;
@ -111,40 +108,24 @@ public class ColorButton extends AbstractSelectBox<Color> {
}
if (e.getX() >= bounds.getWidth() - DEL_WIDTH && e.getY() <= DEL_WIDTH) {
deleteButton();
hidePopupMenu();
return;
}
}
//打开颜色选择面板
showPopupMenu();
showDialog();
}
public JPanel initWindowPane(double preferredWidth) {
// 下拉的时候重新生成面板,刷新最近使用颜色
colorPane = new ColorSelectPane(false) {
@Override
public void setVisible(boolean b) {
super.setVisible(b);
}
@Override
protected boolean selectRealTime() {
return false;
}
};
colorPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
hidePopupMenu();
color = ((ColorSelectPane) e.getSource()).getColor();
fireDisplayComponent(ColorBackground.getInstance(color));
ColorButton.this.stateChanged();
}
});
return colorPane;
private void showDialog() {
ColorSelectDetailPane pane = new ColorSelectDetailPane(getColor());
ColorSelectDialog.showDialog(DesignerContext.getDesignerFrame(), pane, getColor(), this, true);
Color color = this.getColor();
if (color != null) {
DesignerEnvManager.getEnvManager().getColorConfigManager().addToColorQueue(color);
}
}
public void stateChanged() {
if (changeListener != null) {
if (changeListener != null) {
changeListener.stateChanged(null);
}
}
@ -153,26 +134,18 @@ public class ColorButton extends AbstractSelectBox<Color> {
this.changeListener = changeListener;
}
@Override
public void setColor(Color color) {
this.color = color;
this.stateChanged();
}
/**
* 获取当前选中的颜色
*
* @return 当前选中的颜色
*/
public Color getSelectObject() {
@Override
public Color getColor() {
return this.color;
}
/**
* 设置选中的颜色
*
* @param color 颜色
*/
public void setSelectObject(Color color) {
this.color = color;
colorPane.setColor(color);
fireDisplayComponent(ColorBackground.getInstance(color));
@Override
public void colorSetted(ColorCell colorCell) {
}
}
}

10
designer-base/src/main/java/com/fr/design/style/color/ColorCell.java

@ -76,17 +76,21 @@ public class ColorCell extends JComponent implements ColorSelectable {
g.fillRect(b.left, b.top, right, bottom);
}
if (colorSelectable.getColor() != null
&& ComparatorUtils.equals(colorSelectable.getColor(), this.getColor())) {
if (isColorSelected(colorSelectable)) {
g.setColor(UIConstants.LINE_COLOR);
g.drawRect(b.left, b.top, right - 1, bottom - 1);
}
}
protected boolean isColorSelected(ColorSelectable colorSelectable){
return colorSelectable.getColor() != null
&& ComparatorUtils.equals(colorSelectable.getColor(), this.getColor());
}
/**
* 鼠标事件处理
* @param 鼠标事件
* @param e 鼠标事件
*/
public void processMouseEvent(MouseEvent e) {
if (!isEnabled()) {

12
designer-base/src/main/java/com/fr/design/style/color/ColorControlWindow.java

@ -58,15 +58,19 @@ public abstract class ColorControlWindow extends JPopupMenu {
}
protected void initSelectionPopupPane(boolean isSupportTransparent) {
selectionPopupPane = new ColorSelectionPopupPane(isSupportTransparent);
selectionPopupPane = new ColorSelectionPopupPane(isSupportTransparent, supportThemeColor());
this.add(selectionPopupPane, BorderLayout.CENTER);
}
protected boolean supportThemeColor(){
return true;
}
class ColorSelectionPopupPane extends NewColorSelectPane {
private static final long serialVersionUID = 7822856562329146354L;
public ColorSelectionPopupPane(boolean isSupportTransparent) {
super(isSupportTransparent);
public ColorSelectionPopupPane(boolean isSupportTransparent, boolean isSupportThemeColor) {
super(isSupportTransparent, isSupportThemeColor);
this.addChangeListener(new ChangeListener() {
@Override
@ -77,7 +81,7 @@ public abstract class ColorControlWindow extends JPopupMenu {
}
@Override
protected void doTransparent() {
public void doTransparent() {
popupHider.hidePopupMenu();
super.doTransparent();
}

2
designer-base/src/main/java/com/fr/design/style/color/ColorControlWindowWithAuto.java

@ -61,7 +61,7 @@ public abstract class ColorControlWindowWithAuto extends ColorControlWindow {
});
}
protected void doTransparent() {
public void doTransparent() {
getPopupHider().hidePopupMenu();
setColor(null);
}

13
designer-base/src/main/java/com/fr/design/style/color/ColorFactory.java

@ -71,5 +71,18 @@ public interface ColorFactory {
new Color(0, 0, 255)
};
public static final Color STANDARD_COLORS[] = {
new Color(166, 89, 66),
new Color(166, 123, 66),
new Color(166, 66, 66),
new Color(103, 166, 66),
new Color(66, 121, 166),
new Color(68, 66, 166),
new Color(98, 66, 166),
new Color(146, 66, 166),
new Color(75, 18, 89),
new Color(89, 18, 51)
};
}

14
designer-base/src/main/java/com/fr/design/style/color/ColorSelectBox.java

@ -17,7 +17,7 @@ public class ColorSelectBox extends AbstractSelectBox<Color> implements UIObserv
private static final long serialVersionUID = 2782150678943960557L;
private Color color;
private ColorSelectPane colorPane;
private NewColorSelectPane colorPane;
private UIObserverListener uiObserverListener;
public ColorSelectBox(int preferredWidth) {
@ -40,12 +40,8 @@ public class ColorSelectBox extends AbstractSelectBox<Color> implements UIObserv
}
}
protected ColorSelectPane getColorSelectPane(){
return new ColorSelectPane() {
public void setVisible(boolean b) {
super.setVisible(b);
}
};
protected NewColorSelectPane getColorSelectPane(){
return new NewColorSelectPane();
}
/**
@ -56,14 +52,14 @@ public class ColorSelectBox extends AbstractSelectBox<Color> implements UIObserv
public JPanel initWindowPane(double preferredWidth) {
// 下拉的时候重新生成面板,刷新最近使用颜色
colorPane = getColorSelectPane();
colorPane.setColor(color);
colorPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
hidePopupMenu();
color = ((ColorSelectPane) e.getSource()).getColor();
color = ((NewColorSelectPane) e.getSource()).getColor();
fireDisplayComponent(ColorBackground.getInstance(color));
}
});
colorPane.setColor(color);
return colorPane;
}

14
designer-base/src/main/java/com/fr/design/style/color/ColorSelectDetailPane.java

@ -36,6 +36,10 @@ public class ColorSelectDetailPane extends BasicPane {
return selectedPanel;
}
private SwatchChooserPanel swatchChooserPanel;
private CustomChooserPanel customChooserPanel;
public void setSelectedPanel(JColorChooser selectedPanel) {
this.selectedPanel = selectedPanel;
}
@ -69,9 +73,9 @@ public class ColorSelectDetailPane extends BasicPane {
selectedPanel.setPreferredSize(new Dimension(selectedPanel.getWidth(), SELECT_PANEL_HEIGHT));
selectedPanel.setPreviewPanel(new JPanel());
AbstractColorChooserPanel swatchChooserPanel = new SwatchChooserPanel();
AbstractColorChooserPanel customChooserPanel = new CustomChooserPanel();
selectedPanel.setChooserPanels(new AbstractColorChooserPanel[]{swatchChooserPanel, customChooserPanel});
swatchChooserPanel = new SwatchChooserPanel();
customChooserPanel = new CustomChooserPanel();
selectedPanel.setChooserPanels(new AbstractColorChooserPanel[]{customChooserPanel, swatchChooserPanel});
this.add(selectedPanel, BorderLayout.NORTH);
// 最近使用面板
@ -98,4 +102,8 @@ public class ColorSelectDetailPane extends BasicPane {
previewPanel.add(colorChooserPreview);
this.add(previewPanel, BorderLayout.SOUTH);
}
public void populate(Color color){
customChooserPanel.setColor(color);
}
}

1
designer-base/src/main/java/com/fr/design/style/color/ColorSelectDialog.java

@ -77,6 +77,7 @@ public class ColorSelectDialog extends MiddleChartDialog{
this.okListener = (ColorTracker) okListener;
this.seletePane = seletePane;
initComponent();
this.pane.populate(initialColor);
}
private void initComponent() {

1
designer-base/src/main/java/com/fr/design/style/color/ColorSelectPane.java

@ -30,6 +30,7 @@ import java.awt.event.MouseEvent;
/**
* The pane used to select color
*/
@Deprecated
public class ColorSelectPane extends TransparentPane implements ColorSelectable {
private static final long serialVersionUID = -8634152305687249392L;

10
designer-base/src/main/java/com/fr/design/style/color/DetailColorSelectPane.java

@ -29,10 +29,14 @@ import com.fr.design.dialog.BasicPane;
* Often used for foreground selection.
*/
public class DetailColorSelectPane extends BasicPane {
private ColorSelectPane colorSelectPane;
private NewColorSelectPane colorSelectPane;
private UILabel colorPreviewLabel;
public DetailColorSelectPane() {
public DetailColorSelectPane(){
this(true);
}
public DetailColorSelectPane(boolean supportTheme) {
this.setBorder(BorderFactory.createEmptyBorder(4, 4, 0, 4));
this.setLayout(FRGUIPaneFactory.createBorderLayout());
@ -44,7 +48,7 @@ public class DetailColorSelectPane extends BasicPane {
defaultPane.add(Box.createHorizontalStrut(4));
JPanel colorSelectContainPane =FRGUIPaneFactory.createBorderLayout_L_Pane();
defaultPane.add(colorSelectContainPane);
colorSelectPane = new ColorSelectPane();
colorSelectPane = NewColorSelectPane.createColorSelectPaneWithTheme(supportTheme);
colorSelectContainPane.add(colorSelectPane, BorderLayout.NORTH);
defaultPane.add(Box.createHorizontalStrut(8));

38
designer-base/src/main/java/com/fr/design/style/color/FineColorCell.java

@ -0,0 +1,38 @@
package com.fr.design.style.color;
import com.fr.base.FineColor;
import com.fr.general.ComparatorUtils;
import java.awt.Color;
public class FineColorCell extends ColorCell {
private final int x;
private final int y;
public FineColorCell(Color color, ColorSelectable colorSelectable) {
this(color, colorSelectable, -1, -1);
}
public FineColorCell(Color color, ColorSelectable colorSelectable, int x, int y) {
super(color, colorSelectable);
this.x = x;
this.y = y;
}
public Color getColor() {
Color color = super.getColor();
FineColor fineColor = new FineColor(x, y, color);
return fineColor;
}
protected boolean isColorSelected(ColorSelectable colorSelectable) {
Color color = colorSelectable.getColor();
if (color instanceof FineColor) {
return super.isColorSelected(colorSelectable) && (x == ((FineColor) color).getHor()) && (y == ((FineColor) color).getVer());
}
return super.isColorSelected(colorSelectable);
}
}

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

Loading…
Cancel
Save