Browse Source

REPORT-58064 【主题切换】悬浮元素-样式的显示同交互稿不符

【问题原因】
实现表格悬浮元素样式设置面板的主题化

【改动思路】
同上
research/11.0
Starryi 3 years ago
parent
commit
8622576dca
  1. 605
      designer-realize/src/main/java/com/fr/design/report/ReportStylePane.java

605
designer-realize/src/main/java/com/fr/design/report/ReportStylePane.java

@ -1,52 +1,591 @@
package com.fr.design.report;
import com.fr.config.ServerPreferenceConfig;
import com.fr.base.NameStyle;
import com.fr.base.ScreenResolution;
import com.fr.base.Style;
import com.fr.design.border.UIRoundedBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.designer.IntervalConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.style.StylePane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.design.fun.StyleUIConfigProvider;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.design.mainframe.cell.settingpane.style.ThemedCellStyleListPane;
import com.fr.design.mainframe.theme.ui.NoEdgeTitleBorder;
import com.fr.design.style.AlignmentPane;
import com.fr.design.style.BorderPane;
import com.fr.design.style.BorderUtils;
import com.fr.design.style.FRFontPane;
import com.fr.design.style.FormatPane;
import com.fr.design.style.background.BackgroundPane;
import com.fr.general.FRFont;
import com.fr.grid.selection.CellSelection;
import com.fr.grid.selection.FloatSelection;
import com.fr.grid.selection.Selection;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.solution.sandbox.collection.PluginSandboxCollections;
import com.fr.report.cell.CellElement;
import com.fr.report.cell.DefaultTemplateCellElement;
import com.fr.report.cell.FloatElement;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.elementcase.ElementCase;
import com.fr.report.elementcase.TemplateElementCase;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
public class ReportStylePane extends StylePane {
public class ReportStylePane extends BasicPane {
public static final String[] FOLLOWING_THEME_STRING_ARRAYS = new String[]{
Toolkit.i18nText("Fine-Design_Style_Follow_Theme"),
Toolkit.i18nText("Fine-Design_Style_Not_Follow_Theme"),
};
public static final int DEFAULT_SELECTED_INDEX = 0;
private static final int Y_OFFSET = 8;
private final PreviewArea previewArea;
private final UIButtonGroup<String> followingThemeButtonGroup;
private final CustomFloatStyleSettingPane customStylePane;
private final ThemedCellStyleListPane themedCellStyleListPane;
private final CardLayout cardLayout;
private final JComponent[] panes = new JComponent[2];
private final JPanel contentPane;
public ReportStylePane() {
super();
getPreviewArea().addMouseListener(new MouseAdapter() {
setLayout(FRGUIPaneFactory.createBorderLayout());
setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
previewArea = new PreviewArea();
followingThemeButtonGroup = new UIButtonGroup<>(FOLLOWING_THEME_STRING_ARRAYS);
customStylePane = new CustomFloatStyleSettingPane();
themedCellStyleListPane = new ThemedCellStyleListPane();
panes[0] = createThemedStylePane();
panes[1] = createCustomStylePane();
cardLayout = new CardLayout();
contentPane = createTabbedContentPane();
initializePane();
themedCellStyleListPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
updatePreviewArea();
}
});
customStylePane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
updatePreviewArea();
}
});
}
private void initializePane() {
add(createPreviewPane(), BorderLayout.NORTH);
JPanel settingContainer = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel followingThemePane = createFollowingThemePane();
followingThemePane.setBorder(BorderFactory.createEmptyBorder(20, 0, 10, 0));
settingContainer.add(followingThemePane, BorderLayout.NORTH);
settingContainer.add(contentPane, BorderLayout.CENTER);
add(settingContainer, BorderLayout.CENTER);
}
private JPanel createPreviewPane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Preview")));
container.setPreferredSize(new Dimension(container.getPreferredSize().width, 60));
JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane();
content.setBorder(BorderFactory.createEmptyBorder(4, 4, 2, 2));
previewArea.setPreferredSize(new Dimension(container.getPreferredSize().width, 42));
content.add(previewArea, BorderLayout.NORTH);
container.add(content, BorderLayout.NORTH);
return container;
}
private JPanel createFollowingThemePane() {
followingThemeButtonGroup.setSelectedIndex(DEFAULT_SELECTED_INDEX);
followingThemeButtonGroup.addActionListener(new ActionListener() {
@Override
public void mousePressed(MouseEvent evt) {
if (!SwingUtilities.isRightMouseButton(evt)) {
return;
}
JPopupMenu popupMenu = new JPopupMenu();
UIMenuItem menuItem = new UIMenuItem(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Save_As_Global_Style"));
popupMenu.add(menuItem);
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String name = FineJOptionPane.showInputDialog(getParent(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Input_The_Name_Of_Gloabel_Style"));
if (ComparatorUtils.equals(name, "")) {
return;
public void actionPerformed(ActionEvent e) {
int selectedIndex = followingThemeButtonGroup.getSelectedIndex();
cardLayout.show(contentPane, FOLLOWING_THEME_STRING_ARRAYS[selectedIndex]);
if (selectedIndex == 1) {
// 对于同一个单元格,跟随主题切换到自定义,若跟随主题面板有选中项,则自定义中的配置与其保持一致,否则自定义中配置保持不变
NameStyle lastSelectedNameStyle = themedCellStyleListPane.updateBean();
if (lastSelectedNameStyle != null) {
Style lastSelectedRealStyle = lastSelectedNameStyle.getRealStyle();
try {
lastSelectedRealStyle = (Style) lastSelectedRealStyle.clone();
if (lastSelectedRealStyle != null) {
customStylePane.populateBean(lastSelectedRealStyle);
}
} catch (CloneNotSupportedException ex) {
FineLoggerFactory.getLogger().error(ex.getMessage(), ex);
}
if (ServerPreferenceConfig.getInstance().getStyle(name) == null) {
ServerPreferenceConfig.getInstance().putStyle(name, ReportStylePane.this.updateBean());
} else {
FineJOptionPane.showMessageDialog(getParent(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_This_Name_Has_Exsit") + "!", com.fr.design.i18n.Toolkit.i18nText("FR-Designer_Warning"), JOptionPane.WARNING_MESSAGE);
}
} else {
// 对于同一个单元格,自定义切换到跟随主题,跟随主题应当清除选中项,即没有选中任何主题中的单元格样式,
// 因为还未选中,所以自定义中的配置保持不变,此时若用户切换会自定义,配置应当与之前一样
themedCellStyleListPane.populateBean(null);
}
}
});
UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Style_Setting"));
double p = TableLayout.PREFERRED;
return TableLayoutHelper.createGapTableLayoutPane(
new Component[][]{ new Component[] { uiLabel, followingThemeButtonGroup} },
new double[] { p }, new double[] { p, 160},
IntervalConstants.INTERVAL_L1, 0);
}
protected JPanel createTabbedContentPane() {
JPanel contentPane = new JPanel(cardLayout) {
@Override
public Dimension getPreferredSize() {
int selectedIndex = followingThemeButtonGroup.getSelectedIndex();
if (selectedIndex < 0) {
return super.getPreferredSize();
} else {
return panes[selectedIndex].getPreferredSize();
}
}
};
for (int i = 0; i < FOLLOWING_THEME_STRING_ARRAYS.length; i++) {
contentPane.add(panes[i], FOLLOWING_THEME_STRING_ARRAYS[i]);
}
cardLayout.show(contentPane, FOLLOWING_THEME_STRING_ARRAYS[DEFAULT_SELECTED_INDEX]);
return contentPane;
}
private JPanel createThemedStylePane() {
JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane();
container.setBorder(createTitleBorder(Toolkit.i18nText("Fine-Design_Style_Selecting")));
themedCellStyleListPane.setBorder(BorderFactory.createEmptyBorder());
UIScrollPane scrollPane = new UIScrollPane(themedCellStyleListPane);
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 0));
scrollPane.setPreferredSize(new Dimension(620, scrollPane.getPreferredSize().height));
container.add(scrollPane, BorderLayout.CENTER);
return container;
}
private JPanel createCustomStylePane() {
return customStylePane;
}
public void setSelectedIndex(int index) {
if (0 <= index && index < FOLLOWING_THEME_STRING_ARRAYS.length) {
followingThemeButtonGroup.setSelectedIndex(index);
cardLayout.show(contentPane, FOLLOWING_THEME_STRING_ARRAYS[index]);
}
}
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style");
}
public int getSelectedIndex() {
return followingThemeButtonGroup.getSelectedIndex();
}
public void populate(ElementCasePane reportPane) {
populateBean(this.analyzeCurrentStyle(reportPane));
updatePreviewArea();
}
private Style analyzeCurrentStyle(ElementCasePane reportPane) {
Style style = null;
// p:从选中的CellElement那里先获得原始的Style.
Selection sel = reportPane.getSelection();
if (sel instanceof FloatSelection) {
// got simple cell element from column and row.
ElementCase report = reportPane.getEditingElementCase();
FloatElement selectedFloatElement = report.getFloatElement(((FloatSelection) sel).getSelectedFloatName());
style = selectedFloatElement.getStyle();
} else {
CellSelection cs = (CellSelection) sel;
// got simple cell element from column and row.
ElementCase report = reportPane.getEditingElementCase();
CellElement editCellElement = report.getCellElement(cs.getColumn(), cs.getRow());
if (editCellElement != null && editCellElement.getStyle() != null) {// editCellElement
// cellstyle.
try {
style = (Style) editCellElement.getStyle().clone();
} catch (CloneNotSupportedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
if (style == null) {
// peter:获取默认的Style.
style = Style.DEFAULT_STYLE;
}
return style;
}
public boolean update(ElementCasePane reportPane) {
return applyStyle(reportPane, updateBean());
}
private boolean applyStyle(ElementCasePane reportPane, Style style) {
TemplateElementCase report = reportPane.getEditingElementCase();
Selection sel = reportPane.getSelection();
if (sel instanceof FloatSelection) {
FloatElement floatElement = report.getFloatElement(((FloatSelection) sel).getSelectedFloatName());
// Apply style.
floatElement.setStyle(style);
} else {
CellSelection cs = (CellSelection) sel;
// Got editCellElement.
TemplateCellElement editCellElement;
// 需要先行后列地增加新元素。
for (int j = 0; j < cs.getRowSpan(); j++) {
for (int i = 0; i < cs.getColumnSpan(); i++) {
int column = i + cs.getColumn();
int row = j + cs.getRow();
editCellElement = report.getTemplateCellElement(column, row);
if (editCellElement == null) {
editCellElement = new DefaultTemplateCellElement(column, row);
report.addCellElement(editCellElement);
}
// Apply cellstyle.
editCellElement.setStyle(style);
}
}
}
if (getSelectedIndex() == 1) {
// p:因为borderpane特殊,update borderpane
customStylePane.dealBorder(reportPane);
}
reportPane.repaint();
return true;
}
public Style updateBean() {
if (getSelectedIndex() == 0) {
NameStyle nameStyle = themedCellStyleListPane.updateBean();
if (nameStyle != null) {
// 只有当前样式面板是跟随主题面板,且跟随主题面板中存在选中项,才使用该样式设置单元格
return nameStyle;
}
}
return customStylePane.updateBean();
}
public void populateBean(Style style) {
if (style instanceof NameStyle) {
NameStyle nameStyle = (NameStyle) style;
setSelectedIndex(0);
themedCellStyleListPane.populateBean(nameStyle);
Style realStyle = nameStyle.getRealStyle();
try {
realStyle = (Style) realStyle.clone();
customStylePane.populateBean(realStyle);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
} else {
setSelectedIndex(1);
customStylePane.populateBean(style);
}
}
public void updatePreviewArea() {
previewArea.setStyle(updateBean());
}
private static class PreviewArea extends JComponent {
private static final String paintText = "Report";
private Style style = Style.DEFAULT_STYLE;
public void setStyle(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();
}
}
private static class CustomFloatStyleSettingPane extends BasicPane implements ChangeListener {
private static final int ALIGNMENT_INDEX = 1;
private static final int FONT_INDEX = 2;
private static final int BORDER_INDEX = 3;
private static final int BACKGROUND_INDEX = 4;
private static final int NEXT_TAB_INDEX = 5;
protected Style editing;
private FormatPane formatPane = null;
private AlignmentPane alignmentPane = null;
private FRFontPane frFontPane = null;
private BorderPane borderPane = null;
private BackgroundPane backgroundPane = null;
private static final List<StyleUIConfigProvider> configList = PluginSandboxCollections.newSandboxList();
private final List<ChangeListener> changeListeners = new ArrayList<>();
public CustomFloatStyleSettingPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
UITabbedPane mainTabbedPane = new UITabbedPane();
mainTabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Format"), this.getFormatPane());
mainTabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Alignment"), FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane());
mainTabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Sytle_FRFont"), FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane());
mainTabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Border"), FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane());
mainTabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Background"), FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane());
for (StyleUIConfigProvider config : configList) {
mainTabbedPane.addTab(config.configName(), FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane());
}
mainTabbedPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent evt) {
Object tabObj = evt.getSource();
if (!(tabObj instanceof JTabbedPane)) {
return;
}
JTabbedPane tabbedPane = (JTabbedPane) tabObj;
int selectedIndex = tabbedPane.getSelectedIndex();
if (tabbedPane.getComponentAt(selectedIndex).getClass() == JPanel.class) {// 是JPanel,需要替换
if (selectedIndex == ALIGNMENT_INDEX) {
tabbedPane.setComponentAt(selectedIndex, getAlignmentPane());
} else if (selectedIndex == FONT_INDEX) {
tabbedPane.setComponentAt(selectedIndex, getFRFontPane());
} else if (selectedIndex == BORDER_INDEX) {
tabbedPane.setComponentAt(selectedIndex, getBorderPane());
} else if (selectedIndex == BACKGROUND_INDEX) {
tabbedPane.setComponentAt(selectedIndex, getBackgroundPane());
} else if (configList.size() + NEXT_TAB_INDEX > selectedIndex && configList.get(selectedIndex - NEXT_TAB_INDEX) != null) {
tabbedPane.setComponentAt(selectedIndex, configList.get(selectedIndex - NEXT_TAB_INDEX).uiComponent(this));
configList.get(selectedIndex - NEXT_TAB_INDEX).populateConfig(editing);
}
}
});
GUICoreUtils.showPopupMenu(popupMenu, ReportStylePane.this, evt.getX() - 1, evt.getY() + Y_OFFSET);
stateChanged(evt);
}
});
add(mainTabbedPane, BorderLayout.CENTER);
}
public void addChangeListener(ChangeListener changeListener) {
this.changeListeners.add(changeListener);
}
protected FormatPane getFormatPane() {
if (this.formatPane == null) {
this.formatPane = new FormatPane();
if (this.editing != null) {
this.formatPane.populate(this.editing.getFormat());
}
}
return this.formatPane;
}
private AlignmentPane getAlignmentPane() {
if (this.alignmentPane == null) {
this.alignmentPane = new AlignmentPane();
this.alignmentPane.addChangeListener(this);
if (this.editing != null) {
this.alignmentPane.populate(this.editing);
}
}
});
return this.alignmentPane;
}
private FRFontPane getFRFontPane() {
if (this.frFontPane == null) {
this.frFontPane = new FRFontPane();
this.frFontPane.addChangeListener(this);
if (this.editing != null) {
this.frFontPane.populate(this.editing.getFRFont());
}
}
return this.frFontPane;
}
private BorderPane getBorderPane() {
if (this.borderPane == null) {
this.borderPane = new BorderPane();
this.borderPane.addChangeListener(this);
if (this.editing != null) {
this.borderPane.populate(this.editing);
}
}
return this.borderPane;
}
private BackgroundPane getBackgroundPane() {
if (this.backgroundPane == null) {
this.backgroundPane = new BackgroundPane();
this.backgroundPane.addChangeListener(this);
if (this.editing != null) {
this.backgroundPane.populate(this.editing.getBackground());
}
}
return this.backgroundPane;
}
public void populateBean(Style ob) {
this.editing = ob == null ? Style.getInstance() : ob;
if (this.formatPane != null) {
this.formatPane.populate(editing.getFormat());
}
if (this.alignmentPane != null) {
this.alignmentPane.populate(editing);
}
if (this.frFontPane != null) {
this.frFontPane.populate(editing.getFRFont());
}
if (this.borderPane != null) {
this.borderPane.populate(editing);
}
if (this.backgroundPane != null) {
this.backgroundPane.populate(editing.getBackground());
}
for(StyleUIConfigProvider tabConfig : configList){
tabConfig.populateConfig(this.editing);
}
}
public Style updateBean() {
// need the check the valid of CellAlignment pane.
try {
if (this.alignmentPane != null) {
this.alignmentPane.checkValid();
}
} catch (Exception exp) {
FineJOptionPane.showMessageDialog(this, exp.getMessage());
return editing;
}
Style style = editing;
if (this.formatPane != null) {
style = style.deriveFormat(this.formatPane.update());
}
if (this.alignmentPane != null) {
style = this.alignmentPane.update(style);
}
if (this.frFontPane != null) {
style = style.deriveFRFont(this.frFontPane.update());
}
if (this.borderPane != null) {
style = this.borderPane.update(style);
}
if (this.backgroundPane != null) {
style = style.deriveBackground(this.backgroundPane.update());
}
for(StyleUIConfigProvider tabConfig : configList){
style = tabConfig.updateConfig();
}
return style;
}
public void dealBorder(ElementCasePane reportPane) {
if (this.borderPane != null) {
BorderUtils.update(reportPane, this.borderPane.update());
}
}
@Override
protected String title4PopupWindow() {
return null;
}
@Override
public void stateChanged(ChangeEvent e) {
for (ChangeListener changeListener: changeListeners) {
changeListener.stateChanged(e);
}
}
}
private Border createTitleBorder(String title) {
return new NoEdgeTitleBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(
0,
0,
0,
0),
new UIRoundedBorder(
UIConstants.TITLED_BORDER_COLOR,
1,
10)
),
title,
TitledBorder.LEADING,
TitledBorder.TOP,
FRFont.getInstance().deriveFont(12F),
new Color(0x2F8EF1)
);
}
}

Loading…
Cancel
Save