Browse Source

FRM组件复用自适应布局bug修复,不能粘贴时弹窗提示

master
yaoh.wu 7 years ago
parent
commit
ae78f289b6
  1. 2
      designer_base/src/com/fr/design/locale/designer.properties
  2. 2
      designer_base/src/com/fr/design/locale/designer_en_US.properties
  3. 2
      designer_base/src/com/fr/design/locale/designer_zh_CN.properties
  4. 2
      designer_base/src/com/fr/design/locale/designer_zh_TW.properties
  5. 26
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRBodyLayoutAdapter.java
  6. 15
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRTabFitLayoutAdapter.java
  7. 29
      designer_form/src/com/fr/design/designer/beans/models/SelectionModel.java
  8. 187
      designer_form/src/com/fr/design/designer/beans/painters/AbstractPainter.java
  9. 12
      designer_form/src/com/fr/design/mainframe/FormSelection.java
  10. 7
      designer_form/src/com/fr/design/mainframe/FormSelectionUtils.java

2
designer_base/src/com/fr/design/locale/designer.properties

@ -585,3 +585,5 @@ FR-Designer-Move_Tab_First=move to first
FR-Designer-Move_Tab_End=move to end
FR-Designer-Move_Tab_Next=move to next
FR-Designer-Move_Tab_Prev=move to previous
FR-Designer_Too_Large_To_Paste=too large to paste
FR-Designer_Too_Small_To_Paste=Too small to paste

2
designer_base/src/com/fr/design/locale/designer_en_US.properties

@ -586,3 +586,5 @@ FR-Designer-Move_Tab_First=move to first
FR-Designer-Move_Tab_End=move to end
FR-Designer-Move_Tab_Next=move to next
FR-Designer-Move_Tab_Prev=move to previous
FR-Designer_Too_Large_To_Paste=Too large to paste!
FR-Designer_Too_Small_To_Paste=Too small to paste!

2
designer_base/src/com/fr/design/locale/designer_zh_CN.properties

@ -590,3 +590,5 @@ FR-Designer-Move_Tab_First=\u79FB\u52A8\u5230\u9996\u4F4D
FR-Designer-Move_Tab_End=\u79FB\u52A8\u5230\u672B\u5C3E
FR-Designer-Move_Tab_Next=\u5F80\u540E\u79FB\u52A8
FR-Designer-Move_Tab_Prev=\u5F80\u524D\u79FB\u52A8
FR-Designer_Too_Large_To_Paste=\u7EC4\u4EF6\u5927\u5C0F\u8D85\u51FA\u8FB9\u754C\uFF0C\u65E0\u6CD5\u7C98\u8D34\uFF01
FR-Designer_Too_Small_To_Paste=\u6B64\u5904\u65E0\u6CD5\u7C98\u8D34\uFF0C\u5C0F\u4E8E\u7EC4\u4EF6\u6700\u5C0F\u9AD8\u5EA6\uFF01

2
designer_base/src/com/fr/design/locale/designer_zh_TW.properties

@ -578,3 +578,5 @@ FR-Designer-Move_Tab_First=\u79FB\u52D5\u5230\u9996\u4F4D
FR-Designer-Move_Tab_End=\u79FB\u52D5\u5230\u672B\u5C3E
FR-Designer-Move_Tab_Next=\u5F80\u5F8C\u79FB\u52D5
FR-Designer-Move_Tab_Prev=\u5F80\u524D\u79FB\u52D5
FR-Designer_Too_Large_To_Paste=\u7D44\u4EF6\u5927\u5C0F\u8D85\u51FA\u908A\u754C\uFF0C\u7121\u6CD5\u7C98\u8CBC\uFF01
FR-Designer_Too_Small_To_Paste=\u6B64\u8655\u7121\u6CD5\u7C98\u8CBC\uFF0C\u5C0F\u65BC\u7D44\u4EF6\u6700\u5C0F\u9AD8\u5EA6\uFF01

26
designer_form/src/com/fr/design/designer/beans/adapters/layout/FRBodyLayoutAdapter.java

