From ffe42c5b6a0b9d57508d803260ebf0e78c7bfb4c Mon Sep 17 00:00:00 2001 From: Starryi Date: Mon, 5 Jul 2021 17:53:13 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-53175=E3=80=9010.0.18=E3=80=91=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E8=83=8C=E6=99=AF=E5=88=86=E7=A6=BB=E4=B8=BA=E6=A0=87?= =?UTF-8?q?=E9=A2=98/=E8=83=8C=E6=99=AF/=E8=BE=B9=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 子功能: 组件线型边框/圆角/背景样式优化 1. 修改组件边框/圆角/背景在设计器端布局面板中展示效果 2. 组件边框为整体边框 3. 组件圆角为整体圆角 4. 不管有无边框线,组件圆角裁剪总是生效 5. 组件背景为整体背景 --- .../com/fr/design/border/UIRoundedBorder.java | 25 ++- .../creator/XBorderStyleWidgetCreator.java | 146 ++++++++++++++++-- .../design/designer/creator/XChartEditor.java | 2 +- .../design/designer/creator/XElementCase.java | 2 +- .../designer/creator/XLayoutContainer.java | 2 +- .../creator/XWAbsoluteBodyLayout.java | 2 +- .../designer/creator/XWTitleLayout.java | 14 +- .../creator/cardlayout/XWCardLayout.java | 2 +- 8 files changed, 171 insertions(+), 24 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/border/UIRoundedBorder.java b/designer-base/src/main/java/com/fr/design/border/UIRoundedBorder.java index 757bbbbe0..4530f0f48 100644 --- a/designer-base/src/main/java/com/fr/design/border/UIRoundedBorder.java +++ b/designer-base/src/main/java/com/fr/design/border/UIRoundedBorder.java @@ -1,32 +1,33 @@ package com.fr.design.border; import com.fr.base.GraphHelper; +import com.fr.stable.GraphDrawHelper; import javax.swing.border.LineBorder; -import java.awt.Color; -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; +import java.awt.*; import java.awt.geom.RoundRectangle2D; public class UIRoundedBorder extends LineBorder { private static final long serialVersionUID = 1L; + private BasicStroke stroke4Thickness; private int roundedCorner; private int lineStyle; public UIRoundedBorder(Color color) { super(color); + this.stroke4Thickness = new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); } public UIRoundedBorder(Color color, int thickness){ super(color, thickness); + this.stroke4Thickness = new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); } public UIRoundedBorder(Color color, int thickness, int roundedCorners){ super(color, thickness, true); + this.stroke4Thickness = new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); this.roundedCorner = roundedCorners; } @@ -51,7 +52,19 @@ public class UIRoundedBorder extends LineBorder { Graphics2D g2d = (Graphics2D)g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(lineColor); - GraphHelper.draw(g2d, new RoundRectangle2D.Double(x, y, width - 1.0D, height - 1.0D, roundedCorner, roundedCorner), lineStyle); + + Shape shape = new RoundRectangle2D.Double(x, y, width - 1.0D, height - 1.0D, roundedCorner, roundedCorner); + + if (stroke4Thickness != null) { + Stroke oldStroke = g2d.getStroke(); + g2d.setStroke(stroke4Thickness); + g2d.draw(shape); + + g2d.setStroke(oldStroke); + } else { + GraphHelper.draw(g2d, shape, lineStyle); + } + g2d.setColor(oldColor); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java index e174c122f..fc40b1d12 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java @@ -11,6 +11,7 @@ import com.fr.form.ui.Widget; import com.fr.form.ui.WidgetTitle; import com.fr.form.ui.WidgetValue; import com.fr.form.ui.container.WTitleLayout; +import com.fr.general.Background; import com.fr.general.ComparatorUtils; import com.fr.general.act.BorderPacker; import com.fr.general.act.TitlePacker; @@ -18,7 +19,11 @@ import com.fr.stable.Constants; import com.fr.stable.StringUtils; import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.LineBorder; import java.awt.*; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; /** * Created with IntelliJ IDEA. @@ -29,6 +34,7 @@ import java.awt.*; public class XBorderStyleWidgetCreator extends XWidgetCreator{ protected static final Dimension BORDER_PREFERRED_SIZE = new Dimension(250, 150); + protected Background background4Painting; // 设计器预览界面中绘制组件背景图 public XBorderStyleWidgetCreator(Widget widget, Dimension initSize) { super(widget, initSize); @@ -38,8 +44,17 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ this.setShareId(sharableAttrMark.getShareId()); } } - - /** + + public Background getBackground4Painting() { + return this.background4Painting; + } + + public void setBackground4Painting(Background background4Painting) { + this.background4Painting = background4Painting; + this.repaint(); + } + + /** * 返回容器对应的widget * @return 同上 */ @@ -58,22 +73,37 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ protected void initStyle() { BorderPacker style = toData().getBorderStyle(); - initBorderStyle(); + initBorderAndBackgroundStyle(); if (ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)) { initTitleStyle(style); } else { clearTitleWidget(); } + + // 编辑右侧栏组件样式面板后,重新调整组件/标题/边框的显示效果 + reshuffleBorderAndBackgroundPaintingEffectIfTitleExists(); } - // 边框默认值设为NONE,不然像scalelayout这种只用默认边框的会不显示边框 - protected void initBorderStyle() { + protected void initBorderAndBackgroundStyle() { BorderPacker style = toData().getBorderStyle(); - if (style != null && style.getBorder() != Constants.LINE_NONE) { - this.setBorder(new UIRoundedBorder(style.getBorder(), style.getColor(), style.getBorderRadius())); - } else { - this.setBorder(DEFALUTBORDER); + LineBorder DEFAULT_LINE_BORDER = (LineBorder) DEFALUTBORDER; + + // 边框默认值设为NONE,不然像scalelayout这种只用默认边框的会不显示边框 + Border border = DEFAULT_LINE_BORDER; + if (style != null) { + int radius = style.getBorderRadius(); // 不管有无边框线, 圆角裁剪总是生效 + if (style.getBorder() != Constants.LINE_NONE) { + // 设置了边框线 + border = new UIRoundedBorder(style.getBorder(), style.getColor(), radius); + } else { + // 为设置边框线 + border = new UIRoundedBorder(DEFAULT_LINE_BORDER.getLineColor(), DEFAULT_LINE_BORDER.getThickness(), radius); + } } + + this.setBorder(border); + + this.setBackground4Painting(style != null ? style.getBackground() : null); } private void clearTitleWidget() { @@ -143,6 +173,75 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ return new WidgetValue(value); } + // 如果存在标题栏,则需要重新弄调整边框和背景的显示效果,使得边框和背景的视觉效果出现在包含组件和标题的整体区域上, + // 而不是组件和标题各自出现独立的边框和背景,同时如存在标题栏,则标题栏下方还应有底部边框,作为标题和内容的分界线 + protected void reshuffleBorderAndBackgroundPaintingEffectIfTitleExists() { + Container parent = this.getParent(); + if (parent instanceof XWTitleLayout) { + XWTitleLayout titleParent = (XWTitleLayout) parent; + if (parent.getComponentCount() > 1) { + XCreator titleCreator = titleParent.getTitleCreator(); + XCreator bodyXCreator = titleParent.getBodyCreator(); + + Border border = bodyXCreator.getBorder(); + + titleParent.setBorder(border); // 容器绘制完整边框 + bodyXCreator.setBorder(BorderFactory.createEmptyBorder()); // body不绘制边框 + titleCreator.setBorder(BorderFactory.createEmptyBorder()); // title绘制底部边框 + if (border instanceof LineBorder) { + Color color = ((LineBorder) border).getLineColor(); + int thickness = ((LineBorder) border).getThickness(); + titleCreator.setBorder(new BottomLineBorder(color, thickness)); + } + + if (bodyXCreator instanceof XBorderStyleWidgetCreator) { + XBorderStyleWidgetCreator styledBodyXCreator = (XBorderStyleWidgetCreator) bodyXCreator; + Background background4Painting = styledBodyXCreator.getBackground4Painting(); + + styledBodyXCreator.setBackground4Painting(null); // body不绘制背景 + titleParent.setBackground4Painting(background4Painting); // 容器绘制完整背景 + } + } + } + } + + + // 根据当前组件边框裁剪内容,如果当前组件存在圆角,则应当按圆角裁剪内容 + private void clipByRoundedBorder(Graphics2D g2d) { + Border currentBorder = getBorder(); + if (currentBorder instanceof UIRoundedBorder) { + int thickness = ((UIRoundedBorder) currentBorder).getThickness(); + int radius = ((UIRoundedBorder) currentBorder).getRoundedCorner(); + int currentClipX = 0; + int currentClipY = 0; + int currentClipWidth = getWidth(); + int currentClipHeight = getHeight(); + int currentClipRadius = Math.max(radius - thickness, 0); // 应沿着边框外围进行裁剪 + g2d.clip(new RoundRectangle2D.Double(currentClipX, currentClipY, currentClipWidth, currentClipHeight, currentClipRadius, currentClipRadius)); + } + } + + // 设计器预览界面中绘制组件背景效果 + private void paintBackground(Graphics2D g2d) { + Background background4Painting = getBackground4Painting(); + if (background4Painting != null) { + background4Painting.paint(g2d, new Rectangle2D.Double(0, 0, getWidth(), getHeight())); + } + } + + @Override + protected void paintComponent(Graphics g) { + this.paintBackground((Graphics2D) g); + super.paintComponent(g); + } + + @Override + public void paint(Graphics g) { + this.clipByRoundedBorder((Graphics2D) g); + super.paint(g); + paintBorder(g); + } + @Override protected String getIconName() { return StringUtils.EMPTY; @@ -169,8 +268,33 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ * data属性改变触发其他操作 * */ - public void firePropertyChange(){ + public void firePropertyChange() { } - + + // 适用于标题栏的底部边框 + public static class BottomLineBorder extends LineBorder { + + private BottomLineBorder(Color color, int thickness) { + super(color, thickness); + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Graphics2D g2d = (Graphics2D)g; + + Color oldColor = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2d.setColor(getLineColor()); + g2d.setStroke(new BasicStroke(getThickness())); + g2d.drawLine(0, height, width, height); + + g2d.setStroke(oldStroke); + g2d.setColor(oldColor); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + } } \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java index 354a60ecb..bbd2f52d9 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java @@ -165,7 +165,7 @@ public class XChartEditor extends XBorderStyleWidgetCreator { @Override protected void initXCreatorProperties() { super.initXCreatorProperties(); - initBorderStyle(); + initBorderAndBackgroundStyle(); BaseChartCollection collection = ((BaseChartEditor) data).getChartCollection(); isRefreshing = true; ((MiddleChartComponent) designerEditor.getEditorTarget()).populate(collection); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java index e08cb658c..4729be0b5 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java @@ -57,7 +57,7 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme super.initXCreatorProperties(); // 报表块初始化时要加载对应的borderStyle - initBorderStyle(); + initBorderAndBackgroundStyle(); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java b/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java index 07220df0d..50c5967c5 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java @@ -118,7 +118,7 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme @Override protected void initXCreatorProperties() { super.initXCreatorProperties(); - initBorderStyle(); + initBorderAndBackgroundStyle(); this.initLayoutManager(); this.convert(); } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteBodyLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteBodyLayout.java index a43ed0125..aa5612c09 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteBodyLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteBodyLayout.java @@ -106,7 +106,7 @@ public class XWAbsoluteBodyLayout extends XWAbsoluteLayout { @Override protected void initStyle() { - initBorderStyle(); + initBorderAndBackgroundStyle(); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java index bfa841a4a..ba864e607 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java @@ -10,10 +10,9 @@ import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.form.ui.Label; import com.fr.form.ui.Widget; import com.fr.form.ui.WidgetTitle; +import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; import com.fr.form.ui.container.WTitleLayout; import com.fr.general.ComparatorUtils; -import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; -import com.fr.stable.StringUtils; import java.awt.*; import java.awt.event.ContainerEvent; @@ -46,6 +45,17 @@ public class XWTitleLayout extends DedicateLayoutContainer { super(widget, initSize); } + @Override + protected void initXCreatorProperties() { + super.initXCreatorProperties(); + + // 初始化后(如打开旧模版),需要重新调整组件/标题/边框的显示效果 + XCreator xCreator = getBodyCreator(); + if (xCreator instanceof XBorderStyleWidgetCreator) { + ((XBorderStyleWidgetCreator) xCreator).reshuffleBorderAndBackgroundPaintingEffectIfTitleExists(); + } + } + /** * 初始化容器对应的布局 由于是只装一个需要保持原样高度的控件,布局设为absolute */ 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 1ff3f41c5..4fb422c0a 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 @@ -400,7 +400,7 @@ public class XWCardLayout extends XLayoutContainer { protected void initStyle() { BorderPacker style = toData().getBorderStyle(); initBorderTitleStyle(style); - initBorderStyle(); + initBorderAndBackgroundStyle(); clearOrShowTitleLayout(ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)); }