Browse Source

Pull request #5378: REPORT-51919 主题切换

Merge in DESIGN/design from ~STARRYI/design:feature/x to feature/x

* commit '14fb652f1263dd7e2196b3e7832c58d697ef3e21':
  REPORT-51919 主题切换
research/11.0
starryi 3 years ago
parent
commit
b3be611504
  1. 20
      designer-base/src/main/java/com/fr/design/gui/style/AbstractBorderPackerPane.java
  2. 99
      designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java
  3. 33
      designer-base/src/main/java/com/fr/design/gui/style/ComponentBodyStylePane.java
  4. 109
      designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java
  5. 289
      designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java
  6. 24
      designer-base/src/main/java/com/fr/design/gui/style/TextInsetImageBackgroundSpecialPane.java
  7. 27
      designer-base/src/main/java/com/fr/design/gui/style/TitleTranslucentBackgroundSpecialPane.java
  8. 45
      designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java
  9. 81
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  10. 72
      designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java
  11. 54
      designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java
  12. 181
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java
  13. 180
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java
  14. 241
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java
  15. 29
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java
  16. 592
      designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java
  17. 99
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java
  18. 72
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java
  19. 49
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java
  20. 119
      designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java
  21. 242
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/CellStyleListEditPane.java
  22. 96
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleEditPane.java
  23. 112
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java
  24. 44
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/FormBodyStyleEditPane.java
  25. 34
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ReportBodyStyleEditPane.java
  26. 51
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/AbstractBackgroundDetailPane.java
  27. 136
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/BackgroundSettingPane.java
  28. 105
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ColorDetailPane.java
  29. 35
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/EmptyBackgroundPane.java
  30. 160
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/GradientDetailPane.java
  31. 216
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ImageDetailPane.java
  32. 120
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/PatternDetailPane.java
  33. 98
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/TextureDetailObservePane.java
  34. 208
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java
  35. 49
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/AbstractChartStylePane.java
  36. 69
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartAxisStylePane.java
  37. 113
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartBackgroundStylePane.java
  38. 58
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartDataSheetStylePane.java
  39. 160
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java
  40. 78
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLabelStylePane.java
  41. 49
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLegendStylePane.java
  42. 49
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleStylePane.java
  43. 101
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/component/ComponentMarginStylePane.java
  44. 148
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListExtendedPane.java
  45. 199
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java
  46. 26
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java
  47. 73
      designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java
  48. 26
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartComponentPreviewPane.java
  49. 39
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartPreviewPane.java
  50. 161
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java
  51. 26
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ECComponentPreviewPane.java
  52. 160
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ECPreviewPane.java
  53. 74
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java
  54. 17
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ReportThemePreviewPane.java
  55. 10
      designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ThemePreviewed.java
  56. 30
      designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BorderUtils.java
  57. 320
      designer-base/src/main/java/com/fr/design/mainframe/theme/ui/NoEdgeTitleBorder.java
  58. 36
      designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java
  59. 8
      designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java
  60. 11
      designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutStylePane.java
  61. 535
      designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java
  62. 28
      designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java
  63. 47
      designer-form/src/main/java/com/fr/design/mainframe/JForm.java
  64. BIN
      designer-form/src/main/resources/com/fr/design/form/images/theme4currentTemplate.png
  65. BIN
      designer-form/src/main/resources/com/fr/design/form/images/theme4newTemplate.png
  66. 24
      designer-realize/src/main/java/com/fr/design/actions/cell/GlobalStyleMenuDef.java
  67. 52
      designer-realize/src/main/java/com/fr/design/actions/server/TemplateThemeManagerAction.java
  68. 43
      designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java
  69. 12
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java
  70. 166
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/ThemedCellStyleListPane.java
  71. 13
      designer-realize/src/main/java/com/fr/start/MainDesigner.java
  72. 5
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

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

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

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

