Browse Source

Pull request #3935: KERNEL-7376 优化设计器上一些性能问题

Merge in DESIGN/design from ~HENRY.WANG/design:feature/10.0 to feature/10.0

* commit '66bbd54f45db034d8ffaa82ff3022d687b61f1b7':
  KERNEL-7376 优化设计器上一些性能问题
  KERNEL-7376 优化设计器上一些性能问题
  KERNEL-7376 优化设计器上一些性能问题
  KERNEL-7376 优化设计器上一些性能问题
  KERNEL-7376 优化设计器上一些性能问题
feature/10.0
Henry.Wang 4 years ago
parent
commit
c99794ce4c
  1. 21
      designer-base/src/main/java/com/fr/base/svg/SVGIcon.java
  2. 7
      designer-base/src/main/java/com/fr/design/gui/chart/BaseChartPropertyPane.java
  3. 66
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  4. 12
      designer-base/src/main/java/com/fr/design/selection/SelectableElement.java
  5. 147
      designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java
  6. 165
      designer-chart/src/main/java/com/fr/design/mainframe/MiddleChartPropertyPane.java
  7. 2
      designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java
  8. 14
      designer-realize/src/main/java/com/fr/grid/selection/CellSelection.java
  9. 11
      designer-realize/src/main/java/com/fr/grid/selection/FloatSelection.java
  10. 5
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

21
designer-base/src/main/java/com/fr/base/svg/SVGIcon.java

