diff --git a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java b/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java index 6b72255ed..e54271cd0 100644 --- a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java +++ b/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java @@ -9,18 +9,31 @@ import com.fr.design.designer.beans.painters.FRAbsoluteLayoutPainter; import com.fr.design.designer.creator.*; import com.fr.design.designer.properties.BoundsGroupModel; import com.fr.design.designer.properties.FRAbsoluteLayoutPropertiesGroupModel; -import com.fr.design.designer.properties.FRFitLayoutPropertiesGroupModel; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.LayoutUtils; +import com.fr.general.ComparatorUtils; +import com.fr.general.FRLogger; -public class FRAbsoluteLayoutAdapter extends AbstractLayoutAdapter { +public class FRAbsoluteLayoutAdapter extends FRBodyLayoutAdapter { + //是不是添加到父容器上 + private boolean isAdd2ParentLayout = false; private HoverPainter painter; + public FRAbsoluteLayoutAdapter(XLayoutContainer container) { super(container); painter = new FRAbsoluteLayoutPainter(container); + initMinSize(); } + private void initMinSize() { + XWAbsoluteLayout layout = (XWAbsoluteLayout) container; + minWidth = layout.getActualMinWidth(); + minHeight = layout.getActualMinHeight(); + actualVal = layout.getAcualInterval(); + margin = layout.toData().getMargin(); + } + @Override public HoverPainter getPainter() { return painter; @@ -37,39 +50,169 @@ public class FRAbsoluteLayoutAdapter extends AbstractLayoutAdapter { public boolean accept(XCreator creator, int x, int y) { Component comp = container.getComponentAt(x, y); //布局控件要先判断是不是可编辑 + //可以编辑,按原有逻辑判断 + //不可编辑,当成一整个控件处理 + if (comp == null){ + return false; + } XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer((XCreator)comp).getTopLayout(); - if(topLayout != null && !topLayout.isEditable()){ + if(topLayout != null){ + if (topLayout.isEditable()){ + return x >= 0 && y >= 0 && creator.getHeight() <= container.getHeight() + && creator.getWidth() <= container.getWidth(); + } + else { + return acceptWidget(creator, x, y); + } + } + else{ + FRLogger.getLogger().error("top layout is null!"); + } + + return false; + } + + /** + * 判断是否鼠标在组件的三等分区域,如果组件在布局管理器中间,上下左右都可能会三等分 + * @param parentComp 鼠标所在区域的组件 + * @param x 坐标x + * @param y 坐标y + * @return 是则返回true + */ + public boolean isTrisectionArea(Component parentComp, int x, int y) { + XCreator creator = (XCreator)parentComp; + trisectAreaDirect = 0; + if (container.getComponentCount()<=1) { return false; } - boolean isAccept = x >= 0 && y >= 0 && creator.getHeight() <= container.getHeight() - && creator.getWidth() <= container.getWidth(); - return isAccept; + int maxWidth = parentComp.getWidth(); + int maxHeight = parentComp.getHeight(); + int xL = parentComp.getX(); + int yL = parentComp.getY(); + // 组件宽高的十分之一和默认值取大 + int minRangeWidth = Math.max(maxWidth/BORDER_PROPORTION, DEFAULT_AREA_LENGTH); + int minRangeHeight = Math.max(maxHeight/BORDER_PROPORTION, DEFAULT_AREA_LENGTH); + if(yyL+maxHeight-minRangeHeight) { + // 在组件下侧三等分 + trisectAreaDirect = COMP_BOTTOM; + } else if (xxL+maxWidth-minRangeWidth) { + // 在组件右侧三等分 + trisectAreaDirect = COMP_RIGHT; + } + // tab布局的边界特殊处理,不进行三等分 + if(!creator.getTargetChildrenList().isEmpty()){ + return false; + } + + return !ComparatorUtils.equals(trisectAreaDirect, 0); } - @Override + private boolean acceptWidget(XCreator creator, int x, int y){ + isFindRelatedComps = false; + //拖入组件判断时,先判断是否为交叉点区域,其次三等分区域,再次平分区域 + Component comp = container.getComponentAt(x, y); + boolean isMatchEdge = false; + //如果当前处于边缘地带, 那么就把他贴到父容器上 + XLayoutContainer parent = container.findNearestFit(); + container = parent != null ? parent : container; + isAdd2ParentLayout = true; + + int componentHeight = comp.getHeight(); + int componentWidth = comp.getWidth(); + //上半部分高度 + int upHeight = (int) (componentHeight * TOP_HALF) + comp.getY(); + //下半部分高度 + int downHeight = (int) (componentHeight * BOTTOM_HALF) + comp.getY(); + + if (isCrossPointArea(comp, x, y)) { + return canAcceptWhileCrossPoint(comp, x, y); + } + + if (isTrisectionArea(comp, x, y)) { + return canAcceptWhileTrisection(comp, x, y); + } + + boolean horizonValid = componentWidth >= minWidth * 2 + actualVal; + boolean verticalValid = componentHeight >= minHeight * 2 + actualVal; + return y > upHeight && y < downHeight ? horizonValid : verticalValid; + } + + /** + * 组件的ComponentAdapter在添加组件时,如果发现布局管理器不为空,会继而调用该布局管理器的 + * addComp方法来完成组件的具体添加。在该方法内,布局管理器可以提供额外的功能。 + * + * @param creator 被添加的新组件 + * @param x 添加的位置x,该位置是相对于container的 + * @param y 添加的位置y,该位置是相对于container的 + * @return 是否添加成功,成功返回true,否则false + */ + @Override + public boolean addBean(XCreator creator, int x, int y) { + Rectangle rect = ComponentUtils.getRelativeBounds(container); + + int posX = x + rect.x; + int posY = y + rect.y; + if (!accept(creator, x, y)) { + return false; + } + addComp(creator, posX, posY); + ((XWidgetCreator) creator).recalculateChildrenSize(); + return true; + } + + @Override protected void addComp(XCreator creator, int x, int y) { - if (XCreatorUtils.getParentXLayoutContainer(creator) != null) { + if(!isAdd2ParentLayout) { Rectangle r = ComponentUtils.getRelativeBounds(container); - Rectangle creatorRectangle = ComponentUtils.getRelativeBounds(creator); - x = creatorRectangle.x - r.x; - y = creatorRectangle.y - r.y; - } else { - int w = creator.getWidth() / 2; - int h = creator.getHeight() / 2; - x = x - w; - y = y - h; - } + x = x - r.x; + y = y - r.y; + if (XCreatorUtils.getParentXLayoutContainer(creator) != null) { - fix(creator, x, y); + Rectangle creatorRectangle = ComponentUtils.getRelativeBounds(creator); + x = creatorRectangle.x - r.x; + y = creatorRectangle.y - r.y; + } else { + int w = creator.getWidth() / 2; + int h = creator.getHeight() / 2; + x = x - w; + y = y - h; + } + fix(creator, x, y); - if (creator.shouldScaleCreator() || creator.hasTitleStyle()) { - addParentCreator(creator); - } else { - container.add(creator, creator.toData().getWidgetName()); + if (creator.hasTitleStyle()) { + addParentCreator(creator); + } else { + container.add(creator, creator.toData().getWidgetName()); + } + XWAbsoluteLayout layout = (XWAbsoluteLayout) container; + layout.updateBoundsWidget(creator); + LayoutUtils.layoutRootContainer(container); + }else{ + fixAbsolute(creator, x, y); + if (creator.shouldScaleCreator() || creator.hasTitleStyle()) { + addParentCreator(creator); + } else { + container.add(creator, creator.toData().getWidgetName()); + } + XWFitLayout layout = (XWFitLayout) container; + // 更新对应的BoundsWidget + layout.updateBoundsWidget(); + updateCreatorBackBound(); + } + } + + private void updateCreatorBackBound() { + for (int i=0,size=container.getComponentCount(); i rightComps; + protected java.util.List leftComps; + protected java.util.List downComps; + protected java.util.List upComps; + // 三等分时计算对应侧的组件 + protected boolean isFindRelatedComps = false; + // 渲染时只计算对应的bounds而不调整 + private boolean isCalculateChildPos = false; + private int[] childPosition = null; //painter用的位置 + protected int minWidth = 0; // 最小尺寸,由于屏幕百分比里不同,显示的最小大小也不同 + protected int minHeight = 0; + protected int actualVal = 0; // 存在间隔时,add move drag 判断对齐等都要考虑 + protected PaddingMargin margin; // 布局容器边距 + /** + * 在添加组件状态时,当鼠标移动到某个容器上方时,如果该容器有布局管理器,则会调用该布局 + * 管理适配器的accept来决定当前位置是否可以放置,并提供特殊的标识,比如红色区域标识。比 + * 如在BorderLayout中,如果某个方位已经放置了组件,则此时应该返回false标识该区域不可以 + * 放置。 + * + * @param creator 组件 + * @param x 添加的位置x,该位置是相对于container的 + * @param y 添加的位置y,该位置是相对于container的 + * @return 是否可以放置 + */ + @Override + public boolean accept(XCreator creator, int x, int y) { + return false; + } + + @Override + protected void addComp(XCreator creator, int x, int y) { + + } + + public FRBodyLayoutAdapter(XLayoutContainer container) { + super(container); + } + + /** + * 交叉点区域时,能否对应位置放入组件 + * @param comp 待放置组件 + * @param x x + * @param y y + * @return 能否放入 + */ + protected boolean canAcceptWhileCrossPoint(Component comp, int x, int y) { + int cX = comp.getX(), cY = comp.getY(), cH = comp.getHeight(), cW = comp.getWidth(); + Component topComp = container.getTopComp(cX, cY); + Component bottomComp = container.getBottomComp(cX, cY, cH); + Component rightComp = container.getRightComp(cX, cY, cW); + Component leftComp = container.getLeftComp(cX, cY); + int minLength = 0, min = minHeight * 2; + boolean isNotDefaultArea = false; + if (ComparatorUtils.equals(crossPointAreaDirect, COMP_LEFT_TOP)) { + isNotDefaultArea = (topComp == null) || (topComp.getX() != cX); + minLength = isNotDefaultArea ? Math.min(cH, leftComp.getHeight()) : Math.min(cW, topComp.getWidth()); + min = isNotDefaultArea ? min : minWidth * 2; + } else if (ComparatorUtils.equals(crossPointAreaDirect, COMP_RIGHT_BOTTOM)) { + bottomComp = container.getRightBottomComp(cX, cY, cH, cW); + isNotDefaultArea = (bottomComp == null) || (bottomComp.getX()+bottomComp.getWidth() != cX + cW) ; + rightComp = container.getBottomRightComp(cX, cY, cH, cW); + minLength = isNotDefaultArea ? Math.min(cH, rightComp.getHeight()) : Math.min(cW, bottomComp.getWidth()); + min = isNotDefaultArea ? min : minWidth * 2; + } else if (ComparatorUtils.equals(crossPointAreaDirect, COMP_LEFT_BOTTOM)) { + leftComp = container.getBottomLeftComp(cX, cY, cH); + isNotDefaultArea = (leftComp == null) || (leftComp.getY() + leftComp.getHeight() != cY + cH); + minLength = isNotDefaultArea ? Math.min(cW, bottomComp.getWidth()) : Math.min(cH, leftComp.getHeight()); + min = isNotDefaultArea ? minWidth * 2 : min; + } else if (ComparatorUtils.equals(crossPointAreaDirect, COMP_RIGHT_TOP)) { + isNotDefaultArea = (rightComp == null) || (rightComp.getY() != cY) ; + topComp = container.getRightTopComp(cX, cY, cW); + minLength = isNotDefaultArea ? Math.min(cW, topComp.getWidth()) : Math.min(cH, rightComp.getWidth()); + min = isNotDefaultArea ? minWidth * 2 : min ; + } else if (ComparatorUtils.equals(crossPointAreaDirect, COMP_TOP)) { + minLength= Math.min(rightComp.getHeight(), Math.min(cH, leftComp.getHeight())); + } else if (ComparatorUtils.equals(crossPointAreaDirect, COMP_BOTTOM)) { + leftComp = container.getBottomLeftComp(cX, cY, cH); + rightComp = container.getBottomRightComp(cX, cY, cH, cW); + minLength = Math.min(rightComp.getHeight(), Math.min(cH, leftComp.getHeight())); + } else { + if (ComparatorUtils.equals(crossPointAreaDirect, COMP_RIGHT)) { + topComp = container.getRightTopComp(cX, cY, cW); + bottomComp = container.getRightBottomComp(cX, cY, cH, cW); + } + minLength = Math.min(topComp.getWidth(), Math.min(cW, bottomComp.getWidth())); + min = minWidth * 2; + } + // 有间隔的话,要考虑容纳间隔 + return minLength >= min + actualVal; + } + + /** + * 三等分区域时,能否对应位置放入组件 + * @param comp 待放置组件 + * @param x x + * @param y y + * @return 能否放入 + */ + protected boolean canAcceptWhileTrisection(Component comp, int x, int y) { + //符合三等分,实际区域不满足三等分的大小 + int cX = comp.getX(), cY = comp.getY(), cH = comp.getHeight(), cW = comp.getWidth(); + int upMinHeight = 0, downMinHeight = 0, leftMinWidth = 0, rightMinWidth = 0; + if (ComparatorUtils.equals(trisectAreaDirect, COMP_TOP)) { + upMinHeight = getUpMinHeightComp(cY, x); + downMinHeight = getDownMinHeightComp(comp, y); + return upMinHeight == 0 ? downMinHeight >= minHeight * 2 + actualVal : (upMinHeight + downMinHeight) >= minHeight * 3 + actualVal; + } else if(ComparatorUtils.equals(trisectAreaDirect, COMP_BOTTOM)) { + upMinHeight = getUpMinHeightComp(cY + cH + actualVal, x); + if (cY + cH + DEFAULT_AREA_LENGTH>container.getHeight() - margin.getBottom()){ + downMinHeight = 0; + } else { + Component targetComp = container.getBottomComp(x, cY, cH); + downMinHeight = getDownMinHeightComp(targetComp, cY + cH + DEFAULT_AREA_LENGTH + actualVal); + } + return downMinHeight == 0 ? (upMinHeight >= minHeight * 2 + actualVal) : ((upMinHeight+downMinHeight) >= minHeight * 3 + actualVal); + } else if(ComparatorUtils.equals(trisectAreaDirect, COMP_LEFT)) { + rightMinWidth = getMinRightWidth(cX, 0, y); + if(cX - DEFAULT_AREA_LENGTH < margin.getLeft()) { + leftMinWidth = 0; + } else { + Component targetRightComp = container.getLeftComp(cX, y); + leftMinWidth = getMinLeftWidth(targetRightComp, cX - DEFAULT_AREA_LENGTH - actualVal); + } + return leftMinWidth == 0 ? (rightMinWidth >= minWidth * 2 + actualVal) : ((leftMinWidth+rightMinWidth) >= minWidth * 3 + actualVal); + } else if(ComparatorUtils.equals(trisectAreaDirect, COMP_RIGHT)) { + leftMinWidth = getMinLeftWidth(comp, x); + rightMinWidth = getMinRightWidth(cX, cW, y); + return rightMinWidth == 0 ? (leftMinWidth >= minWidth * 2 + actualVal) : ((leftMinWidth+rightMinWidth) >= minWidth * 3 + actualVal); + } + return false; + } + + /** + * 返回当前组件所在y值上方的所有组件中最小高度,且保证这些控件是相邻不隔断的 + * 判断对齐时考虑间隔 + */ + private int getUpMinHeightComp(int cY, int x) { + if (cY == margin.getTop()) { + return 0; + } + int max=container.getWidth() - margin.getRight(); + int mouseX = x; + int minHeight = cY; + int bott = 0; + if (isFindRelatedComps) { + upComps = new ArrayList(); + } + for(; mouseX margin.getLeft()) { + Component comp = container.getTopComp(mouseX, cY); + bott = comp.getHeight() + comp.getY()+actualVal; + if (bott == cY) { + if (comp.getHeight() < minHeight) { + minHeight = comp.getHeight(); + } + mouseX = comp.getX()-DEFAULT_AREA_LENGTH-actualVal; + if (isFindRelatedComps) { + upComps.add(comp); + } + } else{ + break; + } + } + return minHeight; + } + + /** + * 返回和当前组件相同y坐标的所有组件中最小高度,且保证这些控件是相邻不隔断的 + * 判断对齐时考虑间隔 + */ + private int getDownMinHeightComp(Component currentcomp, int y) { + int cX = currentcomp.getX(); + int cY = currentcomp.getY(); + int minHeight = currentcomp.getHeight(); + int max=container.getWidth() - margin.getRight(); + if (isFindRelatedComps) { + downComps = new ArrayList(); + } + int mouseX = cX + DEFAULT_AREA_LENGTH; + while (mouseX < max) { + Component comp = container.getComponentAt(mouseX, y); + if (comp.getY() == cY) { + if (comp.getHeight() < minHeight) { + minHeight = comp.getHeight(); + } + mouseX = comp.getX() + comp.getWidth() + DEFAULT_AREA_LENGTH + actualVal; + if (isFindRelatedComps) { + downComps.add(comp); + } + }else{ + break; + } + } + mouseX = cX - DEFAULT_AREA_LENGTH - actualVal; + while(mouseX > margin.getLeft()) { + Component comp = container.getComponentAt(mouseX, y); + if (comp.getY() == cY) { + if (comp.getHeight() < minHeight) { + minHeight = comp.getHeight(); + } + mouseX = comp.getX() - DEFAULT_AREA_LENGTH - actualVal; + if (isFindRelatedComps) { + downComps.add(comp); + } + }else{ + break; + } + } + return minHeight; + } + + /** + * 返回当前组件右侧相同x的所有组件中最小宽度,且保证这些控件是相邻不隔断的 + * 判断对齐时考虑间隔 + */ + private int getMinRightWidth(int cX, int cW, int y) { + int xL = cX + DEFAULT_AREA_LENGTH ; + xL = cW == 0 ? xL : (xL + cW + actualVal); + if (xL > container.getWidth() - margin.getRight()){ + return 0; + } + // 以当前组件紧挨着右侧的组件为基准,在y轴方向查找符合条件的组件 + Component targetComp = container.getComponentAt(xL, y); + int minWidth = targetComp.getWidth(); + int max = container.getHeight() - margin.getBottom(); + if (isFindRelatedComps) { + rightComps = new ArrayList(); + } + int mouseY = targetComp.getY() + DEFAULT_AREA_LENGTH; + while (mouseY margin.getTop()) { + Component comp = container.getComponentAt(xL, mouseY); + if (comp.getX() == targetComp.getX()) { + if (comp.getWidth() < minWidth) { + minWidth = comp.getWidth(); + } + mouseY = comp.getY() - DEFAULT_AREA_LENGTH - actualVal; + if (isFindRelatedComps) { + rightComps.add(comp); + } + }else{ + break; + } + } + return minWidth; + } + + /** + * 返回当前组件垂直方向同侧的组件(组件右边界相连)中最小宽度 + * 判断对齐时考虑间隔 + */ + private int getMinLeftWidth(Component currentComp, int x) { + int minWidth = currentComp.getWidth(); + int compRightLength = currentComp.getX() + currentComp.getWidth(); + int max = container.getHeight() - margin.getBottom(); + if (isFindRelatedComps) { + leftComps = new ArrayList(); + } + int rightx = 0; + int mouseY = currentComp.getY() + DEFAULT_AREA_LENGTH; + while(mouseYmargin.getTop()) { + Component comp = container.getComponentAt(x, mouseY); + rightx = comp.getX()+comp.getWidth(); + if (rightx == compRightLength) { + if (comp.getWidth() < minWidth) { + minWidth = comp.getWidth(); + } + mouseY = comp.getY() - DEFAULT_AREA_LENGTH - actualVal; + if (isFindRelatedComps) { + leftComps.add(comp); + } + }else{ + break; + } + } + return minWidth; + } + + /** + * 判断是否鼠标在组件的三等分区域,如果组件在布局管理器中间,上下左右都可能会三等分 + * @param parentComp 鼠标所在区域的组件 + * @param x 坐标x + * @param y 坐标y + * @return 是则返回true + */ + public boolean isTrisectionArea(Component parentComp, int x, int y) { + XCreator creator = (XCreator)parentComp; + if (container.getComponentCount() <= 1) { + return false; + } + int maxWidth = parentComp.getWidth(); + int maxHeight = parentComp.getHeight(); + int xL = parentComp.getX(); + int yL = parentComp.getY(); + // 组件宽高的十分之一和默认值取大 + int minRangeWidth = Math.max(maxWidth/BORDER_PROPORTION, DEFAULT_AREA_LENGTH); + int minRangeHeight = Math.max(maxHeight/BORDER_PROPORTION, DEFAULT_AREA_LENGTH); + if(y < yL+minRangeHeight ) { + // 在组件上侧三等分 + trisectAreaDirect = COMP_TOP; + } else if(y > yL + maxHeight - minRangeHeight) { + // 在组件下侧三等分 + trisectAreaDirect = COMP_BOTTOM; + } else if (x < xL + minRangeWidth) { + // 在组件左侧三等分 + trisectAreaDirect = COMP_LEFT; + } else if(x > xL + maxWidth - minRangeWidth) { + // 在组件右侧三等分 + trisectAreaDirect = COMP_RIGHT; + } + // tab布局的边界特殊处理,不进行三等分 + if(!creator.getTargetChildrenList().isEmpty()){ + return false; + } + + return !ComparatorUtils.equals(trisectAreaDirect, 0); + } + + /** + * 是否为组件交叉点区域 或者是相邻三组建中间点 + * @param currentComp 当前组件 + * @param x 坐标x + * @param y 坐标y + * @return 是则返回true + */ + public boolean isCrossPointArea(Component currentComp, int x, int y) { + // 3个及以上都会出现交叉点区域(包括边界处的) + if(currentComp == null || container.getComponentCount() <= 2){ + return false; + } + int cX = currentComp.getX(); + int cY = currentComp.getY(); + int cW = currentComp.getWidth(); + int cH = currentComp.getHeight(); + int areaWidth = Math.max(cW / BORDER_PROPORTION ,DEFAULT_AREA_LENGTH); + int areaHeight = Math.max(cH / BORDER_PROPORTION, DEFAULT_AREA_LENGTH); + int rx = cX + cW; + int by = cY + cH; + int objX = cX + areaWidth; + int objY = cY + areaHeight; + int containerW = container.getWidth() - margin.getRight(); + int containerH = container.getHeight() - margin.getBottom(); + if (x < objX && y < objY) { + //左上角区域 + crossPointAreaDirect = cY > margin.getTop() || cX > margin.getLeft() ? COMP_LEFT_TOP : 0; + } else if (y < objY && x > rx - areaWidth){ + //右上角 + crossPointAreaDirect = cY > margin.getTop() || rx < containerW ? COMP_RIGHT_TOP : 0; + } else if (x < objX && y > by - areaHeight) { + //左下角 + crossPointAreaDirect = cX > margin.getLeft() || by < containerH ? COMP_LEFT_BOTTOM : 0; + } else if (x > rx-areaWidth && y > by - areaHeight) { + //右下角 + crossPointAreaDirect = by < containerH || rx < containerW ? COMP_RIGHT_BOTTOM : 0; + } else { + isMiddlePosition(currentComp, x, y, areaWidth, areaHeight); + } + // tab布局的边界特殊处理 + XCreator creator = (XCreator)currentComp; + if(!creator.getTargetChildrenList().isEmpty()){ + return false; + } + return crossPointAreaDirect != 0; + } + + private void isMiddlePosition(Component comp, int x, int y, int areaWidth , int areaHeight) { + int cX = comp.getX(); + int cY = comp.getY(); + int cW = comp.getWidth(); + int cH = comp.getHeight(); + boolean isCrosspoint = false; + if (x > (cX + cW / 2 - areaWidth) && x < (cX + cW / 2 + areaWidth)) { + // 上下边框线中间位置 + Component leftComp = container.getLeftComp(cX, cY); + Component rightComp = container.getRightComp(cX, cY, cW); + if (y < cY + areaHeight) { + isCrosspoint = leftComp != null && rightComp != null && leftComp.getY() == cY && rightComp.getY() == cY; + crossPointAreaDirect = isCrosspoint ? COMP_TOP : 0; + } else if (y > cY + cH - areaHeight) { + leftComp = container.getBottomLeftComp(cX, cY, cH); + rightComp = container.getBottomRightComp(cX, cY, cH, cW); + if (leftComp != null && rightComp != null) { + isCrosspoint = leftComp.getY() + leftComp.getHeight() == cY + cH && rightComp.getY() + rightComp.getHeight() == cY + cH; + } + crossPointAreaDirect = isCrosspoint ? COMP_BOTTOM : 0; + } + } else if (y > (cY + cH / 2 - areaHeight) && y < (cY + cH / 2 + areaHeight)) { + // 左右边框线中间位置 + Component topComp = container.getTopComp(cX, cY); + Component bottomComp = container.getBottomComp(cX, cY, cH); + if (x < (cX + areaWidth)) { + isCrosspoint = topComp != null && bottomComp != null && topComp.getX() == cX && bottomComp.getX() == cX; + crossPointAreaDirect = isCrosspoint ? COMP_LEFT : 0; + } else if (x > (cX + cW - areaWidth)) { + topComp = container.getRightTopComp(cX, cY, cW); + bottomComp = container.getRightBottomComp(cX, cY, cH, cW); + if (topComp != null && bottomComp != null) { + isCrosspoint = topComp.getX() + topComp.getWidth() == cX + cW && bottomComp.getX() + bottomComp.getWidth() == cX+cW; + } + crossPointAreaDirect = isCrosspoint ? COMP_RIGHT : 0; + } + } + } + + /** + * 初始化周边组件列表 + */ + protected void initCompsList() { + rightComps = new ArrayList(); + leftComps = new ArrayList(); + upComps = new ArrayList(); + downComps = new ArrayList(); + } + + /** + * 清除周边组件列表 + */ + protected void clearCompsList() { + rightComps = null; + leftComps = null; + upComps = null; + downComps = null; + } + + /** + * 平分,正常情况拖入组件时,按照上1/4区域、下1/4区域为上下平分,中左侧1/2区域、中右侧1/2区域为左右平分 + * @param currentComp 当前位置组件 + * @param child 待放置组件 + * @param x x + * @param y y + */ + protected void fixHalve(Component currentComp, XCreator child, int x, int y) { + XCreator creator = (XCreator)currentComp; + if(!creator.getTargetChildrenList().isEmpty()){ + fixHalveOfTab(creator,child,x,y); + return; + } + int maxWidth = currentComp.getWidth(); + int maxHeight = currentComp.getHeight(); + int xL = currentComp.getX(); + int yL = currentComp.getY(); + Dimension dim = new Dimension(); + boolean isDividUp = y - yL <= maxHeight * TOP_HALF; + boolean isDividDown = y - yL >= maxHeight * BOTTOM_HALF; + boolean isDividLeft = x - xL < maxWidth / 2; + int finalX = xL; + int finalY = yL; + int finalW = maxWidth; + int finalH = maxHeight; + if (isDividUp){ + dim.width = maxWidth; + dim.height = maxHeight / 2 - actualVal / 2; + finalY = yL + dim.height + actualVal; + finalH = maxHeight - dim.height - actualVal; + } else if(isDividDown){ + // 若当前区域高度非偶数,那么和isDividUp时计算一致,否则永远都是上半部分小1px + dim.height = maxHeight / 2 - actualVal / 2; + dim.width = maxWidth; + finalH = maxHeight - dim.height - actualVal; + yL = yL + finalH + actualVal; + } else if(isDividLeft){ + dim.width = maxWidth / 2 - actualVal / 2; + dim.height = maxHeight; + finalX = xL + dim.width + actualVal; + finalW = maxWidth - dim.width - actualVal; + } else { + finalW = maxWidth / 2 - actualVal / 2; + xL = xL + finalW + actualVal; + dim.width = maxWidth - finalW - actualVal; + dim.height = maxHeight; + } + if (isCalculateChildPos) { + childPosition = new int[]{xL, yL, dim.width, dim.height}; + } else { + currentComp.setLocation(finalX, finalY); + currentComp.setSize(finalW, finalH); + child.setLocation(xL, yL); + child.setSize(dim); + } + } + + // 边界判断抄得原来的逻辑 + // tab布局的边界拖入新组件,和当前tab布局平分,这时候的actualVal组建间隔是tab里面的组建间隔 + // 不应该在外层自适应布局添加 + private void fixHalveOfTab(XCreator currentCreator, XCreator child, int x, int y){ + int maxWidth = currentCreator.getWidth(); + int maxHeight = currentCreator.getHeight(); + int xL = currentCreator.getX(); + int yL = currentCreator.getY(); + Dimension dim = new Dimension(); + int position = getPositionOfFix(currentCreator, x, y); + int finalX = xL; + int finalY = yL; + int finalW = maxWidth; + int finalH = maxHeight; + switch(position){ + case COMP_TOP: + dim.width = maxWidth; + dim.height = maxHeight / 2; + finalY = yL + dim.height; + finalH = maxHeight - dim.height; + break; + case COMP_BOTTOM: + dim.height = maxHeight / 2; + dim.width = maxWidth; + finalH = maxHeight-dim.height; + yL = yL + finalH; + break; + case COMP_LEFT: + dim.width = maxWidth / 2; + dim.height = maxHeight; + finalX = xL + dim.width; + finalW = maxWidth - dim.width; + break; + default: + finalW = maxWidth / 2; + xL = xL + finalW; + dim.width = maxWidth - finalW; + dim.height = maxHeight; + } + if (isCalculateChildPos) { + childPosition = new int[]{xL, yL, dim.width, dim.height}; + } else { + currentCreator.setLocation(finalX, finalY); + currentCreator.setSize(finalW, finalH); + currentCreator.recalculateChildWidth(finalW); + currentCreator.recalculateChildHeight(finalH); + child.setLocation(xL, yL); + child.setSize(dim); + } + } + + private int getPositionOfFix(XCreator currentCreator,int x,int y){ + int position = 0; + XLayoutContainer cardLayout = ((XWCardMainBorderLayout) currentCreator).getCardPart(); + XLayoutContainer container = (XLayoutContainer) cardLayout.getComponent(0); + Rectangle rect = ComponentUtils.getRelativeBounds(container); + int tempX = x - rect.x; + int tempY = y - rect.y + WCardMainBorderLayout.TAB_HEIGHT; + int containerX = container.getX(); + int containerY = container.getY(); + int containerWidth = container.getWidth(); + int containerHeight = container.getHeight(); + // 当前坐标点 + Rectangle currentXY = new Rectangle(tempX, tempY, 1, 1); + // 上边缘 + Rectangle upEdge = new Rectangle(containerX, containerY, containerWidth, BORDER_PROPORTION); + if(upEdge.intersects(currentXY)){ + position = COMP_TOP; + } + int bottomY = containerY + containerHeight - BORDER_PROPORTION; + // 下边缘 + Rectangle bottomEdge = new Rectangle(containerX, bottomY, containerWidth, BORDER_PROPORTION); + if(bottomEdge.intersects(currentXY)){ + position = COMP_BOTTOM; + } + //左右边缘的高度 -10*2 是为了不和上下边缘重合 + int verticalHeight = containerHeight - BORDER_PROPORTION * 2; + int leftY = containerY + BORDER_PROPORTION; + // 左边缘 + Rectangle leftEdge = new Rectangle(containerX, leftY, BORDER_PROPORTION, verticalHeight); + if(leftEdge.intersects(currentXY)){ + position = COMP_LEFT; + } + return position; + } + + /** + * 组件交叉区域进行插入时,调整受到变动的其他组件,之前是交叉区域插入也按照三等分逻辑,后面测试中发现有bug,改为和bi一样的鼠标所在侧平分 + * 默认左上角、右下角区域是垂直方向插入组件 + * 右上角和左下角是水平方向插入组件,这样避免田字块时重复 + * @param currentComp 当前位置组件 + * @param child 待放置组件 + * @param x x + * @param y y + */ + protected void fixCrossPointArea(Component currentComp, XCreator child, int x, int y) { + //计算前先全部初始化待调整控件所在的list + initCompsList(); + switch(crossPointAreaDirect) { + case COMP_LEFT_TOP : + dealCrossPointAtLeftTop(currentComp, child); + break; + case COMP_RIGHT_BOTTOM : + dealCrossPointAtRightBottom(currentComp, child); + break; + case COMP_LEFT_BOTTOM : + dealCrossPointAtLeftBottom(currentComp, child); + break; + case COMP_RIGHT_TOP : + dealCrossPointAtRightTop(currentComp, child); + break; + case COMP_TOP : + dealCrossPointAtTop(currentComp, child); + break; + case COMP_BOTTOM : + dealCrossPointAtBottom(currentComp, child); + break; + case COMP_LEFT : + dealCrossPointAtLeft(currentComp, child); + break; + case COMP_RIGHT : + dealCrossPointAtRight(currentComp, child); + break; + } + crossPointAreaDirect = 0; + clearCompsList(); + } + + /** + * 左上交叉区域插入组件,默认垂直方向插入 + */ + private void dealCrossPointAtLeftTop(Component currentComp, XCreator child) { + int minDH = 0, minRW = 0, childw = 0, childh = 0; + int cX = currentComp.getX(); + int cY = currentComp.getY(); + int cH = currentComp.getHeight(); + int cW = currentComp.getWidth(); + Component topComp = container.getTopComp(cX, cY); + Component leftComp = container.getLeftComp(cX, cY); + //上方没有组件或者有一个x坐标不相同的组件 + if (topComp==null || topComp.getX()!=cX) { + minDH = cH < leftComp.getHeight() ? cH : leftComp.getHeight(); + downComps.add(leftComp); + downComps.add(currentComp); + int dLength = minDH / 2; + childw = leftComp.getWidth()+cW+actualVal; + childh = dLength-actualVal / 2; + if (isCalculateChildPos) { + childPosition = new int[]{leftComp.getX(), leftComp.getY(), childw, childh}; + } else{ + //先设置child位置,不然leftComp坐标调整后就不对了 + child.setLocation(leftComp.getX(), leftComp.getY()); + child.setSize(childw, childh); + calculateBottomComps(dLength); + } + } else { + rightComps.add(currentComp); + rightComps.add(topComp); + minRW = cW margin.getLeft()) { + Component targetRightComp = container.getLeftComp(cX, y); + minLeftW = getMinLeftWidth(targetRightComp, cX-DEFAULT_AREA_LENGTH); + } + dealTrisectAtRight(child, minLeftW, minRightW); + } + crossPointAreaDirect = 0; + clearCompsList(); + } + + /** + * 当前组件上边界区域三等分 + */ + private void dealTrisectAtTop(XCreator child, int minUH, int minDH) { + // 三等分有间隔时,实际是两侧都要减去半个间隔大小 + int averageH = (minUH+minDH - actualVal) / 3; + int dLength = 0; + int uLength = 0; + if (minDH==0) { + dLength = 0; + uLength = minUH / 2; + calculateTopComps(uLength, child, uLength); + return; + } else if(minUH == 0){ + dLength = minDH / 2; + int witdh = container.getWidth() - margin.getLeft() - margin.getRight(); + if (!isCalculateChildPos) { + calculateBottomComps(dLength); + child.setLocation(margin.getLeft(), margin.getRight()); + child.setSize(witdh, dLength - actualVal / 2); + } else { + childPosition = new int[] {margin.getLeft(), margin.getRight(), witdh, dLength - actualVal / 2}; + } + return; + } else if (minUH >= minDH) { + minDH -= actualVal / 2; + if ((minDH * 2 / 3) < minHeight) { + dLength = minDH - minHeight; + }else { + dLength = minDH / 3; + } + uLength = averageH - dLength; + } else{ + minUH -= actualVal / 2; + if ((minUH * 2 / 3) < minHeight) { + uLength = minUH - minHeight; + }else { + uLength = minUH / 3; + } + dLength = averageH - uLength; + } + if (!isCalculateChildPos) { + calculateBottomComps(dLength); + } + // 计算两侧时,都额外去掉半个间隔,3等分和平分交叉点不同,只能特殊处理下 + averageH += actualVal / 2; + calculateTopComps(uLength, child, averageH); + } + + /** + * 当前组件右边界区域三等分 + */ + private void dealTrisectAtRight(XCreator child, int minLW, int minRW) { + int averageW = (minLW + minRW - actualVal) / 3; + int leftLength = 0; + int rightLength = 0; + if (minLW == 0) { + rightLength = minRW / 2; + int height = container.getHeight() - margin.getBottom() - margin.getTop(); + if (!isCalculateChildPos) { + calculateRightComps(rightLength); + child.setLocation(margin.getLeft(), margin.getRight()); + child.setSize(rightLength - actualVal / 2, height); + } else { + childPosition = new int[] {margin.getLeft(), margin.getRight(), rightLength - actualVal / 2, height}; + } + return; + } else if(minRW == 0){ + leftLength = minLW / 2; + calculateLeftComps(leftLength, child, leftLength); + return; + } else if (minRW >= minLW) { + minLW -= actualVal / 2; + if(minLW * 2 / 3 < minWidth) { + leftLength = minLW - minWidth; + } else { + leftLength = minLW / 3; + } + rightLength = averageW - leftLength; + } else { + minRW -= actualVal / 2; + if(minRW * 2 / 3 < minWidth) { + rightLength = minRW - minWidth; + } else { + rightLength = minRW / 3; + } + leftLength = averageW - rightLength; + } + if (!isCalculateChildPos) { + calculateRightComps(rightLength); + } + // averageW 是已经去除间隔后的大小,所以再加上半个间隔,否则处理时会变小 + averageW += actualVal / 2; + calculateLeftComps(leftLength, child, averageW); + } + + private void calculateBottomComps(int length) { + length += actualVal / 2; + for (int i = 0,num = downComps.size(); i < num; i++){ + Component comp = downComps.get(i); + comp.setLocation(comp.getX(), comp.getY() + length); + int offset = comp.getHeight() - length; + comp.setSize(comp.getWidth(), offset); + XCreator creator = (XCreator)comp; + creator.recalculateChildHeight(offset); + } + } + + private void calculateTopComps(int length, XCreator child, int averageH) { + length += actualVal / 2; + int childWidth = (upComps.size() - 1) * actualVal; + int childX = container.getWidth() - margin.getLeft() - margin.getRight(); + int childY = 0; + if(upComps.size() > INDEX_ZERO){ + childY = upComps.get(INDEX_ZERO).getY() + upComps.get(INDEX_ZERO).getHeight() - length; + } + for (int i = 0,num = upComps.size(); i < num; i++){ + Component comp = upComps.get(i); + childWidth += comp.getWidth(); + if (comp.getX() < childX){ + childX = comp.getX(); + } + if (!isCalculateChildPos) { + int offset = comp.getHeight() - length; + comp.setSize(comp.getWidth(), offset); + XCreator creator = (XCreator)comp; + creator.recalculateChildHeight(offset); + } + } + childY += actualVal; + averageH -= actualVal/2; + if (isCalculateChildPos) { + childPosition = new int[]{childX, childY, childWidth, averageH}; + } else { + child.setLocation(childX, childY); + child.setSize(childWidth, averageH); + } + } + + private void calculateLeftComps(int length, XCreator child, int averageW) { + length += actualVal / 2; + if (leftComps.isEmpty()) { + return; + } + int childH = (leftComps.size() - 1) * actualVal; + int childX = 0; + if(leftComps.size() > INDEX_ZERO){ + childX = leftComps.get(INDEX_ZERO).getX() + leftComps.get(INDEX_ZERO).getWidth() - length; + } + int childY = container.getHeight() - margin.getBottom(); + for (int i = 0,num = leftComps.size(); i < num; i++){ + Component comp = leftComps.get(i); + childH += comp.getHeight(); + if (comp.getY() < childY){ + childY = comp.getY(); + } + if (!isCalculateChildPos) { + int offset = comp.getWidth() - length; + comp.setSize(offset, comp.getHeight()); + XCreator creator = (XCreator)comp; + creator.recalculateChildWidth(offset); + } + } + childX += actualVal; + averageW -= actualVal/2; + if (isCalculateChildPos) { + childPosition = new int[]{childX, childY, averageW, childH}; + } else { + child.setLocation(childX, childY); + child.setSize(averageW, childH); + } + } + + private void calculateRightComps(int length) { + length += actualVal / 2; + for (int i=0,num=rightComps.size(); i rightComps; - private List leftComps; - private List downComps; - private List upComps; - // 三等分时计算对应侧的组件 - private boolean isFindRelatedComps = false; - // 渲染时只计算对应的bounds而不调整 - private boolean isCalculateChildPos = false; - private int[] childPosition = null; //painter用的位置 private HoverPainter painter; - private int minWidth = 0; // 最小尺寸,由于屏幕百分比里不同,显示的最小大小也不同 - private int minHeight = 0; - private int actualVal = 0; // 存在间隔时,add move drag 判断对齐等都要考虑 - private PaddingMargin margin; // 布局容器边距 /** * 构造函数 @@ -129,7 +95,7 @@ public class FRFitLayoutAdapter extends AbstractLayoutAdapter { updateCreatorBackBound(); } - private void updateCreatorBackBound() { + public void updateCreatorBackBound() { for (int i=0,size=container.getComponentCount(); i= min+actualVal; - } - - private boolean canAcceptWhileTrisection(Component comp, int x, int y) { - //符合三等分,实际区域不满足三等分的大小 - int cX = comp.getX(), cY = comp.getY(), cH = comp.getHeight(), cW = comp.getWidth(); - int upMinHeight = 0, downMinHeight = 0, leftMinWidth = 0, rightMinWidth = 0; - if (ComparatorUtils.equals(trisectAreaDirect, COMP_TOP)) { - upMinHeight = getUpMinHeightComp(cY, x); - downMinHeight = getDownMinHeightComp(comp, y); - return upMinHeight==0 ? downMinHeight>= minHeight*2+actualVal : (upMinHeight+downMinHeight)>= minHeight*3+actualVal; - } else if(ComparatorUtils.equals(trisectAreaDirect, COMP_BOTTOM)) { - upMinHeight = getUpMinHeightComp(cY+cH+actualVal, x); - if (cY+cH+DEFAULT_AREA_LENGTH>container.getHeight() - margin.getBottom()){ - downMinHeight = 0; - } else { - Component targetComp = container.getBottomComp(x, cY, cH); - downMinHeight = getDownMinHeightComp(targetComp, cY+cH+DEFAULT_AREA_LENGTH+actualVal); - } - return downMinHeight == 0 ? upMinHeight>= minHeight*2+actualVal : (upMinHeight+downMinHeight)>= minHeight*3+actualVal; - } else if(ComparatorUtils.equals(trisectAreaDirect, COMP_LEFT)) { - rightMinWidth = getMinRightWidth(cX, 0, y); - if(cX-DEFAULT_AREA_LENGTH < margin.getLeft()) { - leftMinWidth = 0; - } else { - Component targetRightComp = container.getLeftComp(cX, y); - leftMinWidth = getMinLeftWidth(targetRightComp, cX-DEFAULT_AREA_LENGTH - actualVal); - } - return leftMinWidth==0 ? rightMinWidth>=minWidth*2+actualVal : (leftMinWidth+rightMinWidth)>= minWidth*3+actualVal; - } else if(ComparatorUtils.equals(trisectAreaDirect, COMP_RIGHT)) { - leftMinWidth = getMinLeftWidth(comp, x); - rightMinWidth = getMinRightWidth(cX, cW, y); - return rightMinWidth==0 ? leftMinWidth>=minWidth*2+actualVal : (leftMinWidth+rightMinWidth)>= minWidth*3+actualVal; - } - return false; - } - - /** - * 返回当前组件所在y值上方的所有组件中最小高度,且保证这些控件是相邻不隔断的 - * 判断对齐时考虑间隔 - */ - private int getUpMinHeightComp(int cY, int x) { - if (cY == margin.getTop()) { - return 0; - } - int max=container.getWidth() - margin.getRight(); - int mouseX = x; - int minHeight = cY; - int bott = 0; - if (isFindRelatedComps) { - upComps = new ArrayList(); - } - for(; mouseX margin.getLeft()) { - Component comp = container.getTopComp(mouseX, cY); - bott = comp.getHeight()+comp.getY()+actualVal; - if (bott == cY) { - if (comp.getHeight() < minHeight) { - minHeight = comp.getHeight(); - } - mouseX = comp.getX()-DEFAULT_AREA_LENGTH-actualVal; - if (isFindRelatedComps) { - upComps.add(comp); - } - } else{ - break; - } - } - return minHeight; - } - - /** - * 返回和当前组件相同y坐标的所有组件中最小高度,且保证这些控件是相邻不隔断的 - * 判断对齐时考虑间隔 - */ - private int getDownMinHeightComp(Component currentcomp, int y) { - int cX = currentcomp.getX(); - int cY = currentcomp.getY(); - int minHeight = currentcomp.getHeight(); - int max=container.getWidth() - margin.getRight(); - if (isFindRelatedComps) { - downComps = new ArrayList(); - } - int mouseX = cX + DEFAULT_AREA_LENGTH; - while (mouseX < max) { - Component comp = container.getComponentAt(mouseX, y); - if (comp.getY()==cY) { - if (comp.getHeight() < minHeight) { - minHeight = comp.getHeight(); - } - mouseX = comp.getX()+comp.getWidth()+DEFAULT_AREA_LENGTH + actualVal; - if (isFindRelatedComps) { - downComps.add(comp); - } - }else{ - break; - } - } - mouseX = cX - DEFAULT_AREA_LENGTH-actualVal; - while(mouseX > margin.getLeft()) { - Component comp = container.getComponentAt(mouseX, y); - if (comp.getY()==cY) { - if (comp.getHeight() < minHeight) { - minHeight = comp.getHeight(); - } - mouseX = comp.getX() - DEFAULT_AREA_LENGTH - actualVal; - if (isFindRelatedComps) { - downComps.add(comp); - } - }else{ - break; - } - } - return minHeight; + protected boolean canAcceptWhileCrossPoint(Component comp, int x, int y) { + return super.canAcceptWhileCrossPoint(comp, x, y); } - - /** - * 返回当前组件右侧相同x的所有组件中最小宽度,且保证这些控件是相邻不隔断的 - * 判断对齐时考虑间隔 - */ - private int getMinRightWidth(int cX, int cW, int y) { - int xL = cX+DEFAULT_AREA_LENGTH ; - xL = cW==0 ? xL : xL+cW+actualVal; - if (xL>container.getWidth() - margin.getRight()){ - return 0; - } - // 以当前组件紧挨着右侧的组件为基准,在y轴方向查找符合条件的组件 - Component targetComp = container.getComponentAt(xL, y); - int minWidth = targetComp.getWidth(); - int max=container.getHeight() - margin.getBottom(); - if (isFindRelatedComps) { - rightComps = new ArrayList(); - } - int mouseY = targetComp.getY() + DEFAULT_AREA_LENGTH; - while (mouseYmargin.getTop()) { - Component comp = container.getComponentAt(xL, mouseY); - if (comp.getX()==targetComp.getX()) { - if (comp.getWidth() < minWidth) { - minWidth = comp.getWidth(); - } - mouseY = comp.getY() - DEFAULT_AREA_LENGTH - actualVal; - if (isFindRelatedComps) { - rightComps.add(comp); - } - }else{ - break; - } - } - return minWidth; - } - - /** - * 返回当前组件垂直方向同侧的组件(组件右边界相连)中最小宽度 - * 判断对齐时考虑间隔 - */ - private int getMinLeftWidth(Component currentComp, int x) { - int minWidth = currentComp.getWidth(); - int compRightLength = currentComp.getX()+currentComp.getWidth(); - int max=container.getHeight() - margin.getBottom(); - if (isFindRelatedComps) { - leftComps = new ArrayList(); - } - int rightx = 0; - int mouseY = currentComp.getY()+DEFAULT_AREA_LENGTH; - while(mouseYmargin.getTop()) { - Component comp = container.getComponentAt(x, mouseY); - rightx = comp.getX()+comp.getWidth(); - if (rightx == compRightLength) { - if (comp.getWidth() < minWidth) { - minWidth = comp.getWidth(); - } - mouseY = comp.getY() - DEFAULT_AREA_LENGTH - actualVal; - if (isFindRelatedComps) { - leftComps.add(comp); - } - }else{ - break; - } - } - return minWidth; + + protected boolean canAcceptWhileTrisection(Component comp, int x, int y) { + return super.canAcceptWhileTrisection(comp, x, y); } /** @@ -543,36 +240,7 @@ public class FRFitLayoutAdapter extends AbstractLayoutAdapter { * @return 是则返回true */ public boolean isTrisectionArea(Component parentComp, int x, int y) { - XCreator creator = (XCreator)parentComp; - if (container.getComponentCount()<=1) { - return false; - } - int maxWidth = parentComp.getWidth(); - int maxHeight = parentComp.getHeight(); - int xL = parentComp.getX(); - int yL = parentComp.getY(); - // 组件宽高的十分之一和默认值取大 - int minRangeWidth = Math.max(maxWidth/BORDER_PROPORTION, DEFAULT_AREA_LENGTH); - int minRangeHeight = Math.max(maxHeight/BORDER_PROPORTION, DEFAULT_AREA_LENGTH); - if(yyL+maxHeight-minRangeHeight) { - // 在组件下侧三等分 - trisectAreaDirect = COMP_BOTTOM; - } else if (xxL+maxWidth-minRangeWidth) { - // 在组件右侧三等分 - trisectAreaDirect = COMP_RIGHT; - } - // tab布局的边界特殊处理,不进行三等分 - if(!creator.getTargetChildrenList().isEmpty()){ - return false; - } - - return !ComparatorUtils.equals(trisectAreaDirect, 0); + return super.isTrisectionArea(parentComp, x, y); } /** @@ -583,96 +251,15 @@ public class FRFitLayoutAdapter extends AbstractLayoutAdapter { * @return 是则返回true */ public boolean isCrossPointArea(Component currentComp, int x, int y) { - // 3个及以上都会出现交叉点区域(包括边界处的) - if(currentComp == null || container.getComponentCount() <= 2){ - return false; - } - int cX = currentComp.getX(); - int cY = currentComp.getY(); - int cW = currentComp.getWidth(); - int cH = currentComp.getHeight(); - int areaWidth = Math.max(cW/BORDER_PROPORTION ,DEFAULT_AREA_LENGTH); - int areaHeight = Math.max(cH/BORDER_PROPORTION, DEFAULT_AREA_LENGTH); - int rx = cX + cW; - int by = cY + cH; - int objX = cX + areaWidth; - int objY = cY + areaHeight; - int containerW = container.getWidth() - margin.getRight(); - int containerH = container.getHeight() - margin.getBottom(); - if (x margin.getTop() || cX > margin.getLeft() ? COMP_LEFT_TOP : 0; - } else if (yrx-areaWidth){ - //右上角 - crossPointAreaDirect = cY>margin.getTop() || rx < containerW ? COMP_RIGHT_TOP : 0; - } else if (xby-areaHeight) { - //左下角 - crossPointAreaDirect = cX>margin.getLeft() || byrx-areaWidth && y>by-areaHeight) { - //右下角 - crossPointAreaDirect = bycX+cW/2-areaWidth && x cY + cH - areaHeight) { - leftComp = container.getBottomLeftComp(cX, cY, cH); - rightComp = container.getBottomRightComp(cX, cY, cH, cW); - if (leftComp!=null && rightComp!=null) { - isCrosspoint = leftComp.getY()+leftComp.getHeight() == cY + cH && rightComp.getY()+rightComp.getHeight()== cY + cH; - } - crossPointAreaDirect = isCrosspoint ? COMP_BOTTOM : 0; - } - } else if (y>cY+cH/2-areaHeight && y cX+cW-areaWidth) { - topComp = container.getRightTopComp(cX, cY, cW); - bottomComp = container.getRightBottomComp(cX, cY, cH, cW); - if (topComp!=null && bottomComp!=null) { - isCrosspoint = topComp.getX()+topComp.getWidth()==cX+cW && bottomComp.getX()+bottomComp.getWidth()== cX+cW; - } - crossPointAreaDirect = isCrosspoint ? COMP_RIGHT : 0; - } - } - } - - private void initCompsList() { - rightComps = new ArrayList(); - leftComps = new ArrayList(); - upComps = new ArrayList(); - downComps = new ArrayList(); + + protected void initCompsList() { + super.initCompsList(); } - - private void clearCompsList() { - rightComps = null; - leftComps = null; - upComps = null; - downComps = null; + + protected void clearCompsList() { + super.clearCompsList(); } private Rectangle adjustBackupBound(Rectangle backupBound,XWCardMainBorderLayout mainLayout){ // 参数界面高度对纵坐标产生的影响 @@ -1057,604 +644,28 @@ public class FRFitLayoutAdapter extends AbstractLayoutAdapter { /** * 平分,正常情况拖入组件时,按照上1/4区域、下1/4区域为上下平分,中左侧1/2区域、中右侧1/2区域为左右平分 */ - private void fixHalve(Component currentComp, XCreator child, int x, int y) { - XCreator creator = (XCreator)currentComp; - if(!creator.getTargetChildrenList().isEmpty()){ - fixHalveOfTab(creator,child,x,y); - return; - } - int maxWidth = currentComp.getWidth(); - int maxHeight = currentComp.getHeight(); - int xL = currentComp.getX(); - int yL = currentComp.getY(); - Dimension dim = new Dimension(); - boolean isDividUp = y - yL<=maxHeight*TOP_HALF; - boolean isDividDown = y - yL>=maxHeight*BOTTOM_HALF; - boolean isDividLeft = x -xL margin.getLeft()) { - Component targetRightComp = container.getLeftComp(cX, y); - minLeftW = getMinLeftWidth(targetRightComp, cX-DEFAULT_AREA_LENGTH); - } - dealTrisectAtRight(child, minLeftW, minRightW); - } - crossPointAreaDirect = 0; - clearCompsList(); + protected void fixTrisect(Component currentComp, XCreator child, int x, int y) { + super.fixTrisect(currentComp, child, x, y); } - - /** - * 当前组件上边界区域三等分 - */ - private void dealTrisectAtTop(XCreator child, int minUH, int minDH) { - // 三等分有间隔时,实际是两侧都要减去半个间隔大小 - int averageH = (minUH+minDH - actualVal)/3; - int dLength = 0; - int uLength = 0; - if (minDH==0) { - dLength = 0; - uLength = minUH/2; - calculateTopComps(uLength, child, uLength); - return; - } else if(minUH==0){ - dLength = minDH/2; - int witdh = container.getWidth() - margin.getLeft() - margin.getRight(); - if (!isCalculateChildPos) { - calculateBottomComps(dLength); - child.setLocation(margin.getLeft(), margin.getRight()); - child.setSize(witdh, dLength - actualVal/2); - } else { - childPosition = new int[] {margin.getLeft(), margin.getRight(), witdh, dLength - actualVal/2}; - } - return; - } else if (minUH >= minDH) { - minDH -= actualVal/2; - if ((minDH*2/3)=minLW) { - minLW -= actualVal/2; - if(minLW*2/3 INDEX_ZERO){ - childY = upComps.get(INDEX_ZERO).getY()+upComps.get(INDEX_ZERO).getHeight()-length; - } - for (int i=0,num=upComps.size(); i INDEX_ZERO){ - childX = leftComps.get(INDEX_ZERO).getX()+leftComps.get(INDEX_ZERO).getWidth()-length; - } - int childY = container.getHeight() - margin.getBottom(); - for (int i=0,num=leftComps.size(); i designer.getRootComponent().getHeight() + } else if (y + current_bounds.getHeight() > (designer.getRootComponent().getHeight() + designer.getParaHeight()) && designer.getSelectionModel().hasSelectionComponent()) { - y = designer.getRootComponent().getHeight() - current_bounds.height; + y = designer.getRootComponent().getHeight() + designer.getParaHeight() - current_bounds.height; } return new Point(x, y); } diff --git a/designer_form/src/com/fr/design/designer/beans/painters/FRAbsoluteLayoutPainter.java b/designer_form/src/com/fr/design/designer/beans/painters/FRAbsoluteLayoutPainter.java index 04e6018fc..a6da42a04 100644 --- a/designer_form/src/com/fr/design/designer/beans/painters/FRAbsoluteLayoutPainter.java +++ b/designer_form/src/com/fr/design/designer/beans/painters/FRAbsoluteLayoutPainter.java @@ -1,6 +1,13 @@ package com.fr.design.designer.beans.painters; +import com.fr.design.designer.beans.adapters.layout.FRAbsoluteLayoutAdapter; +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.form.util.XCreatorConstants; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.FormDesigner; +import com.fr.general.FRLogger; import java.awt.*; @@ -8,19 +15,188 @@ import java.awt.*; * Created by zhouping on 2016/7/11. */ public class FRAbsoluteLayoutPainter extends AbstractPainter { + + private static final int BORDER_PROPORTION = 10; + private static final int X = 0; + private static final int Y = 1; + private static final int WIDTH = 2; + private static final int HEIGHT = 3; + + private static final Color DEPEND_LINE_COLOR = new Color(200, 200, 200); + private static final int DEPEND_LINE_SCOPE = 3; + + /** + * 构造函数 + * @param container + */ public FRAbsoluteLayoutPainter(XLayoutContainer container) { super(container); } /** * 组件渲染 - * - * @param g 画图类 + * @param g 画图类 * @param startX 开始位置x * @param startY 开始位置y */ @Override public void paint(Graphics g, int startX, int startY) { + if(hotspot_bounds == null && creator != null && container != null){ + drawDependingLine(g); + return; + } super.paint(g, startX, startY); + //如果absolute不可编辑那么就将之当普通控件处理,在周围添加控件, + //否则,只往内部添加,不需要出现蓝色悬浮提示框 + if(container.isEditable()){ + return; + } + int x = hotspot.x - hotspot_bounds.x; + int y = hotspot.y - hotspot_bounds.y; + FRAbsoluteLayoutAdapter adapter = (FRAbsoluteLayoutAdapter) container.getLayoutAdapter(); + + int[] hot_rec; + + boolean accept = adapter.accept(creator, x, y); + Component currentComp = container.getComponentAt(x, y); + //不可编辑的时候要获取顶层的绝对布局容器 + if (XCreatorUtils.getHotspotContainer((XCreator) currentComp) != null) { + currentComp = XCreatorUtils.getHotspotContainer((XCreator) currentComp).getTopLayout(); + if (currentComp == null) { + FRLogger.getLogger().info("FRAbsoluteLayoutPainter get currentComp null!"); + return; + } + } + else{ + FRLogger.getLogger().info("FRAbsoluteLayoutPainter getHotspotContainer currentComp null!"); + return; + } + Color bColor = XCreatorConstants.FIT_LAYOUT_HOTSPOT_COLOR; + if (accept) { + y = (y == container.getHeight()) ? y - 1 : y; + x = (x == container.getWidth()) ? x - 1 : x; + hot_rec = adapter.getChildPosition(currentComp, creator, x + hotspot_bounds.x, y + hotspot_bounds.y); + } else { + bColor = XCreatorConstants.LAYOUT_FORBIDDEN_COLOR; + Rectangle rec = currentComp.getBounds(); + hot_rec = currentComp == container ? new int[]{x, y, 0, 0} : new int[]{rec.x, rec.y, rec.width, rec.height}; + } + drawRegionBackground(g, hot_rec[X], hot_rec[Y] + startY, hot_rec[WIDTH], hot_rec[HEIGHT], bColor, accept); + if (accept) { + //画交叉区域和中间点区域 + //拖入的区域也改为整个渲染,点区域的后画下,不然被遮住了 + paintCrossPoint(currentComp, g, x, y); + } + } + + private void paintCrossPoint(Component currentComp, Graphics g, int x, int y) { + if (currentComp == container) { + return; + } + Color bColor = XCreatorConstants.FIT_LAYOUT_POINT_COLOR; + int cX = currentComp.getX(), cY = currentComp.getY(), cH = currentComp.getHeight(), cW = currentComp.getWidth(); + int defaultWidth = cW / BORDER_PROPORTION, defaultHeight = cH / BORDER_PROPORTION; + // 交叉点提示区域最大值为10px + int defaultLength = Math.min(BORDER_PROPORTION, Math.min(defaultWidth, defaultHeight)); + Component topComp = container.getTopComp(cX, cY); + Component bottomComp = container.getBottomComp(cX, cY, cH); + Component rightComp = container.getRightComp(cX, cY, cW); //组件的左右组件要区分上侧和下侧 + Component leftComp = container.getLeftComp(cX, cY); + boolean top = topComp != null && topComp != container, left = leftComp != null && leftComp != container, + bottom = bottomComp != null && bottomComp != container, right = rightComp != null && rightComp != container; + if (top || left) { + drawRegionBackground(g, cX + hotspot_bounds.x, cY + hotspot_bounds.y, defaultLength, defaultLength, bColor, true); + } + if (bottom || left) { + drawRegionBackground(g, cX + hotspot_bounds.x, cY + cH - defaultLength + hotspot_bounds.y, defaultLength, defaultLength, bColor,true); + } + if (top || right) { + drawRegionBackground(g, cX + cW - defaultLength + hotspot_bounds.x, cY + hotspot_bounds.y, defaultLength, defaultLength, bColor,true); + } + if (bottom || right) { + drawRegionBackground(g, cX + cW - defaultLength + hotspot_bounds.x, cY + cH - defaultLength + hotspot_bounds.y, defaultLength, defaultLength, bColor,true); + } + if (left && right) { + if (leftComp.getY() == cY && rightComp.getY() == cY) { + drawRegionBackground(g, cX + cW / 2 - defaultWidth + hotspot_bounds.x, cY + hotspot_bounds.y, defaultWidth * 2, defaultLength, bColor,true); + } + //底边线位置,左右组件都不为null且低端对齐,取左、右靠下侧组件判断 + leftComp = container.getBottomLeftComp(cX, cY, cH); + rightComp = container.getBottomRightComp(cX, cY, cH, cW); + if ((leftComp.getY() + leftComp.getHeight() == cY + cH) && (rightComp.getY() + rightComp.getHeight()== cY + cH)) { + drawRegionBackground(g, cX + cW / 2 - defaultWidth + hotspot_bounds.x, cY + cH - defaultLength + hotspot_bounds.y, defaultWidth * 2, defaultLength, bColor,true); + } + } + if (top && bottom) { + if (topComp.getX() == cX && bottomComp.getX() == cX) { + drawRegionBackground(g, cX + hotspot_bounds.x, cY + cH / 2 - defaultHeight + hotspot_bounds.y, defaultLength, defaultHeight * 2, bColor,true); + } + // 右边线位置,上下组件不为null且右端对齐,取上、下靠右侧组件判断 + topComp = container.getRightTopComp(cX, cY, cW); + bottomComp = container.getRightBottomComp(cX, cY, cH, cW); + if ((topComp.getX() + topComp.getWidth() == cX + cW) && (bottomComp.getX() + bottomComp.getWidth() == cX + cW)) { + drawRegionBackground(g, cX + cW - defaultLength + hotspot_bounds.x, cY + cH / 2 - defaultHeight + hotspot_bounds.y, defaultLength, defaultHeight * 2, bColor,true); + } + } + } + + // 画依附线 + private void drawDependingLine(Graphics g){ + Graphics2D g2d = (Graphics2D) g; + Stroke backup = g2d.getStroke(); + + // 当前拖拽组件的坐标 + int oriX = creator.getX(); + int oriY = creator.getY(); + + // 拖拽位置的即时坐标 + double x = hotspot.getX(); + double y = hotspot.getY(); + + // 容器所有的内部组件的横纵坐标值 + int[] posXs = container.getHors(); + int[] posYs = container.getVeris(); + + // 依附线的坐标 + int lineX = 0; + int lineY = 0; + + // 根据拖拽位置调整依附线的坐标 + lineX = getDependLinePos(lineX, posXs, oriX, x); + lineY = getDependLinePos(lineY, posYs, oriY, y); + + + g2d.setStroke(backup); + g2d.setColor(DEPEND_LINE_COLOR); + if(lineX != 0){ + g2d.drawRect(lineX, 0, 0, container.getHeight()); + } + if(lineY != 0){ + g2d.drawRect(0, lineY, container.getWidth(), 0); + } + + } + + /** + * 根据容器内部组件的横纵坐标值画依附线 + * + * @param lineCoordinate 依附线坐标值 + * @param referCoordinates 容器内部所有组件坐标值 + * @param oriCoordinate 当前拖拽组件坐标 + * @param currentCoordinate 拖拽位置的即时坐标 + * @return 依附线的坐标 + * + */ + private int getDependLinePos(int lineCoordinate,int referCoordinates[],int oriCoordinate,double currentCoordinate){ + for(int i = 0; i < referCoordinates.length; i++){ + if(referCoordinates[i] == oriCoordinate){ + continue; + } + if(currentCoordinate > referCoordinates[i] - DEPEND_LINE_SCOPE && currentCoordinate < referCoordinates[i] + DEPEND_LINE_SCOPE){ + lineCoordinate = referCoordinates[i]; + break; + } + } + return lineCoordinate; } } diff --git a/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java b/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java index 3a110e321..4c543300b 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java +++ b/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java @@ -21,10 +21,9 @@ import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; import com.fr.design.form.layout.FRAbsoluteLayout; import com.fr.design.form.util.XCreatorConstants; +import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.icon.IconPathConstants; -import com.fr.design.mainframe.EditingMouseListener; -import com.fr.design.mainframe.FormArea; -import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.*; import com.fr.design.mainframe.widget.editors.PaddingMarginEditor; import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor; import com.fr.design.mainframe.widget.renderer.LayoutBorderStyleRenderer; @@ -34,10 +33,14 @@ import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; import com.fr.form.ui.container.WFitLayout; +import com.fr.form.ui.container.WLayout; import com.fr.general.FRScreen; import com.fr.general.IOUtils; import com.fr.general.Inter; import com.fr.stable.core.PropertyChangeAdapter; +import org.eclipse.swt.internal.gdip.Rect; + +import javax.swing.*; /** * @author richer @@ -47,6 +50,8 @@ public class XWAbsoluteLayout extends XLayoutContainer { private static final int EDIT_BTN_WIDTH = 60; private static final int EDIT_BTN_HEIGHT = 24; + private int minWidth = WLayout.MIN_WIDTH; + private int minHeight = WLayout.MIN_HEIGHT; //由于屏幕分辨率不同,界面上的容器大小可能不是默认的100%,此时拖入组件时,保存的大小按照100%时的计算 protected double containerPercent = 1.0; @@ -97,6 +102,35 @@ public class XWAbsoluteLayout extends XLayoutContainer { */ public void setContainerPercent(double containerPercent) { this.containerPercent = containerPercent; + minWidth = (int) (XWAbsoluteLayout.MIN_WIDTH*containerPercent); + minHeight = (int) (XWAbsoluteLayout.MIN_HEIGHT*containerPercent); + } + + /** + * 返回界面处根据百分比调整后的最小宽度 + * @return 最小宽度 + */ + public int getActualMinWidth() { + return this.minWidth; + } + + /** + * 返回界面处根据百分比调整后的最小高度 + * @return 最小高度 + */ + public int getActualMinHeight() { + return this.minHeight; + } + + /** + * 返回界面处根据百分比调整后的间隔大小(且为偶数) + * @return 间隔 + */ + public int getAcualInterval() { + // adapter那边交叉三等分、删除都要判断是否对齐,所以间隔转为偶数 + int interval = (int) (toData().getCompInterval()*containerPercent); + int val = interval/2; + return val*2; } /** @@ -114,16 +148,46 @@ public class XWAbsoluteLayout extends XLayoutContainer { } /** - * 新增删除拉伸后更新每个组件的BoundsWidget + * 新增删除拉伸后单个组件的BoundsWidget */ public void updateBoundsWidget(XCreator xCreator) { WAbsoluteLayout layout = this.toData(); - if (xCreator.shouldScaleCreator() || xCreator.hasTitleStyle()) { + if (xCreator.hasTitleStyle()) { xCreator = (XLayoutContainer)xCreator.getParent(); } BoundsWidget boundsWidget = layout.getBoundsWidget(xCreator.toData()); Rectangle rectangle = dealWidgetBound(xCreator.getBounds()); - boundsWidget.setCalculatedBounds(rectangle); + } + + private Rectangle calculateBound(Rectangle rec, double pw, double ph){ + Rectangle calRec = new Rectangle(0,0,0,0); + calRec.x = (int)(rec.x / pw); + calRec.y = (int)(rec.y / ph); + calRec.width = (int)(rec.width / pw); + calRec.height = (int)(rec.height / ph); + return calRec; + } + + /** + * 新增删除拉伸后每个组件的BoundsWidget + */ + public void updateBoundsWidget() { + WAbsoluteLayout layout = this.toData(); + Rectangle backupBound = this.getBackupBound(); + Rectangle currentBound = this.getBounds(); + if (backupBound != null && layout.getCompState() == WAbsoluteLayout.STATE_FIT) { + double percentW = ((double) backupBound.width / (double) currentBound.width); + double percentH = ((double) backupBound.height / (double) currentBound.height); + for (int index = 0, n = this.getComponentCount(); index < n; index++){ + XCreator creator = (XCreator) this.getComponent(index); + BoundsWidget wgt = layout.getBoundsWidget(creator.toData()); + // 用当前的显示大小计算后调正具体位置 + Rectangle wgtBound = dealWidgetBound(creator.getBounds()); + Rectangle rec = calculateBound(wgtBound, percentW, percentH); + wgt.setBounds(rec); + creator.setBounds(rec); + } + } } /** diff --git a/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java b/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java index a67e7c878..8f4df6e74 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java +++ b/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java @@ -744,6 +744,10 @@ public class XWFitLayout extends XLayoutContainer { tabLayout.updateBoundsWidget(); } } + //如果子组件是绝对布局,则内部的widget也要更新 + if (creator.acceptType(XWAbsoluteLayout.class)){ + ((XWAbsoluteLayout) creator).updateBoundsWidget(); + } } layout.setContainerHeight(containerHeight); layout.setContainerWidth(containerWidth); @@ -801,6 +805,7 @@ public class XWFitLayout extends XLayoutContainer { BoundsWidget bw = wlayout.getBoundsWidget(wgt); wlayout.removeWidget(bw); updateBoundsWidget(); + ((FRFitLayoutAdapter)getLayoutAdapter()).updateCreatorBackBound(); } /** diff --git a/designer_form/src/com/fr/design/designer/creator/XWParameterLayout.java b/designer_form/src/com/fr/design/designer/creator/XWParameterLayout.java index e1ab80b7c..d847245e1 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWParameterLayout.java +++ b/designer_form/src/com/fr/design/designer/creator/XWParameterLayout.java @@ -183,4 +183,11 @@ public class XWParameterLayout extends XWAbsoluteLayout { @Override public void updateBoundsWidget(XCreator xCreator) { } + + /** + * 新增删除拉伸后每个组件的BoundsWidget + */ + @Override + public void updateBoundsWidget() { + } } \ No newline at end of file diff --git a/designer_form/src/com/fr/design/gui/core/FormWidgetOption.java b/designer_form/src/com/fr/design/gui/core/FormWidgetOption.java index e99888c72..76287c30f 100644 --- a/designer_form/src/com/fr/design/gui/core/FormWidgetOption.java +++ b/designer_form/src/com/fr/design/gui/core/FormWidgetOption.java @@ -1 +1 @@ -package com.fr.design.gui.core; import javax.swing.Icon; import com.fr.base.BaseUtils; import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WBorderLayout; import com.fr.form.ui.container.WCardLayout; import com.fr.form.ui.container.WFitLayout; import com.fr.form.ui.container.WHorizontalBoxLayout; import com.fr.form.ui.container.WParameterLayout; import com.fr.form.ui.container.WVerticalBoxLayout; import com.fr.general.Inter; /** * Author : Shockway * Date: 13-6-17 * Time: 上午10:40 */ public class FormWidgetOption extends WidgetOption { /** * 返回名字 * @return 名字 */ @Override public String optionName() { return null; } /** * 返回图标 * @return 图标 */ @Override public Icon optionIcon() { return null; } /** * 组件类 * @return 类 */ @Override public Class widgetClass() { return null; } /** * 返回组件 * @return 控件 */ @Override public Widget createWidget() { return null; } /* * 表单容器 */ public static WidgetOption[] getFormContainerInstance() { return new WidgetOption[] { ABSOLUTELAYOUTCONTAINER, BORDERLAYOUTCONTAINER, HORIZONTALBOXLAYOUTCONTAINER, VERTICALBOXLAYOUTCONTAINER, CARDLAYOUTCONTAINER, FITLAYOUTCONTAINER }; } /** * 表单工具栏上的布局 * @return 控件 */ public static WidgetOption[] getFormLayoutInstance() { return new WidgetOption[] {CARDLAYOUTCONTAINER/*, ABSOLUTELAYOUTCONTAINER*/}; } public static final WidgetOption ABSOLUTELAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_AbsoluteLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_absolute.png"), WAbsoluteLayout.class); public static final WidgetOption BORDERLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_BorderLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_border.png"), WBorderLayout.class); public static final WidgetOption CARDLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_CardLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/card_layout_16.png"), WCardLayout.class); public static final WidgetOption HORIZONTALBOXLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Layout-HBox"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_h_16.png"), WHorizontalBoxLayout.class); public static final WidgetOption VERTICALBOXLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_VerticalBoxLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_v_16.png"), WVerticalBoxLayout.class); public static final WidgetOption FITLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter.getLocText("FR-Designer-Layout_Adaptive_Layout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_v_16.png"), WFitLayout.class); public static final WidgetOption PARAMETERCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Para-Body"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_parameter.png"), WParameterLayout.class); public static final WidgetOption ELEMENTCASE = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Form-Report"), BaseUtils.readIcon("/com/fr/web/images/form/resources/report_16.png"), ElementCaseEditor.class); } \ No newline at end of file +package com.fr.design.gui.core; import javax.swing.Icon; import com.fr.base.BaseUtils; import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WBorderLayout; import com.fr.form.ui.container.WCardLayout; import com.fr.form.ui.container.WFitLayout; import com.fr.form.ui.container.WHorizontalBoxLayout; import com.fr.form.ui.container.WParameterLayout; import com.fr.form.ui.container.WVerticalBoxLayout; import com.fr.general.Inter; /** * Author : Shockway * Date: 13-6-17 * Time: 上午10:40 */ public class FormWidgetOption extends WidgetOption { /** * 返回名字 * @return 名字 */ @Override public String optionName() { return null; } /** * 返回图标 * @return 图标 */ @Override public Icon optionIcon() { return null; } /** * 组件类 * @return 类 */ @Override public Class widgetClass() { return null; } /** * 返回组件 * @return 控件 */ @Override public Widget createWidget() { return null; } /* * 表单容器 */ public static WidgetOption[] getFormContainerInstance() { return new WidgetOption[] { ABSOLUTELAYOUTCONTAINER, BORDERLAYOUTCONTAINER, HORIZONTALBOXLAYOUTCONTAINER, VERTICALBOXLAYOUTCONTAINER, CARDLAYOUTCONTAINER, FITLAYOUTCONTAINER }; } /** * 表单工具栏上的布局 * @return 控件 */ public static WidgetOption[] getFormLayoutInstance() { return new WidgetOption[] {CARDLAYOUTCONTAINER, ABSOLUTELAYOUTCONTAINER}; } public static final WidgetOption ABSOLUTELAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_AbsoluteLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_absolute.png"), WAbsoluteLayout.class); public static final WidgetOption BORDERLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_BorderLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_border.png"), WBorderLayout.class); public static final WidgetOption CARDLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_CardLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/card_layout_16.png"), WCardLayout.class); public static final WidgetOption HORIZONTALBOXLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Layout-HBox"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_h_16.png"), WHorizontalBoxLayout.class); public static final WidgetOption VERTICALBOXLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_VerticalBoxLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_v_16.png"), WVerticalBoxLayout.class); public static final WidgetOption FITLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter.getLocText("FR-Designer-Layout_Adaptive_Layout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_v_16.png"), WFitLayout.class); public static final WidgetOption PARAMETERCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Para-Body"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_parameter.png"), WParameterLayout.class); public static final WidgetOption ELEMENTCASE = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Form-Report"), BaseUtils.readIcon("/com/fr/web/images/form/resources/report_16.png"), ElementCaseEditor.class); } \ No newline at end of file diff --git a/designer_form/src/com/fr/design/mainframe/FormDesignerUI.java b/designer_form/src/com/fr/design/mainframe/FormDesignerUI.java index 9fc5cb1bf..259e1b65e 100644 --- a/designer_form/src/com/fr/design/mainframe/FormDesignerUI.java +++ b/designer_form/src/com/fr/design/mainframe/FormDesignerUI.java @@ -95,9 +95,9 @@ public class FormDesignerUI extends ComponentUI { if (designer.getPainter() != null) { // ComponentAdapter和LayoutAdapter提供的额外的Painter,该Painter一般用于提示作用, - // 相当于一个浮动层 + // 相当于一个浮动层, 要考虑参数面板的高度 designer.getPainter().paint(g, designer.getArea().getHorizontalValue(), - designer.getArea().getVerticalValue()); + designer.getArea().getVerticalValue() + designer.getParaHeight()); } AddingModel addingModel = designer.getAddingModel();