@ -0,0 +1,289 @@
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.design.mainframe.backgroundpane.GradientBackgroundQuickPane;
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.Component;
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);
// 标题可见
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 final int uiLabelWidth;
private final int uiSettingWidth;
private final boolean supportTitleVisible;
protected final boolean supportTitleContent;
public ComponentTitleStylePane(int uiLabelWidth) {
this(uiLabelWidth, -1, true, true);
}
public ComponentTitleStylePane(
int uiLabelWidth, int uiSettingWidth,
boolean supportTitleVisible, boolean supportTitleContent) {
this.uiLabelWidth = uiLabelWidth;
this.uiSettingWidth = uiSettingWidth;
this.supportTitleVisible = supportTitleVisible;
this.supportTitleContent = supportTitleContent;
this.initializePane();
}
private void initializeComponents() {
visibleCheckbox = new UICheckBox();
textContentPane = new TinyFormulaPane();
fontFamilyComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
FRFont frFont = new WidgetTitle().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")
});
backgroundPane = new TitleTranslucentBackgroundSpecialPane(this.uiLabelWidth, this.uiSettingWidth);
}
private void initializePane() {
this.setLayout(new BorderLayout(0, 0));
this.initializeComponents();
JPanel titleVisiblePane = this.createTitleVisiblePane();
JPanel detailedTitleStylePane = this.createDetailedTitleStylePane();
detailedTitleStylePane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0));
if (this.supportTitleVisible) {
titleVisiblePane.setVisible(true);
detailedTitleStylePane.setVisible(false);
} else {
titleVisiblePane.setVisible(false);
detailedTitleStylePane.setVisible(true);
}
add(titleVisiblePane, BorderLayout.NORTH, 0);
add(detailedTitleStylePane, BorderLayout.CENTER, 1);
}
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) {
Component detailedTitleStylePane = getComponent(1);
if (detailedTitleStylePane != null) {
detailedTitleStylePane.setVisible(visibleCheckbox.isSelected());
}
}
});
return container;
}
private JPanel createDetailedTitleStylePane() {
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}
};
if (this.supportTitleContent) {
rowSize = new double[]{p, p, p, p, p, p};
components = new JComponent[][]{
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Content")), textContentPane},
{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;
visibleCheckbox.setSelected(style.getType() != LayoutBorderStyle.STANDARD);
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;
}
}

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[] {

81
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;
@ -87,6 +92,7 @@ import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.undo.UndoManager;
import java.awt.BorderLayout;
@ -99,13 +105,14 @@ 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 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;
@ -140,9 +147,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) {
@ -184,6 +194,11 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
this.undoState = createUndoState();
initAndStartPlugin();
if (isNewFile) {
setUpTheme4NewTemplate();
}
startListenThemeConfig();
}
private void initAndStartPlugin() {
@ -213,6 +228,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);
@ -372,6 +416,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public void whenClose() {
// stop的时候 pluginListener 和 PluginFilter 都会移除
PluginListenerRegistration.getInstance().stopListen(this.pluginListener);
stopListenThemeConfig();
}
@ -567,6 +612,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
*/
public void undo() {
this.getUndoManager().undo();
// 撤销前模版使用主题可能已经被删除或修改,需要重置模版样式
checkAndResetTheme();
fireSuperTargetModified();
}
@ -575,7 +622,8 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
*/
public void redo() {
this.getUndoManager().redo();
// 重做前模版使用主题可能已经被删除或修改,需要重置模版样式
checkAndResetTheme();
fireSuperTargetModified();
}
@ -1411,6 +1459,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;
}
@ -1419,6 +1469,16 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
return new UIButton[]{new CheckButton()};
}
protected UIButton createTemplateThemeButton() {
UIButton button = new UIButton(BaseUtils.readIcon("/com/fr/design/icon/icon_predefined_style.png"));
button.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Predefined_Template_Style"));
button.setText(getTemplateTheme().getName());
button.setAlignmentX(SwingConstants.LEFT);
button.set4ToolbarButton();
button.setEnabled(true);
return button;
}
/**
* 由于老版本的模板没有模板ID当勾选使用参数模板时候就加一个模板ID attr
*
@ -1662,4 +1722,21 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public String getRuntimeId() {
return runtimeId;
}
private void setUpTheme4NewTemplate() {
TemplateTheme theme = getUsingTemplateThemeConfig().getTheme4NewTemplate();
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);
templateThemeButton.setText(newTheme.getName());
}
}

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

@ -0,0 +1,72 @@
package com.fr.design.mainframe.theme;
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.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 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 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);
}
}

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

@ -0,0 +1,54 @@
package com.fr.design.mainframe.theme;
import com.fr.base.theme.ReportTheme;
import com.fr.base.theme.TemplateThemeConfig;
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;
/**
* @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 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());
}
}

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

@ -0,0 +1,181 @@
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.ibutton.UIButton;
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.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
/**
* @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 UILabel thumbnailLabel;
private boolean selected = false;
private boolean hovering = false;
private MouseAdapter clickListener;
public TemplateThemeBlock(String name, TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) {
this.name = name;
this.config = config;
this.theme = this.config.find(name);
this.profilePane = profilePane;
initializePane();
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (clickListener != null) {
clickListener.mouseClicked(e);
}
}
@Override
public void mouseEntered(MouseEvent e) {
hovering = true;
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
hovering = false;
repaint();
}
});
refresh();
}
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.WEST);
if (profilePane != null) {
addProfileButton(infoPane, profilePane);
}
add(thumbnailLabel, BorderLayout.CENTER);
add(infoPane, BorderLayout.SOUTH);
}
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, TemplateThemeProfilePane<T> profilePane) {
UIButton profileLabel = new UIButton(profileIcon);
// profileLabel.setUI(new BasicLabelUI());
profileLabel.setBackground(null);
profileLabel.setOpaque(false);
profileLabel.setPreferredSize(new Dimension(24, 24));
profileLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Window parent = SwingUtilities.getWindowAncestor(TemplateThemeBlock.this);
TemplateThemeProfileDialog<T> profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane);
profilePane.populateBean(theme);
profileDialog.setVisible(true);
}
});
panel.add(profileLabel, BorderLayout.EAST);
}
public void refresh() {
theme = this.config.find(name);
ThemeThumbnail thumbnail = theme.getThumbnail();
if (thumbnail != null) {
BufferedImage image = thumbnail.getImage();
if (image != null) {
thumbnailLabel.setIcon(new ImageIcon(thumbnail.getImage()));
}
}
repaint();
}
@Override
public void paint(Graphics g) {
super.paint(g);
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(), theme.getName())) {
theme4currentTemplateMarkIcon.paintIcon(this, g, 176, 0);
}
}
T theme4newTemplate = config.getTheme4NewTemplate();
if (StringUtils.equals(theme4newTemplate.getName(), 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);
}
}
}

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

@ -0,0 +1,180 @@
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;
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(TemplateThemeConfig<T> config, TemplateThemeProfilePane<T> profilePane) {
this.config = config;
this.profilePane = profilePane;
this.contentListPane = new JPanel();
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) {
T theme = config.find(name);
if (theme != null) {
TemplateThemeBlock<T> block = createCachedTemplateThemeBlock(name);
contentListPane.add(block);
if (StringUtils.equals(name, config.getTheme4NewTemplate().getName())) {
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, config, profilePane);
block.addClickListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if (selectedBlock != null) {
selectedBlock.setSelected(false);
}
selectedBlock = block;
selectedBlock.setSelected(true);
if (changeListener != null) {
changeListener.fireChanged(new ChangeEvent(selectedBlock));
}
}
});
return block;
}
public void setChangeListener(ChangeListener changeListener) {
this.changeListener = changeListener;
}
@Override
protected String title4PopupWindow() {
return null;
}
public T getSelectedTheme() {
return selectedBlock.getTheme();
}
public void startListenThemeConfig() {
if (themeConfigChangeListener == null) {
themeConfigChangeListener = new TemplateThemeConfig.ThemeConfigChangeListener() {
@Override
public void onThemeConfigChanged(TemplateThemeConfig.ThemeConfigEvent event) {
TemplateThemeBlock<T> existingBlock = blockCache.get(event.themName);
switch (event.action) {
case DEFAULT_THEME_4_NEW_TEMPLATE_UPDATE: {
if (block4newTemplate != null) {
block4newTemplate.refresh();
}
if (existingBlock != null) {
existingBlock.refresh();
}
block4newTemplate = existingBlock;
break;
}
case UPDATE: {
if (existingBlock != null) {
existingBlock.refresh();
}
break;
}
case REMOVE: {
if (existingBlock != null) {
contentListPane.remove(existingBlock);
validate();
repaint();
blockCache.remove(event.themName);
}
break;
}
case ADD: {
if (existingBlock == null) {
// TODO 这里是否还能继续优化?
fillContentListPane();
validate();
repaint();
}
break;
}
}
}
};
config.addThemeConfigChangeListener(themeConfigChangeListener);
}
}
public void stopListenThemeConfig() {
if (themeConfigChangeListener != null) {
config.removeThemeConfigChangeListener(themeConfigChangeListener);
themeConfigChangeListener = null;
}
}
}

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

@ -0,0 +1,241 @@
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 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 RemoveThemeAction removeAction;
private final TemplateThemeConfig<T> config;
private final TemplateThemeListPane<T> themeListPane;
private final TemplateThemeProfilePane<T> profilePane;
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<>(config, profilePane);
profilePane.setThemeListPane(themeListPane);
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.setChangeListener(new ChangeListener() {
@Override
public void fireChanged(ChangeEvent event) {
T theme = themeListPane.getSelectedTheme();
removeAction.setEnabled(theme.isRemovable());
}
});
nextContainer.add(themeListPane, BorderLayout.CENTER);
repaint();
}
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();
removeAction = new RemoveThemeAction(false);
ToolBarDef toolbarDef = new ToolBarDef();
toolbarDef.addShortCut(addMenuDef, removeAction);
toolbarDef.updateToolBar(toolBar);
UIButton defaultSettingBtn = new UIButton(Toolkit.i18nText("Fine-Design_Template_Theme_Manager_Pane_Default_Setting"));
defaultSettingBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
T style = themeListPane.getSelectedTheme();
if (style != null) {
config.setTheme4NewTemplate(style.getName());
}
}
});
content.add(defaultSettingBtn, 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_Template_Theme_Manager_Pane_Create_Light_Theme"), config.getLightTheme4New()));
menuDef.addShortCut(new AddThemeAction(Toolkit.i18nText("Fine-Design_Template_Theme_Manager_Pane_Create_Dark_Theme"), config.getDarkTheme4New()));
return menuDef;
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Predefined_Server_Style");
}
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();
int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this),
Toolkit.i18nText("Fine-Design_Predefined_Remove_Style_Confirm", theme.getName()),
Toolkit.i18nText("Fine-Design_Basic_Delete"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
removeTheme(theme.getName());
}
}
}
private class AddThemeAction extends UpdateAction {
private final T theme4New;
public AddThemeAction(String name, T theme4New) {
setName(name);
setMnemonic('R');
this.theme4New = theme4New;
}
@Override
public void actionPerformed(ActionEvent e) {
Window parent = SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this);
TemplateThemeProfileDialog<T> profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane);
try {
T theme = (T) theme4New.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);
}
}
}
private void removeTheme(String name) {
config.removeTheme(name);
}
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();
}
}

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

@ -0,0 +1,29 @@
package com.fr.design.mainframe.theme;
import com.fr.base.chart.chartdata.CallbackEvent;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.mainframe.theme.preview.ThemePreviewed;
import javax.swing.JPanel;
/**
* @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();
}
}
}

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

@ -0,0 +1,592 @@
package com.fr.design.mainframe.theme;
import com.fr.base.Style;
import com.fr.base.background.ColorBackground;
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.ThemedCellStyle;
import com.fr.base.theme.settings.ThemedCellStyleList;
import com.fr.base.theme.settings.ThemedColorScheme;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane;
import com.fr.design.gui.frpane.AttributeChangeListener;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog;
import com.fr.design.mainframe.theme.edit.CellStyleListEditPane;
import com.fr.design.mainframe.theme.edit.ChartStyleEditPane;
import com.fr.design.mainframe.theme.ui.BorderUtils;
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.utils.gui.GUICoreUtils;
import com.fr.general.FRFont;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
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.Graphics2D;
import java.awt.Transparency;
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.awt.image.BufferedImage;
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 = 360;
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;
protected TemplateThemeListPane<T> themeListPane;
private final TemplateThemeConfig<T> config;
private final UIButton saveButton = new UIButton();
private final UIButton saveAsButton = new UIButton();
private boolean currentIsNewTheme;
private T theme;
public TemplateThemeProfilePane(TemplateThemeConfig<T> config) {
this.config = config;
theme = config.createNewTheme();
}
public void setThemeListPane(TemplateThemeListPane<T> themeListPane) {
this.themeListPane = themeListPane;
}
@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_Predefined_Style_Edit");
}
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_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.setOpaque(true);
themePreviewPane.setBackground(Color.WHITE);
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_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_Template_Theme_Edit_Pane_Color_Scheme_Preview_Label")), BorderLayout.NORTH);
JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListPane},
{null, LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_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_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) {
colorListExtendedPane.populate(colorListPane.update());
}
});
return container;
}
protected JPanel createCustomEditorsPane() {
JPanel container = new JPanel(new BorderLayout());
container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_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(350, 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 populateBean(T theme) {
this.theme = theme;
isPopulating = true;
String name = theme.getName();
currentIsNewTheme = config.find(name) == null;
nameTextField.setText(name);
nameTextField.setEnabled(StringUtils.isEmpty(name));
saveButton.setEnabled(theme.isMutable() && !currentIsNewTheme);
saveAsButton.setEnabled(!currentIsNewTheme);
cellStyleSettingPane.populateBean(theme.getCellStyleList());
colorListPane.populate(theme.getColorScheme().getColors());
colorListExtendedPane.populate(colorListPane.update());
chartStyleSettingPane.populateBean(theme.getChartStyle());
isPopulating = false;
}
public T updateBean() {
if (theme == null) {
theme = config.createNewTheme();
}
theme.setName(this.nameTextField.getText());
theme.setThumbnail(updateThumbnail());
ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean();
theme.setCellStyleList(cellStyleConfig);
ThemedColorScheme colorScheme = theme.getColorScheme();
colorScheme.setColors(this.colorListPane.update());
updateCellStyleByColorStyle(colorScheme, cellStyleConfig);
theme.setColorScheme(colorScheme);
theme.setChartStyle(this.chartStyleSettingPane.updateBean());
updateBean(theme);
return theme;
}
protected abstract void updateBean(T theme);
protected void updateCellStyleByColorStyle(ThemedColorScheme colorStyle, ThemedCellStyleList cellStyleConfig) {
ThemedCellStyle headerStyle = cellStyleConfig.find(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
ThemedCellStyle highlightStyle = cellStyleConfig.find(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text"));
List<Color> colorList = colorStyle.getColors();
if (headerStyle != null) {
Style style = headerStyle.getStyle();
Color color = colorList.get(0);
headerStyle.setStyle(style.deriveBackground(ColorBackground.getInstance(color)));
}
if (highlightStyle != null) {
Style style = highlightStyle.getStyle();
Color color = colorList.get(1);
FRFont font = style.getFRFont();
font.setForeground(color);
highlightStyle.setStyle(style.deriveFRFont(font));
}
}
protected ThemeThumbnail updateThumbnail() {
BufferedImage image = null;
int width = themePreviewPane.getWidth();
int height = themePreviewPane.getHeight();
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);
themePreviewPane.paint(g2d);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
ThemeThumbnail thumbnail = new ThemeThumbnail();
thumbnail.setImage(image);
return thumbnail;
}
public void saveTheme(T theme) {
if (StringUtils.isEmpty(theme.getName())) {
FineJOptionPane.showMessageDialog(this, Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Name_Cannot_Empty"));
} else {
config.addTheme(theme, true);
}
}
public UIButton createSaveButton() {
saveButton.setText(Toolkit.i18nText("Fine-Design_Basic_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.setName(nameTextField.getText());
saveTheme(theme);
populateBean(theme);
}
}
});
return saveButton;
}
public UIButton createSaveAsButton(final TemplateThemeProfileDialog<T> profileDialog) {
saveAsButton.setText(Toolkit.i18nText("Fine-Design_Basic_Predefined_Save_As_New"));
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_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) {
boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(true, nameTextField, nameErrorLabel, confirmButton);
if (canBeSaved) {
T theme = updateBean();
theme.setName(nameTextField.getText());
saveTheme(theme);
exit();
parent.exit();
}
}
});
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.add(nameTextField);
nameTextPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Template_Theme_Save_As_Pane_Name_Label")));
container.add(nameTextPane, BorderLayout.CENTER);
container.add(nameErrorLabel, BorderLayout.SOUTH);
return container;
}
public void exit() {
this.dispose();
}
}
private boolean isThemeNameEmpty(String name) {
return StringUtils.isEmpty(name);
}
private boolean isThemeNameDuplicated(String name) {
return config.find(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_Template_Theme_Edit_Pane_Empty_Name_Error_Tip");
} else if (checkDuplicated && isThemeNameDuplicated(name)) {
error = Toolkit.i18nText("Fine-Design_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip");
}
errorLabel.setText(error);
boolean valid = StringUtils.isEmpty(error);
if (!valid) {
textField.requestFocus();
}
errorLabel.setVisible(!valid);
for (UIButton button: actionButtons) {
button.setEnabled(valid);
}
return valid;
}
}

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

@ -0,0 +1,99 @@
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) {
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();
}
}

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

@ -0,0 +1,72 @@
package com.fr.design.mainframe.theme.dialog;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.ReportTheme;
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.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 TemplateThemeManagePane<FormTheme> formThemesManagerPane;
private TemplateThemeManagePane<ReportTheme> reportThemesManagerPane;
public TemplateThemeManageDialog(Window parent) {
super(parent, Toolkit.i18nText("Fine-Design_Template_Theme_Manager_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT);
setContentPane(createDialogContentPane(createContent(), new UIButton[]{
createCompleteButton()
}));
}
private JPanel createContent() {
JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane();
content.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
UITabbedPane tabbedPane = new UITabbedPane();
content.add(tabbedPane, BorderLayout.NORTH);
formThemesManagerPane = TemplateThemeManagePane.createFormThemesManagerPane();
formThemesManagerPane.startListenThemeConfig();
reportThemesManagerPane = TemplateThemeManagePane.createReportThemesManagerPane();
reportThemesManagerPane.startListenThemeConfig();
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Template_Theme_Manager_Dialog_FORM_TAB"), formThemesManagerPane);
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Template_Theme_Manager_Dialog_REPORT_TAB"), reportThemesManagerPane);
return content;
}
private UIButton createCompleteButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Template_Theme_Manager_Dialog_Complete"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exit();
}
});
return button;
}
@Override
public void exit(){
formThemesManagerPane.stopListenThemeConfig();
reportThemesManagerPane.stopListenThemeConfig();
super.exit();
}
}

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

@ -0,0 +1,49 @@
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.theme.TemplateThemeProfilePane;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
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 TemplateThemeProfileDialog<T extends TemplateTheme> extends TemplateThemeDialog {
public static final int CONTENT_WIDTH = 778;
public static final int CONTENT_HEIGHT = 558;
public TemplateThemeProfileDialog(Window parent, TemplateThemeProfilePane<T> profilePane) {
super(parent, Toolkit.i18nText("Fine-Design_Template_Theme_Profile_Dialog_Title"), 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[]{
profilePane.createSaveButton(),
profilePane.createSaveAsButton(this),
createCancelButton()
}));
}
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;
}
}

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

@ -0,0 +1,119 @@
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.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.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_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT);
this.currentTemplate = template;
this.themeListPane = new TemplateThemeListPane<>(config, null);
JPanel content = createContent();
UIButton openThemeManagerButton = createOpenThemeManagerButton();
UIButton usingCurrentThemeButton = createUsingCurrentThemeButton();
UIButton completeButton = createCompleteButton();
if (WorkContext.getCurrent().isRoot()) {
setContentPane(createDialogContentPane(content,
new UIButton[]{ openThemeManagerButton },
new UIButton[]{ usingCurrentThemeButton, completeButton }
));
} else {
setContentPane(createDialogContentPane(content,
new UIButton[]{ usingCurrentThemeButton, completeButton }
));
}
themeListPane.startListenThemeConfig();
}
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_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() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_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;
}
private UIButton createUsingCurrentThemeButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Template_Theme_Using_Dialog_Use"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
apply2CurrentTemplate();
}
});
return button;
}
private UIButton createCompleteButton() {
UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Template_Theme_Using_Dialog_Complete"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exit();
}
});
return button;
}
public void exit() {
themeListPane.stopListenThemeConfig();
super.exit();
}
public void apply2CurrentTemplate() {
TemplateTheme theme = themeListPane.getSelectedTheme();
if (theme != null) {
currentTemplate.setTemplateTheme(theme);
themeListPane.repaint();
}
}
}

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

@ -0,0 +1,242 @@
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.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.ListModelElement;
import com.fr.design.gui.ilist.ModNameActionListener;
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.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.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
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_Predefined_Style_Empty_Name"), index);
return;
}
if (isNameRepeated(new List[]{Arrays.asList(allNames)}, newName)) {
showTipDialogAndReset(i18nText("Fine-Design_Basic_Predefined_Style_Duplicate_Name", newName), 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 CellStyleNameObjectCreator()};
}
@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(260, 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);
}
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() {
super(i18nText("Fine-Design_Predefined_Cell_New_Style"), ThemedCellStyle.class, CellStyleEditPane.class);
}
public Nameable createNameable(UnrepeatedNameHelper helper) {
ThemedCellStyle cellStyle = new ThemedCellStyle();
cellStyle.setName(menuName);
cellStyle.setStyle(Style.getInstance());
return new NameObject(helper.createUnrepeatedName(this.menuName()), cellStyle);
}
public Object acceptObject2Populate(Object ob) {
if (ob instanceof NameObject) {
ob = ((NameObject) ob).getObject();
}
if (clazzOfObject != null && clazzOfObject.isInstance(ob) && acceptDefaultNameObject(ob)) {
doSthChanged4Icon(ob);
return ob;
}
return null;
}
public boolean acceptDefaultNameObject(Object ob) {
return !((ThemedCellStyle) ob).isDefault4New();
}
}
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;
}
}

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

@ -0,0 +1,96 @@
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.ChartBackgroundStylePane;
import com.fr.design.mainframe.theme.edit.chart.ChartTitleStylePane;
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 javax.swing.BorderFactory;
import java.util.ArrayList;
import java.util.List;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-16
*/
public class ChartStyleEditPane extends MultiTabPane<ThemedChartStyle> {
private ChartTitleStylePane chartTitleStylePane;
private ChartLegendStylePane chartLegendStylePane;
private ChartLabelStylePane chartLabelPane;
private ChartAxisStylePane chartAxisStylePane;
private ChartDataSheetStylePane chartDataSheetStylePane;
private ChartBackgroundStylePane chartBackgroundStylePane;
public ChartStyleEditPane() {
}
@Override
protected void initLayout() {
super.initLayout();
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
}
@Override
protected List<BasicPane> initPaneList() {
this.chartTitleStylePane = new ChartTitleStylePane();
this.chartLegendStylePane = new ChartLegendStylePane();
this.chartLabelPane = new ChartLabelStylePane();
this.chartAxisStylePane = new ChartAxisStylePane();
this.chartDataSheetStylePane = new ChartDataSheetStylePane();
this.chartBackgroundStylePane = new ChartBackgroundStylePane();
paneList = new ArrayList<>();
paneList.add(this.chartTitleStylePane);
paneList.add(this.chartLegendStylePane);
paneList.add(this.chartLabelPane);
paneList.add(this.chartAxisStylePane);
paneList.add(this.chartDataSheetStylePane);
paneList.add(this.chartBackgroundStylePane);
return paneList;
}
@Override
public void populateBean(ThemedChartStyle ob) {
chartTitleStylePane.populate(ob);
chartLegendStylePane.populate(ob);
chartLabelPane.populate(ob);
chartAxisStylePane.populate(ob);
chartDataSheetStylePane.populate(ob);
chartBackgroundStylePane.populate(ob);
}
@Override
public void updateBean(ThemedChartStyle ob) {
}
@Override
public ThemedChartStyle updateBean() {
ThemedChartStyle chartStyle = new ThemedChartStyle();
chartTitleStylePane.update(chartStyle);
chartLegendStylePane.update(chartStyle);
chartLabelPane.update(chartStyle);
chartAxisStylePane.update(chartStyle);
chartDataSheetStylePane.update(chartStyle);
chartBackgroundStylePane.update(chartStyle);
return chartStyle;
}
@Override
public boolean accept(Object ob) {
return false;
}
@Override
public void reset() {
}
}

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

