帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

589 lines
16 KiB

/*
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved.
*/
package com.fr.design.designer.creator;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.form.layout.FRLayoutManager;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.widget.editors.PaddingMarginEditor;
import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor;
import com.fr.design.parameter.ParameterBridge;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WLayout;
import com.fr.general.Background;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.core.PropertyChangeAdapter;
import javax.swing.JComponent;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.beans.IntrospectionException;
import java.util.List;
/**
* @author richer
* @since 6.5.3
*/
public abstract class XLayoutContainer extends XBorderStyleWidgetCreator implements ContainerListener, ParameterBridge {
// 布局内部组件默认最小宽度36,最小高度21
public static int MIN_WIDTH = 36;
public static int MIN_HEIGHT = 21;
protected static final Dimension LARGEPREFERREDSIZE = new Dimension(200, 200);
protected boolean isRefreshing;
protected int default_Length = 5; // 取指定点坐在的组件,默认为5保证取四侧相邻的组件时x、y在组件内非边框上
/**
* 布局是否可编辑,不可则显示编辑层
*/
protected boolean editable = false;
//鼠标移动到布局画出编辑层
protected boolean isMouseEnter = false;
private volatile boolean dragInAble;
public void setMouseEnter(boolean mouseEnter) {
isMouseEnter = mouseEnter;
}
public XLayoutContainer(WLayout widget, Dimension initSize) {
super(widget, initSize);
this.addContainerListener(this);
}
/**
* 得到属性名
*
* @return 属性名
* @throws IntrospectionException
*/
public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException {
return new CRPropertyDescriptor[]{
new CRPropertyDescriptor("widgetName", this.data.getClass()).setI18NName(Toolkit.i18nText("Fine-Design_Form-Widget_Name")),
new CRPropertyDescriptor("borderStyle", this.data.getClass()).setEditorClass(
WLayoutBorderStyleEditor.class).setI18NName(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Engine_Style")).putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced")
.setPropertyChangeListener(new PropertyChangeAdapter() {
@Override
public void propertyChange() {
refreshStylePreviewEffect();
}
}),
new CRPropertyDescriptor("margin", this.data.getClass()).setEditorClass(PaddingMarginEditor.class)
.setI18NName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))
.putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced"),
};
}
/**
* 控件名属性
*
* @return
* @throws IntrospectionException
*/
public CRPropertyDescriptor createWidgetNameDescriptor() throws IntrospectionException {
return new CRPropertyDescriptor("widgetName", this.data.getClass()).setI18NName(Toolkit.i18nText("Fine-Design_Form-Widget_Name"));
}
/**
* 边距属性
*
* @return
* @throws IntrospectionException
*/
public CRPropertyDescriptor createMarginDescriptor() throws IntrospectionException {
return new CRPropertyDescriptor("margin", this.data.getClass()).setEditorClass(PaddingMarginEditor.class)
.setI18NName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))
.putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Fine-Design_Basic_Advanced");
}
/**
* 返回对应的wlayout
*
* @return wlayout控件
*/
public WLayout toData() {
return (WLayout) data;
}
@Override
protected void initXCreatorProperties() {
super.initXCreatorProperties();
refreshBorderAndBackgroundStylePreviewEffect();
this.initLayoutManager();
this.convert();
}
@Override
protected JComponent initEditor() {
return this;
}
public void setComponentZOrder(XCreator creator, int targetIndex) {
super.setComponentZOrder(creator, targetIndex); // 设计器界面上更改
// 以下是数据层更改,会反映到 web 端
WLayout layout = this.toData();
String widgetName = creator.toData().getWidgetName();
layout.setWidgetIndex(layout.getWidget(widgetName), targetIndex);
}
/**
* 当前组件zorder位置替换新的控件
*
* @param widget 控件
* @param oldcreator 旧组件
* @return 组件
*/
public XCreator replace(Widget widget, XCreator oldcreator) {
int i = this.getComponentZOrder(oldcreator);
if (i != -1) {
this.toData().replace(widget, oldcreator.toData());
this.convert();
XCreator creator = (XCreator) this.getComponent(i);
creator.setSize(oldcreator.getSize());
return creator;
}
return null;
}
/**
* 初始化时默认的组件大小
*
* @return 默认Dimension
*/
public Dimension initEditorSize() {
return LARGEPREFERREDSIZE;
}
protected abstract void initLayoutManager();
/**
* 将WLayout转换为XLayoutContainer
*/
public void convert() {
isRefreshing = true;
WLayout layout = this.toData();
this.removeAll();
addWidgetToSwingComponent(layout);
isRefreshing = false;
}
protected void addWidgetToSwingComponent(WLayout layout) {
for (int i = 0; i < layout.getWidgetCount(); i++) {
Widget wgt = layout.getWidget(i);
if (wgt != null) {
XWidgetCreator comp = (XWidgetCreator) XCreatorUtils.createXCreator(wgt, calculatePreferredSize(wgt));
this.add(comp, i);
}
}
}
/**
* 设计界面中有组件添加时,要通知WLayout容器重新paint
*
* @param e 待说明
*/
@Override
public void componentAdded(ContainerEvent e) {
if (isRefreshing) {
return;
}
XWidgetCreator creator = (XWidgetCreator) e.getChild();
WLayout wlayout = this.toData();
Widget wgt = creator.toData();
wlayout.addWidget(wgt);
this.recalculateChildrenPreferredSize();
}
/**
* 设计界面中有组件添加时,要通知WLayout容器重新paint
*
* @param e 待说明
*/
@Override
public void componentRemoved(ContainerEvent e) {
if (isRefreshing) {
return;
}
WLayout wlayout = this.toData();
Widget wgt = ((XWidgetCreator) e.getChild()).toData();
wlayout.removeWidget(wgt);
this.recalculateChildrenPreferredSize();
}
/**
* 根据widget的属性值来获取
*
* @param wgt
* @return
*/
protected Dimension calculatePreferredSize(Widget wgt) {
return new Dimension();
}
/**
* 重新调整子组件的大小
*/
public void recalculateChildrenPreferredSize() {
for (int i = 0; i < this.getComponentCount(); i++) {
XCreator creator = this.getXCreator(i);
Widget wgt = creator.toData();
Dimension dim = calculatePreferredSize(wgt);
creator.setPreferredSize(dim);
creator.setMaximumSize(dim);
}
}
public int getShowXCreatorCount() {
return getXCreatorCount();
}
public int getXCreatorCount() {
return getComponentCount();
}
public XCreator getXCreator(int i) {
return (XCreator) getComponent(i);
}
/**
* 该组件是否可以拖入参数面板
*
* @return 是则返回true
*/
public boolean canEnterIntoParaPane() {
return false;
}
/**
* 是否作为控件树的叶子节点
*
* @return 是则返回true
*/
public boolean isComponentTreeLeaf() {
return false;
}
public List<String> getAllXCreatorNameList(XCreator xCreator, List<String> namelist) {
for (int i = 0; i < ((XLayoutContainer) xCreator).getXCreatorCount(); i++) {
XCreator creatorSon = ((XLayoutContainer) xCreator).getXCreator(i);
creatorSon.getAllXCreatorNameList(creatorSon, namelist);
}
return namelist;
}
/**
* 是否有查询按钮
*
* @param xCreator 控件或容器
* @return 有无查询按钮
*/
public boolean SearchQueryCreators(XCreator xCreator) {
for (int i = 0; i < ((XLayoutContainer) xCreator).getXCreatorCount(); i++) {
XCreator creatorSon = ((XLayoutContainer) xCreator).getXCreator(i);
if (creatorSon.SearchQueryCreators(creatorSon)) {
return true;
}
}
return false;
}
public FRLayoutManager getFRLayout() {
LayoutManager layout = getLayout();
if (layout instanceof FRLayoutManager) {
return (FRLayoutManager) layout;
}
FineLoggerFactory.getLogger().error("FRLayoutManager isn't exsit!");
return null;
}
public abstract LayoutAdapter getLayoutAdapter();
public int getIndexOfChild(Object child) {
int count = getComponentCount();
for (int i = 0; i < count; i++) {
Component comp = getComponent(i);
if (comp == child) {
return i;
}
}
return -1;
}
/**
* 主要为自适应用
* 返回指定point的上方组件
*
* @param x x位置
* @param y y位置
* @return 指定位置的组件
*/
public Component getTopComp(int x, int y) {
return this.getComponentAt(x, y - default_Length);
}
/**
* 主要为自适应用
* 返回指定point的左方组件
*
* @param x x位置
* @param y y位置
* @return 指定位置的组件
*/
public Component getLeftComp(int x, int y) {
return this.getComponentAt(x - default_Length, y);
}
/**
* 返回指定point的右方组件
*
* @param x x位置
* @param y y位置
* @param w 宽度
* @return 指定位置的组件
*/
public Component getRightComp(int x, int y, int w) {
return this.getComponentAt(x + w + default_Length, y);
}
/**
* 返回指定point的下方组件
*
* @param x x位置
* @param y y位置
* @param h 高度
* @return 指定位置的组件
*/
public Component getBottomComp(int x, int y, int h) {
return this.getComponentAt(x, y + h + default_Length);
}
/**
* 返回指定point的上方且是右侧的组件
*
* @param x x位置
* @param y y位置
* @param w 宽度
* @return 指定位置的组件
*/
public Component getRightTopComp(int x, int y, int w) {
return this.getComponentAt(x + w - default_Length, y - default_Length);
}
/**
* 返回指定point的左方且是下侧的组件
*
* @param x x位置
* @param y y位置
* @param h 高度
* @return 指定位置的组件
*/
public Component getBottomLeftComp(int x, int y, int h) {
return this.getComponentAt(x - default_Length, y + h - default_Length);
}
/**
* 返回指定point的右方且是下侧的组件
*
* @param x x位置
* @param y y位置
* @param h 高度
* @param w 宽度
* @return 指定位置的组件
*/
public Component getBottomRightComp(int x, int y, int h, int w) {
return this.getComponentAt(x + w + default_Length, y + h - default_Length);
}
/**
* 返回指定point的下方且是右侧的组件
*
* @param x x位置
* @param y y位置
* @param h 高度
* @param w 宽度
* @return 指定位置的组件
*/
public Component getRightBottomComp(int x, int y, int h, int w) {
return this.getComponentAt(x + w - default_Length, y + h + default_Length);
}
/**
* 是否延迟展示报表内容,也就是说是否要等点击了查询之后才执行报表
*
* @return 如果是true,则表示点击之后才开始计算,false则表示会根据参数默认值直接计算报表并展现
*/
public boolean isDelayDisplayContent() {
return false;
}
/**
* 是否启用参数模板
* @return 显示参数模板界面则返回true,否则返回false
*/
public boolean isUseParamsTemplate() {
return false;
}
/**
* 是否显示参数界面
*
* @return 显示参数界面则返回true,否则返回false
*/
public boolean isDisplay() {
return false;
}
public Background getDataBackground() {
return toData().getBackground();
}
/**
* 获取参数界面的宽度
*
* @return 宽度
*/
public int getDesignWidth() {
return 0;
}
/**
* 获取参数面板的对齐方式
*
* @return 左中右三种对齐方式
*/
public int getPosition() {
return 0;
}
/**
* 切换到非添加状态
*
* @param designer 表单设计器
*/
public void stopAddingState(FormDesigner designer) {
}
/**
* 寻找最近的为自适应布局的父容器
*
* @return 布局容器
* @date 2014-12-30-下午3:15:28
*/
public XLayoutContainer findNearestFit() {
//一层一层网上找, 找到最近的fit那一层就return
XLayoutContainer parent = this.getBackupParent();
return parent == null ? null : parent.findNearestFit();
}
/**
* 获取容器所有内部组件横坐标值
*
* @return 横坐标数组
*/
public int[] getHors() {
return ArrayUtils.EMPTY_INT_ARRAY;
}
/**
* 获取容器所有内部组件纵坐标值
*
* @return 纵坐标数组
*/
public int[] getVeris() {
return ArrayUtils.EMPTY_INT_ARRAY;
}
public void setDelayDisplayContent(boolean delayPlaying) {
}
public void setUseParamsTemplate(boolean isUse) {
}
public void setPosition(int align) {
}
public void setDisplay(boolean showWindow) {
}
public void setBackground(Background background) {
}
/**
* 布局是否可编辑,不可则显示编辑蒙层
*
* @return 可否编辑
*/
public boolean isEditable() {
return this.editable;
}
/**
* 设置布局是否可编辑,不可则显示编辑蒙层
*
* @param isEditable 可否编辑
*/
public void setEditable(boolean isEditable) {
this.editable = isEditable;
}
/**
* data属性改变触发其他操作
*
*/
public void firePropertyChange(){
refreshStylePreviewEffect();
}
/**
* 是否支持设置可见
* return boolean
*/
public boolean supportSetVisible(){
return false;
}
/**
* 是否支持设置可用
* return boolean
*/
public boolean supportSetEnable(){
return false;
}
/**
* 内部组件是否支持叠加顺序的调整
* return boolean
*/
public boolean supportInnerOrderChangeActions() {
return false;
}
@Override
public boolean supportMobileStyle() {
return false;
}
public boolean isDragInAble() {
return dragInAble;
}
public void setDragInAble(boolean dragInAble) {
this.dragInAble = dragInAble;
}
}