@ -640,11 +640,7 @@ public class FRBodyLayoutAdapter extends AbstractLayoutAdapter {
* 又通过ComponentUtils.getRelativeBounds()方法获取到了绝对坐标
* 再次计算相对坐标所以将y值重新变成绝对坐标
* */
if (currentCreator.getBackupParent().getLocation().y == WBorderLayout.DEFAULT_SIZE) {
y = y + WCardMainBorderLayout.TAB_HEIGHT + WBorderLayout.DEFAULT_SIZE;
} else {
y = y + WCardMainBorderLayout.TAB_HEIGHT;
}
y = y + WCardMainBorderLayout.TAB_HEIGHT + this.getParaEditorYOffset();
int tempX = x - rect.x;
int tempY = y - rect.y;
int containerX = container.getX();
@ -675,6 +671,26 @@ public class FRBodyLayoutAdapter extends AbstractLayoutAdapter {
return position;
}
/**
* 获取因为参数面板导致的Y坐标偏移
*
* @return 参数面板导致的Y坐标偏移
*/
protected int getParaEditorYOffset() {
int offset = 0;
if (container.getParent() != null) {
Component components[] = container.getParent().getComponents();
for (Component component : components) {
if (component instanceof XWParameterLayout) {
offset = component.getY() + component.getHeight();
break;
}
}
}
return offset;
}
/**
* 组件交叉区域进行插入时调整受到变动的其他组件,之前是交叉区域插入也按照三等分逻辑后面测试中发现有bug改为和bi一样的鼠标所在侧平分
* 默认左上角右下角区域是垂直方向插入组件

15
designer_form/src/com/fr/design/designer/beans/adapters/layout/FRTabFitLayoutAdapter.java

@ -7,11 +7,13 @@ package com.fr.design.designer.beans.adapters.layout;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.designer.creator.XWidgetCreator;
import com.fr.design.designer.creator.cardlayout.XWCardLayout;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
import com.fr.design.designer.creator.cardlayout.XWTabFitLayout;
import com.fr.design.designer.properties.FRTabFitLayoutPropertiesGroupModel;
import com.fr.design.mainframe.widget.editors.ParameterEditor;
import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.container.WBorderLayout;
@ -82,16 +84,14 @@ public class FRTabFitLayoutAdapter extends FRFitLayoutAdapter {
return true;
}
// tab布局的纵坐标受到tab高度的影响,判断的上边界取得是里面XWTabFitLayout的上边界,
// 实际计算的时候的纵坐标用了外层的CardMainBorerLayout,需要将tab高度减掉
//将y值变为相对坐标以实现获取到鼠标drop位置的控件
//TODO 可以直接在这边将x,y都变成相对坐标,这样在后面判断拖进来的新控件放置方式的时候就不用再判断了
// tab布局的纵坐标受到tab高度以及参数面板高度的影响,判断的上边界取得是里面XWTabFitLayout的上边界,
// 实际计算的时候的纵坐标用了外层的CardMainBorerLayout,需要将tab高度和参数面板高度减掉
// 将y值变为相对坐标以实现获取到鼠标drop位置的控件
// TODO 可以直接在这边将x,y都变成相对坐标,这样在后面判断拖进来的新控件放置方式的时候就不用再判断了
private int adjustY(int y, XWTabFitLayout tabLayout) {
XWCardLayout cardLayout = (XWCardLayout) tabLayout.getBackupParent();
LayoutBorderStyle style = cardLayout.toData().getBorderStyle();
if (container.getLocation().y == WBorderLayout.DEFAULT_SIZE) {
y = y - WBorderLayout.DEFAULT_SIZE;
}
y = y - this.getParaEditorYOffset();
if (ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)) {
y = y - WCardMainBorderLayout.TAB_HEIGHT;
}
@ -101,4 +101,5 @@ public class FRTabFitLayoutAdapter extends FRFitLayoutAdapter {
protected Rectangle getLayoutBound(XWCardMainBorderLayout mainLayout) {
return ComponentUtils.getRelativeBounds(mainLayout);
}
}

29
designer_form/src/com/fr/design/designer/beans/models/SelectionModel.java

@ -13,6 +13,7 @@ import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormSelection;
import com.fr.design.mainframe.FormSelectionUtils;
import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.stable.ArrayUtils;
@ -26,7 +27,7 @@ import java.util.ArrayList;
public class SelectionModel {
//被粘贴组件在所选组件位置处往下、往右各错开20像素。执行多次粘贴时,在上一次粘贴的位置处错开20像素。
private static final int DELTA_X_Y = 20; //粘贴时候的偏移距离
private static final int BORDER_PROPORTION = 20;
private static final double OFFSET_RELATIVE = 0.80;
private static FormSelection clipboard = new FormSelection();
private FormDesigner designer;
private FormSelection selection;
@ -140,14 +141,14 @@ public class SelectionModel {
FormSelectionUtils.paste2Container(designer, (XLayoutContainer) selection.getSelectedCreator(),
clipboard,
rec.x + rec.width / 2,
rec.y + BORDER_PROPORTION);
rec.y + DELTA_X_Y);
} else {
Rectangle rec = selection.getRelativeBounds();
//自适应布局
FormSelectionUtils.paste2Container(designer, designer.getRootComponent(),
clipboard,
rec.x + rec.width / 2,
rec.y + BORDER_PROPORTION);
rec.y + DELTA_X_Y);
}
} else {
//绝对布局
@ -172,18 +173,22 @@ public class SelectionModel {
* 粘贴时选择组件
*/
private void selectedPaste() {
XLayoutContainer parent = null;
XLayoutContainer container = null;
//获取到编辑器的表层容器(已选的组件的父容器就是表层容器)
parent = XCreatorUtils.getParentXLayoutContainer(selection.getSelectedCreator());
if (parent != null && selection.getSelectedCreator().getParent() instanceof XWFitLayout) {
container = XCreatorUtils.getParentXLayoutContainer(selection.getSelectedCreator());
if (container != null && selection.getSelectedCreator().getParent() instanceof XWFitLayout) {
//自适应布局
Rectangle rec = selection.getRelativeBounds();
FormSelectionUtils.paste2Container(designer, parent, clipboard, rec.x + rec.width / 2, rec.y +
rec.height - BORDER_PROPORTION);
} else if (parent != null && selection.getSelectedCreator().getParent() instanceof XWAbsoluteLayout) {
Rectangle selectionRec = selection.getRelativeBounds();
Rectangle containerRec = ComponentUtils.getRelativeBounds(container);
//计算自适应布局位置
int positionX = selectionRec.x - containerRec.x + selectionRec.width / 2;
int positionY = (int) (selectionRec.y - containerRec.y + selectionRec.height * OFFSET_RELATIVE);
FormSelectionUtils.paste2Container(designer, container, clipboard, positionX, positionY);
} else if (container != null && selection.getSelectedCreator().getParent() instanceof XWAbsoluteLayout) {
//绝对布局
Rectangle rec = selection.getSelctionBounds();
FormSelectionUtils.paste2Container(designer, parent, clipboard, rec.x + DELTA_X_Y, rec.y + DELTA_X_Y);
FormSelectionUtils.paste2Container(designer, container, clipboard, rec.x + DELTA_X_Y, rec.y + DELTA_X_Y);
}
}
@ -198,13 +203,13 @@ public class SelectionModel {
if (creator.acceptType(XWParameterLayout.class)) {
designer.removeParaComponent();
}
removeCreatorFromContainer(creator, creator.getWidth(), creator.getHeight());
creator.removeAll();
// 清除被选中的组件
selection.reset();
}
setSelectedCreator(designer.getRootComponent());
FormSelectionUtils.rebuildSelection(designer);
// 触发事件
designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_DELETED);
designer.repaint();

187
designer_form/src/com/fr/design/designer/beans/painters/AbstractPainter.java

@ -1,93 +1,96 @@
package com.fr.design.designer.beans.painters;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import com.fr.design.designer.beans.HoverPainter;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.general.Inter;
public abstract class AbstractPainter implements HoverPainter {
protected Point hotspot;
protected Rectangle hotspot_bounds;
protected XLayoutContainer container;
protected XCreator creator;
/**
* 构造函数
* @param container 容器
*/
public AbstractPainter(XLayoutContainer container) {
this.container = container;
}
@Override
public void setHotspot(Point p) {
hotspot = p;
}
/**
* 画初始区域
* @param g 画图类
* @param startX 起始x位置
* @param startY 起始y位置
*/
public void paint(Graphics g, int startX, int startY) {
if(hotspot_bounds != null){
drawHotspot(g, hotspot_bounds.x, hotspot_bounds.y, hotspot_bounds.width, hotspot_bounds.height, Color.lightGray, true, false);
}
}
/**
* 设置边界
* @param rect 位置
*/
@Override
public void setRenderingBounds(Rectangle rect) {
hotspot_bounds = rect;
}
@Override
public void setCreator(XCreator component) {
this.creator = component;
}
protected void drawHotspot(Graphics g, int x, int y, int width, int height, boolean accept) {
Color bColor = accept ? XCreatorConstants.LAYOUT_HOTSPOT_COLOR : XCreatorConstants.LAYOUT_FORBIDDEN_COLOR;
drawHotspot(g, x, y, width, height, bColor, accept, false);
}
/**
* 自适应布局那边渲染提示要画整个背景不是画边框
*/
protected void drawRegionBackground(Graphics g, int x, int y, int width, int height, Color bColor, boolean accept) {
drawHotspot(g, x, y, width, height, bColor, accept, true);
}
protected void drawHotspot(Graphics g, int x, int y, int width, int height, Color bColor, boolean accept, boolean drawBackground) {
Graphics2D g2d = (Graphics2D) g;
Color color = g2d.getColor();
Stroke backup = g2d.getStroke();
// 设置线条的样式
g2d.setStroke(XCreatorConstants.STROKE);
g2d.setColor(bColor);
if (!accept) {
g2d.drawString(Inter.getLocText("Cannot-Add_To_This_Area") + "!", x + width / 3, y + height / 2);
} else if (drawBackground) {
g2d.fillRect(x, y, width, height);
} else {
g2d.drawRect(x, y, width, height);
}
g2d.setStroke(backup);
g2d.setColor(color);
}
package com.fr.design.designer.beans.painters;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import com.fr.design.designer.beans.HoverPainter;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.general.Inter;
public abstract class AbstractPainter implements HoverPainter {
protected Point hotspot;
protected Rectangle hotspot_bounds;
protected XLayoutContainer container;
protected XCreator creator;
/**
* 构造函数
*
* @param container 容器
*/
public AbstractPainter(XLayoutContainer container) {
this.container = container;
}
@Override
public void setHotspot(Point p) {
hotspot = p;
}
/**
* 画初始区域
*
* @param g 画图类
* @param startX 起始x位置
* @param startY 起始y位置
*/
public void paint(Graphics g, int startX, int startY) {
if (hotspot_bounds != null) {
drawHotspot(g, hotspot_bounds.x, hotspot_bounds.y, hotspot_bounds.width, hotspot_bounds.height, Color.lightGray, true, false);
}
}
/**
* 设置边界
*
* @param rect 位置
*/
@Override
public void setRenderingBounds(Rectangle rect) {
hotspot_bounds = rect;
}
@Override
public void setCreator(XCreator component) {
this.creator = component;
}
protected void drawHotspot(Graphics g, int x, int y, int width, int height, boolean accept) {
Color bColor = accept ? XCreatorConstants.LAYOUT_HOTSPOT_COLOR : XCreatorConstants.LAYOUT_FORBIDDEN_COLOR;
drawHotspot(g, x, y, width, height, bColor, accept, false);
}
/**
* 自适应布局那边渲染提示要画整个背景不是画边框
*/
protected void drawRegionBackground(Graphics g, int x, int y, int width, int height, Color bColor, boolean accept) {
drawHotspot(g, x, y, width, height, bColor, accept, true);
}
protected void drawHotspot(Graphics g, int x, int y, int width, int height, Color bColor, boolean accept, boolean drawBackground) {
Graphics2D g2d = (Graphics2D) g;
Color color = g2d.getColor();
Stroke backup = g2d.getStroke();
// 设置线条的样式
g2d.setStroke(XCreatorConstants.STROKE);
g2d.setColor(bColor);
if (!accept) {
g2d.drawString(Inter.getLocText("Cannot-Add_To_This_Area") + "!", x + width / 3, y + height / 2);
} else if (drawBackground) {
g2d.fillRect(x, y, width, height);
} else {
g2d.drawRect(x, y, width, height);
}
g2d.setStroke(backup);
g2d.setColor(color);
}
}

12
designer_form/src/com/fr/design/mainframe/FormSelection.java

@ -8,12 +8,7 @@ import com.fr.base.FRContext;
import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.location.Direction;
import com.fr.design.designer.creator.XComponent;
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.XWAbsoluteLayout;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.designer.creator.*;
import com.fr.form.ui.Widget;
import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils;
@ -273,6 +268,11 @@ public class FormSelection {
if (parent == null) {
return;
}
boolean changeCreator = creator.shouldScaleCreator() || creator.hasTitleStyle();
if (parent.acceptType(XWFitLayout.class) && changeCreator) {
creator = (XCreator) creator.getParent();
}
parent.getLayoutAdapter().removeBean(creator, creator.getWidth(), creator.getHeight());
// 删除其根组件,同时就删除了同时被选择的叶子组件
parent.remove(creator);
LayoutManager layout = parent.getLayout();

7
designer_form/src/com/fr/design/mainframe/FormSelectionUtils.java

@ -8,6 +8,7 @@ import com.fr.design.designer.creator.*;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WTitleLayout;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import java.awt.*;
import java.util.ArrayList;
@ -61,7 +62,7 @@ public class FormSelectionUtils {
x + creator.getX() - rec.x + copiedCreator.getWidth() / 2,
y + creator.getY() - rec.y + copiedCreator.getHeight() / 2);
if (!adapter.accept(copiedCreator, point.x, point.y)) {
designer.showMessageDialog("Too large to paste into container");
designer.showMessageDialog(Inter.getLocText("FR-Designer_Too_Large_To_Paste"));
return;
}
boolean addSuccess = adapter.addBean(copiedCreator, point.x, point.y);
@ -87,6 +88,10 @@ public class FormSelectionUtils {
try {
Widget copied = copyWidget(designer, creator);
XCreator copiedCreator = XCreatorUtils.createXCreator(copied, creator.getSize());
if (!adapter.accept(copiedCreator, x, y)) {
designer.showMessageDialog(Inter.getLocText("FR-Designer_Too_Small_To_Paste"));
return;
}
boolean addSuccess = adapter.addBean(copiedCreator, x, y);
if (addSuccess) {
designer.getSelectionModel().getSelection().addSelectedCreator(copiedCreator);

Loading…
Cancel
Save