@ -0,0 +1,112 @@
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 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 = 150;
private final ComponentTitleStylePane componentTitleStylePane;
private final ComponentBodyStylePane componentBodyStylePane;
private final ExtendedComponentIntegralStylePane componentIntegralStylePane;
public ComponentStyleEditPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
componentTitleStylePane = new ComponentTitleStylePane(LABEL_WIDTH, SETTING_WIDTH, false, false);
componentBodyStylePane = new ComponentBodyStylePane(LABEL_WIDTH, SETTING_WIDTH);
componentIntegralStylePane = new ExtendedComponentIntegralStylePane();
JPanel content = new TabbedPane(
new String[] {
Toolkit.i18nText("Fine-Design_Template_Theme_Edit_Pane_Component_Title"),
Toolkit.i18nText("Fine-Design_Template_Theme_Edit_Pane_Component_Body"),
Toolkit.i18nText("Fine-Design_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 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_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(0XC6C6C6), 8);
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 = 150;
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;
}
}

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

@ -0,0 +1,34 @@
package com.fr.design.mainframe.theme.edit;
import com.fr.base.theme.settings.ThemedReportBodyStyle;
import com.fr.design.mainframe.predefined.ui.detail.background.BackgroundSettingPane;
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 ReportBodyStyleEditPane extends JScrollPane {
private final BackgroundSettingPane backgroundPane;
public ReportBodyStyleEditPane() {
backgroundPane = new BackgroundSettingPane();
setViewportView(backgroundPane);
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.updateBean());
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) {
}
}

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

@ -0,0 +1,208 @@
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;
BasicPane borderPane = null;
for (BasicPane basicPane : paneList) {
((AbstractBasicStylePane) basicPane).populateBean(ob.getStyle());
previewArea.preview(ob.getStyle());
if (basicPane instanceof BorderPane) {
borderPane = basicPane;
}
}
if (borderPane != null && ob.isDefault4New()) {
// 默认单元格样式不显示边框面板,禁止用户编辑边框
paneList.remove(borderPane);
relayoutWhenListChange();
}
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();
}
}
}

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

