From 14fb652f1263dd7e2196b3e7832c58d697ef3e21 Mon Sep 17 00:00:00 2001 From: Starryi Date: Tue, 17 Aug 2021 18:26:32 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-51919=20=E4=B8=BB=E9=A2=98=E5=88=87?= =?UTF-8?q?=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【问题原因】 新增模版主题功能 【改动思路】 同上 --- .../gui/style/AbstractBorderPackerPane.java | 20 + ...tractTranslucentBackgroundSpecialPane.java | 99 +++ .../gui/style/ComponentBodyStylePane.java | 33 + .../gui/style/ComponentIntegralStylePane.java | 109 ++++ .../gui/style/ComponentTitleStylePane.java | 289 +++++++++ .../TextInsetImageBackgroundSpecialPane.java | 24 +- ...TitleTranslucentBackgroundSpecialPane.java | 27 + .../style/TranslucentBorderSpecialPane.java | 45 +- .../com/fr/design/mainframe/JTemplate.java | 81 ++- .../mainframe/theme/FormThemeProfilePane.java | 72 +++ .../theme/ReportThemeProfilePane.java | 54 ++ .../mainframe/theme/TemplateThemeBlock.java | 181 ++++++ .../theme/TemplateThemeListPane.java | 180 ++++++ .../theme/TemplateThemeManagePane.java | 241 +++++++ .../theme/TemplateThemePreviewPane.java | 29 + .../theme/TemplateThemeProfilePane.java | 592 ++++++++++++++++++ .../theme/dialog/TemplateThemeDialog.java | 99 +++ .../dialog/TemplateThemeManageDialog.java | 72 +++ .../dialog/TemplateThemeProfileDialog.java | 49 ++ .../dialog/TemplateThemeUsingDialog.java | 119 ++++ .../theme/edit/CellStyleListEditPane.java | 242 +++++++ .../theme/edit/ChartStyleEditPane.java | 96 +++ .../theme/edit/ComponentStyleEditPane.java | 112 ++++ .../theme/edit/FormBodyStyleEditPane.java | 44 ++ .../theme/edit/ReportBodyStyleEditPane.java | 34 + .../AbstractBackgroundDetailPane.java | 51 ++ .../background/BackgroundSettingPane.java | 136 ++++ .../edit/background/ColorDetailPane.java | 105 ++++ .../edit/background/EmptyBackgroundPane.java | 35 ++ .../edit/background/GradientDetailPane.java | 160 +++++ .../edit/background/ImageDetailPane.java | 216 +++++++ .../edit/background/PatternDetailPane.java | 120 ++++ .../background/TextureDetailObservePane.java | 98 +++ .../theme/edit/cell/CellStyleEditPane.java | 208 ++++++ .../edit/chart/AbstractChartStylePane.java | 49 ++ .../theme/edit/chart/ChartAxisStylePane.java | 69 ++ .../edit/chart/ChartBackgroundStylePane.java | 113 ++++ .../edit/chart/ChartDataSheetStylePane.java | 58 ++ .../theme/edit/chart/ChartFontPane.java | 160 +++++ .../theme/edit/chart/ChartLabelStylePane.java | 78 +++ .../edit/chart/ChartLegendStylePane.java | 49 ++ .../theme/edit/chart/ChartTitleStylePane.java | 49 ++ .../component/ComponentMarginStylePane.java | 101 +++ .../theme/edit/ui/ColorListExtendedPane.java | 148 +++++ .../theme/edit/ui/ColorListPane.java | 199 ++++++ .../mainframe/theme/edit/ui/LabelUtils.java | 26 + .../mainframe/theme/edit/ui/TabbedPane.java | 73 +++ .../preview/ChartComponentPreviewPane.java | 26 + .../theme/preview/ChartPreviewPane.java | 39 ++ .../theme/preview/ComponentPreviewPane.java | 161 +++++ .../theme/preview/ECComponentPreviewPane.java | 26 + .../theme/preview/ECPreviewPane.java | 160 +++++ .../theme/preview/FormThemePreviewPane.java | 74 +++ .../theme/preview/ReportThemePreviewPane.java | 17 + .../theme/preview/ThemePreviewed.java | 10 + .../mainframe/theme/ui/BorderUtils.java | 30 + .../mainframe/theme/ui/NoEdgeTitleBorder.java | 320 ++++++++++ .../design/notification/SnapChatAllTypes.java | 36 +- .../creator/XBorderStyleWidgetCreator.java | 8 + .../gui/xpane/CardTagLayoutStylePane.java | 11 +- .../fr/design/gui/xpane/LayoutStylePane.java | 535 +++------------- .../mainframe/FormCreatorDropTarget.java | 28 + .../java/com/fr/design/mainframe/JForm.java | 47 +- .../form/images/theme4currentTemplate.png | Bin 0 -> 15541 bytes .../design/form/images/theme4newTemplate.png | Bin 0 -> 411 bytes .../actions/cell/GlobalStyleMenuDef.java | 24 +- .../server/TemplateThemeManagerAction.java | 52 ++ .../com/fr/design/mainframe/JWorkBook.java | 43 ++ .../cell/settingpane/style/StylePane.java | 12 +- .../style/ThemedCellStyleListPane.java | 166 +++++ .../main/java/com/fr/start/MainDesigner.java | 13 +- .../fr/start/module/DesignerActivator.java | 5 +- 72 files changed, 6565 insertions(+), 522 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/gui/style/AbstractBorderPackerPane.java create mode 100644 designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java create mode 100644 designer-base/src/main/java/com/fr/design/gui/style/ComponentBodyStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java rename designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java => designer-base/src/main/java/com/fr/design/gui/style/TextInsetImageBackgroundSpecialPane.java (95%) create mode 100644 designer-base/src/main/java/com/fr/design/gui/style/TitleTranslucentBackgroundSpecialPane.java rename designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java => designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java (96%) create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/CellStyleListEditPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleEditPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/FormBodyStyleEditPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ReportBodyStyleEditPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/AbstractBackgroundDetailPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/BackgroundSettingPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ColorDetailPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/EmptyBackgroundPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/GradientDetailPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ImageDetailPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/PatternDetailPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/TextureDetailObservePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/AbstractChartStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartAxisStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartBackgroundStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartDataSheetStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLabelStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLegendStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/component/ComponentMarginStylePane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListExtendedPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartComponentPreviewPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartPreviewPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ECComponentPreviewPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ECPreviewPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ReportThemePreviewPane.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ThemePreviewed.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BorderUtils.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/ui/NoEdgeTitleBorder.java create mode 100644 designer-form/src/main/resources/com/fr/design/form/images/theme4currentTemplate.png create mode 100644 designer-form/src/main/resources/com/fr/design/form/images/theme4newTemplate.png create mode 100644 designer-realize/src/main/java/com/fr/design/actions/server/TemplateThemeManagerAction.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/ThemedCellStyleListPane.java diff --git a/designer-base/src/main/java/com/fr/design/gui/style/AbstractBorderPackerPane.java b/designer-base/src/main/java/com/fr/design/gui/style/AbstractBorderPackerPane.java new file mode 100644 index 000000000..4356f133a --- /dev/null +++ b/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; + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java b/designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java new file mode 100644 index 000000000..fe6318ad3 --- /dev/null +++ b/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 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); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/style/ComponentBodyStylePane.java b/designer-base/src/main/java/com/fr/design/gui/style/ComponentBodyStylePane.java new file mode 100644 index 000000000..8463ed6f5 --- /dev/null +++ b/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 { + + 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()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java b/designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java new file mode 100644 index 000000000..ef47a148b --- /dev/null +++ b/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); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java b/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java new file mode 100644 index 000000000..86fdf67a8 --- /dev/null +++ b/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; + } +} diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java b/designer-base/src/main/java/com/fr/design/gui/style/TextInsetImageBackgroundSpecialPane.java similarity index 95% rename from designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java rename to designer-base/src/main/java/com/fr/design/gui/style/TextInsetImageBackgroundSpecialPane.java index 3671259a2..b3556dc6f 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java +++ b/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); } diff --git a/designer-base/src/main/java/com/fr/design/gui/style/TitleTranslucentBackgroundSpecialPane.java b/designer-base/src/main/java/com/fr/design/gui/style/TitleTranslucentBackgroundSpecialPane.java new file mode 100644 index 000000000..db8c64e19 --- /dev/null +++ b/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 { + + 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()); + } +} diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java b/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java similarity index 96% rename from designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java rename to designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java index 0f2b853d1..237a5659a 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java +++ b/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[] { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index 4fb13150e..61e31cff3 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/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> extends TargetComponent implements ToolBarMenuDockPlus, DesignerProxy, JTemplateSave, TabChangeListener { +public abstract class JTemplate> extends TargetComponent 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> 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> this.undoState = createUndoState(); initAndStartPlugin(); + + if (isNewFile) { + setUpTheme4NewTemplate(); + } + startListenThemeConfig(); } private void initAndStartPlugin() { @@ -213,6 +228,35 @@ public abstract class JTemplate> 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 config = getUsingTemplateThemeConfig(); + if (config != null) { + config.addThemeConfigChangeListener(themeConfigChangeListener); + } + } + } + private void stopListenThemeConfig() { + if (themeConfigChangeListener != null) { + TemplateThemeConfig 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> public void whenClose() { // stop的时候 pluginListener 和 PluginFilter 都会移除 PluginListenerRegistration.getInstance().stopListen(this.pluginListener); + stopListenThemeConfig(); } @@ -567,6 +612,8 @@ public abstract class JTemplate> */ public void undo() { this.getUndoManager().undo(); + // 撤销前模版使用主题可能已经被删除或修改,需要重置模版样式 + checkAndResetTheme(); fireSuperTargetModified(); } @@ -575,7 +622,8 @@ public abstract class JTemplate> */ public void redo() { this.getUndoManager().redo(); - + // 重做前模版使用主题可能已经被删除或修改,需要重置模版样式 + checkAndResetTheme(); fireSuperTargetModified(); } @@ -1411,6 +1459,8 @@ public abstract class JTemplate> 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> 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> 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()); + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java new file mode 100644 index 000000000..7c5b2231e --- /dev/null +++ b/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 { + public static final int LABEL_WIDTH = 60; + + private FormBodyStyleEditPane formBodyStyleSettingPane; + private ComponentStyleEditPane componentStyleSettingPane; + + public FormThemeProfilePane(TemplateThemeConfig 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); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java new file mode 100644 index 000000000..3af535e84 --- /dev/null +++ b/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 { + private ReportBodyStyleEditPane reportBodyStyleSettingPane; + + public ReportThemeProfilePane(TemplateThemeConfig 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()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java new file mode 100644 index 000000000..ba16de00a --- /dev/null +++ b/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 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 config; + private T theme; + private final TemplateThemeProfilePane 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 config, TemplateThemeProfilePane 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 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 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 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); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java new file mode 100644 index 000000000..ee1795318 --- /dev/null +++ b/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 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 config; + private final TemplateThemeProfilePane profilePane; + private final JPanel contentListPane; + + private final Map> blockCache = new HashMap<>(); + + private TemplateThemeBlock selectedBlock; + private TemplateThemeBlock block4newTemplate; + + private TemplateThemeConfig.ThemeConfigChangeListener themeConfigChangeListener; + + private ChangeListener changeListener; + + public TemplateThemeListPane(TemplateThemeConfig config, TemplateThemeProfilePane 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 names = config.getThemeNames(); + for (String name: names) { + T theme = config.find(name); + if (theme != null) { + TemplateThemeBlock block = createCachedTemplateThemeBlock(name); + contentListPane.add(block); + if (StringUtils.equals(name, config.getTheme4NewTemplate().getName())) { + block4newTemplate = block; + } + } + } + } + private TemplateThemeBlock createCachedTemplateThemeBlock(String name) { + TemplateThemeBlock block = blockCache.get(name); + if (block == null) { + block = createNewTemplateThemeBlock(name); + blockCache.put(name, block); + } + return block; + } + + private TemplateThemeBlock createNewTemplateThemeBlock(String name) { + final TemplateThemeBlock 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 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; + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java new file mode 100644 index 000000000..f62612c57 --- /dev/null +++ b/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 extends BasicPane { + private RemoveThemeAction removeAction; + + private final TemplateThemeConfig config; + private final TemplateThemeListPane themeListPane; + private final TemplateThemeProfilePane profilePane; + + public static TemplateThemeManagePane createFormThemesManagerPane() { + FormThemeConfig config = FormThemeConfig.getInstance(); + FormThemeProfilePane editPane = new FormThemeProfilePane(config); + return new TemplateThemeManagePane<>(config, editPane); + } + + public static TemplateThemeManagePane createReportThemesManagerPane() { + ReportThemeConfig config = ReportThemeConfig.getInstance(); + ReportThemeProfilePane editPane = new ReportThemeProfilePane(config); + return new TemplateThemeManagePane<>(config, editPane); + } + + public TemplateThemeManagePane(TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { + this.config = config; + this.profilePane = profilePane; + this.themeListPane = new TemplateThemeListPane<>(config, profilePane); + profilePane.setThemeListPane(themeListPane); + + initializePane(); + } + + public TemplateThemeConfig 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 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(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java new file mode 100644 index 000000000..af4669041 --- /dev/null +++ b/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 extends JPanel implements CallbackEvent, ThemePreviewed { + private JPanel parent; + + public void setParent(JPanel parent) { + this.parent = parent; + } + + @Override + public void callback() { + if (parent != null) { + parent.repaint(); + } else { + this.repaint(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java new file mode 100644 index 000000000..12bfa934b --- /dev/null +++ b/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 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 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 themeListPane; + + private final TemplateThemeConfig config; + + private final UIButton saveButton = new UIButton(); + private final UIButton saveAsButton = new UIButton(); + + private boolean currentIsNewTheme; + private T theme; + + public TemplateThemeProfilePane(TemplateThemeConfig config) { + this.config = config; + theme = config.createNewTheme(); + } + + public void setThemeListPane(TemplateThemeListPane 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 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 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 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 parent; + + private UITextField nameTextField; + private UILabel nameErrorLabel; + private UIButton confirmButton; + + public SaveAsDialog(TemplateThemeProfileDialog 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; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java new file mode 100644 index 000000000..54628a6c4 --- /dev/null +++ b/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(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java new file mode 100644 index 000000000..3af94a48a --- /dev/null +++ b/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 formThemesManagerPane; + private TemplateThemeManagePane 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(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java new file mode 100644 index 000000000..de1c76a0e --- /dev/null +++ b/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 extends TemplateThemeDialog { + public static final int CONTENT_WIDTH = 778; + public static final int CONTENT_HEIGHT = 558; + + public TemplateThemeProfileDialog(Window parent, TemplateThemeProfilePane 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; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java new file mode 100644 index 000000000..cde30ca4e --- /dev/null +++ b/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 extends TemplateThemeDialog { + public static final int CONTENT_WIDTH = 660; + public static final int CONTENT_HEIGHT = 515; + + private final TemplateThemeListPane themeListPane; + private final ThemedTemplate currentTemplate; + + public TemplateThemeUsingDialog(Window parent, ThemedTemplate template, TemplateThemeConfig 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(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/CellStyleListEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/CellStyleListEditPane.java new file mode 100644 index 000000000..c3b359a44 --- /dev/null +++ b/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 nameObjectList = new ArrayList<>(); + + List 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; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ChartStyleEditPane.java new file mode 100644 index 000000000..c4219233f --- /dev/null +++ b/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 { + + 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 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() { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java new file mode 100644 index 000000000..5bf93ea51 --- /dev/null +++ b/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; + + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/FormBodyStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/FormBodyStyleEditPane.java new file mode 100644 index 000000000..35a1ebe9e --- /dev/null +++ b/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; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ReportBodyStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ReportBodyStyleEditPane.java new file mode 100644 index 000000000..9de8cc605 --- /dev/null +++ b/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; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/AbstractBackgroundDetailPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/AbstractBackgroundDetailPane.java new file mode 100644 index 000000000..76f948ffd --- /dev/null +++ b/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 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) { + + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/BackgroundSettingPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/BackgroundSettingPane.java new file mode 100644 index 000000000..667c60114 --- /dev/null +++ b/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 { + 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 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; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ColorDetailPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ColorDetailPane.java new file mode 100644 index 000000000..12eea2c52 --- /dev/null +++ b/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 { + 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; + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/EmptyBackgroundPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/EmptyBackgroundPane.java new file mode 100644 index 000000000..b7b345c63 --- /dev/null +++ b/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; + } + + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/GradientDetailPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/GradientDetailPane.java new file mode 100644 index 000000000..042e8d4d3 --- /dev/null +++ b/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 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"); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ImageDetailPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/ImageDetailPane.java new file mode 100644 index 000000000..208c21045 --- /dev/null +++ b/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 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"); + } + + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/PatternDetailPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/PatternDetailPane.java new file mode 100644 index 000000000..7d5ee66a7 --- /dev/null +++ b/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 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(); + } + } + }); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/TextureDetailObservePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/background/TextureDetailObservePane.java new file mode 100644 index 000000000..a1d0fcb2c --- /dev/null +++ b/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 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) { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java new file mode 100644 index 000000000..5fc429853 --- /dev/null +++ b/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 { + 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 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(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/AbstractChartStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/AbstractChartStylePane.java new file mode 100644 index 000000000..95354191d --- /dev/null +++ b/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); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartAxisStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartAxisStylePane.java new file mode 100644 index 000000000..5a52bb28c --- /dev/null +++ b/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()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartBackgroundStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartBackgroundStylePane.java new file mode 100644 index 000000000..a6880471c --- /dev/null +++ b/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 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()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartDataSheetStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartDataSheetStylePane.java new file mode 100644 index 000000000..07ec893f7 --- /dev/null +++ b/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()); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartFontPane.java new file mode 100644 index 000000000..6258a49ac --- /dev/null +++ b/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())); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLabelStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLabelStylePane.java new file mode 100644 index 000000000..8eb736444 --- /dev/null +++ b/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 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()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLegendStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartLegendStylePane.java new file mode 100644 index 000000000..40f4652a0 --- /dev/null +++ b/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()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/chart/ChartTitleStylePane.java new file mode 100644 index 000000000..885f5ab84 --- /dev/null +++ b/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()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/component/ComponentMarginStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/component/ComponentMarginStylePane.java new file mode 100644 index 000000000..643c1e960 --- /dev/null +++ b/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); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListExtendedPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListExtendedPane.java new file mode 100644 index 000000000..ddab72c80 --- /dev/null +++ b/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 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 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 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); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/ColorListPane.java new file mode 100644 index 000000000..03e24cb13 --- /dev/null +++ b/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 colorList = new ArrayList<>(); + private final List 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 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 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 { + 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)); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java new file mode 100644 index 000000000..5d12f9498 --- /dev/null +++ b/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; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java new file mode 100644 index 000000000..3f4667e11 --- /dev/null +++ b/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); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartComponentPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartComponentPreviewPane.java new file mode 100644 index 000000000..60283148d --- /dev/null +++ b/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 { + private ChartPreviewPane contentPane; + + @Override + protected Component createContentPane() { + contentPane = new ChartPreviewPane(); + return contentPane; + } + + @Override + public void refresh(FormTheme theme) { + super.refresh(theme); + contentPane.refresh(theme); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ChartPreviewPane.java new file mode 100644 index 000000000..e9945cddc --- /dev/null +++ b/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 { + + @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) { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java new file mode 100644 index 000000000..727ce6a04 --- /dev/null +++ b/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 { + 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)); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ECComponentPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ECComponentPreviewPane.java new file mode 100644 index 000000000..54ff036ce --- /dev/null +++ b/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); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ECPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ECPreviewPane.java new file mode 100644 index 000000000..c24180328 --- /dev/null +++ b/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 { + + private static final List DATA_LIST = createDataList(); + private static final String BLANK_CHAR = " "; + private final List> grid = new ArrayList<>(); + + private static List 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 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 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 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); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java new file mode 100644 index 000000000..159c98144 --- /dev/null +++ b/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 { + 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(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ReportThemePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ReportThemePreviewPane.java new file mode 100644 index 000000000..3597d0d0d --- /dev/null +++ b/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 { + + @Override + public void refresh(ReportTheme theme) { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ThemePreviewed.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ThemePreviewed.java new file mode 100644 index 000000000..bb2aa05c2 --- /dev/null +++ b/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 { + void refresh(T style); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BorderUtils.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BorderUtils.java new file mode 100644 index 000000000..3b7a8b6c0 --- /dev/null +++ b/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) + ); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/NoEdgeTitleBorder.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/NoEdgeTitleBorder.java new file mode 100644 index 000000000..bf532b00f --- /dev/null +++ b/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; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java b/designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java index d94da0c88..ae83a0bb9 100644 --- a/designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java +++ b/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()}, "-" + ); + } + } + } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java index 485c73b16..395647db3 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java +++ b/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(); diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutStylePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutStylePane.java index 37db55102..98fe066e2 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/CardTagLayoutStylePane.java +++ b/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); } } diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java index 453bd5e0d..2365a919a 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java +++ b/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 { - 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 { 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( - 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 { } 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 { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java index 7a6a73f4b..820183eab 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/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(); + } + } + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java index d98e0e8f7..d55be3431 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java +++ b/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 implements BaseJForm
, Releasable { private static final String FORM_CARD = "FORM"; @@ -133,6 +140,7 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm 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 implements BaseJForm 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); + } } diff --git a/designer-form/src/main/resources/com/fr/design/form/images/theme4currentTemplate.png b/designer-form/src/main/resources/com/fr/design/form/images/theme4currentTemplate.png new file mode 100644 index 0000000000000000000000000000000000000000..e022f1cfb441d988a64f398489e14c86dbb33911 GIT binary patch literal 15541 zcmeI3e{2)y8OM*NkPwtsO;KqX=^Td?(sH@;**@Dh$4M5aP1-t1ldK7iw&Z+1J2z~f z@tqSVo!X6n*xI6PEG=zmI+}upXd4xZHVPXsw!uKClrl7xt_*>oNkhprnl7Lf_MRR8 z$Q$QXq_)~WuO<8Ld7tQ zZqX+N%k*RW4(N4~r%c~scG0d-mDnlO^oGTz-nwR?ca>oC=*u0s_9zDg0;0<6q5*$U z;i6^wm@Ws-wP8xHi%n5imFX+Bgt}H&gRV*ri#l^DOA0h=(OGPz2D8OtvaHZCw82c# zM#@N&jFB_ZoQcs*e)Nu9aApsCyj-L6!O3*MD${qWYKWt#?(Xi=Zeyt&_E83#%|_7- z#V{n8K`K2#m5-7^r6?|v&~b{25SBu!BnNexF7K8jYMEZIB}#rK?<){WCJHK(>;Oe7 z%7-XJDNSVx@(9V8P$cY+U7AOrM86migQ^1J3>o7>ow6z`o$?GRlkOQ4gEeuvlDRWp zZy=B{wW3yc0R)psGe#=SJt2{56csrV7R2f&LS0o=tg3X&Tcn^z?p8|d6daOT@06P8X9W4pct*q1~X?eaE$o@+RD*%nn-*mq~Vf1lD8+52FsZ(=^AM>VGYnf9$w{VrIJ23 zO~)f}UO61#RfiPdeIgYK`s`F{Fl}bCs<vGN+e1Xo0h0PEP;KG_ovO# z?!^O=xmgpq6J8*VwAVyh3??sW^%#sKFL+tTXkb~l+m=X?L1tR28c6}w+LKnrpq67h zTa&nY>S)5@mts3qhz~2G)_-OCL<1(bwB(MZ#l-rU;{|PRa|l{{h#osNWi)kJ$;int zY5H=`4nbT$Eqvx2-JN0()n0L_*sPgF6xpkG^I@^l2P$MXogY`78V1YTDeb?&FMR_G zq3~T_Z5d|QRbO!#(s!u;-!i1CSm@+~KGEZ#5(S(XnBB_7*K=xTCAxKbC)%|?Ck}Km zs3<wW-@?$~Lm9N+$I%L(ckKnz&@;K`w5eXfgKqGSI!ie=9mnOFIC!O zS*!=+qu`+rJa1CT2hM5jncT&`&Xd#~eVwY17ES^IL7NyCnh)f~xF8^C6XQbjfxH+O z1O#njTxdR!7vq9}piPVm%?I*gTo4eniE*L%KwgXs0)jR%E;Jv=i*Z3f&?d%(<^y># zE(i$P#JJFWATP!R0YRG>7n%>`#ke3KXcOZ?^MSk=7X$=tVq9oGkQd{EfS^r`3(W`e zVq6dqw25({`9NNb3j%^RF)lP8$cu47K+q<}h2{f!F)j!Q+Qhifd>}8z1pz^u7#Erk zzdT3~w^Y?SE1RQdcE3W@FNuHaHb z!4F%1x%~G0_g?#8e&O(mZG(LSdp}>#jBnWcZo!!ifws2Dz*yj{Jn_`ovF}`c(thFW zFRn!Ff5_T?-_qxc2fn!R?-vc%-AhjsEAq1P=j?BL_#eAnJ##1W@4B@DobPgdn7#F3 zbD;GeGH1?&x8x+hIZWK$zWm%dw$i7palJ7(w~!bki_iF*9K=({7rotmHUEjOM|#&U z>lrUJKd?0K_q+S8zRk@1=PrHg^yAgT+{TVb;KTM&ZVAc5_~XIRlA-_9|5xbTdTQimal_d4%1swW1}awU z+wYL;GsJQ;0kFLIU!)ly+`I$=n!F&IH`;hI`AN;Cq`@(sPZfn`a zS1-KzvFWoiVXHTH^TIx&Kg;+1a_eW&z0B`)?s@C`&t2Ja-?-A%_in{sm)JfY`u1hT zUeG>F-*u{G%jw3!6YRFz7Tof$JFMQ4)qi3yesZni(&Cn(rJ=u#_pwJ#Mfgf$u;TU6 z?1GmLyqA-;aYOH>(dgD4DuQ%?m-R~t%G@joRI9AxfJy&-lO0*fX_HBFra8dt| ziT0PQ{(!ys(ebN;RlBwak6`uu3)`5l2{_jcIdtlRa()1U0z|K%#;;Ka$I=BIbB)m|*Ft*&zpeYa!H{{Y$L BH$(sc literal 0 HcmV?d00001 diff --git a/designer-form/src/main/resources/com/fr/design/form/images/theme4newTemplate.png b/designer-form/src/main/resources/com/fr/design/form/images/theme4newTemplate.png new file mode 100644 index 0000000000000000000000000000000000000000..43e7c8ff03fca793c903fcb397b43992b800e0e8 GIT binary patch literal 411 zcmV;M0c8G(P)Px$RY^oaR5(wa(!EPUVHC&l?@{T+LZd+nax0>usiDSbiyB%A8j5I1!nvWpBZ8o< z2znbt{12jru%(2cAu6aLMB|nwdOcxkX5FjVv)s#bpYu7t=W>M7(j9j<;v7L8?($wk zPsyiHGb#(Ir$U|Ru4fWt3srwZP~~tObQ>HOXg)2AMz{of?@|1q|8zgg5+H$Uc*k23 zE#UqD6mIqqs@F6QvWjWOWa%|lOl$|c+F<4qGI0ox0(pB}I7D@ilo62?vet0dI1I0W zrw>|vMJ)9QFE( literal 0 HcmV?d00001 diff --git a/designer-realize/src/main/java/com/fr/design/actions/cell/GlobalStyleMenuDef.java b/designer-realize/src/main/java/com/fr/design/actions/cell/GlobalStyleMenuDef.java index 4699ab886..142b6a6e7 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/cell/GlobalStyleMenuDef.java +++ b/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 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); diff --git a/designer-realize/src/main/java/com/fr/design/actions/server/TemplateThemeManagerAction.java b/designer-realize/src/main/java/com/fr/design/actions/server/TemplateThemeManagerAction.java new file mode 100644 index 000000000..7b41b106f --- /dev/null +++ b/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; + } + }; +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java index 0887ffdea..58da3ee58 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java +++ b/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 { 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 dialog = new TemplateThemeUsingDialog<>(designerFrame, JWorkBook.this, ReportThemeConfig.getInstance()); + dialog.setVisible(true); + } + }); + return button; + } + @Override public TemplateProcessInfo getProcessInfo() { if (processInfo == null) { @@ -1238,4 +1259,26 @@ public class JWorkBook extends JTemplate { designer.hidePopup(); } } + + @Override + public TemplateThemeConfig 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); + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java index e2d824757..72ee9b221 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/StylePane.java +++ b/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