帆软报表设计器源代码。
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.
 
 
 
 

2117 lines
74 KiB

package com.fr.design.mainframe;
import com.fr.base.Parameter;
import com.fr.base.chart.BaseChartCollection;
import com.fr.base.vcs.DesignerMode;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chartx.attr.ChartProvider;
import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignState;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.UpdateAction;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.designer.TargetComponent;
import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.ComponentAdapter;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.Painter;
import com.fr.design.designer.beans.actions.CopyAction;
import com.fr.design.designer.beans.actions.CutAction;
import com.fr.design.designer.beans.actions.FormDeleteAction;
import com.fr.design.designer.beans.actions.MoveDownAction;
import com.fr.design.designer.beans.actions.MoveToBottomAction;
import com.fr.design.designer.beans.actions.MoveToTopAction;
import com.fr.design.designer.beans.actions.MoveUpAction;
import com.fr.design.designer.beans.actions.PasteAction;
import com.fr.design.designer.beans.adapters.component.CompositeComponentAdapter;
import com.fr.design.designer.beans.adapters.layout.DefaultDesignerBaseOperate;
import com.fr.design.designer.beans.adapters.layout.DesignerBaseOperate;
import com.fr.design.designer.beans.adapters.layout.FRParameterLayoutAdapter;
import com.fr.design.designer.beans.events.AddingWidgetListenerTable;
import com.fr.design.designer.beans.events.CreatorEventListenerTable;
import com.fr.design.designer.beans.events.DesignerEditListener;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.beans.location.Direction;
import com.fr.design.designer.beans.location.Location;
import com.fr.design.designer.beans.location.RootResizeDirection;
import com.fr.design.designer.beans.models.AddingModel;
import com.fr.design.designer.beans.models.DraggingModel;
import com.fr.design.designer.beans.models.ModelUtil;
import com.fr.design.designer.beans.models.SelectionModel;
import com.fr.design.designer.beans.models.StateModel;
import com.fr.design.designer.creator.XChartEditor;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWAbsoluteBodyLayout;
import com.fr.design.designer.creator.XWAbsoluteLayout;
import com.fr.design.designer.creator.XWBorderLayout;
import com.fr.design.designer.creator.XWFitLayout;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
import com.fr.design.designer.properties.FormWidgetAuthorityEditPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.event.DesignerOpenedListener;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.fun.RightSelectionHandlerProvider;
import com.fr.design.mainframe.chart.info.ChartInfoCollector;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef;
import com.fr.design.mod.bean.ChangeItem;
import com.fr.design.mod.bean.ContentChangeItem;
import com.fr.design.mod.event.TableDataModifyEvent;
import com.fr.design.parameter.ParaDefinitePane;
import com.fr.design.parameter.ParameterPropertyPane;
import com.fr.design.roleAuthority.RolesAlreadyEditedPane;
import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.event.EventDispatcher;
import com.fr.form.FormElementCaseContainerProvider;
import com.fr.form.FormElementCaseProvider;
import com.fr.form.main.Form;
import com.fr.form.parameter.FormSubmitButton;
import com.fr.form.share.SharableWidgetProvider;
import com.fr.form.share.ShareLoader;
import com.fr.form.share.editor.SharableEditorProvider;
import com.fr.form.ui.EditorHolder;
import com.fr.form.ui.PaddingMargin;
import com.fr.form.ui.Widget;
import com.fr.form.ui.WidgetValue;
import com.fr.form.ui.container.WBorderLayout;
import com.fr.form.ui.container.WFitLayout;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRLogger;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.bridge.StableFactory;
import com.fr.third.javax.annotation.Nullable;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import javax.swing.border.Border;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 设计界面组件。该组件是界面设计工具的核心,主要负责的是被设计界面的显示,界面设计操作状态的 显示,编辑状态的显示等等。
*/
public class FormDesigner extends TargetComponent<Form> implements TreeSelectionListener, InvocationHandler, BaseFormDesigner, ParaDefinitePane {
protected static final ArrayList<String> NAME_ARRAY_LIST = new ArrayList<String>(
Arrays.asList(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Cut"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Copy"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_M_Edit_Delete")})
);
protected static final ArrayList<String> PARAMETER_TOOLAR_BAN_LIST = new ArrayList<String>(
Arrays.asList(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Cut"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Copy")})
);
private double scale = 1.0D;
//底层容器的默认大小
protected static final Dimension LARGE_PREFERRED_SIZE = new Dimension(WBorderLayout.DEFAULT_WIDTH, WBorderLayout.DEFAULT_HEIGHT);
private int paraHeight = 0;
/**
* 当前正在设计的组件树的根节点。目前只支持JPanel作为根节点。可以很容易的修改使其支持其他
* 容器。被设计的组件其name属性都不为空,其值为该组件的变量名称。
*/
private XLayoutContainer rootComponent;
private XLayoutContainer paraComponent;
private boolean drawLineMode;
private FormArea formArea;
private ConnectorHelper connectorHelper;
private boolean isReportBlockEditing = false;
private TopXCreators topXCreators;
private FormSpacingLineDrawer spacingLineDrawer;
//组件重叠
private boolean isWidgetsIntersect = false;
/**
* 下面的变量都是非序列化成员,不记录设计状态,只作为设计时临时状态使用。
*/
// 编辑状态时鼠标处理器
private transient EditingMouseListener editingMouseListener;
// 编辑状态下的model,存储编辑状态下的临时状态,比如拖拽区域、鼠标热点等等
private transient StateModel stateModel;
// 添加状态下的model,存储添加状态下的临时状态,比如要添加的组件、当前鼠标位置等等
private transient AddingModel addingModel;
private transient DraggingModel draggingModel;
// 当前负责额外渲染的painter,主要目的用来渲染添加组件的位置提示,它通常由外部类设置,在
// 设计器渲染时被调用渲染这些位置提示。
private transient Painter painter;
// 存储被选择组件和剪切板的model
private transient SelectionModel selectionModel;
// 编辑状态的事件表
private CreatorEventListenerTable edit;
protected List<UpdateAction> designerActions;
protected List<UpdateAction> basicActions;
private FormDesignerModeForSpecial<?> desigerMode;
private Action switchAction;
private FormElementCaseContainerProvider elementCaseContainer;
private Parameter[] parameterArray;
//控制添加参数位置
private int currentIndex;
private static final int NUM_IN_A_LINE = 4;
private static final int H_COMPONENT_GAP = 165;
private static final int V_COMPONENT_GAP = 25;
private static final int FIRST_V_LOCATION = 35;
private static final int FIRST_H_LOCATION = 90;
private static final int SECOND_H_LOCATION = 170;
private static final int ADD_HEIGHT = 20;
private static final int H_GAP = 105;
private static final int SUBMIT_BUTTON_H_LOCATION = 270;
private AddingWidgetListenerTable addingWidgetListeners;
public FormDesigner(Form form) {
this(form, null);
}
public FormDesigner(Form form, Action switchAction) {
super(form);
setDoubleBuffered(true);
// 为了处理键盘事件,需要FormDesigner能够获取焦点
setFocusable(true);
setFocusTraversalKeysEnabled(false);
this.setOpaque(true);
this.setBackground(Color.WHITE);
// 初始化
edit = new CreatorEventListenerTable();
addingWidgetListeners = new AddingWidgetListenerTable();
selectionModel = new SelectionModel(this);
stateModel = new StateModel(this);
desigerMode = createFormDesignerTargetMode();
updateUI();// 初始化界面设计工具的UI实例
refreshRoot();// 初始化缺省的设计组件
initializeListener();// 初始化事件处理器
new FormDesignerDropTarget(this);// 添加Drag and Drop.
this.switchAction = switchAction;
topXCreators=new TopXCreators(this);
topXCreators.setVisible(true);
// 必须刷新"参数/控件树"面板,否则,若最近一次打开模版为 cpt,重启设计器,打开 frm,控件树消失
populateParameterPropertyPane();
spacingLineDrawer = new FormSpacingLineDrawer(this);
clearDropTarget();
}
public void paintBorder(Graphics g){
//不绘制designer的边框
}
/**
* 刷新控件树面板
*/
public void populateParameterPropertyPane() {
//参数
setParameterArray(DesignModelAdapter.getCurrentModelAdapter().getParameters());
refreshParameter();
//容器
ParameterPropertyPane.getInstance().populateBean(this);
}
public Parameter[] getNoRepeatParas(Parameter[] paras) {
List<Parameter> paraList = new ArrayList<Parameter>();
Set set = new java.util.HashSet();
for (Parameter p : paras) {
if (!set.contains(p.getName().toLowerCase())) {
paraList.add(p);
set.add(p.getName().toLowerCase());
}
}
return paraList.toArray(new Parameter[paraList.size()]);
}
public void setParameterArray(Parameter[] ps) {
parameterArray = ps;
}
public Parameter[] getParameterArray() {
return parameterArray;
}
/**
* 刷新参数
*/
public void refreshParameter() {
XLayoutContainer rootContainer = this.getParaComponent();
if (rootContainer != null) {
List<String> namelist = new ArrayList<String>();
rootContainer.getAllXCreatorNameList(rootContainer, namelist);
// parameterArray是报表的所有参数, nameList是已经在参数面板添加过控件的参数名
// 与已有的参数列表比较 如果已经存在 就除去
Parameter[] ps = getParameterArray();
if (ps != null) {
removeSame(ps, namelist);
}
}
ParameterPropertyPane.getInstance().getParameterToolbarPane().populateBean(
getParameterArray() == null ? new Parameter[0] : getParameterArray());
ParameterPropertyPane.getInstance(this).repaintContainer(); // 传入this的同时会更新参数面板高度
}
private void removeSame(Parameter[] parameters, List<String> namelist) {
for (Parameter parameter : parameters) {
for (String name : namelist) {
if (name.equalsIgnoreCase(parameter.getName())) {
setParameterArray((Parameter[]) ArrayUtils.removeElement(getParameterArray(), parameter));
}
}
}
}
/**
* 是否有查询按钮
*
* @return 有无查询按钮
*/
public boolean isWithQueryButton() {
XLayoutContainer rootContainer = this.getParaComponent();
return rootContainer != null && rootContainer.SearchQueryCreators(rootContainer);
}
/**
* 加入参数到参数面板
*
* @param parameter 参数
* @return 是否加入
*/
public void addingParameter2Editor(Parameter parameter) {
if (getParaComponent() == null) {
addParaPaneTooltips();
return;
}
com.fr.form.ui.Label label = new com.fr.form.ui.Label();
String name = parameter.getName();
label.setWidgetName("Label" + name);
label.setWidgetValue(new WidgetValue(name + ":"));
XCreator xLabel = XCreatorUtils.createXCreator(label);
EditorHolder editor = new EditorHolder(parameter);
XCreator xCreator = XCreatorUtils.createXCreator(editor);
if (!(this.autoAddComponent(xLabel, H_COMPONENT_GAP * (currentIndex % NUM_IN_A_LINE)
+ FIRST_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP * (currentIndex / NUM_IN_A_LINE)))) {
return;
}
if (!(this.autoAddComponent(xCreator, H_COMPONENT_GAP * (currentIndex % NUM_IN_A_LINE)
+ SECOND_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP * (currentIndex / NUM_IN_A_LINE)))) {
return;
}
currentIndex++;
parameterArray = (Parameter[]) ArrayUtils.removeElement(parameterArray, parameter);
refreshParameter();
fireTargetModified();
}
/**
* 加入参数到参数面板,有查询按钮
*
* @param parameter 参数
* @return 是否加入
*/
public void addingParameter2EditorWithQueryButton(Parameter parameter) {
if (getParaComponent() == null) {
addParaPaneTooltips();
return;
}
com.fr.form.ui.Label label = new com.fr.form.ui.Label();
String name = parameter.getName();
label.setWidgetName("Label" + name);
label.setWidgetValue(new WidgetValue(name + ":"));
XCreator xLabel = XCreatorUtils.createXCreator(label);
EditorHolder editor = new EditorHolder(parameter);
editor.setWidgetName(name);
XCreator xCreator = XCreatorUtils.createXCreator(editor);
if (!(this.autoAddComponent(xLabel, FIRST_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP
* (currentIndex / NUM_IN_A_LINE)))) {
return;
}
if (!(this.autoAddComponent(xCreator, SECOND_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP
* (currentIndex / NUM_IN_A_LINE)))) {
return;
}
FormSubmitButton formSubmitButton = new FormSubmitButton();
formSubmitButton.setWidgetName("Search");
formSubmitButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Query"));
xCreator = XCreatorUtils.createXCreator(formSubmitButton);
if (!(this.autoAddComponent(xCreator, SUBMIT_BUTTON_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP
* (currentIndex / NUM_IN_A_LINE)))) {
return;
}
currentIndex = currentIndex + NUM_IN_A_LINE - currentIndex % NUM_IN_A_LINE;
parameterArray = (Parameter[]) ArrayUtils.removeElement(parameterArray, parameter);
refreshParameter();
fireTargetModified();
}
/**
* 一键添加所有参数
*/
public void addingAllParameter2Editor() {
if (getParaComponent() == null) {
addParaPaneTooltips();
return;
}
if (parameterArray == null) {
return;
}
for (int i = 0; i < parameterArray.length; i++) {
com.fr.form.ui.Label label = new com.fr.form.ui.Label();
label.setWidgetName("Label" + parameterArray[i].getName());
label.setWidgetValue(new WidgetValue(parameterArray[i].getName() + ":"));
XCreator xLabel = XCreatorUtils.createXCreator(label);
// 每行显示5组
EditorHolder editor = new EditorHolder(parameterArray[i]);
editor.setWidgetName(parameterArray[i].getName());
XCreator xCreator = XCreatorUtils.createXCreator(editor);
if (!(this.autoAddComponent(xLabel, H_COMPONENT_GAP * (currentIndex % NUM_IN_A_LINE)
+ FIRST_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP * (currentIndex / NUM_IN_A_LINE)))) {
break;
}
if (!(this.autoAddComponent(xCreator, H_COMPONENT_GAP * (currentIndex % NUM_IN_A_LINE)
+ SECOND_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP * (currentIndex / NUM_IN_A_LINE)))) {
break;
}
currentIndex++;
}
if (!isWithQueryButton()) {
FormSubmitButton formSubmitButton = new FormSubmitButton();
formSubmitButton.setWidgetName("Search");
formSubmitButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Query"));
XCreator xCreator = XCreatorUtils.createXCreator(formSubmitButton);
if (!(this.autoAddComponent(xCreator, H_COMPONENT_GAP * 3 + H_GAP, FIRST_V_LOCATION
+ V_COMPONENT_GAP * (currentIndex / NUM_IN_A_LINE)))) {
return;
}
}
parameterArray = null;
//parameter多的时候,不刷新会出现控件边界交叉
refreshRoot();
// 最后刷新"添加参数面板"和控件树
refreshParameter();
}
private void addParaPaneTooltips() {
FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Please_Drag_ParaPane"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
}
public void paintChildren(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
AffineTransform old = g2d.getTransform();
AffineTransform at = new AffineTransform();
at.translate(this.getPaintX(), this.getPaintY());
at.scale(this.getScale(), this.getScale());
g2d.transform(at);
super.paintChildren(g);
g2d.setTransform(old);
}
/**
* 自动添加组件
*
* @param xCreator 组件
* @param x 横坐标
* @param y 纵坐标
* @return 是否添加成功
*/
public boolean autoAddComponent(XCreator xCreator, int x, int y) {
XWParameterLayout layout = (XWParameterLayout) this.getParaComponent();
FRParameterLayoutAdapter adapter = (FRParameterLayoutAdapter) layout.getLayoutAdapter();
if (prepareForAdd(xCreator, x, y, layout)) {
adapter.addBean(xCreator, x, y);
}
this.getSelectionModel().setSelectedCreator(xCreator);
repaint();
return true;
}
/**
* 在参数很多时,全部添加的时候,可以向下一次排版,若去掉就会在参数面板堆到一起
*
* @param creator 组件
* @param x 长度
* @param y 长度
* @param layout 布局
* @return 是否扩展
*/
public boolean prepareForAdd(XCreator creator, int x, int y, XWParameterLayout layout) {
// 参数界面,自动扩展
Dimension size = layout.getSize();
Boolean needResize = false;
if (creator.getWidth() / 2 + x > layout.getWidth()) {
size.width = creator.getWidth() / 2 + x + ADD_HEIGHT;
needResize = true;
}
if (creator.getHeight() / 2 + y > layout.getHeight()) {
size.height = creator.getHeight() / 2 + y + ADD_HEIGHT;
needResize = true;
}
if (needResize) {
layout.setSize(size);
setParaHeight(size.height);
}
return true;
}
/**
* 加入参数面板
*/
public void addParaComponent() {
if (paraComponent != null) {
return;
}
paraHeight = WBorderLayout.DEFAULT_SIZE;
paraComponent = new XWParameterLayout();
paraComponent.toData().setWidgetName("para");
paraComponent.setSize(paraComponent.initEditorSize());
XWBorderLayout formLayoutContainer = (XWBorderLayout) rootComponent.getParent();
formLayoutContainer.toData().setNorthSize(paraHeight);
formLayoutContainer.add(paraComponent, WBorderLayout.NORTH);
//设下northSize,增加para后,重置border大小,这时候para和root的大小会自适应调整
formLayoutContainer.setSize(formLayoutContainer.getWidth(), formLayoutContainer.getHeight() + paraHeight);
selectionModel.reset();
selectionModel.setSelectedCreator(paraComponent);
invalidateLayout();
populateParameterPropertyPane();
}
/**
* 返回根节点父容器
*
* @return 父容器
*/
public Component getTopContainer() {
if (rootComponent != null) {
// 返回root所在的父容器,非designer
return LayoutUtils.getTopContainer(rootComponent);
}
return XCreatorUtils.createXCreator(this.getTarget().getContainer());
}
/**
* 返回参数界面高度
*
* @return para高度
*/
public int getParaHeight() {
return paraHeight;
}
/**
* 重置para的高度
*
* @param height 高度
*/
public void setParaHeight(int height) {
XWBorderLayout container = (XWBorderLayout) getTopContainer();
container.toData().setNorthSize(height);
container.setSize(container.getWidth(), container.getHeight() + height - getParaHeight());
paraHeight = height;
}
/**
* 删除参数界面
*/
public void removeParaComponent() {
XWBorderLayout formLayoutContainer = (XWBorderLayout) getTopContainer();
formLayoutContainer.toData().removeWidget(paraComponent.toData());
paraHeight = 0;
paraComponent = null;
formLayoutContainer.setSize(rootComponent.getWidth(), rootComponent.getHeight());
//atat
//EastRegionContainerPane.getInstance().addTitlePane(ParameterPropertyPane.getInstance(FormDesigner.this));
//删除后重绘下
invalidateLayout();
}
/**
* 切换
*
* @param elementCaseContainer 容器
*/
public void switchTab(FormElementCaseContainerProvider elementCaseContainer) {
if (this.switchAction == null) {
return;
}
this.elementCaseContainer = elementCaseContainer;
this.switchAction.actionPerformed(null);
}
public void setElementCaseContainer(FormElementCaseContainerProvider elementCaseContainer) {
this.elementCaseContainer = elementCaseContainer;
}
public FormElementCaseProvider getElementCase() {
return this.elementCaseContainer.getElementCase();
}
public String getElementCaseContainerName() {
return this.elementCaseContainer.getElementCaseContainerName();
}
public void setElementCase(FormElementCaseProvider elementCase) {
this.elementCaseContainer.setElementCase(elementCase);
}
public void setElementCaseBackground(BufferedImage image) {
this.elementCaseContainer.setBackground(image);
}
public Dimension getElementCaseContainerSize() {
return this.elementCaseContainer.getSize();
}
public FormElementCaseContainerProvider getElementCaseContainer() {
return this.elementCaseContainer;
}
protected FormDesignerModeForSpecial<?> createFormDesignerTargetMode() {
return new FormTargetMode(this);
}
public FormDesignerModeForSpecial<?> getDesignerMode() {
return this.desigerMode;
}
public CreatorEventListenerTable getEditListenerTable() {
return edit;
}
public AddingWidgetListenerTable getAddingWidgetListeners() {
return addingWidgetListeners;
}
/**
* 增加监听事件
*
* @param listener 界面组件编辑事件
*/
public void addDesignerEditListener(DesignerEditListener listener) {
getEditListenerTable().addListener(listener);
}
/**
* 取消格式
*/
public void cancelFormat() {
return;
}
/**
* 表单则判断参数面板是否为绝对布局
*
* @return 是则返回true
*/
public boolean hasWAbsoluteLayout() {
if (paraComponent != null && paraComponent.acceptType(XWParameterLayout.class)) {
return true;
} else {
XCreator creator = this.getSelectionModel().getSelection().getSelectedCreator();
if (creator != null && creator.getParent() != null
&& ((XLayoutContainer) creator.getParent()).acceptType(XWAbsoluteLayout.class)) {
return true;
}
}
return false;
}
/**
* 设置是否为报表块编辑
*
* @param isEditing 是否为报表块编辑
*/
public void setReportBlockEditing(boolean isEditing) {
this.isReportBlockEditing = isEditing;
}
/**
* 是否为报表块编辑
*
* @return 是否为报表块编辑
*/
public boolean isReportBlockEditing() {
return this.isReportBlockEditing;
}
public void setWidgetsIntersect(boolean isWidgetsIntersect) {
this.isWidgetsIntersect = isWidgetsIntersect;
}
public boolean isWidgetsIntersect() {
return this.isWidgetsIntersect;
}
/**
* 是否重命名控件
*
* @param creator 组件
* @param newName 新的组件名
* @return 组件名有变化,且不和其他一样返回true
*/
public boolean renameCreator(XCreator creator, String newName) {
if (ComparatorUtils.equals(creator.toData().getWidgetName(), newName)) {
return false;
}
if (this.getTarget().isNameExist(newName)) {
FineJOptionPane.showMessageDialog(this, "\"" + newName + "\"" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Utils_Has_Been_Existed")
+ "!", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE);
return false;
}
creator.resetCreatorName(newName);
getEditListenerTable().fireCreatorModified(creator, DesignerEvent.CREATOR_EDITED);
return true;
}
public void showMessageDialog(String message) {
FineJOptionPane.showMessageDialog(this, message, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE);
FormSelectionUtils.rebuildSelection(this);
repaint();
}
/**
* 保存参数界面的宽度
*
* @param width 指定的宽度
*/
public void updateWidth(int width) {
//TODO
}
/**
* 更新界面布局,重绘
*
* @param proxy 动态代理类
* @param method 接口方法
* @param args 参数
* @return 不返回任何对象
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (rootComponent != null) {
LayoutUtils.layoutRootContainer(rootComponent);
}
if (paraComponent != null) {
LayoutUtils.layoutRootContainer(paraComponent);
}
repaint();
return null;
}
/**
* 初始化事件处理器,初始状态为编辑状态,所以下初始化并添加编辑类的事件处理器
*/
private void initializeListener() {
addKeyListener(new FormEditorKeyListener(this));
// 点击
editingMouseListener = new EditingMouseListener(this);
addMouseMotionListener(editingMouseListener);
addMouseListener(editingMouseListener);
addInvocationHandler(this);
getEditListenerTable().addListener(new DesignerEditListener() {
@Override
public void fireCreatorModified(DesignerEvent evt) {
// 只有选择组件时不触发模版更新,其他都要触发
if (evt.getCreatorEventID() != DesignerEvent.CREATOR_SELECTED) {
FormDesigner.this.fireTargetModified();
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_DELETED) {
setParameterArray(getNoRepeatParas(DesignModelAdapter.getCurrentModelAdapter().getParameters()));
refreshParameter();
}
} else {
for (UpdateAction action : getActions()) {
action.update();
}
}
}
});
DesignerContext.getDesignerFrame().addDesignerOpenedListener(new DesignerOpenedListener() {
@Override
public void designerOpened() {
setToolbarButtons();
}
});
}
/**
* 增加组件事件
*
* @param h 动态代理
*/
public void addInvocationHandler(InvocationHandler h) {
ClassLoader loader = getClass().getClassLoader();
Class[] interfaces = new Class[]{DesignerEditListener.class};
Object proxyListener = Proxy.newProxyInstance(loader, interfaces, h);
addDesignerEditListener((DesignerEditListener) proxyListener);
addDesignerEditListener(new FormWidgetAuthorityEditAdapter());
}
/**
* 停止添加模式、返回编辑模式
*/
public void stopAddingState() {
// 恢复为空,UI类根据addingModel是否空决定是否停止渲染要添加的组件
addingModel = null;
painter = null;
// DropTarget依然是addingMouseListener,改成这个,数据源拖拽用
new FormDesignerDropTarget(this);
// 触发停止添加模式的事件
repaint();
}
/**
* 停止拖拽
*/
public void stopDragging() {
draggingModel = null;
}
public void clearDropTarget() {
this.setDropTarget(null);
}
/**
* 更新拖拽model的位置
*/
public void updateDraggingPosition(int x, int y) {
if (draggingModel != null) {
draggingModel.moveTo(x, y);
}
}
/**
* 重置拖拽model的位置
*/
public void resetDraggingPosition() {
if (draggingModel != null) {
draggingModel.reset();
}
}
/**
* 设置其UI类为DesignerUI,负责渲染
*/
@Override
public void updateUI() {
setUI(new FormDesignerUI());
}
/**
* 在拖拽区域选择方式鼠标释放时调用此函数来更新所选择的组件
*
* @param e 当前鼠标事件,用来和起始点构成选择框,计算被圈入的组件
*/
public void selectComponents(MouseEvent e) {
// 调用stateModel的selectComponent更新被选择的组件,stateModel定义了拖拽起始点
stateModel.selectCreators(e);
// 清除stateModel为非拖拽状态
stateModel.reset();
repaint();
}
/**
* 从root组件递归查找x,y所在的组件,注意是正在被设计的组件,因此其name属性必须不为空
*/
private XCreator xCreatorAt(int x, int y, XCreator root, XCreator[] except) {
if (root == null || !root.isVisible()) {
return null;
}
x -= root.getX();
y -= root.getY();
if (root instanceof XLayoutContainer) {
XLayoutContainer rootContainer = (XLayoutContainer) root;
int count = rootContainer.getXCreatorCount();
for (int i = 0; i < count; i++) {
XCreator child = rootContainer.getXCreator(i);
if (ArrayUtils.contains(except, child)) {
continue;
}
// 只有name不为空的组件才是搜索范围,这儿递归下溯调用
XCreator dest = xCreatorAt(x, y, child, except);
if (dest != null && !ArrayUtils.contains(except, child)) {
return dest;
}
}
}
Rectangle rect = ComponentUtils.computeVisibleRect(root);
if (isIntersectArea(x, y, rect)) {
// 判断是否处于交叉区域
return root;
}
return null;
}
/**
* 从root里面查找层级为level的控件
*/
private XCreator xCreatorAt(int x, int y, XCreator root, int level) {
if (root == null || !root.isVisible()) {
return null;
}
x -= root.getX();
y -= root.getY();
if (root instanceof XLayoutContainer) {
XLayoutContainer rootContainer = (XLayoutContainer) root;
int count = rootContainer.getXCreatorCount();
for (int i = 0; i < count; i++) {
XCreator child = rootContainer.getXCreator(i);
XCreator dest = xCreatorAt(x, y, child, level);
if (dest != null && dest.getLevel() == level) {
return dest;
}
}
}
Rectangle rect = ComponentUtils.computeVisibleRect(root);
if (isIntersectArea(x, y, rect)) {
// 判断是否处于交叉区域
return root;
}
return null;
}
/**
* 从已选择的组件中找x,y所在的组件
*/
private XCreator xCreatorAt(int x, int y, XCreator root) {
XCreator[] xCreators = selectionModel.getSelection().getSelectedCreators();
for (XCreator creator : xCreators) {
boolean shouldContinue = creator == null
|| !creator.isVisible()
|| !XCreatorUtils.containComponent(root, creator);
if (shouldContinue) {
continue;
}
//获取当前组件父组件相对于rootComponent或者paraComponent的距离
int relativeParentX = getRelativeParentX(creator.getParent());
int relativeParentY = getRelativeParentY(creator.getParent());
//如果不是布局容器,直接进行对比
if (!(creator instanceof XLayoutContainer)) {
int newX = x - relativeParentX - creator.getX();
int newY = y - relativeParentY - creator.getY();
Rectangle rect = ComponentUtils.computeVisibleRect(creator);
// 判断是否处于交叉区域
if (isIntersectArea(newX, newY, rect)) {
return creator;
}
}
//如果是布局容器,从布局容器向下找
if (creator instanceof XLayoutContainer) {
XCreator result = xCreatorAt(x - relativeParentX, y - relativeParentY, creator, null);
if (result != null) {
return result;
}
}
//最后,如果组件为Tab容器中的子组件,再从Tab容器中去找
XWCardMainBorderLayout borderLayout = XCreatorUtils.getTopXMainBorderLayout(creator);
if (borderLayout != null) {
relativeParentX = getRelativeParentX(borderLayout.getParent());
relativeParentY = getRelativeParentY(borderLayout.getParent());
return xCreatorAt(x - relativeParentX, y - relativeParentY, borderLayout, null);
}
}
return null;
}
/**
* 获取当前组件相对于rootComponent或者paraComponent的横向距离
*/
private int getRelativeParentX(Container container) {
return returnZero(container) ? 0 : container.getX() + getRelativeParentX(container.getParent());
}
/**
* 获取当前组件相对于rootComponent或者paraComponent的纵向距离
*/
private int getRelativeParentY(Container container) {
return returnZero(container) ? 0 : container.getY() + getRelativeParentY(container.getParent());
}
private boolean returnZero(Container container) {
return !(container instanceof XLayoutContainer)
|| container == rootComponent
|| (paraComponent != null && container == paraComponent);
}
/**
* 刷新顶层组件
* */
public void refreshTopXCreator(boolean isEditing){
topXCreators.refresh();
topXCreators.setVisible(!isEditing);
}
private boolean isIntersectArea(int x, int y, Rectangle rect) {
return x >= rect.getX() && (x <= (rect.getX() + rect.getWidth())) && (y >= rect.getY())
&& (y <= (rect.getY() + rect.getHeight()));
}
/**
* 更新边框线状态
*
* @param e 鼠标事件
*/
public void updateDrawLineMode(MouseEvent e) {
Point p = connectorHelper.getNearWidgetPoint(e);
if (p == null && getComponentAt(e) == rootComponent) {
p = new Point(e.getX() + formArea.getHorizontalValue(), e.getY() + formArea.getVerticalValue());
}
stateModel.startDrawLine(p);
}
/**
* 刷新底层容器
*/
public void refreshRoot() {
// 撤销恢复操作都会refreshRoot,这时候的target.getContainer里的widget会和之前不一样,所以不用root判断来取
XLayoutContainer formLayoutContainer = (XLayoutContainer) XCreatorUtils.createXCreator(this.getTarget().getContainer());
// 布局默认都是1,底层的border改为0,不然没意义
this.getTarget().getContainer().setMargin(new PaddingMargin(0, 0, 0, 0));
formLayoutContainer.setBorder(null);
if (formLayoutContainer.acceptType(XWBorderLayout.class)) {
WBorderLayout borderLayout = (WBorderLayout) formLayoutContainer.toData();
Widget northWidget = borderLayout.getLayoutWidget(WBorderLayout.NORTH);
Widget centerWidget = borderLayout.getLayoutWidget(WBorderLayout.CENTER);
//本身含有,这儿得先清空再加
formLayoutContainer.removeAll();
refreshNorth(northWidget, formLayoutContainer);
refreshCenter(centerWidget, formLayoutContainer);
} else {
formLayoutContainer.setSize(LARGE_PREFERRED_SIZE);
setRootComponent(formLayoutContainer);
}
}
private void refreshNorth(Widget northWidget, XLayoutContainer formLayoutContainer) {
// 如果没有参数界面, 那么就处理下高度以及参数界面的按钮要点亮
if (northWidget == null) {
paraComponent = null;
paraHeight = 0;
FormParaWidgetPane.getInstance(this);
return;
}
XLayoutContainer northContainer = (XLayoutContainer) XCreatorUtils.createXCreator(northWidget);
paraHeight = ((XWBorderLayout) formLayoutContainer).toData().getNorthSize();
paraComponent = northContainer;
northContainer.setSize(0, paraHeight);
formLayoutContainer.add(northContainer, WBorderLayout.NORTH);
}
private void refreshCenter(Widget centerWidget, XLayoutContainer formLayoutContainer) {
XLayoutContainer centerContainer = (XLayoutContainer) XCreatorUtils.createXCreator(centerWidget);
Dimension d = new Dimension();
d.width = ((WFitLayout) centerWidget).getContainerWidth();
d.height = ((WFitLayout) centerWidget).getContainerHeight();
centerContainer.setSize(d);
formLayoutContainer.setSize(d.width, d.height + paraHeight);
setRootComponent(centerContainer);
// 再次打开时,layout下root,有内边距的话组件加上
LayoutUtils.layoutContainer(centerContainer);
formLayoutContainer.add(rootComponent, WBorderLayout.CENTER);
}
protected Insets getOutlineInsets() {
return new Insets(10, 10, 10, 10);
}
public Painter getPainter() {
return painter;
}
public void setPainter(Painter p) {
painter = p;
}
public XLayoutContainer getRootComponent() {
return rootComponent;
}
public XLayoutContainer getParaComponent() {
return paraComponent;
}
/**
* 是否是报表的参数面板
*
* @return 否(表单的)
*/
public boolean isFormParaDesigner() {
return false;
}
/**
* 是否为底层容器
*
* @param comp 组件
* @return 是则返回true
*/
public boolean isRoot(XCreator comp) {
return comp != null && (comp == rootComponent || comp.acceptType(XWAbsoluteBodyLayout.class));
}
// 计算鼠标事件e所发生的位置相对根组件的位置关系
public Direction getLoc2Root(MouseEvent e) {
int x = e.getX() + formArea.getHorizontalValue();
int y = e.getY() + formArea.getVerticalValue();
int width = rootComponent.getWidth();
int height = rootComponent.getHeight();
Insets insets = getOutlineInsets();
if (x < width) {
if ((y >= height) && (y <= (height + insets.bottom))) {
return RootResizeDirection.BOTTOM_RESIZE;
} else {
return Location.outer;
}
} else if (x <= (width + insets.right)) {
if ((y >= 0) && (y < height)) {
return RootResizeDirection.RIGHT_RESIZE;
} else if ((y >= height) && (y <= (height + insets.bottom))) {
return RootResizeDirection.RIGHT_BOTTOM_RESIZE;
} else {
return Location.outer;
}
} else {
return Location.outer;
}
}
protected void setRootComponent(XLayoutContainer component) {
this.rootComponent = component;
component.setOpaque(true);
component.setBackground(XCreatorConstants.FORM_BG);
selectionModel.reset();
// 默认还是选中RootPane吧
selectionModel.setSelectedCreator(rootComponent);
invalidateLayout();
}
public TopXCreators getTopXCreators() {
return topXCreators;
}
public StateModel getStateModel() {
return stateModel;
}
public AddingModel getAddingModel() {
return addingModel;
}
public DraggingModel getDraggingModel() {
return draggingModel;
}
public XCreator getComponentAt(MouseEvent e) {
return getComponentAt(e.getX(), e.getY());
}
@Override
public XCreator getComponentAt(Point p) {
return getComponentAt(p.x, p.y);
}
/**
* 先从已选择则的组件中去找,再遍历root去找
* */
@Override
public XCreator getComponentAt(int x, int y) {
XLayoutContainer container = getRootContainer(y);
XCreator result = xCreatorAt(getRelativeScaleX(x) - container.getX(), getRelativeScaleY(y) - container.getY(), container);
return result == null ? getComponentAt(x, y, null) : result;
}
@Nullable
public XCreator getComponentAt(int x, int y, XCreator[] except) {
XLayoutContainer container = getRootContainer(y);
XCreator comp = xCreatorAt(getRelativeScaleX(x), getRelativeScaleY(y), container, except);
return comp == null ? container : comp;
}
public XCreator getComponentAt(int x, int y, int level) {
XLayoutContainer container = getRootContainer(y);
XCreator comp = xCreatorAt(getRelativeScaleX(x), getRelativeScaleY(y), container, level);
return comp == null ? container : comp;
}
public XLayoutContainer getRootContainer(int y) {
XLayoutContainer container = y < paraHeight - formArea.getVerticalValue() ? paraComponent : rootComponent;
if (container == null) {
container = rootComponent;
}
return container;
}
private int getRelativeScaleX(int x) {
return x + (int)(formArea.getHorizontalValue() / scale);
}
private int getRelativeScaleY(int y) {
return y + (int)(formArea.getVerticalValue() / scale);
}
public SelectionModel getSelectionModel() {
if (paraComponent != null) {
paraComponent.setSize(paraComponent.getWidth(), getParaHeight());
Rectangle rec = rootComponent.getBounds();
rootComponent.setBounds(rec.x, getParaHeight(), rec.width, rec.height);
}
return selectionModel;
}
/**
* 移除选中状态
*/
public void removeSelection() {
selectionModel.reset();
this.repaint();
}
/**
* 拖入新的组件
*
* @param xCreator
* @param startDragEvent
* @param currentDragEvent
*/
public void startDraggingNewWidget(XCreator xCreator, MouseEvent startDragEvent, MouseEvent currentDragEvent) {
if (currentDragEvent == null) {
return;
}
instantiateCreator(xCreator);
draggingModel = new DraggingModel()
.designer(this)
.creator(xCreator)
.startDragEvent(startDragEvent)
.currentDragEvent(currentDragEvent);
this.setDropTarget(new FormCreatorDropTarget(this, xCreator));
repaint();
}
/**
* 拖拽表单上的组件
*
* @param xCreator
* @param startDragEvent
* @param currentDragEvent
*/
public void startDraggingFormWidget(XCreator xCreator, MouseEvent startDragEvent, MouseEvent currentDragEvent) {
if (currentDragEvent == null) {
return;
}
backUpCreator(xCreator);
draggingModel = new DraggingModel()
.designer(this)
.creator(xCreator)
.startDragEvent(startDragEvent)
.currentDragEvent(currentDragEvent);
XLayoutContainer container = this.getDraggingHotspotLayout();
LayoutAdapter adapter = container.getLayoutAdapter();
adapter.dragging(this.getDraggingModel());
repaint();
}
/**
* 绑定transferHandler,貌似这边用的还是低级的DND方式绑定的鼠标手势,高级的可参考ToolBarButton那边,"rootComponent"常量是
* 从原来的DesignerTransferHandler里面直接搬来的,目前意义还不明确
*
* @param e
*/
public void bindTransferHandler(MouseEvent e) {
TransferHandler handler = new TransferHandler("rootComponent");
this.setTransferHandler(handler);
handler.exportAsDrag(this, e, TransferHandler.COPY);
}
/**
* 触发父组件布局的dragStart事件,目前只在非固定布局下有用,用来删除占位块
*
* @param xCreator
*/
public void fireParentLayoutDragStart(XCreator xCreator) {
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(xCreator);
if (parent != null) {
parent.getLayoutAdapter().dragStart(xCreator, selectionModel);
}
}
/**
* 获取拖拽当前鼠标所在位置的布局
*
* @return
*/
public XLayoutContainer getDraggingHotspotLayout() {
DraggingModel model = this.draggingModel;
MouseEvent dragEvent = model.getCurrentDragEvent();
XCreator hotspot = this.getComponentAt(dragEvent.getX(), dragEvent.getY());
return XCreatorUtils.getHotspotContainer(hotspot);
}
/**
* 改变组件值
*
* @param e 组件选择事件
*/
@Override
public void valueChanged(TreeSelectionEvent e) {
if (DesignerContext.getDesignerFrame().getSelectedJTemplate() == null) { // 初始化完成前,不响应事件
return;
}
ComponentTree tree = (ComponentTree) e.getSource();
TreePath[] paths = tree.getSelectionPaths();
if (paths != null) {
ArrayList<XCreator> selected = new ArrayList<XCreator>();
for (TreePath path : paths) {
selected.add((XCreator) path.getLastPathComponent());
}
if (!DesignerMode.isAuthorityEditing()) {
selectionModel.setSelectedCreators(selected);
if (formArea != null) {
TreePath path = e.getNewLeadSelectionPath();
XCreator comp = (XCreator) path.getLastPathComponent();
formArea.scrollPathToVisible(comp);
}
} else {
showAuthorityEditPane();
}
//先选中再检查
setToolbarButtons();
}
}
/**
* 是否选中了自适应布局或底层form
*/
public boolean isRootSelected() {
ComponentTree tree = FormHierarchyTreePane.getInstance().getComponentTree();
TreePath[] paths = tree.getSelectionPaths();
if (paths == null) {
return true;
}
boolean isForm = paths.length == 1 && tree.getSelectionPath().getParentPath() == null;
return isForm || isRoot(getSelectionModel().getSelection().getSelectedCreator());
}
public boolean isParameterSelected() {
XCreator xCreator = getSelectionModel().getSelection().getSelectedCreator();
return xCreator != null && xCreator.acceptType(XWParameterLayout.class);
}
/**
* 显示权限编辑界面
*/
public void showAuthorityEditPane() {
HistoryTemplateListPane.getInstance().getCurrentEditingTemplate().setAuthorityMode(true);
if (isSupportAuthority()) {
AuthorityPropertyPane authorityPropertyPane = new AuthorityPropertyPane(this);
authorityPropertyPane.populate();
EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.AUTHORITY_EDITION);
EastRegionContainerPane.getInstance().replaceAuthorityEditionPane(authorityPropertyPane);
} else {
EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.AUTHORITY_EDITION_DISABLED);
EastRegionContainerPane.getInstance().replaceAuthorityEditionPane(new NoSupportAuthorityEdit());
}
EastRegionContainerPane.getInstance().replaceConfiguredRolesPane(RolesAlreadyEditedPane.getInstance());
}
/**
* 是否支持权限编辑
*
* @return 是则返回true
*/
public boolean isSupportAuthority() {
int size = getSelectionModel().getSelection().size();
XCreator creator = size == 0 ? getRootComponent() : getSelectionModel().getSelection()
.getSelectedCreator();
return !(creator instanceof XLayoutContainer) && !(creator instanceof XChartEditor);
}
protected void setToolbarButtons() {
if (isParameterSelected()) {
DesignerContext.getDesignerFrame().checkCombineUp(false, PARAMETER_TOOLAR_BAN_LIST);
}
}
private void invalidateLayout() {
Container parent = this.getArea();
if (parent != null) {
parent.doLayout();
parent.repaint();
}
}
/**
* 是否含有action名
*
* @param name action名
* @return 有则返回true
*/
public boolean isRootRelatedAction(String name) {
return NAME_ARRAY_LIST.contains(name);
}
/**
* 显示组件
*
* @param comp 组件
*/
public void makeVisible(XCreator comp) {
XCreator parent = AdapterBus.getFirstInvisibleParent(comp);
if (isRoot(parent)) {
return;
}
while (parent != null) {
XLayoutContainer parentContainer = XCreatorUtils.getParentXLayoutContainer(parent);
if (parentContainer == null) {
// parent.setVisible(true);
break;
} else {
parentContainer.getLayoutAdapter().showComponent(parent);
parent = AdapterBus.getFirstInvisibleParent(parent);
}
}
}
/**
* 刷新界面渲染容器
*/
public void refreshDesignerUI() {
LayoutUtils.layoutRootContainer(getRootComponent());
repaint();
}
/**
* 返回复制粘贴删除等动作
* 鼠标右键菜单
*
* @return 同上
*/
public UpdateAction[] getActions() {
if (designerActions == null) {
designerActions = new ArrayList<UpdateAction>(getBasicActions());
designerActions.add(new MoveToTopAction(this));
designerActions.add(new MoveToBottomAction(this));
designerActions.add(new MoveUpAction(this));
designerActions.add(new MoveDownAction(this));
dmlActions(designerActions);
}
return designerActions.toArray(new UpdateAction[designerActions.size()]);
}
private List<UpdateAction> getBasicActions(){
if (basicActions == null) {
basicActions = new ArrayList<UpdateAction>();
basicActions.add(new CutAction(this));
basicActions.add(new CopyAction(this));
basicActions.add(new PasteAction(this));
basicActions.add(new FormDeleteAction(this));
}
return basicActions;
}
public JComponent[] getBasicActionComponent() {
List<UpdateAction> actions = getBasicActions();
int size = actions.size();
JComponent[] jComponents = new JComponent[size];
for (int i = 0; i < size; i++) {
jComponents[i] = actions.get(i).createToolBarComponentByName("Global_Toolbar");
}
return jComponents;
}
/**
* 扩展菜单项
*
* @param actions
*/
public void dmlActions(List<UpdateAction> actions) {
try {
Set<RightSelectionHandlerProvider> selectionHandlerProviders = ExtraDesignClassManager.getInstance().getArray(RightSelectionHandlerProvider.XML_TAG);
for (RightSelectionHandlerProvider handler : selectionHandlerProviders) {
if (handler.accept(this)) {
handler.dmlUpdateActions(this, actions);
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private DesignerBaseOperate getLayoutBaseOperate(){
FormSelection selection = this.getSelectionModel().getSelection();
XCreator creator = selection.getSelectedCreator();
XLayoutContainer container = null;
if (creator != null) {
container = (XLayoutContainer) creator.getParent();
}
if (container == null) {
return new DefaultDesignerBaseOperate();
}
return container.getLayoutAdapter().getDesignerBaseOperate();
}
public boolean isCurrentComponentCutable() {
DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate();
return !(isRootSelected() || isParameterSelected()) && designerBaseOperate.supportCutAction();
}
public boolean isCurrentComponentCopyable() {
DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate();
return !(isRootSelected() || isParameterSelected()) && designerBaseOperate.supportCopyAction();
}
public boolean isCurrentComponentDeletable() {
DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate();
return !isRootSelected() && designerBaseOperate.supportDeleteAction();
}
public boolean isCurrentComponentPastable() {
DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate();
return designerBaseOperate.supportPasteAction();
}
// 当前选中控件可以上移一层吗?
public boolean isCurrentComponentMovableUp() {
XCreator creator = getSelectionModel().getSelection().getSelectedCreator();
if (null == creator) {
return false;
}
XLayoutContainer container = (XLayoutContainer) creator.getParent();
if (container == null || !container.supportInnerOrderChangeActions()) {
return false;
}
return creator.isMovable() && container.getComponentZOrder(creator) > 0;
}
// 当前选中控件可以下移一层吗?
public boolean isCurrentComponentMovableDown() {
XCreator creator = getSelectionModel().getSelection().getSelectedCreator();
if (null == creator) {
return false;
}
XLayoutContainer container = (XLayoutContainer) creator.getParent();
if (container == null || !container.supportInnerOrderChangeActions()) {
return false;
}
return creator.isMovable() && container.getComponentZOrder(creator) < container.getComponentCount() - 1;
}
protected Border getOuterBorder() {
return XCreatorConstants.AREA_BORDER;
}
protected Rectangle getOutlineBounds() {
Insets insets = getOuterBorder().getBorderInsets(this);
int w = rootComponent.getWidth() + insets.left + insets.right;
int h = rootComponent.getHeight() + insets.top + insets.bottom;
return new Rectangle(0, 0, w, h);
}
/**
* 同步
*/
public void populateRootSize() {
// do nothing
}
/**
* 返回表单区域
*
* @return 表单区域
*/
public FormArea getArea() {
return formArea;
}
public void switchBodyLayout(XLayoutContainer xLayoutContainer){
formArea.switchBodyLayout(xLayoutContainer);
}
/**
* 设置上层区域
*
* @param formArea 表单区域
*/
public void setParent(FormArea formArea) {
this.formArea = formArea;
}
/**
* 绘制组件根节点
*
* @param clipg 图形
*/
public void paintContent(Graphics clipg) {
rootComponent.paint(clipg);
}
public void paintPara(Graphics clipg) {
if (paraComponent != null) {
paraComponent.paint(clipg);
}
}
public void paintTopCreators(Graphics clipg){
topXCreators.paint(clipg);
}
/**
* 重置组件边界
*/
public void resetEditorComponentBounds() {
editingMouseListener.resetEditorComponentBounds();
}
/**
* 返回连线类
*
* @return ConnectorHelper类
*/
public ConnectorHelper getDrawLineHelper() {
return connectorHelper;
}
/**
* 是否画线模式
*
* @return 是则返回true
*/
public boolean isDrawLineMode() {
return this.drawLineMode;
}
/**
* 设置DrawLineMode
*
* @param mode 是or或
*/
public void setDrawLineMode(boolean mode) {
this.drawLineMode = mode;
}
/**
* 鼠标按定位置(evtX, evtY).
*
* @param evtX event x position 坐标
* @param evtY event y position 坐标
*/
public void doMousePress(double evtX, double evtY) {
dispatchEvent(new MouseEvent(this, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), 0, (int) evtX,
(int) evtY, 1, false));
}
/**
* TODO ALEX_SEP 暂时不做什么事
*/
@Override
public void stopEditing() {
// do nothing
}
public void stopEditing(TreePath path) {
// do nothing
XCreator comp = (XCreator) path.getLastPathComponent();
editingMouseListener.stopEditing();
editingMouseListener.stopEditTopLayout(comp);
XCreator selectXCreator = editingMouseListener.getSelectionModel().getSelection().getSelectedCreator();
if (selectXCreator != null && comp != null) {
if (StringUtils.equals(selectXCreator.toData().getWidgetName(), comp.toData().getWidgetName())) {
return;
}
}
editingMouseListener.getSelectionModel().reset();
editingMouseListener.getSelectionModel().selectACreator(comp);
}
/**
* 返回表单控件权限编辑pane
*
* @return 同上
*/
public AuthorityEditPane createAuthorityEditPane() {
return new FormWidgetAuthorityEditPane(this);
}
public JPanel getEastUpPane() {
return WidgetPropertyPane.getInstance(this);
}
public JPanel getEastDownPane() {
final JPanel pane = new JPanel();
if (EastRegionContainerPane.getInstance().getDownPane() == null) {
new Thread() {
public void run() {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
FRLogger.getLogger().error(e.getMessage(), e);
Thread.currentThread().interrupt();
}
pane.setLayout(new BorderLayout());
pane.add(FormWidgetDetailPane.getInstance(FormDesigner.this), BorderLayout.CENTER);
EastRegionContainerPane.getInstance().replaceConfiguredRolesPane(pane);
}
}.start();
} else {
pane.setLayout(new BorderLayout());
pane.add(FormWidgetDetailPane.getInstance(this), BorderLayout.CENTER);
EastRegionContainerPane.getInstance().replaceConfiguredRolesPane(pane);
}
return pane;
}
public ToolBarMenuDockPlus getToolBarMenuDockPlus() {
return StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, ToolBarMenuDockPlus.class);
}
/**
* 复制
*/
@Override
public void copy() {
if (DesignModeContext.isBanCopyAndCut()) {
return;
}
selectionModel.copySelectedCreator2ClipBoard();
}
/**
* 粘贴
*
* @return 否
*/
@Override
public boolean paste() {
selectionModel.pasteFromClipBoard();
return false;
}
/**
* 剪切
*
* @return 否
*/
@Override
public boolean cut() {
if (DesignModeContext.isBanCopyAndCut()) {
return false;
}
selectionModel.cutSelectedCreator2ClipBoard();
return false;
}
// ////////////////////////////////////////////////////////////////////
// ////////////////for toolbarMenuAdapter//////////////////////////////
// ////////////////////////////////////////////////////////////////////
/**
* 工具栏菜单
*
* @return 同上
*/
@Override
public MenuDef[] menus4Target() {
return new MenuDef[0];
}
public int getMenuState() {
return DesignState.JFORM;
}
/**
* 模版菜单
*
* @return 同上
*/
@Override
public ShortCut[] shortcut4TemplateMenu() {
return new ShortCut[0];
}
/**
* 权限菜单
*
* @return 同上
*/
public ShortCut[] shortCuts4Authority() {
return new ShortCut[0];
}
/**
* 返回ToolBarDef
*
* @return 同上
*/
@Override
public ToolBarDef[] toolbars4Target() {
return new ToolBarDef[0];
}
/**
* 返回工具栏按钮组件
*
* @return 同上
*/
public JComponent[] toolBarButton4Form() {
return new JComponent[]{new CutAction(this).createToolBarComponent(), new CopyAction(this).createToolBarComponent(), new PasteAction(this).createToolBarComponent(),
new FormDeleteAction(this).createToolBarComponent()};
}
private class FormWidgetAuthorityEditAdapter implements DesignerEditListener {
@Override
public void fireCreatorModified(DesignerEvent evt) {
if (!DesignerMode.isAuthorityEditing()) {
return;
}
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_DELETED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) {
TreePath paths = getSelectedTreePath();
if (paths == null) {
return;
}
if (DesignerMode.isAuthorityEditing()) {
showAuthorityEditPane();
}
} else if (evt.getCreatorEventID() == DesignerEvent.CREATOR_RESIZED) {
repaint();
}
}
public TreePath getSelectedTreePath() {
XCreator creator = selectionModel.getSelection().getSelectedCreator();
return buildTreePath(creator);
}
@Override
public boolean equals(Object o) {
return o instanceof FormWidgetAuthorityEditAdapter;
}
private TreePath buildTreePath(Component comp) {
ArrayList<Component> path = new ArrayList<Component>();
Component parent = comp;
while (parent != null) {
path.add(0, parent);
parent = parent.getParent();
}
Object[] components = (Object[]) path.toArray();
if (components.length == 0) {
return null;
}
return new TreePath(components);
}
}
public double getScale() {
return scale;
}
public void setScale(double scale) {
this.scale = scale;
}
public int getPaintX() {
if (this.rootComponent == null || this.rootComponent.getParent() == null) {
return 0;
}
int width = this.rootComponent.getParent().getWidth();
int x = (int) ((this.getWidth() - width * scale) / 2);
return Math.max(x, 0);
}
public int getPaintY() {
if (this.rootComponent == null || this.rootComponent.getParent() == null) {
return 0;
}
int height = this.rootComponent.getParent().getHeight();
int y = (int) ((this.getHeight() - height * scale) / 2);
return Math.max(y, 0);
}
public int getRelativeX(int x) {
return (int) ((x - this.getPaintX()) / this.getScale());
}
public int getRelativeY(int y) {
return (int) ((y - this.getPaintY()) / this.getScale());
}
public int getOriginX(int x) {
return (int) (x * this.getScale() + this.getPaintX());
}
public int getOriginY(int y) {
return (int) (y * this.getScale() + this.getPaintY());
}
public int getHorizontalScaleValue() {
return (int) (this.getArea().getHorizontalValue() / this.scale);
}
public int getVerticalScaleValue() {
return (int) (this.getArea().getVerticalValue() / this.scale);
}
public boolean checkIfBeyondValidArea(MouseEvent e){
if (e.getX() < 0 || e.getY() < 0 ||
e.getX() > this.getRootComponent().getWidth() ||
e.getY() > (this.getRootComponent().getHeight() + this.getParaHeight())) {
return true;
}
return false;
}
public void processPopup(boolean canVisible) {
XCreator creator = this.getSelectionModel().getSelection().getSelectedCreator();
if (creator != null) {
creator.processPopup(canVisible);
}
}
public void hidePopup() {
XCreator creator = this.getSelectionModel().getSelection().getSelectedCreator();
if (creator != null) {
creator.hidePopup();
}
}
public boolean isMultiSelection() {
XCreator[] creators = this.getSelectionModel().getSelection().getSelectedCreators();
if (creators != null && creators.length > 1) {
for (int i = 0; i < creators.length - 1; i++) {
if (creators[i].getParent() != creators[i + 1].getParent() || !creators[i].isParentAbsolute()) {
return false;
}
}
return creators[creators.length - 1].isParentAbsolute();
}
return false;
}
public FormSpacingLineDrawer getSpacingLineDrawer() {
return spacingLineDrawer;
}
public void instantiateCreator(XCreator creator) {
if (creator != null) {
ModelUtil.renameWidgetName(this.getTarget(), creator);
creator.addNotify();
ComponentAdapter adapter = new CompositeComponentAdapter(this, creator);
adapter.initialize();
creator.putClientProperty(AdapterBus.CLIENT_PROPERTIES, adapter);
}
}
public void backUpCreator(XCreator creator) {
if (creator != null) {
creator.backupCurrentSize();
creator.backupParent();
}
}
public void addWidgetToForm(XCreator creator, int x, int y) {
if(creator == null) {
return;
}
addingModel = new AddingModel(creator);
// 当前鼠标所在的组件
XCreator hoveredComponent = this.getComponentAt(x, y);
// 获取该组件所在的焦点容器
XLayoutContainer container = XCreatorUtils.getHotspotContainer(hoveredComponent);
boolean success = false;
if (container != null) {
// 如果是容器,则调用其acceptComponent接受组件
boolean chartEnter2Para = !addingModel.getXCreator().canEnterIntoParaPane() && container.acceptType(XWParameterLayout.class);
boolean formSubmit2Adapt = !addingModel.getXCreator().canEnterIntoAdaptPane() && container.acceptType(XWFitLayout.class);
if (!chartEnter2Para && !formSubmit2Adapt) {
getAddingWidgetListeners().beforeAdded();
success = container.addWidgetToContainer(
creator,
x + this.getHorizontalScaleValue(),
y + this.getVerticalScaleValue()
);
}
getAddingWidgetListeners().afterAdded(success);
defaultAfterWidgetAdded(success, container);
}
// 取消提示
this.setPainter(null);
// 切换添加状态到普通状态
this.stopAddingState();
getAddingWidgetListeners().clearListeners();
}
private void dealChartBuryingPoint(Widget widget) {
List<BaseChartCollection> chartCollections = widget.getChartCollections();
for (BaseChartCollection baseChartCollection : chartCollections) {
ChartCollection chartCollection = (ChartCollection) baseChartCollection;
for (int i = 0, size = chartCollection.getChartCount(); i < size; i++) {
ChartProvider chart = chartCollection.getChart(i, ChartProvider.class);
//是否是共享的复用组件
boolean isReuse = StringUtils.isNotEmpty(this.addingModel.getXCreator().getShareId());
ChartInfoCollector.getInstance().collection(chart, null, isReuse);
ChartInfoCollector.getInstance().checkTestChart(chart);
}
}
}
private void defaultAfterWidgetAdded(boolean addResult, XLayoutContainer container) {
if (addResult) {
// 如果添加成功,则触发相应事件
XCreator xCreator = container.acceptType(XWParameterLayout.class) ? this.getParaComponent() : this.getRootComponent();
//SetSelection时要确保选中的是最顶层的布局
//tab布局添加的时候是初始化了XWCardLayout,实际上最顶层的布局是XWCardMainBorderLayout
XCreator addingXCreator = addingModel.getXCreator();
Widget widget = (addingXCreator.getBackupParent() != null && addingXCreator.getTopLayout() != null) ? (addingXCreator.getTopLayout().toData()) : addingXCreator.toData();
//图表埋点
dealChartBuryingPoint(widget);
if (addingXCreator.isShared()) {
if (container.acceptType(XWAbsoluteLayout.class)) {
// 绝对布局中新添加的共享组件默认锁定尺寸比例
Rectangle bounds = new Rectangle(addingXCreator.getBounds());
Widget addingWidget = addingXCreator.toData();
if (addingWidget != null && bounds.width > 0 && bounds.height > 0) {
addingXCreator.toData().setAspectRatioLocked(true);
addingXCreator.toData().setAspectRatioBackup(1.0 * bounds.width / bounds.height);
}
}
String shareId = addingXCreator.getShareId();
SharableEditorProvider sharableEditor = ShareLoader.getLoader().getSharedElCaseEditorById(shareId);
SharableWidgetProvider bindInfo = ShareLoader.getLoader().getElCaseBindInfoById(shareId);
Map<String, String> tdNameMap = Collections.emptyMap();
if (sharableEditor != null && bindInfo != null) {
tdNameMap = TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()).addTableData(bindInfo.getName(), sharableEditor.getTableDataSource(), true);
//合并数据集之后,可能会有数据集名称变化,做一下联动
//共享的组件拿的时候都是克隆的,这边改拖拽中克隆的对象而非新克隆对象,上面这个新克隆的对象只是为了拿数据集
Map<String, String> map = new HashMap<>();
for (Map.Entry<String, String> entry : tdNameMap.entrySet()) {
this.getTarget().renameTableData(widget, entry.getKey(), entry.getValue());
map.put(entry.getKey(), entry.getValue());
}
if (!map.isEmpty()) {
DesignTableDataManager.fireDSChanged(map);
}
}
EventDispatcher.fire(TableDataModifyEvent.INSTANCE, new ContentChangeItem(tdNameMap, widget, ChangeItem.TABLE_DATA_NAME));
}
this.getSelectionModel().setSelectedCreators(
FormSelectionUtils.rebuildSelection(xCreator, new Widget[]{widget}));
if (!addingModel.isAddedIllegal()) {
this.getEditListenerTable().fireCreatorModified(addingModel.getXCreator(), DesignerEvent.CREATOR_ADDED);
}
} else {
Toolkit.getDefaultToolkit().beep();
// 拖入失败 取消选中
XCreator creator = addingModel.getXCreator();
if (creator != null) {
creator.setSelected(false);
}
}
}
}