@ -0,0 +1,49 @@
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 e = 155;
double p = TableLayout.PREFERRED;
double[] columnSize = {p, 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());
}
}

113
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartBackgroundStylePane.java

@ -0,0 +1,113 @@
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.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
/**
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-09-17
*/
public class ChartBackgroundStylePane extends AbstractChartStylePane {
private UIComboBox typeComboBox;
private List<BackgroundQuickPane> paneList;
private JPanel centerPane;
//网格线颜色
private ColorSelectBox mainGridColor;
protected void initComponents() {
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());
}
});
}
protected Component[][] getComponent() {
return new Component[][]{
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};
}
private void initList() {
paneList = new ArrayList<>();
paneList.add(new NullBackgroundQuickPane());
paneList.add(new ColorBackgroundQuickPane());
paneList.add(new ImageBackgroundQuickPane(false));
paneList.add(new VanChartGradientPane());
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Chart_Background");
}
public void populate(ThemedChartStyle chartStyle) {
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.setChartBackground(paneList.get(typeComboBox.getSelectedIndex()).updateBean());
if (chartStyle.getChartBackground() instanceof ImageBackground) {
((ImageBackground) chartStyle.getChartBackground()).setLayout(Constants.IMAGE_EXTEND);
}
chartStyle.setGridMainLineColor(mainGridColor.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());
}
}

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

@ -0,0 +1,160 @@
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 e = 155;
double p = TableLayout.PREFERRED;
double[] rows = {p, p, p};
double[] columnSize = {p, 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());
}
}

49
designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleStylePane.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 ChartTitleStylePane extends AbstractChartStylePane {
//字体样式
private ChartFontPane chartFontPane;
protected void initComponents() {
chartFontPane = new ChartFontPane() {
public String getUILabelText() {
return Toolkit.i18nText("Fine-Design_Chart_Title_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_Report_Title");
}
public void populate(ThemedChartStyle chartStyle) {
chartFontPane.populate(chartStyle.getTitleFont());
}
public void update(ThemedChartStyle chartStyle) {
chartStyle.setTitleFont(chartFontPane.update());
}
}

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

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

@ -0,0 +1,148 @@
package com.fr.design.mainframe.theme.edit.ui;
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) {
float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), new float[3]);
hsb[2] *= 1.0F * (index + 1) / count;
return Color.getHSBColor(hsb[0], hsb[1], hsb[2]);
}
};
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);
}
}

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

@ -0,0 +1,199 @@
package com.fr.design.mainframe.theme.edit.ui;
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.ColorSelectPane;
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 ColorSelectPane 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 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));
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));
}
}
}

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

@ -0,0 +1,26 @@
package com.fr.design.mainframe.theme.edit.ui;
import com.fr.design.gui.ilable.UILabel;
import java.awt.Color;
/**
* @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);
uiLabel.setFont(uiLabel.getFont().deriveFont(size));
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);
}
}

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

@ -0,0 +1,26 @@
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;
@Override
protected Component createContentPane() {
contentPane = new ChartPreviewPane();
return contentPane;
}
@Override
public void refresh(FormTheme theme) {
super.refresh(theme);
contentPane.refresh(theme);
}
}

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

@ -0,0 +1,39 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.chart.BaseChartCollection;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.gui.chart.MiddleChartComponent;
import com.fr.stable.core.PropertyChangeListener;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class ChartPreviewPane extends MiddleChartComponent implements ThemePreviewed<TemplateTheme> {
@Override
public void populate(BaseChartCollection cc) {
}
@Override
public BaseChartCollection update() {
return null;
}
@Override
public void reset() {
}
@Override
public void addStopEditingListener(PropertyChangeListener list) {
}
@Override
public void refresh(TemplateTheme style) {
}
}

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

@ -0,0 +1,161 @@
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.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 JPanel implements ThemePreviewed<FormTheme> {
public static final int TITLE_HEIGHT = 35;
private final JPanel container;
private final TitleDemoPane titlePane;
private BorderPacker style = new LayoutBorderStyle();
public ComponentPreviewPane() {
container = FRGUIPaneFactory.createBorderLayout_S_Pane();
setLayout(new BorderLayout());
titlePane = new TitleDemoPane();
titlePane.setPreferredSize(new Dimension(titlePane.getPreferredSize().width, 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));
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.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(g2d);
super.paintBorder(g2d);
}
private static class TitleDemoPane extends JPanel {
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);
}
@Override
public Dimension getPreferredSize() {
return getSize();
}
}
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));
}
}
}

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

@ -0,0 +1,26 @@
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 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);
}
}

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

@ -0,0 +1,160 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.ScreenResolution;
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.log.FineLoggerFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
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 JPanel implements ThemePreviewed<TemplateTheme> {
private static final List<String[]> DATA_LIST = createDataList();
private static final String BLANK_CHAR = " ";
private final List<List<Cell>> grid = new ArrayList<>();
private static List<String[]> createDataList() {
String csv =
"城市 当月目标 当月实际完成 月度完成率\n" +
"南通市 324,646 324,646 100%\n" +
"合肥市 248,938 348,938 140%\n" +
"邵阳市 248,938 348,938 140%\n" +
"合计 1,071,460 1,371,460 128%";
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() {
setOpaque(false);
setBackground(null);
GridBagLayout gridBagLayout = new GridBagLayout();
setLayout(gridBagLayout);
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.BOTH;
for (int i = 0; i < DATA_LIST.size(); i++) {
String[] textLine = DATA_LIST.get(i);
List<Cell> row = new ArrayList<>();
for (int j = 0; j < textLine.length ; j++) {
String text = textLine[j];
constraints.gridx = j;
constraints.gridy = i;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.weightx = 1.0;
constraints.weighty = 1.0;
Cell cell = new Cell(text);
cell.setPreferredSize(new Dimension(50, 20));
gridBagLayout.setConstraints(cell, constraints);
add(cell);
row.add(cell);
}
grid.add(row);
}
}
@Override
public void refresh(TemplateTheme theme) {
ThemedCellStyleList cellStyleConfig = theme.getCellStyleList();
for (int i = 0; i < grid.size(); i++) {
Style style = getMainContentStyle(cellStyleConfig);
if (i == 0) {
style = getReportHeaderStyle(cellStyleConfig);
}
if (i == DATA_LIST.size() - 1) {
style = getHighLightStyle(cellStyleConfig);
}
List<Cell> row = grid.get(i);
for (Cell cell : row) {
cell.refresh(style);
}
}
}
private Style getReportHeaderStyle(ThemedCellStyleList cellStyleList) {
return getCellStyle(cellStyleList, Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header"));
}
private Style getMainContentStyle(ThemedCellStyleList cellStyleList) {
return getCellStyle(cellStyleList, Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text"));
}
private Style getHighLightStyle(ThemedCellStyleList cellStyleList) {
return getCellStyle(cellStyleList, Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text"));
}
private Style getCellStyle(ThemedCellStyleList cellStyleList, String styleName) {
ThemedCellStyle cellStyle = cellStyleList.find(styleName);
if (cellStyle == null) {
return Style.DEFAULT_STYLE;
}
return cellStyle.getStyle();
}
private static class Cell extends JComponent {
private Style style = Style.DEFAULT_STYLE;
private final String value;
public Cell(String value) {
this.value = value;
}
public void refresh(Style style) {
this.style = style;
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int resolution = ScreenResolution.getScreenResolution();
if (style == Style.DEFAULT_STYLE) {
Style.paintContent(g2d, value, style, getWidth() - 3, getHeight() - 3, resolution);
return;
}
Style.paintBackground(g2d, style, getWidth(), getHeight());
Style.paintContent(g2d, value, style, getWidth() - 3, getHeight() - 3, resolution);
Style.paintBorder(g2d, style, getWidth() , getHeight() );
}
@Override
public Dimension getMinimumSize() {
return new Dimension(125, 30);
}
}
}

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

@ -0,0 +1,74 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.theme.FormTheme;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.theme.TemplateThemePreviewPane;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class FormThemePreviewPane extends TemplateThemePreviewPane<FormTheme> {
private final ECComponentPreviewPane elementCasePane;
private final ChartComponentPreviewPane chart1Pane;
private final ChartComponentPreviewPane chart2Pane;
private final ChartComponentPreviewPane chart3Pane;
public FormThemePreviewPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel content = new JPanel();
GridBagLayout gridBagLayout = new GridBagLayout();
content.setLayout(gridBagLayout);
add(content, BorderLayout.CENTER);
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridheight = 1;
constraints.weighty = 1.0;
elementCasePane = new ECComponentPreviewPane();
gridBagLayout.setConstraints(elementCasePane, constraints);
content.add(elementCasePane, constraints);
constraints.gridx = 0;
constraints.gridy = 1;
constraints.weightx = 1.0;
constraints.weighty = 1.0;
chart1Pane = new ChartComponentPreviewPane();
// add(chart1Pane, constraints);
constraints.gridx = 0;
constraints.gridy = 2;
constraints.weightx = 1.0;
constraints.weighty = 1.0;
chart2Pane = new ChartComponentPreviewPane();
// add(chart2Pane, constraints);
constraints.gridx = 1;
constraints.gridy = 2;
constraints.gridwidth = 1;
constraints.gridheight = 1;
chart3Pane = new ChartComponentPreviewPane();
// add(chart3Pane, constraints);
}
@Override
public void refresh(FormTheme theme) {
elementCasePane.refresh(theme);
chart1Pane.refresh(theme);
chart2Pane.refresh(theme);
chart3Pane.refresh(theme);
repaint();
}
}

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

@ -0,0 +1,17 @@
package com.fr.design.mainframe.theme.preview;
import com.fr.base.theme.ReportTheme;
import com.fr.design.mainframe.theme.TemplateThemePreviewPane;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/13
*/
public class ReportThemePreviewPane extends TemplateThemePreviewPane<ReportTheme> {
@Override
public void refresh(ReportTheme theme) {
}
}

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

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()}, "-"
);
}
}
}

8
designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java

