|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|