@ -7,6 +7,8 @@ import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* SVG转化而来的Icon * SVG转化而来的Icon
@ -28,6 +30,8 @@ public class SVGIcon implements Icon {
this.image = image; this.image = image;
} }
private static Map<String, Icon> iconCache = new ConcurrentHashMap<>();
@Override @Override
public void paintIcon(Component c, Graphics g, int x, int y) { public void paintIcon(Component c, Graphics g, int x, int y) {
if (HI_DPI_SURPORT) { if (HI_DPI_SURPORT) {
@ -58,11 +62,26 @@ public class SVGIcon implements Icon {
* @return * @return
*/ */
public static Icon readSVGIcon(String url) { public static Icon readSVGIcon(String url) {
return readSVGIconWithCache(url, true);
}
public static Icon readSVGIconWithCache(String url, boolean cacheRead) {
Icon icon = null;
if (cacheRead) {
icon = iconCache.get(url);
}
if (icon == null) {
if (!url.startsWith(ICON_PREFIX)) { if (!url.startsWith(ICON_PREFIX)) {
url = ICON_PREFIX + url; url = ICON_PREFIX + url;
} }
BufferedImage image = (BufferedImage) SVGLoader.load(url); BufferedImage image = (BufferedImage) SVGLoader.load(url);
return image == null ? IOUtils.readIcon(url) : new SVGIcon(image); icon = image == null ? IOUtils.readIcon(url) : new SVGIcon(image);
//只缓存svg图标
if (image != null){
iconCache.put(url, icon);
}
}
return icon;
} }
/** /**

7
designer-base/src/main/java/com/fr/design/gui/chart/BaseChartPropertyPane.java

@ -10,9 +10,6 @@ import com.fr.design.mainframe.DockingView;
* @version 创建时间2013-7-10 上午09:12:11 * @version 创建时间2013-7-10 上午09:12:11
*/ */
public abstract class BaseChartPropertyPane extends DockingView { public abstract class BaseChartPropertyPane extends DockingView {
public abstract void setSureProperty();
/** /**
* 设置是否支持单元格数据. * 设置是否支持单元格数据.
*/ */
@ -22,7 +19,5 @@ public abstract class BaseChartPropertyPane extends DockingView {
public abstract ChartEditPaneProvider getChartEditPane(); public abstract ChartEditPaneProvider getChartEditPane();
public abstract void addChartEditPane(String plotID); public abstract void updateChartEditPane(String plotID);
//public abstract void clear();
} }

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

@ -83,9 +83,9 @@ import javax.swing.JOptionPane;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.undo.UndoManager; import javax.swing.undo.UndoManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Collections;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import java.awt.BorderLayout; import java.awt.BorderLayout;
/** /**
@ -846,33 +846,61 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
TemplateFileTree tt = TemplateTreePane.getInstance().getTemplateFileTree(); TemplateFileTree tt = TemplateTreePane.getInstance().getTemplateFileTree();
DefaultMutableTreeNode gen = (DefaultMutableTreeNode) tt.getModel().getRoot(); DefaultMutableTreeNode gen = (DefaultMutableTreeNode) tt.getModel().getRoot();
String[] str = new String[gen.getChildCount()]; String[] str = new String[gen.getChildCount()];
ArrayList<String> al = new ArrayList<String>();
List<Integer> reportNum = new ArrayList<>();
for (int j = 0; j < gen.getChildCount(); j++) { for (int j = 0; j < gen.getChildCount(); j++) {
str[j] = gen.getChildAt(j).toString(); str[j] = gen.getChildAt(j).toString();
if (str[j].contains(prefix) && str[j].contains(".")) { //返回文件名中的index(算法中没有再匹配文件后缀了,因为DefaultMutableTreeNode中已经匹配过了)
for (int i = 0; i < PREFIX_NUM; i++) { Integer index = getFileNameIndex(prefix, str[j]);
if (ComparatorUtils.equals(str[j].split("[.]")[0], (prefix + i))) { if (index != null) {
al.add(str[j]); reportNum.add(index);
}
}
} }
} }
Collections.sort(reportNum);
int idx = reportNum.size() > 0 ? reportNum.get(reportNum.size() - 1) + 1 : 1;
int[] reportNum = new int[al.size()];
for (int i = 0; i < al.size(); i++) {
Pattern pattern = Pattern.compile("[" + prefix + ".]+");
String[] strs = pattern.split(al.get(i).toString());
reportNum[i] = Integer.parseInt(strs[1]);
}
Arrays.sort(reportNum);
int idx = reportNum.length > 0 ? reportNum[reportNum.length - 1] + 1 : 1;
idx = idx + currentIndex; idx = idx + currentIndex;
currentIndex++; currentIndex++;
return prefix + idx; return prefix + idx;
} }
/**
* @Description 返回文件名中的index
* @param: prefix 前缀
* @param: fileName 文件名称全名
* @return java.lang.Integer WorkBook11.cpt则返回11如果没有找到index返回null
* @Author Henry.Wang
* @Date 2021/4/9 11:13
**/
private static Integer getFileNameIndex(String prefix, String fileName) {
char[] chars = new char[fileName.length()];
int i = 0;
for (; i < fileName.length(); i++) {
char c = fileName.charAt(i);
//匹配前缀
if (i < prefix.length()) {
if (c != prefix.charAt(i)) {
return null;
}
} else {
if (c == '.') {
break;
} else {
//匹配0~9
if (c < 48 || c > 57) {
return null;
}
chars[i - prefix.length()] = c;
}
}
}
String s = new String(chars).substring(0, i - prefix.length());
if (StringUtils.isBlank(s)) {
return null;
}
return Integer.valueOf(s);
}
// /////////////////////////////toolbarMenuDock////////////////////////////////// // /////////////////////////////toolbarMenuDock//////////////////////////////////
/** /**

12
designer-base/src/main/java/com/fr/design/selection/SelectableElement.java

@ -15,6 +15,16 @@ public interface SelectableElement {
* @return * @return
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public QuickEditor getQuickEditor(TargetComponent tc); QuickEditor getQuickEditor(TargetComponent tc);
/**
* @Description 有些实现类中getQuickEditor会在获取editor后再填充面板这个方法只会获取editor不会填充面板
* @param: tc
* @return com.fr.design.selection.QuickEditor
* @Author Henry.Wang
* @Date 2021/4/2 15:02
**/
default QuickEditor getQuickEditorWithoutPopulate(TargetComponent tc){
return null;
}
} }

147
designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java

@ -3,45 +3,162 @@
*/ */
package com.fr.design.mainframe; package com.fr.design.mainframe;
import com.fr.design.gui.ilable.UILabel;
import com.fr.base.BaseUtils;
import com.fr.base.chart.BaseChartCollection;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chartx.attr.ChartProvider;
import com.fr.design.ChartTypeInterfaceManager;
import com.fr.design.designer.TargetComponent;
import com.fr.design.gui.chart.BaseChartPropertyPane;
import com.fr.design.gui.chart.ChartEditPaneProvider;
import com.fr.design.gui.frpane.UITitlePanel;
import com.fr.design.mainframe.chart.ChartEditPane;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
public class ChartPropertyPane extends MiddleChartPropertyPane{ public class ChartPropertyPane extends BaseChartPropertyPane {
/** /**
* 创建图表属性表实例. * 创建图表属性表实例.
*/ */
private synchronized static ChartPropertyPane getInstance() { private synchronized static ChartPropertyPane getInstance() {
//todo
//创建新图表时,创建属性表配置面板 //创建新图表时,创建属性表配置面板
if (singleton == null) {
singleton = new ChartPropertyPane(); singleton = new ChartPropertyPane();
}
return singleton; return singleton;
} }
private static ChartPropertyPane singleton; private static ChartPropertyPane singleton;
protected TargetComponentContainer container = new TargetComponentContainer();
protected ChartEditPane chartEditPane;
private ChartPropertyPane() {
initComponent();
}
protected void initComponent() {
this.setLayout(new BorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
}
@Override @Override
protected void createNameLabel() { public void updateChartEditPane(String plotID) {
nameLabel = new UILabel() { chartEditPane = ChartTypeInterfaceManager.getInstance().getChartEditPane(plotID);
chartEditPane.setContainer(container);
resetChartEditPane();
}
@Override @Override
public Dimension getPreferredSize() { public ChartEditPaneProvider getChartEditPane() {
return new Dimension(super.getPreferredSize().width, 18); return chartEditPane;
} }
};
nameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 1, 0));
nameLabel.setHorizontalAlignment(SwingConstants.CENTER); protected void resetChartEditPane() {
removeChartEditPane();
addChartEditPane(this.chartEditPane);
validate();
repaint();
revalidate();
} }
@Override /**
protected void createMainPane() { * @Description 去除BorderLayout.CENTER位置的元素
* @return void
* @Author Henry.Wang
* @Date 2021/4/9 13:54
**/
private void removeChartEditPane() {
BorderLayout layout = (BorderLayout) this.getLayout();
Component component = layout.getLayoutComponent(BorderLayout.CENTER);
if (component != null)
this.remove(component);
}
/**
* @Description 把chartEditPane加到BorderLayout.CENTER中
* @param: chartEditPane
* @return void
* @Author Henry.Wang
* @Date 2021/4/9 13:55
**/
private void addChartEditPane(ChartEditPane chartEditPane) {
this.add(chartEditPane, BorderLayout.CENTER); this.add(chartEditPane, BorderLayout.CENTER);
} }
@Override /**
protected JComponent createNorthComponent() { * 感觉ChartCollection加载图表属性界面.
return nameLabel; * @param collection 收集图表
* @param ePane 面板
*/
public void populateChartPropertyPane(ChartCollection collection, TargetComponent<?> ePane) {
updateChartEditPane(collection.getSelectedChartProvider(ChartProvider.class).getID());
setSupportCellData(true);
this.container.setEPane(ePane);
chartEditPane.populate(collection);
}
/**
* 感觉ChartCollection加载图表属性界面.
* @param collection 收集图表
* @param ePane 面板
*/
public void populateChartPropertyPane(BaseChartCollection collection, TargetComponent<?> ePane) {
if (collection instanceof ChartCollection) {
populateChartPropertyPane((ChartCollection) collection, ePane);
}
}
/**
* 返回View的标题.
*/
public String getViewTitle() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Cell_Element_Property_Table");
}
/**
* 返回View的Icon地址.
*/
public Icon getViewIcon() {
return BaseUtils.readIcon("/com/fr/design/images/m_report/qb.png");
}
/**
* 预定义定位
* @return 定位
*/
public Location preferredLocation() {
return Location.WEST_BELOW;
}
/**
* 创建标题Panel
* @return 标题panel
*/
public UITitlePanel createTitlePanel() {
return new UITitlePanel(this);
}
/**
* 刷新Dockview
*/
public void refreshDockingView() {
// TODO Auto-generated method stub
}
/**
* 设置是否支持单元格数据.
*/
public void setSupportCellData(boolean supportCellData) {
if (chartEditPane != null) {
chartEditPane.setSupportCellData(supportCellData);
}
} }
public synchronized static void clear() { public synchronized static void clear() {

165
designer-chart/src/main/java/com/fr/design/mainframe/MiddleChartPropertyPane.java

@ -1,165 +0,0 @@
/*
* Copyright(c) 2001-2011, FineReport Inc, All Rights Reserved.
*/
package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fr.base.chart.BaseChartCollection;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chartx.attr.ChartProvider;
import com.fr.design.ChartTypeInterfaceManager;
import com.fr.design.designer.TargetComponent;
import com.fr.design.gui.chart.BaseChartPropertyPane;
import com.fr.design.gui.chart.ChartEditPaneProvider;
import com.fr.design.gui.frpane.UITitlePanel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itabpane.TitleChangeListener;
import com.fr.design.mainframe.chart.ChartEditPane;
import com.fr.stable.StableUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import java.awt.BorderLayout;
public abstract class MiddleChartPropertyPane extends BaseChartPropertyPane{
protected TargetComponentContainer container = new TargetComponentContainer();
protected UILabel nameLabel;
protected ChartEditPane chartEditPane;
public MiddleChartPropertyPane() {
initComponenet();
}
protected void initComponenet() {
this.setLayout(new BorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
createNameLabel();
//去掉上方名字,先注释掉
// this.add(createNorthComponent(), BorderLayout.NORTH);
chartEditPane = StableUtils.construct(ChartEditPane.class);
chartEditPane.setSupportCellData(true);
}
public void addChartEditPane(String plotID){
chartEditPane = ChartTypeInterfaceManager.getInstance().getChartEditPane(plotID);
chartEditPane.setSupportCellData(true);
this.createMainPane();
setSureProperty();
}
protected abstract void createNameLabel();
protected abstract JComponent createNorthComponent();
protected abstract void createMainPane();
@Override
public ChartEditPaneProvider getChartEditPane() {
return chartEditPane;
}
public void setSureProperty() {
chartEditPane.setContainer(container);
chartEditPane.addTitleChangeListener(titleListener);
String tabname = chartEditPane.getSelectedTabName();
nameLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Property_Table") + (tabname != null ? ('-' + chartEditPane.getSelectedTabName()) : ""));
resetChartEditPane();
}
protected void resetChartEditPane() {
remove(chartEditPane);
add(chartEditPane, BorderLayout.CENTER);
validate();
repaint();
revalidate();
}
protected TitleChangeListener titleListener = new TitleChangeListener() {
@Override
public void fireTitleChange(String addName) {
nameLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Property_Table") + '-' + addName);
}
};
/**
* 感觉ChartCollection加载图表属性界面.
* @param collection 收集图表
* @param ePane 面板
*/
public void populateChartPropertyPane(ChartCollection collection, TargetComponent<?> ePane) {
addChartEditPane(collection.getSelectedChartProvider(ChartProvider.class).getID());
setSupportCellData(true);
this.container.setEPane(ePane);
chartEditPane.populate(collection);
}
/**
* 感觉ChartCollection加载图表属性界面.
* @param collection 收集图表
* @param ePane 面板
*/
public void populateChartPropertyPane(BaseChartCollection collection, TargetComponent<?> ePane) {
if (collection instanceof ChartCollection) {
populateChartPropertyPane((ChartCollection)collection, ePane);
}
}
// public void clear() {
// this.container.setEPane(null);
// chartEditPane.clear();
// getParent().remove(this);
// }
/**
* 返回View的标题.
*/
public String getViewTitle() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Cell_Element_Property_Table");
}
/**
* 返回View的Icon地址.
*/
public Icon getViewIcon() {
return BaseUtils.readIcon("/com/fr/design/images/m_report/qb.png");
}
/**
* 预定义定位
* @return 定位
*/
public Location preferredLocation() {
return Location.WEST_BELOW;
}
/**
* 创建标题Panel
* @return 标题panel
*/
public UITitlePanel createTitlePanel() {
return new UITitlePanel(this);
}
/**
* 刷新Dockview
*/
public void refreshDockingView() {
// TODO Auto-generated method stub
}
/**
* 设置是否支持单元格数据.
*/
public void setSupportCellData(boolean supportCellData) {
if(chartEditPane != null) {
chartEditPane.setSupportCellData(supportCellData);
}
}
}

2
designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePane.java

@ -529,7 +529,7 @@ public abstract class ElementCasePane<T extends TemplateElementCase> extends Tar
|| DesignModeContext.isAuthorityEditing()) { || DesignModeContext.isAuthorityEditing()) {
try { try {
//旧选中内容编辑器释放模板对象 //旧选中内容编辑器释放模板对象
QuickEditor editor = this.getCurrentEditor(); QuickEditor editor = this.selection.getQuickEditorWithoutPopulate(this);
if (editor != null) { if (editor != null) {
editor.release(); editor.release();
} }

14
designer-realize/src/main/java/com/fr/grid/selection/CellSelection.java

@ -733,6 +733,16 @@ public class CellSelection extends Selection {
@Override @Override
public QuickEditor getQuickEditor(TargetComponent tc) { public QuickEditor getQuickEditor(TargetComponent tc) {
QuickEditor editor = getQuickEditorWithoutPopulate(tc);
if (editor == null) {
return null;
}
editor.populate(tc);
return editor;
}
@Override
public QuickEditor getQuickEditorWithoutPopulate(TargetComponent tc) {
ElementCasePane ePane = (ElementCasePane) tc; ElementCasePane ePane = (ElementCasePane) tc;
TemplateElementCase tplEC = ePane.getEditingElementCase(); TemplateElementCase tplEC = ePane.getEditingElementCase();
TemplateCellElement cellElement = tplEC.getTemplateCellElement(column, row); TemplateCellElement cellElement = tplEC.getTemplateCellElement(column, row);
@ -744,10 +754,6 @@ public class CellSelection extends Selection {
value = value == null ? StringUtils.EMPTY : value; value = value == null ? StringUtils.EMPTY : value;
//之前是少了个bigInteger,刚kunsnat又发现少了个bigDecimal,数字类型的都用stringEditor,没必要那个样子 //之前是少了个bigInteger,刚kunsnat又发现少了个bigDecimal,数字类型的都用stringEditor,没必要那个样子
QuickEditor editor = ActionFactory.getCellEditor((value instanceof Number) ? (Number.class) : (value.getClass())); QuickEditor editor = ActionFactory.getCellEditor((value instanceof Number) ? (Number.class) : (value.getClass()));
if (editor == null) {
return null;
}
editor.populate(tc);
return editor; return editor;
} }

11
designer-realize/src/main/java/com/fr/grid/selection/FloatSelection.java

@ -236,6 +236,15 @@ public class FloatSelection extends Selection {
@Override @Override
public QuickEditor getQuickEditor(TargetComponent tc) { public QuickEditor getQuickEditor(TargetComponent tc) {
QuickEditor editor = getQuickEditorWithoutPopulate(tc);
if (editor == null)
return null;
editor.populate(tc);
return editor;
}
@Override
public QuickEditor getQuickEditorWithoutPopulate(TargetComponent tc) {
ElementCasePane ePane = (ElementCasePane) tc; ElementCasePane ePane = (ElementCasePane) tc;
FloatElement selectedFloat = ePane.getEditingElementCase().getFloatElement(selectedFloatName); FloatElement selectedFloat = ePane.getEditingElementCase().getFloatElement(selectedFloatName);
Object value = null; Object value = null;
@ -246,10 +255,10 @@ public class FloatSelection extends Selection {
value = value == null ? "" : value; value = value == null ? "" : value;
value = value instanceof Number ? value.toString() : value; value = value instanceof Number ? value.toString() : value;
QuickEditor editor = ActionFactory.getFloatEditor(value.getClass()); QuickEditor editor = ActionFactory.getFloatEditor(value.getClass());
editor.populate(tc);
return editor; return editor;
} }
@Override @Override
public void populatePropertyPane(ElementCasePane ePane) { public void populatePropertyPane(ElementCasePane ePane) {
CellElementPropertyPane.getInstance().removeAll(); CellElementPropertyPane.getInstance().removeAll();

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

@ -160,6 +160,9 @@ public class DesignerActivator extends Activator {
@Override @Override
public void afterAllStart() { public void afterAllStart() {
DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE); DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE);
//生成BasicChartQuickEditor对象,需要用到ChartDesignerActivator的注册信息(DesignModuleFactory.registerChartPropertyPaneClass(ChartPropertyPane.class);)
//所以不能在registerCellEditor函数中进行注册
ActionFactory.registerCellEditor(ChartCollection.class, new BasicChartQuickEditor());
} }
private void loadLogAppender() { private void loadLogAppender() {
@ -344,8 +347,6 @@ public class DesignerActivator extends Activator {
ActionFactory.registerCellEditor(BiasTextPainter.class, new CellBiasTextPainterEditor()); ActionFactory.registerCellEditor(BiasTextPainter.class, new CellBiasTextPainterEditor());
ActionFactory.registerCellEditor(BufferedImage.class, new CellImageQuickEditor()); ActionFactory.registerCellEditor(BufferedImage.class, new CellImageQuickEditor());
ActionFactory.registerCellEditor(CellImagePainter.class, new CellImageQuickEditor()); ActionFactory.registerCellEditor(CellImagePainter.class, new CellImageQuickEditor());
//todo 图表编辑器populate没能实现刷新面板显示
ActionFactory.registerCellEditorClass(ChartCollection.class, BasicChartQuickEditor.class);
Set<ElementUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING); Set<ElementUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING);
for (ElementUIProvider provider : providers) { for (ElementUIProvider provider : providers) {

Loading…
Cancel
Save