@ -42,6 +42,9 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{
public XBorderStyleWidgetCreator(Widget widget, Dimension initSize) {
super(widget, initSize);
setOpaque(false);
setBackupBound(null);
ExtendSharableAttrMark sharableAttrMark = this.toData().getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG);
if (sharableAttrMark != null) {
this.setShareId(sharableAttrMark.getShareId());
@ -263,6 +266,11 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{
}
@Override
public void setBackground(Color bg) {
super.setBackground(bg);
}
// 根据当前组件边框裁剪内容,如果当前组件存在圆角,则应当按圆角裁剪内容
private void clipByRoundedBorder(Graphics2D g2d) {
Border currentBorder = getBorder();

11
designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutStylePane.java

@ -10,15 +10,14 @@ import javax.swing.JPanel;
*/
public class CardTagLayoutStylePane extends LayoutStylePane {
@Override
protected JPanel createTitleStylePane(){
JPanel panel = super.createTitleStylePane();
panel.setVisible(false);
return panel;
protected JPanel createNamedTitleStylePane(boolean isRootLayout) {
return null;
}
@Override
protected JPanel createBackgroundStylePane(boolean supportCornerRadius) {
return super.createBackgroundStylePane(false);
protected JPanel createNamedIntegralStylePane(boolean isRootLayout, boolean supportCornerRadius) {
return super.createNamedIntegralStylePane(isRootLayout, false);
}
}

535
designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java

@ -1,40 +1,35 @@
package com.fr.design.gui.xpane;
import com.fr.base.Utils;
import com.fr.base.svg.IconUtils;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.formula.TinyFormulaPane;
import com.fr.design.gui.frpane.UIPercentDragPane;
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.gui.ispinner.UISpinner;
import com.fr.design.gui.style.BackgroundSpecialPane;
import com.fr.design.gui.style.FRFontPane;
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.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.JForm;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.backgroundpane.GradientBackgroundQuickPane;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.WidgetTitle;
import com.fr.general.Background;
import com.fr.general.FRFont;
import com.fr.general.IOUtils;
import com.fr.general.act.TitlePacker;
import com.fr.stable.Constants;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* @author Starryi
@ -44,51 +39,15 @@ import java.awt.*;
* 可配置图片类型边框的样式设置面板
*/
public class LayoutStylePane extends BasicBeanPane<LayoutBorderStyle> {
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")
};
private static final Dimension BUTTON_SIZE = new Dimension(20, 20);
public static final int SETTING_LABEL_WIDTH = 60;
protected LayoutBorderStyle style = new LayoutBorderStyle();
//渲染风格:有无阴影
protected UIComboBox borderStyleCombo;
// 含图片类型边框的边框配置面板(图片类型边框 + 阴影时存在默认的阴影颜色)
protected BorderLineAndImagePane borderLineAndImagePane;
//边框圆角或圆角裁剪
protected UISpinner cornerSpinner;
//主体背景
protected BackgroundSpecialPane backgroundPane;
//主体背景透明度
protected UIPercentDragPane backgroundOpacityPane;
// 标题可见
protected UICheckBox titleVisibleCheckbox;
//标题文字内容
protected TinyFormulaPane titleTextPane;
//标题字体格式
protected UIComboBox titleFontFamilyComboBox;
//标题字体大小
protected UIComboBox titleFontSizeComboBox;
//标题字体颜色
protected UIColorButton titleFontColorSelectPane;
//标题字体特殊效果:粗体、斜体、下划线
private UIToggleButton titleFontBoldButton;
private UIToggleButton titleFontItalicButton;
private UIToggleButton titleFontUnderlineButton;
// private LineComboBox titleFontUnderlineCombo; // 目前前端仅支持短横线类型的下划线,因此设计器端暂时就不展示线型选择框了,待后续优化
// 标题图文混排
protected TitleInsetImagePane titleInsetImagePane;
//对齐方式
protected UIButtonGroup titleAlignPane;
//标题整体背景
protected BackgroundSpecialPane titleBackgroundPane;
//标题背景透明度
protected UIPercentDragPane titleBackgroundOpacityPane;
private boolean supportBorderImage = false;
protected ComponentTitleStylePane titleStylePane;
protected ComponentBodyStylePane bodyStylePane;
protected ComponentIntegralStylePane integralStylePane;
private final boolean supportBorderImage;
public LayoutStylePane() {
this(false);
@ -96,344 +55,92 @@ public class LayoutStylePane extends BasicBeanPane<LayoutBorderStyle> {
public LayoutStylePane(boolean supportBorderImage) {
this.supportBorderImage = supportBorderImage;
this.initLayout();
this.initializePane();
}
protected void initLayout() {
protected void initializePane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
boolean currentIsRootLayout = currentEditingTemplate != null && !currentEditingTemplate.isJWorkBook() && ((JForm)currentEditingTemplate).isSelectRootPane();
boolean isRootLayout = currentEditingTemplate != null && !currentEditingTemplate.isJWorkBook() && ((JForm)currentEditingTemplate).isSelectRootPane();
JPanel titlePane = createTitleStylePane();
JPanel bodyContentPane = currentIsRootLayout ? createBodyContentPane4RootLayout() : createBodyContentPane();
JPanel backgroundPane = createBackgroundStylePane(true);
JPanel titleStylePane = createNamedTitleStylePane(isRootLayout);
JPanel bodyStylePane = createNamedBodyStylePane(isRootLayout);
JPanel integralStylePane = createNamedIntegralStylePane(isRootLayout, true);
if (titlePane != null) {
container.add(titlePane, BorderLayout.NORTH);
if (currentIsRootLayout) {
titlePane.setVisible(false);
}
}
JPanel nextContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(nextContainerPane, BorderLayout.CENTER);
addComponents(new JComponent[] { titleStylePane, bodyStylePane, integralStylePane });
}
if (bodyContentPane != null) {
//界面上表单主体只有背景和透明度可以设置
nextContainerPane.add(bodyContentPane, BorderLayout.NORTH);
protected JPanel createNamedTitleStylePane(boolean isRootLayout) {
if (isRootLayout) {
return null;
}
if (backgroundPane != null) {
nextContainerPane.add(backgroundPane, BorderLayout.CENTER);
if (currentIsRootLayout) {
backgroundPane.setVisible(false);
}
}
this.add(container, BorderLayout.CENTER);
this.titleStylePane = new ComponentTitleStylePane(SETTING_LABEL_WIDTH);
return this.createNamedSubStylePane(i18nText("Fine-Design_Form_Widget_Style_Title"), this.titleStylePane);
}
protected JPanel createBackgroundStylePane(boolean supportCornerRadius) {
borderStyleCombo = new UIComboBox(BORDER_STYLE);
borderLineAndImagePane = new BorderLineAndImagePane(this.supportBorderImage);
cornerSpinner = new UISpinner(0,1000,1,0);
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = supportCornerRadius ? new double[] {p, p, p, p} : new double[]{p, p, p};
double[] columnSize = {SETTING_LABEL_WIDTH, f};
UILabel uiLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Background_Style"));
Font font = uiLabel.getFont().deriveFont(Font.BOLD);
uiLabel.setFont(font);
uiLabel.setForeground(new Color(143, 143, 146));
JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{uiLabel, null},
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Render_Style")), borderStyleCombo},
{this.borderLineAndImagePane, null},
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Radius")), cornerSpinner},
},
rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1);
contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(new BottomLineBorder());
container.add(contentPane, BorderLayout.NORTH);
return container;
protected JPanel createNamedBodyStylePane(boolean isRootLayout) {
this.bodyStylePane = new ComponentBodyStylePane(SETTING_LABEL_WIDTH);
if (isRootLayout) {
return this.bodyStylePane;
}
return this.createNamedSubStylePane(i18nText("Fine-Design_Form_Widget-Style_Body_Content"), this.bodyStylePane);
}
protected JPanel createBodyContentPane() {
backgroundPane = new LayoutBackgroundSpecialPane();
backgroundOpacityPane = new UIPercentDragPane();
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p, p};
double[] columnSize = {SETTING_LABEL_WIDTH, f};
JPanel bodyBackground = createBackgroundAndOpacityPane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Fill"),
this.backgroundPane,
this.backgroundOpacityPane);
protected JPanel createNamedIntegralStylePane(boolean isRootLayout, boolean supportCornerRadius) {
if (isRootLayout) {
return null;
}
this.integralStylePane = new ComponentIntegralStylePane(SETTING_LABEL_WIDTH, supportBorderImage, supportCornerRadius);
return this.createNamedSubStylePane(i18nText("Fine-Design_Form_Widget-Style_Background_Style"), this.integralStylePane);
}
UILabel uiLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Content"));
protected JPanel createNamedSubStylePane(String name, JPanel stylePane) {
UILabel uiLabel = new UILabel(name);
Font font = uiLabel.getFont().deriveFont(Font.BOLD);
uiLabel.setFont(font);
uiLabel.setForeground(new Color(143, 143, 146));
JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{uiLabel, null},
{bodyBackground, null},
},
rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1);
contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(new BottomLineBorder());
container.add(contentPane, BorderLayout.NORTH);
return container;
}
protected JPanel createBodyContentPane4RootLayout() {
backgroundPane = new LayoutBackgroundSpecialPane();
backgroundOpacityPane = new UIPercentDragPane();
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p};
double[] columnSize = {SETTING_LABEL_WIDTH, f};
JPanel bodyBackground = createBackgroundAndOpacityPane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Fill"),
this.backgroundPane,
this.backgroundOpacityPane);
JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{
{bodyBackground, null},
},
rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1);
contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
JPanel content = TableLayoutHelper.createGapTableLayoutPane( new JComponent[][] {
{uiLabel},
{stylePane}
}, TableLayoutHelper.FILL_LASTCOLUMN, 0, IntervalConstants.INTERVAL_L1);
content.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0));
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.add(content, BorderLayout.NORTH);
container.setBorder(new BottomLineBorder());
container.add(contentPane, BorderLayout.NORTH);
return container;
}
protected void initTitleComponents() {
titleVisibleCheckbox = new UICheckBox();
titleTextPane = new TinyFormulaPane();
titleFontFamilyComboBox = new UIComboBox(Utils.getAvailableFontFamilyNames4Report());
TitlePacker title = style.getTitle();
if (title != null) {
FRFont frFont = title.getFrFont();
if (frFont != null) {
String fontFamily = frFont.getFamily();
// 使用style中默认的字体初始化titleFontFamilyComboBox,保证UI和数据的一致性
this.titleFontFamilyComboBox.setSelectedItem(fontFamily);
private void addComponents(JComponent[] components) {
JPanel container = this;
for (JComponent component: components) {
if (component != null) {
container.add(component, BorderLayout.NORTH);
JPanel nextContainer = new JPanel(FRGUIPaneFactory.createBorderLayout());
container.add(nextContainer, BorderLayout.CENTER);
container = nextContainer;
}
}
titleFontFamilyComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Family"));
titleFontSizeComboBox = new UIComboBox(FRFontPane.FONT_SIZES);
titleFontSizeComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Size"));
titleFontColorSelectPane = new UIColorButton();
titleFontColorSelectPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Foreground"));
titleFontColorSelectPane.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Foreground"));
titleFontBoldButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/bold.png"));
titleFontBoldButton.setPreferredSize(BUTTON_SIZE);
titleFontBoldButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Bold"));
titleFontBoldButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Bold"));
titleFontItalicButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/italic.png"));
titleFontItalicButton.setPreferredSize(BUTTON_SIZE);
titleFontItalicButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Italic"));
titleFontItalicButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Italic"));
titleFontUnderlineButton = new UIToggleButton(IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/underline.png"));
titleFontUnderlineButton.setPreferredSize(BUTTON_SIZE);
titleFontUnderlineButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline"));
titleFontUnderlineButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline"));
// titleFontUnderlineCombo = new LineComboBox(UIConstants.BORDER_LINE_STYLE_ARRAY);
// titleFontUnderlineCombo.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Line_Style"));
titleInsetImagePane = new TitleInsetImagePane();
titleAlignPane = new UIButtonGroup<Integer>(
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});
titleAlignPane.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")
});
titleBackgroundPane = new LayoutBackgroundSpecialPane();
titleBackgroundOpacityPane = new UIPercentDragPane();
}
protected JPanel createTitleStylePane() {
initTitleComponents();
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] rowSize = {p,p,p,p,p,p};
double[] columnSize = {SETTING_LABEL_WIDTH, f};
final JPanel bottomPane = TableLayoutHelper.createCommonTableLayoutPane( new JComponent[][]{
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Content")), titleTextPane},
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Format")), titleFontFamilyComboBox},
{null, createTitleFontButtonPane()},
{titleInsetImagePane, null},
{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Text_Align")), titleAlignPane},
{this.createTitleBackgroundAndOpacityPane(), null},
},
rowSize, columnSize, IntervalConstants.INTERVAL_L1);
bottomPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
bottomPane.setVisible(false);
JPanel visibleComposedPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
titleVisibleCheckbox.setSelected(false);
visibleComposedPane.add(titleVisibleCheckbox, BorderLayout.WEST);
visibleComposedPane.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Visible")), BorderLayout.CENTER);
UILabel uiLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title"));
Font font = uiLabel.getFont().deriveFont(Font.BOLD);
uiLabel.setFont(font);
uiLabel.setForeground(new Color(143, 143, 146));
JPanel topPane = TableLayoutHelper.createCommonTableLayoutPane( new JComponent[][] {
{uiLabel, null},
{visibleComposedPane, null}
}, new double[]{p, p}, new double[]{SETTING_LABEL_WIDTH, p}, IntervalConstants.INTERVAL_L1);
topPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(new BottomLineBorder());
container.add(topPane, BorderLayout.NORTH);
container.add(bottomPane, BorderLayout.CENTER);
titleVisibleCheckbox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
bottomPane.setVisible(titleVisibleCheckbox.isSelected());
}
});
return container;
}
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[][] {
{titleFontSizeComboBox, titleFontColorSelectPane, titleFontItalicButton, titleFontBoldButton, titleFontUnderlineButton},
}, rowSize, columnSize, IntervalConstants.INTERVAL_W0);
JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
containerPane.add(buttonPane, BorderLayout.NORTH);
// containerPane.add(titleFontUnderlineCombo, BorderLayout.CENTER);
// titleFontUnderlineCombo.setVisible(false);
// titleFontUnderlineButton.addChangeListener(new ChangeListener() {
// @Override
// public void stateChanged(ChangeEvent e) {
// titleFontUnderlineCombo.setVisible(titleFontUnderlineButton.isSelected());
// }
// });
return containerPane;
}
protected JPanel createTitleBackgroundAndOpacityPane() {
return createBackgroundAndOpacityPane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Background"),
titleBackgroundPane,
titleBackgroundOpacityPane);
}
@Override
public LayoutBorderStyle updateBean() {
LayoutBorderStyle style = new LayoutBorderStyle();
updateMain(style);
updateTitle(style);
return style;
}
protected void updateMain(LayoutBorderStyle style) {
if (borderStyleCombo != null) {
style.setBorderStyle(borderStyleCombo.getSelectedIndex());
}
if (cornerSpinner != null) {
style.setBorderRadius((int) cornerSpinner.getValue());
}
if (borderLineAndImagePane != null) {
borderLineAndImagePane.updateBean(style);
}
if (backgroundPane != null) {
style.setBackground(backgroundPane.update());
if (this.titleStylePane != null) {
this.titleStylePane.updateBean(style);
}
if (backgroundOpacityPane != null) {
style.setAlpha((float)backgroundOpacityPane.updateBean());
if (this.bodyStylePane != null) {
this.bodyStylePane.updateBean(style);
}
}
protected void updateTitle(LayoutBorderStyle style) {
style.setType(titleVisibleCheckbox != null && titleVisibleCheckbox.isSelected() ? LayoutBorderStyle.TITLE : LayoutBorderStyle.STANDARD);
TitlePacker title = style.getTitle() == null ? new WidgetTitle() : style.getTitle();
title.setTextObject(titleTextPane.updateBean());
FRFont frFont = title.getFrFont();
frFont = frFont.applySize((Integer) titleFontSizeComboBox.getSelectedItem());
frFont = frFont.applyName(titleFontFamilyComboBox.getSelectedItem().toString());
frFont = frFont.applyForeground(titleFontColorSelectPane.getColor());
frFont = updateTitleFontItalicBold(frFont);
// int line = titleFontUnderlineButton.isSelected() ? this.titleFontUnderlineCombo.getSelectedLineStyle() : Constants.LINE_NONE;
int line = titleFontUnderlineButton.isSelected() ? Constants.LINE_THIN : Constants.LINE_NONE;
frFont = frFont.applyUnderline(line);
title.setFrFont(frFont);
title.setPosition((Integer) titleAlignPane.getSelectedItem());
titleInsetImagePane.updateBean(title);
title.setBackground(titleBackgroundPane.update());
title.setBackgroundOpacity((float)titleBackgroundOpacityPane.updateBean());
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 (titleFontItalicButton.isSelected() && !isItalic) {
italic_bold += Font.ITALIC;
} else if (!titleFontItalicButton.isSelected() && isItalic) {
italic_bold -= Font.ITALIC;
}
frFont = frFont.applyStyle(italic_bold);
if (titleFontBoldButton.isSelected() && !isBold) {
italic_bold += Font.BOLD;
} else if (!titleFontBoldButton.isSelected() && isBold) {
italic_bold -= Font.BOLD;
if (this.integralStylePane != null) {
this.integralStylePane.updateBean(style);
}
frFont = frFont.applyStyle(italic_bold);
return frFont;
return style;
}
@Override
@ -443,104 +150,20 @@ public class LayoutStylePane extends BasicBeanPane<LayoutBorderStyle> {
}
this.style.setStyle(style);
populateMain();
populateTitle();
}
protected void populateMain() {
if (this.borderStyleCombo != null) {
this.borderStyleCombo.setSelectedIndex(style.getBorderStyle());
if (this.titleStylePane != null) {
this.titleStylePane.populateBean(this.style);
}
if (this.borderLineAndImagePane != null) {
this.borderLineAndImagePane.populateBean(style);
}
if (this.backgroundPane != null) {
this.backgroundPane.populateBean(style.getBackground());
if (this.backgroundOpacityPane != null) {
this.backgroundOpacityPane.populateBean(style.getAlpha());
}
if (this.bodyStylePane != null) {
this.bodyStylePane.populateBean(this.style);
}
if (this.cornerSpinner != null) {
this.cornerSpinner.setValue(style.getBorderRadius());
if (this.integralStylePane != null) {
this.integralStylePane.populateBean(this.style);
}
}
protected void populateTitle() {
TitlePacker widgetTitle = style == null ? new WidgetTitle() : style.getTitle();
widgetTitle = widgetTitle == null ? new WidgetTitle() : widgetTitle;
titleVisibleCheckbox.setSelected(style.getType() != LayoutBorderStyle.STANDARD);
this.titleTextPane.populateBean(widgetTitle.getTextObject().toString());
FRFont frFont = widgetTitle.getFrFont();
this.titleFontSizeComboBox.setSelectedItem(frFont.getSize());
this.titleFontFamilyComboBox.setSelectedItem(frFont.getFamily());
this.titleFontColorSelectPane.setColor(frFont.getForeground());
this.titleFontColorSelectPane.repaint();
titleFontBoldButton.setSelected(frFont.isBold());
titleFontItalicButton.setSelected(frFont.isItalic());
int line = frFont.getUnderline();
if (line == Constants.LINE_NONE) {
titleFontUnderlineButton.setSelected(false);
// titleFontUnderlineCombo.setVisible(false);
} else {
titleFontUnderlineButton.setSelected(true);
// titleFontUnderlineCombo.setVisible(true);
// this.titleFontUnderlineCombo.setSelectedLineStyle(line);
}
titleAlignPane.setSelectedItem(widgetTitle.getPosition());
titleInsetImagePane.populateBean(widgetTitle);
titleBackgroundPane.populateBean(widgetTitle.getBackground());
titleBackgroundOpacityPane.populateBean(widgetTitle.getBackgroundOpacity());
}
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style");
}
private static JPanel createBackgroundAndOpacityPane(String name, BackgroundSpecialPane backgroundPane, UIPercentDragPane opacityPane) {
JPanel container = new JPanel();
container.setLayout(new BorderLayout(0, 6));
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = {SETTING_LABEL_WIDTH, f};
// 确保BackgroundSpecialPane高度变化时,Label依然保持与其顶部对齐
JPanel backgroundLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
backgroundLabelPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0));
backgroundLabelPane.add(new UILabel(name), 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);
container.add(backgroundComposedPane, BorderLayout.NORTH, 0);
container.add(opacityComposedPane, BorderLayout.CENTER, 1);
opacityComposedPane.setVisible(false);
backgroundPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
Background background = backgroundPane.update();
opacityComposedPane.setVisible(background != null);
}
});
return container;
return i18nText("Fine-Design_Form_Widget_Style");
}
protected static class BottomLineBorder extends LineBorder {

28
designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java

@ -2,8 +2,11 @@ package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fr.base.chart.BaseChartCollection;
import com.fr.base.theme.TemplateThemeCompatible;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chartx.attr.ChartProvider;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.TemplateTheme;
import com.fr.design.DesignModelAdapter;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
@ -18,6 +21,7 @@ import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWAbsoluteLayout;
import com.fr.design.designer.creator.XWFitLayout;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.icon.IconPathConstants;
@ -30,6 +34,8 @@ import com.fr.event.EventDispatcher;
import com.fr.form.share.editor.SharableEditorProvider;
import com.fr.form.share.SharableWidgetProvider;
import com.fr.form.share.ShareLoader;
import com.fr.form.ui.ChartEditor;
import com.fr.form.ui.ElementCaseEditor;
import com.fr.form.ui.Widget;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
@ -139,6 +145,11 @@ public class FormCreatorDropTarget extends DropTarget {
}
EventDispatcher.fire(TableDataModifyEvent.INSTANCE, new ContentChangeItem(tdNameMap, widget, ChangeItem.TABLE_DATA_NAME));
}
// 新疆的图表块和报表块默认主题化
addThemeToNewWidget(widget, addingXCreator);
designer.getSelectionModel().setSelectedCreators(
FormSelectionUtils.rebuildSelection(xCreator, new Widget[]{widget}));
designer.getEditListenerTable().fireCreatorModified(addingModel.getXCreator(), DesignerEvent.CREATOR_ADDED);
@ -349,4 +360,21 @@ public class FormCreatorDropTarget extends DropTarget {
public TabDragInner getTabDragInner() {
return this.tabDragInner;
}
private void addThemeToNewWidget(Widget widget, XCreator addingXCreator) {
JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
TemplateTheme theme = template.getTemplateTheme();
if (theme instanceof FormTheme) {
FormTheme formTheme = (FormTheme) theme;
if (widget instanceof ChartEditor) {
((ChartEditor) widget).setBorderStyleFollowingTheme(true);
((ChartEditor) widget).onTemplateUsingThemeChange(formTheme, TemplateThemeCompatible.NONE);
addingXCreator.firePropertyChange();
} else if (widget instanceof ElementCaseEditor) {
((ElementCaseEditor) widget).setBorderStyleFollowingTheme(true);
((ElementCaseEditor) widget).onTemplateUsingThemeChange(formTheme, TemplateThemeCompatible.NONE);
addingXCreator.firePropertyChange();
}
}
}
}

