diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java index 9285b35ca..fd98adc18 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java @@ -26,9 +26,8 @@ public class AddingModel { private boolean added; public AddingModel(FormDesigner designer, XCreator xCreator) { - String creatorName = getXCreatorName(designer, xCreator); this.creator = xCreator; - instantiateCreator(designer, creatorName); + instantiateCreator(designer); // 初始的时候隐藏该组件的图标 currentY = -this.creator.getWidth(); currentX = -this.creator.getHeight(); @@ -37,11 +36,11 @@ public class AddingModel { /** * 待说明 * - * @param designer 设计器 - * @param creatorName 组件名 + * @param designer 设计器 */ - public void instantiateCreator(FormDesigner designer, String creatorName) { - creator.toData().setWidgetName(creatorName); + public void instantiateCreator(FormDesigner designer) { + + ModelUtil.renameWidgetName(designer.getTarget(), creator); ComponentAdapter adapter = new CompositeComponentAdapter(designer, creator); adapter.initialize(); creator.addNotify(); diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java new file mode 100644 index 000000000..b6f073f10 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java @@ -0,0 +1,55 @@ +package com.fr.design.designer.beans.models; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XWParameterLayout; +import com.fr.form.main.Form; +import com.fr.form.ui.Widget; +import com.fr.stable.StringUtils; + +import java.util.HashSet; +import java.util.Set; + +/** + * created by Harrison on 2020/06/05 + **/ +abstract class ModelUtil { + + public static void renameWidgetName(Form form, XCreator xCreator) { + + Set duplicated = new HashSet<>(); + recursiveRenameWidgetName(form, xCreator, duplicated); + } + + private static void recursiveRenameWidgetName(Form form, XCreator xCreator, Set duplicated) { + + Set nameRelatedCreators = new HashSet<>(); + //直接遍历出来目标值,然后按需处理 + xCreator.traversalNameRelatedXCreators(nameRelatedCreators); + for (XCreator target : nameRelatedCreators) { + String uniqueName = uniqueName(form, target, duplicated); + target.resetCreatorName(uniqueName); + } + } + + private static String uniqueName(Form form, XCreator xCreator, Set duplicated) { + + if (xCreator.acceptType(XWParameterLayout.class)) { + return xCreator.createDefaultName(); + } + Widget widget = xCreator.toData(); + String widgetName = widget.getWidgetName(); + if (StringUtils.isEmpty(widgetName)) { + widgetName = xCreator.createDefaultName(); + } + String raw = widgetName; + int i = 0; + while (form.isNameExist(widgetName) || duplicated.contains(widgetName)) { + widgetName = raw + i; + i++; + } + //将名字加入重复集合中 + duplicated.add(widgetName); + return widgetName; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/DedicateLayoutContainer.java b/designer-form/src/main/java/com/fr/design/designer/creator/DedicateLayoutContainer.java index d7f073b45..c8abd8d39 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/DedicateLayoutContainer.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/DedicateLayoutContainer.java @@ -9,6 +9,7 @@ import java.awt.Component; import java.awt.Dimension; import java.beans.IntrospectionException; import java.util.List; +import java.util.Set; /** * 一些控件专属的容器,如标题容器,sclae容器 @@ -69,13 +70,19 @@ public abstract class DedicateLayoutContainer extends XLayoutContainer { //实现WTitleLayout的SetWidgetName child.toData().setWidgetName(name); } - + + @Override + public void traversalNameRelatedXCreators(Set xCreators) { + xCreators.add(this); + } + /** * 重置组件的可见性 + * * @param visible 可见性 */ @Override - public void resetVisible(boolean visible){ + public void resetVisible(boolean visible) { super.resetVisible(visible); XCreator child = getXCreator(XWScaleLayout.INDEX); child.toData().setVisible(visible); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index bef18f96f..a5a59acc8 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -41,6 +41,7 @@ import java.awt.event.MouseEvent; import java.beans.IntrospectionException; import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * @author richer @@ -407,24 +408,43 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo public Component getParentShow(){ return this.getParent(); } - + /** * 重置组件的名称 + * * @param name 名称 */ @Override public void resetCreatorName(String name) { toData().setWidgetName(name); } - + + /** + * 遍历所有命名相关的组件到集合中 + * + * @param xCreators 集合 + */ + public void traversalNameRelatedXCreators(Set xCreators) { + + xCreators.add(this); + int componentCount = getComponentCount(); + for (int i = 0; i < componentCount; i++) { + XCreator xCreator = (XCreator) getComponent(i); + //获取真实的 creator + XCreator realCreator = xCreator.getXCreator(); + realCreator.traversalNameRelatedXCreators(xCreators); + } + } + /** * 重置组件的可见性 + * * @param visible 可见性 */ - public void resetVisible(boolean visible){ + public void resetVisible(boolean visible) { toData().setVisible(visible); } - + /** * 返回编辑的子组件,scale为其内部组件 * @return 组件 diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java index c91d34654..1ff3f41c5 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java @@ -433,13 +433,16 @@ public class XWCardLayout extends XLayoutContainer { //修改相关SwitchButton所绑定的cardLayout控件名 private void changeRelateSwitchCardName(String cardLayoutName) { XWCardMainBorderLayout borderLayout = (XWCardMainBorderLayout) this.getBackupParent(); - WCardMainBorderLayout border = borderLayout.toData(); - WCardTitleLayout titleLayout = border.getTitlePart(); - titleLayout.setCardName(cardLayoutName); - WCardTagLayout tagLayout = titleLayout.getTagPart(); - for (int i = 0, len = tagLayout.getWidgetCount(); i < len; i++) { - CardSwitchButton button = tagLayout.getSwitchButton(i); - button.setCardLayoutName(cardLayoutName); + //可能为空 + if (borderLayout != null) { + WCardMainBorderLayout border = borderLayout.toData(); + WCardTitleLayout titleLayout = border.getTitlePart(); + titleLayout.setCardName(cardLayoutName); + WCardTagLayout tagLayout = titleLayout.getTagPart(); + for (int i = 0, len = tagLayout.getWidgetCount(); i < len; i++) { + CardSwitchButton button = tagLayout.getSwitchButton(i); + button.setCardLayoutName(cardLayoutName); + } } } diff --git a/designer-form/src/test/java/com/fr/design/designer/beans/models/AddingModelTest.java b/designer-form/src/test/java/com/fr/design/designer/beans/models/AddingModelTest.java new file mode 100644 index 000000000..a6bd82300 --- /dev/null +++ b/designer-form/src/test/java/com/fr/design/designer/beans/models/AddingModelTest.java @@ -0,0 +1,146 @@ +package com.fr.design.designer.beans.models; + +import com.fr.config.dao.DaoContext; +import com.fr.config.dao.impl.LocalClassHelperDao; +import com.fr.config.dao.impl.LocalEntityDao; +import com.fr.config.dao.impl.LocalXmlEntityDao; +import com.fr.design.designer.creator.CRPropertyDescriptor; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWTitleLayout; +import com.fr.design.designer.creator.cardlayout.XWCardLayout; +import com.fr.design.mainframe.FormDesigner; +import com.fr.form.main.Form; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WAbsoluteLayout; +import com.fr.form.ui.container.WCardLayout; +import com.fr.form.ui.container.WTitleLayout; +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import javax.swing.JComponent; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.beans.IntrospectionException; + +public class AddingModelTest { + + @Before + public void setUp() { + DaoContext.setXmlEntityDao(new LocalXmlEntityDao()); + DaoContext.setClassHelperDao(new LocalClassHelperDao()); + DaoContext.setEntityDao(new LocalEntityDao()); + } + + @After + public void tearDown() { + DaoContext.setXmlEntityDao(null); + DaoContext.setClassHelperDao(null); + DaoContext.setEntityDao(null); + } + + @Test + public void testInstantiateCreator() throws Exception { + + Dimension dimension = new Dimension(20, 20); + + ChartEditor chartEditor1 = new ChartEditor(); + XCreator xCreator1 = new DemoCreator(chartEditor1, dimension, "test"); + + ChartEditor chartEditor2 = new ChartEditor(); + chartEditor2.setWidgetName("test02"); + XCreator xCreator2 = new DemoCreator(chartEditor2, dimension, "test02"); + xCreator1.add(xCreator2); + + ChartEditor chartEditor3 = new ChartEditor(); + chartEditor3.setWidgetName("test03"); + WAbsoluteLayout.BoundsWidget boundsWidget = new WAbsoluteLayout.BoundsWidget(chartEditor3, new Rectangle(dimension)); + WTitleLayout wTitleLayout03 = new WTitleLayout(); + wTitleLayout03.addWidget(boundsWidget); + //需要和内部的 widget 一样 + wTitleLayout03.setWidgetName("test03"); + XWTitleLayout xCreator3 = new XWTitleLayout(wTitleLayout03, dimension); + xCreator1.add(xCreator3); + + AddingModel addingModel = new AddingModel(xCreator1, 20, 20); + + Form form = EasyMock.mock(Form.class); + EasyMock.expect(form.isNameExist("test")).andReturn(true).once(); + EasyMock.expect(form.isNameExist("test03")).andReturn(true).once(); + EasyMock.expect(form.isNameExist(EasyMock.anyString())).andReturn(false).anyTimes(); + EasyMock.replay(form); + + FormDesigner mock = EasyMock.mock(FormDesigner.class); + EasyMock.expect(mock.getTarget()).andReturn(form).anyTimes(); + EasyMock.replay(mock); + + addingModel.instantiateCreator(mock); + //没有默认参数, 但已经存在 test + Assert.assertEquals("test0", xCreator1.toData().getWidgetName()); + //直接返回 + Assert.assertEquals("test02", xCreator2.toData().getWidgetName()); + //已经存在,后接0 + Assert.assertEquals("test030", xCreator3.toData().getWidgetName()); + } + + @Test + public void testInstantiateCreator_cardLayout() throws Exception { + + Form form = EasyMock.mock(Form.class); + EasyMock.expect(form.isNameExist("cardlayout")).andReturn(true).once(); + EasyMock.expect(form.isNameExist("cardlayout0")).andReturn(true).once(); + EasyMock.expect(form.isNameExist(EasyMock.anyString())).andReturn(false).anyTimes(); + EasyMock.replay(form); + + FormDesigner mock = EasyMock.mock(FormDesigner.class); + EasyMock.expect(mock.getTarget()).andReturn(form).anyTimes(); + EasyMock.replay(mock); + + WCardLayout wCardLayout = new WCardLayout(20, 20); + XWCardLayout xwCardLayout = new XWCardLayout(wCardLayout, new Dimension(40, 40)); + AddingModel addingModel = new AddingModel(mock, xwCardLayout); + Assert.assertEquals("cardlayout1", xwCardLayout.toData().getWidgetName()); + + //依赖于 cardlayout 创建 container + XLayoutContainer parentLayOut = xwCardLayout.initCreatorWrapper(80); + AddingModel parentModel = new AddingModel(mock, parentLayOut); + Assert.assertEquals("tablayout1", parentLayOut.toData().getWidgetName()); + Assert.assertEquals("tabpane1", ((XCreator) (parentLayOut.getComponent(0))).getXCreator().toData().getWidgetName()); + + } + + private static class DemoCreator extends XCreator { + + private String widgetName; + + public DemoCreator(Widget ob, Dimension initSize, String widgetName) { + super(ob, initSize); + this.widgetName = widgetName; + } + + @Override + public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException { + return new CRPropertyDescriptor[0]; + } + + @Override + protected JComponent initEditor() { + return null; + } + + @Override + protected void initXCreatorProperties() { + + } + + @Override + public String createDefaultName() { + return this.widgetName; + } + } + +} \ No newline at end of file