47
designer-form/src/main/java/com/fr/design/mainframe/JForm.java

@ -6,7 +6,12 @@ import com.fr.base.Parameter;
import com.fr.base.Releasable;
import com.fr.base.extension.FileExtension;
import com.fr.base.iofile.attr.ExtendSharableAttrMark;
import com.fr.base.theme.TemplateThemeCompatible;
import com.fr.base.vcs.DesignerMode;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.FormThemeConfig;
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.ExtraDesignClassManager;
@ -39,6 +44,7 @@ import com.fr.design.fun.PreviewProvider;
import com.fr.design.fun.PropertyItemPaneProvider;
import com.fr.design.gui.frpane.HyperlinkGroupPane;
import com.fr.design.gui.frpane.HyperlinkGroupPaneActionProvider;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.gui.xpane.FormHyperlinkGroupPane;
@ -49,6 +55,7 @@ import com.fr.design.mainframe.form.FormECCompositeProvider;
import com.fr.design.mainframe.form.FormECDesignerProvider;
import com.fr.design.mainframe.template.info.JFormProcessInfo;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
import com.fr.design.mainframe.theme.dialog.TemplateThemeUsingDialog;
import com.fr.design.mainframe.toolbar.ToolBarMenuDock;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.menu.KeySetUtils;
@ -94,6 +101,7 @@ import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
@ -107,7 +115,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.swing.tree.TreePath;
public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<Form>, Releasable {
private static final String FORM_CARD = "FORM";
@ -133,6 +140,7 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
public JForm() {
super(new Form(new WBorderLayout("form")), "Form");
// setTemplateTheme(getUsingTemplateThemeConfig().getDefaultTheme4NewTemplate());
}
public JForm(Form form, FILE file, Parameter[] parameters) {
@ -234,6 +242,20 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
return FormHyperlinkGroupPaneNoPop.getInstance(hyperlinkGroupPaneActionProvider);
}
@Override
protected UIButton createTemplateThemeButton() {
UIButton button = super.createTemplateThemeButton();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
TemplateThemeUsingDialog<FormTheme> dialog = new TemplateThemeUsingDialog<>(designerFrame, JForm.this, FormThemeConfig.getInstance());
dialog.setVisible(true);
}
});
return button;
}
//表单返回 FORM_TAB or ELEMENTCASE_TAB
public int getEditingReportIndex() {
return this.index;
@ -1138,4 +1160,27 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
formDesign.hidePopup();
}
}
@Override
public TemplateThemeConfig<? extends TemplateTheme> getUsingTemplateThemeConfig() {
return FormThemeConfig.getInstance();
}
@Override
public FormTheme getTemplateTheme() {
return getTarget().getTemplateTheme();
}
@Override
public void setTemplateTheme(TemplateTheme newTheme, TemplateThemeCompatible compatible) {
FormTheme oldTheme = getTarget().getTemplateTheme();
getTarget().setTemplateTheme(newTheme, compatible);
if (compatible == TemplateThemeCompatible.NONE && StringUtils.equals(oldTheme.getName(), newTheme.getName()) ) {
// 模版主题切换会产生一个回退
fireTargetModified();
}
refreshRoot();
TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()).refreshDockingView();
super.setTemplateTheme(newTheme, compatible);
}
}

BIN
designer-form/src/main/resources/com/fr/design/form/images/theme4currentTemplate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
designer-form/src/main/resources/com/fr/design/form/images/theme4newTemplate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

24
designer-realize/src/main/java/com/fr/design/actions/cell/GlobalStyleMenuDef.java

@ -6,23 +6,27 @@ package com.fr.design.actions.cell;
import com.fr.base.BaseUtils;
import com.fr.base.NameStyle;
import com.fr.config.ServerPreferenceConfig;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyle;
import com.fr.design.actions.SelectionListenerAction;
import com.fr.design.actions.UpdateAction;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.imenu.UIMenu;
import com.fr.design.mainframe.CellElementPropertyPane;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.MenuDef;
import com.fr.design.selection.SelectionListener;
import com.fr.design.style.StylePane;
import com.fr.stable.StringUtils;
import com.fr.stable.pinyin.PinyinHelper;
import java.awt.*;
import java.awt.event.*;
import java.util.Iterator;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.util.List;
public class GlobalStyleMenuDef extends MenuDef {
private static final int MAX_LENTH = 12;
@ -72,10 +76,12 @@ public class GlobalStyleMenuDef extends MenuDef {
public void updateMenu() {
UIMenu createdMenu = this.createJMenu();
createdMenu.removeAll();
Iterator iterator = ServerPreferenceConfig.getInstance().getStyleNameIterator();
while (iterator.hasNext()) {
String name = (String) iterator.next();
NameStyle nameStyle = NameStyle.getInstance(name);
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
TemplateTheme theme = template.getTemplateTheme();
List<ThemedCellStyle> themedCellStyleList = theme.getCellStyleList().getCellStyleList();
for (ThemedCellStyle themedCellStyle: themedCellStyleList) {
String name = themedCellStyle.getName();
NameStyle nameStyle = NameStyle.getPassiveInstance(name, themedCellStyle.getStyle());
UpdateAction.UseMenuItem useMenuItem =new GlobalStyleSelection(ePane, nameStyle).createUseMenuItem();
useMenuItem.setNameStyle(nameStyle);
createdMenu.add(useMenuItem);

52
designer-realize/src/main/java/com/fr/design/actions/server/TemplateThemeManagerAction.java

@ -0,0 +1,52 @@
package com.fr.design.actions.server;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.predefined.ui.ServerPredefinedStylePane;
import com.fr.design.mainframe.theme.dialog.TemplateThemeManageDialog;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.menu.SnapChatUpdateAction;
import com.fr.design.notification.SnapChatAllTypes;
import com.fr.general.IOUtils;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
/**
* @author Starryi
* @version 1.0
* Created by Starryi on 2021/8/6
*/
public class TemplateThemeManagerAction extends SnapChatUpdateAction {
public TemplateThemeManagerAction() {
super(SnapChatAllTypes.UpdateAction.TEMPLATE_THEMES_MANAGER);
this.setMenuKeySet(TEMPLATE_THEMES_MANAGER);
this.setName(getMenuKeySet().getMenuKeySetName() + "...");
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon(IOUtils.readIcon("/com/fr/design/images/m_web/style.png"));
this.generateAndSetSearchText(ServerPredefinedStylePane.class.getName());
}
@Override
protected void actionPerformed0(ActionEvent e) {
TemplateThemeManageDialog dialog = new TemplateThemeManageDialog(DesignerContext.getDesignerFrame());
dialog.setVisible(true);
}
public static final MenuKeySet TEMPLATE_THEMES_MANAGER = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'K';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Predefined_Server_Style");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
}

43
designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java

@ -5,7 +5,13 @@ import com.fr.base.DynamicUnitList;
import com.fr.base.Parameter;
import com.fr.base.ScreenResolution;
import com.fr.base.extension.FileExtension;
import com.fr.base.theme.FormTheme;
import com.fr.base.theme.TemplateThemeCompatible;
import com.fr.base.vcs.DesignerMode;
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.DesignModelAdapter;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.AllowAuthorityEditAction;
@ -45,6 +51,7 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.cell.QuickEditorRegion;
import com.fr.design.mainframe.template.info.JWorkBookProcessInfo;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
import com.fr.design.mainframe.theme.dialog.TemplateThemeUsingDialog;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.MenuDef;
@ -217,6 +224,20 @@ public class JWorkBook extends JTemplate<WorkBook, WorkBookUndoState> {
return centerPane;
}
@Override
protected UIButton createTemplateThemeButton() {
UIButton button = super.createTemplateThemeButton();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
TemplateThemeUsingDialog<ReportTheme> dialog = new TemplateThemeUsingDialog<>(designerFrame, JWorkBook.this, ReportThemeConfig.getInstance());
dialog.setVisible(true);
}
});
return button;
}
@Override
public TemplateProcessInfo<WorkBook> getProcessInfo() {
if (processInfo == null) {
@ -1238,4 +1259,26 @@ public class JWorkBook extends JTemplate<WorkBook, WorkBookUndoState> {
designer.hidePopup();
}
}
@Override
public TemplateThemeConfig<? extends TemplateTheme> getUsingTemplateThemeConfig() {
return ReportThemeConfig.getInstance();
}
@Override
public ReportTheme getTemplateTheme() {
return getTarget().getTemplateTheme();
}
@Override
public void setTemplateTheme(TemplateTheme newTheme, TemplateThemeCompatible compatible) {
ReportTheme oldTheme = getTarget().getTemplateTheme();
getTarget().setTemplateTheme(newTheme, compatible);
if (compatible == TemplateThemeCompatible.NONE && StringUtils.equals(oldTheme.getName(), newTheme.getName()) ) {
// 模版主题切换会产生一个回退
fireTargetModified();
}
DesignModuleFactory.getFormHierarchyPane().refreshRoot();
super.setTemplateTheme(newTheme, compatible);
}
}

12
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java

@ -14,7 +14,7 @@ import com.fr.design.mainframe.ElementCasePane;
public class StylePane extends UIComboBoxPane<Style> {
private CustomStylePane customStylePane;
private PredefinedStylePane predefinedStylePane;
private ThemedCellStyleListPane themedCellStyleListPane;
@Override
protected String title4PopupWindow() {
@ -23,15 +23,15 @@ public class StylePane extends UIComboBoxPane<Style> {
@Override
protected void comboBoxItemStateChanged() {
if (jcb.getSelectedIndex() == 0 && predefinedStylePane.updateBean() != null) {
customStylePane.populateBean(predefinedStylePane.updateBean());
if (jcb.getSelectedIndex() == 0 && themedCellStyleListPane.updateBean() != null) {
customStylePane.populateBean(themedCellStyleListPane.updateBean());
} else {
predefinedStylePane.populateBean(null);
themedCellStyleListPane.populateBean(null);
}
}
public void addPredefinedChangeListener(ChangeListener changeListener) {
predefinedStylePane.addChangeListener(changeListener);
themedCellStyleListPane.addChangeListener(changeListener);
}
public void addCustomTabChangeListener(ChangeListener changeListener) {
@ -62,7 +62,7 @@ public class StylePane extends UIComboBoxPane<Style> {
protected List<FurtherBasicBeanPane<? extends Style>> initPaneList() {
List<FurtherBasicBeanPane<? extends Style>> paneList = new ArrayList<>();
paneList.add(customStylePane = new CustomStylePane());
paneList.add(predefinedStylePane = new PredefinedStylePane());
paneList.add(themedCellStyleListPane = new ThemedCellStyleListPane());
return paneList;
}

166
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/ThemedCellStyleListPane.java

@ -0,0 +1,166 @@
package com.fr.design.mainframe.cell.settingpane.style;
import com.fr.base.NameStyle;
import com.fr.base.ScreenResolution;
import com.fr.base.Style;
import com.fr.base.theme.TemplateTheme;
import com.fr.base.theme.settings.ThemedCellStyle;
import com.fr.design.beans.FurtherBasicBeanPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerBean;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JList;
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.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
public class ThemedCellStyleListPane extends FurtherBasicBeanPane<NameStyle> implements DesignerBean {
private static final int LEFT_BORDER = 10;
private static final int RIGHT_BORDER = 10;
private DefaultListModel<NameStyle> defaultListModel;
private JList<NameStyle> styleList;
private ChangeListener changeListener;
public ThemedCellStyleListPane() {
defaultListModel = new DefaultListModel<>();
styleList = new JList<>(defaultListModel);
DefaultListCellRenderer render = new DefaultListCellRenderer() {
private Style nameStyle;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof Style) {
this.nameStyle = (Style) value;
this.setText(" ");
}
this.setPreferredSize(new Dimension(210, 22));
return this;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (nameStyle == null) {
return;
}
String text = "abcedfgh";
if (nameStyle instanceof NameStyle) {
text = ((NameStyle) nameStyle).getName();
}
Style.paintBackground((Graphics2D) g, nameStyle, getWidth() - 1, getHeight() - 1);
Style.paintContent((Graphics2D) g, text, nameStyle, getWidth() - 1, getHeight() - 1, ScreenResolution.getScreenResolution());
Style.paintBorder((Graphics2D) g, nameStyle, getWidth() - 1, getHeight() - 1);
}
};
styleList.setCellRenderer(render);
setLayout(FRGUIPaneFactory.createBorderLayout());
add(styleList, BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(0 ,LEFT_BORDER, 0, RIGHT_BORDER));
styleList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int clickedNumber = e.getClickCount();
if (clickedNumber == 1) {
if (changeListener != null) {
changeListener.stateChanged(new ChangeEvent(styleList));
}
}
}
});
DesignerContext.setDesignerBean("predefinedStyle", this);
}
/**
* 添加改变监听
*
* @param changeListener 监听事件
*/
public void addChangeListener(ChangeListener changeListener) {
this.changeListener = changeListener;
}
/**
* 重置
*/
public void reset() {
}
@Override
public void populateBean(NameStyle ob) {
refreshBeanElement();
for (int i = 0; i < defaultListModel.getSize(); i++) {
if (ComparatorUtils.equals(ob, defaultListModel.get(i))) {
styleList.setSelectedIndex(i);
break;
}
}
}
@Override
public NameStyle updateBean() {
return (NameStyle) styleList.getSelectedValue();
}
/**
* 获取面板标题
*
* @return 标题
*/
public String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Predefined_Style");
}
/**
* 是否可以接纳对象
*
* @param ob 组件对象
* @return 是否可以接纳对象
*/
public boolean accept(Object ob) {
return ob instanceof NameStyle;
}
/**
* 刷新组件对象
*/
public void refreshBeanElement() {
defaultListModel.removeAllElements();
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (template != null) {
TemplateTheme theme = template.getTemplateTheme();
List<ThemedCellStyle> styleList = theme.getCellStyleList().getCellStyleList();
for (ThemedCellStyle themedCellStyle: styleList) {
String name = themedCellStyle.getName();
Style realStyle = themedCellStyle.getStyle();
NameStyle nameStyle = NameStyle.getPassiveInstance(name, realStyle);
defaultListModel.addElement(nameStyle);
}
}
styleList.setModel(defaultListModel);
GUICoreUtils.repaint(this);
}
}

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

@ -9,6 +9,8 @@ import com.fr.design.actions.file.newReport.NewWorkBookAction;
import com.fr.design.actions.server.LocalAnalyzerAction;
import com.fr.design.actions.server.ServerConfigManagerAction;
import com.fr.design.actions.server.StyleListAction;
import com.fr.design.actions.server.predefined.ServerPredefinedStyleAction;
import com.fr.design.actions.server.TemplateThemeManagerAction;
import com.fr.design.actions.server.WidgetManagerAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.constants.UIConstants;
@ -30,6 +32,8 @@ import com.fr.design.mainframe.JWorkBook;
import com.fr.design.mainframe.alphafine.component.AlphaFinePane;
import com.fr.design.mainframe.bbs.UserInfoLabel;
import com.fr.design.mainframe.bbs.UserInfoPane;
import com.fr.design.module.ChartPreStyleAction;
import com.fr.design.notification.SnapChatAllTypes;
import com.fr.design.notification.ui.NotificationCenterPane;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.menu.KeySetUtils;
@ -37,7 +41,6 @@ import com.fr.design.menu.MenuDef;
import com.fr.design.menu.SeparatorDef;
import com.fr.design.menu.ShortCut;
import com.fr.design.module.ChartEmptyDataStyleAction;
import com.fr.design.module.ChartPreStyleAction;
import com.fr.design.module.DesignModuleFactory;
import com.fr.design.monitor.DesignerLifecycleMonitorContext;
import com.fr.design.share.SharableManager;
@ -168,7 +171,13 @@ public class MainDesigner extends BaseDesigner {
menuDef.addShortCut(SeparatorDef.DEFAULT);
if (WorkContext.getCurrent().isRoot()) {
menuDef.addShortCut(new ServerConfigManagerAction(), new StyleListAction(), new WidgetManagerAction());
menuDef.addShortCut(
new ServerConfigManagerAction(),
new StyleListAction(),
new ServerPredefinedStyleAction(SnapChatAllTypes.UpdateAction.TEMPLATE_THEMES_MANAGER),
new TemplateThemeManagerAction(),
new WidgetManagerAction()
);
menuDef.addShortCut(new ChartPreStyleAction(), new ChartEmptyDataStyleAction(),new ChartMapEditorAction());
menuDef.addShortCut(new LocalAnalyzerAction());
}

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

@ -8,6 +8,8 @@ import com.fr.base.passport.FinePassportManager;
import com.fr.base.process.ProcessOperator;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.config.MarketConfig;
import com.fr.base.theme.migrator.FormThemeConfigMigrator;
import com.fr.base.theme.migrator.ReportThemeConfigMigrator;
import com.fr.decision.update.backup.RecoverManager;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
@ -74,7 +76,6 @@ import com.fr.design.update.actions.RecoverForDesigner;
import com.fr.design.update.push.DesignerPushUpdateManager;
import com.fr.design.widget.ui.btn.FormSubmitButtonDetailPane;
import com.fr.event.EventDispatcher;
import com.fr.form.stable.ElementCaseThumbnailProcessor;
import com.fr.general.GeneralContext;
import com.fr.general.xml.GeneralXMLTools;
import com.fr.js.EmailJavaScript;
@ -153,6 +154,8 @@ public class DesignerActivator extends Activator implements Prepare {
@Override
public void start() {
migrateBBSInfoFromFineDB();
FormThemeConfigMigrator.getInstance().upgrade();
ReportThemeConfigMigrator.getInstance().upgrade();
List<LocaleMarker> markers = findMutable(InterMutableKey.Path);
for (LocaleMarker marker : markers) {
if (marker.match(LocaleScope.DESIGN)) {

Loading…
Cancel
Save