From 2331aa149ee8686fc4838d87106d012e1e62e74e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B9=E7=A3=8A?= <294531121@qq.com> Date: Tue, 3 Aug 2021 17:23:55 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-54885=20=E3=80=9010.0.19=E3=80=91FRM?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E6=8E=A8=E8=8D=90=E4=B9=8B=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/design/dialog/BasicPane.java | 2 - .../gui/frpane/AbstractAttrNoScrollPane.java | 6 +- .../com/fr/design/gui/ibutton/UIHead.java | 63 ++++ .../fr/design/gui/ibutton/UIHeadGroup.java | 135 +++----- .../multi_selection_auto_spacing_tip.png | Bin 0 -> 401 bytes .../multi_selection_bottom_align.png | Bin 0 -> 131 bytes ...ulti_selection_horizontal_auto_spacing.png | Bin 0 -> 133 bytes ...ulti_selection_horizontal_center_align.png | Bin 0 -> 133 bytes .../multi_selection_horizontal_spacing.png | Bin 0 -> 271 bytes .../buttonicon/multi_selection_left_align.png | Bin 0 -> 132 bytes .../multi_selection_right_align.png | Bin 0 -> 130 bytes .../buttonicon/multi_selection_top_align.png | Bin 0 -> 126 bytes .../multi_selection_vertical_auto_spacing.png | Bin 0 -> 137 bytes .../multi_selection_vertical_center_align.png | Bin 0 -> 147 bytes .../multi_selection_vertical_spacing.png | Bin 0 -> 249 bytes .../fr/design/designer/creator/XCreator.java | 3 + .../mainframe/EditingMouseListener.java | 3 +- .../com/fr/design/mainframe/FormDesigner.java | 20 +- .../fr/design/mainframe/FormDesignerUI.java | 13 +- .../mainframe/FormSpacingLineDrawer.java | 262 +++++++++++++++ .../mainframe/MultiSelectionArrangement.java | 218 +++++++++++++ .../design/mainframe/WidgetPropertyPane.java | 36 ++- .../widget/ui/FormMultiWidgetCardPane.java | 271 ++++++++++++++++ .../widget/ui/FormSingleWidgetCardPane.java | 297 ++++++++++++++++++ .../widget/ui/FormWidgetCardPane.java | 284 +---------------- .../widget/ui/FormWidgetCardPaneFactory.java | 13 + 26 files changed, 1259 insertions(+), 367 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/gui/ibutton/UIHead.java create mode 100644 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_auto_spacing_tip.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_bottom_align.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_auto_spacing.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_center_align.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_spacing.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_left_align.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_right_align.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_top_align.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_auto_spacing.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_center_align.png create mode 100755 designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_spacing.png create mode 100644 designer-form/src/main/java/com/fr/design/mainframe/FormSpacingLineDrawer.java create mode 100644 designer-form/src/main/java/com/fr/design/mainframe/MultiSelectionArrangement.java create mode 100644 designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormMultiWidgetCardPane.java create mode 100644 designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormSingleWidgetCardPane.java create mode 100644 designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPaneFactory.java diff --git a/designer-base/src/main/java/com/fr/design/dialog/BasicPane.java b/designer-base/src/main/java/com/fr/design/dialog/BasicPane.java index 930dde76c..d3c592a4e 100644 --- a/designer-base/src/main/java/com/fr/design/dialog/BasicPane.java +++ b/designer-base/src/main/java/com/fr/design/dialog/BasicPane.java @@ -410,6 +410,4 @@ public abstract class BasicPane extends JPanel { } } - - } diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java index 6af119426..381a9cd76 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java @@ -46,8 +46,10 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane { protected void initContentPane() { leftContentPane = createContentPane(); - leftContentPane.setBorder(BorderFactory.createMatteBorder(10, 10, 0, 0, original)); - this.add(leftContentPane, BorderLayout.CENTER); + if (leftContentPane != null) { + leftContentPane.setBorder(BorderFactory.createMatteBorder(10, 10, 0, 0, original)); + this.add(leftContentPane, BorderLayout.CENTER); + } } protected abstract JPanel createContentPane(); diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHead.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHead.java new file mode 100644 index 000000000..0a41aae17 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHead.java @@ -0,0 +1,63 @@ +package com.fr.design.gui.ibutton; + +import com.fr.stable.StringUtils; + +import javax.swing.Icon; + +public class UIHead { + private String text = StringUtils.EMPTY; + private Icon icon = null; + private boolean enable = true; + private int index = 0; + + public UIHead(String text, int index) { + this.text = text; + this.index = index; + } + + public UIHead(String text, int index, boolean enable) { + this(text, index); + this.enable = enable; + } + + public UIHead(Icon icon, int index) { + this.icon = icon; + this.index = index; + } + + public UIHead(Icon icon, int index, boolean enable) { + this(icon, index); + this.enable = enable; + } + + public UIHead(String text, Icon icon, int index) { + this.text = text; + this.icon = icon; + this.index = index; + } + + public UIHead(String text, Icon icon, int index, boolean enable) { + this(text, icon, index); + this.enable = enable; + } + + public boolean isOnlyText() { + return StringUtils.isNotEmpty(text) && icon == null; + } + + public String getText() { + return text; + } + + public Icon getIcon() { + return icon; + } + + public boolean isEnable() { + return enable; + } + + public int getIndex() { + return index; + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java index e21f4c217..0cfe7c390 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java @@ -10,7 +10,6 @@ import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Color; import java.awt.Dimension; -import java.awt.Graphics; import java.awt.GridLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -18,8 +17,10 @@ import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; +// fanglei:不是原作者,只是优化如下问题:代码冗余,无法拓展(例如我想加个enable属性没法加),甚至还有数组越界的问题。 public class UIHeadGroup extends JPanel { private static final int MIN_HEIGHT = 25; + private List uiHeads = new ArrayList<>(); protected List labelButtonList; private boolean isNeedLeftRightOutLine = true; protected int selectedIndex = -1; @@ -29,76 +30,46 @@ public class UIHeadGroup extends JPanel { } public UIHeadGroup(String[] textArray) { - labelButtonList = new ArrayList(textArray.length); - this.setBackground(UIConstants.TREE_BACKGROUND); - this.setLayout(new GridLayout(0, textArray.length, 0, 0)); for (int i = 0; i < textArray.length; i++) { - final int index = i; - String text = textArray[i]; - final UIToggleButton labelButton = new UIToggleButton(text) { - @Override - protected MouseListener getMouseListener() { - return new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - setSelectedIndex(index); - UIHeadGroup.this.repaint(); - } - }; - } - }; - initButton(labelButton); + uiHeads.add(new UIHead(textArray[i], i)); } - setSelectedIndex(0); + initUIHeadGroup(uiHeads); } public UIHeadGroup(Icon[] iconArray) { - labelButtonList = new ArrayList(iconArray.length); - this.setBackground(UIConstants.NORMAL_BACKGROUND); - this.setLayout(new GridLayout(0, iconArray.length, 1, 0)); for (int i = 0; i < iconArray.length; i++) { - final int index = i; - Icon icon = iconArray[i]; - final UIToggleButton labelButton = new UIToggleButton(icon) { - @Override - protected MouseListener getMouseListener() { - return new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - setSelectedIndex(index); - UIHeadGroup.this.repaint(); - } - }; - } - }; - initButton(labelButton); + uiHeads.add(new UIHead(iconArray[i], i)); } - setSelectedIndex(0); + initUIHeadGroup(uiHeads); } public UIHeadGroup(Icon[] iconArray, String[] textArray) { - labelButtonList = new ArrayList(Math.min(textArray.length, iconArray.length)); - this.setBackground(UIConstants.NORMAL_BACKGROUND); - this.setLayout(new GridLayout(0, textArray.length, 1, 0)); - for (int i = 0; i < textArray.length; i++) { - final int index = i; - String text = textArray[i]; - Icon icon = iconArray[i]; - final UIToggleButton labelButton = new UIToggleButton(text, icon) { - @Override - protected MouseListener getMouseListener() { - return new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - setSelectedIndex(index); - UIHeadGroup.this.repaint(); - } - }; + int length = Math.min(textArray.length, iconArray.length); + for (int i = 0; i < length; i++) { + uiHeads.add(new UIHead(textArray[i], iconArray[i], i)); + } + initUIHeadGroup(uiHeads); + } + + public UIHeadGroup(List uiHeads) { + initUIHeadGroup(uiHeads); + } + + public void initUIHeadGroup(List uiHeads) { + if (uiHeads != null) { + labelButtonList = new ArrayList(uiHeads.size()); + this.setLayout(new GridLayout(0, uiHeads.size(), 1, 0)); + + for (UIHead head : uiHeads) { + if (head.isOnlyText()) { + this.setBackground(UIConstants.TREE_BACKGROUND); + } else { + this.setBackground(UIConstants.NORMAL_BACKGROUND); } - }; - initButton(labelButton); + initButton(createUIToggleButton(head)); + } + setSelectedIndex(0); } - setSelectedIndex(0); } @Override @@ -110,32 +81,6 @@ public class UIHeadGroup extends JPanel { return dim; } - @Override - protected void paintBorder(Graphics g) { -// Graphics2D g2d = (Graphics2D)g; -// g2d.setColor(UIConstants.LINE_COLOR); -// -// int width = 0; -// for(int i = 0; i < labelButtonList.size() - 1; i++) { -// int height = labelButtonList.get(i).getHeight(); -// width += labelButtonList.get(i).getWidth() + 1; -// g.drawLine(width, 0, width, height); -// } -// -// width += labelButtonList.get(labelButtonList.size() - 1).getWidth() + 1; -// if(isNeedLeftRightOutLine) { -// g2d.drawRect(0, 0, width, getHeight() - 1); -// } else { -// g2d.drawLine(1, 0, width - 1, 0); -// g2d.drawLine(1, getHeight() - 1, width - 1, getHeight() - 1); -// } -// -// -// g2d.setColor(UIConstants.NORMAL_BACKGROUND); -// UIToggleButton headButton = labelButtonList.get(selectedIndex); -// g2d.drawLine(headButton.getX(), headButton.getHeight() + 1, headButton.getX() + headButton.getWidth() - 1, headButton.getHeight() + 1); - } - private void initButton(UIToggleButton labelButton) { labelButton.setRoundBorder(false); labelButton.setBorderPainted(false); @@ -172,6 +117,26 @@ public class UIHeadGroup extends JPanel { return selectedIndex; } + public UIToggleButton createUIToggleButton(final UIHead head) { + UIToggleButton uiToggleButton = new UIToggleButton(head.getText(), head.getIcon()) { + @Override + protected MouseListener getMouseListener() { + return new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (head.isEnable()) { + setSelectedIndex(head.getIndex()); + UIHeadGroup.this.repaint(); + } + } + }; + } + }; + + uiToggleButton.setEnabled(head.isEnable()); + return uiToggleButton; + } + public static void main(String... args) { JFrame jf = new JFrame("test"); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_auto_spacing_tip.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_auto_spacing_tip.png new file mode 100644 index 0000000000000000000000000000000000000000..74e79ee242366aa74ad78561a04575cfbe229b66 GIT binary patch literal 401 zcmV;C0dD?@P)Px$OG!jQR47xOQB5dBQ562poe59P$_6D9yIGBQU9poQmew+BjVxqiWih2}ZDgmE zEG#UQV(aJK^WLo9PLYy5c@g*M#xPiryE(UW&Ue1P?<2gwa=BboD!)vGDFB@SZbfk5 z-1Az!UcYSYk^g9|Cji<8XajINS(aS~LC^!J89=IlRG9hD?~=cq%jHj_p8iysp-I{hVL!`$c3S) v#BsFc0Y6;&Er&P9F#D0izmjf%{!(87n1;j+99Rr%00000NkvXXu0mjfku$Qg literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_bottom_align.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_bottom_align.png new file mode 100755 index 0000000000000000000000000000000000000000..238e4735dba9b46ead158736ad08c2fd76578a30 GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|Y&~5ZLoEE0 zQx*sqBwc=Q@%wpw&ZFPKHw~}!OC301AjNjroX6v2{DYDQ4`240eikswIR0&IPlT|L dV(*Dh3=bPk1iuL~J_Z`Z;OXk;vd$@?2>|kvExiB$ literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_auto_spacing.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_auto_spacing.png new file mode 100755 index 0000000000000000000000000000000000000000..a1b89ab78b8b4118548dec7e7c827c7b8b6d272c GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|>^)r^LoEE0 zQx*sqR8>@5Z9a2jV{){zX4=6oiKYh%zn%YogXi}AQ|CB@LmmwuYB;b fLE`9-D+~XY{`MtXvXcU8|tDnm{r-UW|GEFZc literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_center_align.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_center_align.png new file mode 100755 index 0000000000000000000000000000000000000000..2f811f7bf8ab557e3b515c583ad142bcba7f4af8 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|>^)r^LoEE0 zQx*sqJi7e;;loh=N%uDXB~)z4*}Q$iB}54bC0 literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_spacing.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_spacing.png new file mode 100755 index 0000000000000000000000000000000000000000..d01dab47ec14643da173944f413007914d8b9038 GIT binary patch literal 271 zcmV+q0r38bP)Px#$w@>(R5(v#WS|f*dU$x%gUr~mV_PFBX2JB)#sJSr|Jk?aG5$n$5xN*o7dTA+ zuE5C3T)RJoEg9JWr#V08|NQ%}{%AVqBak>&1HhV@nf5a^xl@LoEE0 zQx*sqG<~VAsQQ0@W3BcKUoD9|Hj8ure$Jm_aAW?da~(o#i`jBgmss$4bTZDk^>C8V e$&c1P{0we40tELQ)%gcBiNVv=&t;ucLK6VGMJzV} literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_right_align.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_right_align.png new file mode 100755 index 0000000000000000000000000000000000000000..d402fb2bda629e976c52b24b05fe85cebb13c9ef GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|Y&=~YLoEE0 zQx*sqOj>>a@a5nC``$)Nws$l3ZLa^PuB!8G`6lBRL&S3j3^P6`Qd;dd9@C X<&KGg`COmuZK;*X43^ste`$zy;B1h7VDbBTeGt#B`KS1LX&?TDl<|CB%x2)gbn)=v)pC{>>e$xj9}w$!lg%7>r2Nf| tYaX)97jmV0-PqW=4mV8UaVyMYVGv@o5ZtysV=K^L22WQ%mvv4FO#p9AFslFn literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_spacing.png b/designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_spacing.png new file mode 100755 index 0000000000000000000000000000000000000000..8b8019beba78698d2fa3eebda8c93fc071c7b80b GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|Hha1_hFJI~ zrz{XKX!=rJQT1Q__#D~W+l`ud53tIl{a?d=Qr06i|Hx9d<%|kvdw6(w6?*?mN=Ow* zHeF>%IcqSxP_ikJ!R+i09!J9i#h2>8&5x-+^RbotxB0Zmw?9kNAG-2@*Ci>bZ5La^ zo)6u>`$g?$-`uxJ=J0FQ_M7`xOG^IRnqd6Io;mnzW5~6z6ib implements TreeSelection private ConnectorHelper connectorHelper; private boolean isReportBlockEditing = false; private TopXCreators topXCreators; + private FormSpacingLineDrawer spacingLineDrawer; //组件重叠 private boolean isWidgetsIntersect = false; @@ -194,6 +194,8 @@ public class FormDesigner extends TargetComponent
implements TreeSelection // 必须刷新"参数/控件树"面板,否则,若最近一次打开模版为 cpt,重启设计器,打开 frm,控件树消失 populateParameterPropertyPane(); + + spacingLineDrawer = new FormSpacingLineDrawer(this); } @@ -1764,4 +1766,20 @@ public class FormDesigner extends TargetComponent implements TreeSelection } } + public boolean isMultiSelection() { + XCreator[] creators = this.getSelectionModel().getSelection().getSelectedCreators(); + if (creators != null && creators.length > 1) { + for (int i = 0; i < creators.length - 1; i++) { + if (creators[i].getParent() != creators[i + 1].getParent() || !creators[i].isInAbsoluteContainer()) { + return false; + } + } + return creators[creators.length - 1].isInAbsoluteContainer(); + } + return false; + } + + public FormSpacingLineDrawer getSpacingLineDrawer() { + return spacingLineDrawer; + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java index a8ddce03c..776925044 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java @@ -17,15 +17,15 @@ import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.form.util.XCreatorConstants; import com.fr.design.roleAuthority.ReportAndFSManagePane; import com.fr.design.utils.ComponentUtils; - import com.fr.form.main.parameter.FormParameterUI; import com.fr.page.WatermarkPainter; import com.fr.report.core.ReportUtils; import com.fr.stable.ArrayUtils; import com.fr.stable.Constants; -import java.awt.dnd.DropTarget; -import javax.swing.*; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; import javax.swing.plaf.ComponentUI; import java.awt.AlphaComposite; import java.awt.Color; @@ -33,6 +33,7 @@ import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; +import java.awt.dnd.DropTarget; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Rectangle2D; @@ -128,6 +129,8 @@ public class FormDesignerUI extends ComponentUI { // 当前正在添加的组件 paintAddingBean(g, addingModel); } + + designer.getSpacingLineDrawer().draw(g); } // 绘制水印 @@ -518,4 +521,8 @@ public class FormDesignerUI extends ComponentUI { designer.paintTopCreators(g); } + private void paintSpacingLine() { + + } + } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormSpacingLineDrawer.java b/designer-form/src/main/java/com/fr/design/mainframe/FormSpacingLineDrawer.java new file mode 100644 index 000000000..a9f01dcad --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormSpacingLineDrawer.java @@ -0,0 +1,262 @@ +package com.fr.design.mainframe; + +import com.fr.design.designer.creator.XCreator; +import com.fr.stable.Constants; +import com.fr.stable.GraphDrawHelper; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.awt.geom.RoundRectangle2D; + +public class FormSpacingLineDrawer { + private static final Color LINE_COLOR = new Color(230, 82, 81); + private static final Color TEXT_COLOR = new Color(255, 255, 255); + private static final int TEXT_PADDING_HORIZONTAL = 6; + private static final int TEXT_PADDING_VERTICAL = 1; + private static final int MIN_SPACING = 10; + + private FormDesigner designer; + private XCreator hoverCreator; + private Rectangle selectedRec; + private boolean isMouseMoveEvent = false; + + public FormSpacingLineDrawer(FormDesigner designer) { + this.designer = designer; + } + + public void updateMouseEvent(MouseEvent e, boolean isMouseMoveEvent) { + this.hoverCreator = designer.getComponentAt(e); + this.isMouseMoveEvent = isMouseMoveEvent; + } + + public void draw(Graphics g) { + this.selectedRec = designer.getSelectionModel().getSelection().getSelctionBounds(); + if (isSelectedForm() || isSelectedRootComponent() || isHoveredForm() || isHoveredRootComponent() || !isMouseMoveEvent) { + return; + } + + if (!hoverCreator.isInAbsoluteContainer()) { + return; + } + + drawHorizontalSpacingLine(g); + drawVerticalSpacingLine(g); + } + + private void drawSpacingLine(Graphics g, int startX, int startY, int endX, int endY) { + Graphics2D g2d = (Graphics2D) g.create(); + g2d.setColor(LINE_COLOR); + GraphDrawHelper.drawLine(g2d, startX, startY, endX, endY, Constants.LINE_THIN); + } + + private void drawHorizontalSpacingLine(Graphics g) { + int gap = calculateNearestXGap(); + if (gap <= MIN_SPACING) { + return; + } + int[] nearestXSides = calculateNearestXSide(); + if (nearestXSides.length != 2) { + return; + } + int startX = nearestXSides[0]; + int startY = selectedRec.y + selectedRec.height / 2; + int endX = nearestXSides[1]; + int endY = selectedRec.y + selectedRec.height / 2; + drawSpacingLine(g, startX, startY, endX, endY); + drawSpacingText(g, String.valueOf(gap), (startX + endX) / 2, (startY + endY) / 2); + if (isNeedVerticalExtendedLine()) { + drawVerticalExtendedLine(g, nearestXSides); + } + } + + private void drawVerticalSpacingLine(Graphics g) { + int gap = calculateNearestYGap(); + if (gap <= MIN_SPACING) { + return; + } + int[] nearestYSides = calculateNearestYSide(); + if (nearestYSides.length != 2) { + return; + } + int startX = selectedRec.x + selectedRec.width / 2; + int startY = nearestYSides[0]; + int endX = selectedRec.x + selectedRec.width / 2; + int endY = nearestYSides[1]; + drawSpacingLine(g, startX, startY, endX, endY); + drawSpacingText(g, String.valueOf(gap), (startX + endX) / 2, (startY + endY) / 2); + if (isNeedHorizontalExtendedLine()) { + drawHorizontalExtendedLine(g, nearestYSides); + } + } + + private void drawExtendedLine(Graphics g, int startX, int startY, int endX, int endY) { + Graphics2D g2d = (Graphics2D) g.create(); + g2d.setColor(LINE_COLOR); + GraphDrawHelper.drawLine(g2d, startX, startY, endX, endY, Constants.LINE_DASH); + } + + private void drawHorizontalExtendedLine(Graphics g, int[] nearestYSides) { + int startX = 0, endX = 0; + int startY = nearestYSides[1]; + int endY = nearestYSides[1]; + if (isHoveredCreatorLeftYSpacingLine()) { + startX = hoverCreator.getX() + hoverCreator.getWidth(); + endX = selectedRec.x + selectedRec.width; + } else if (isHoveredCreatorRightYSpacingLine()) { + startX = hoverCreator.getX(); + endX = selectedRec.x; + } + drawExtendedLine(g, startX, startY, endX, endY); + } + + private void drawVerticalExtendedLine(Graphics g, int[] nearestXSides) { + int startX = nearestXSides[1]; + int endX = nearestXSides[1]; + int startY = 0, endY = 0; + if (isHoveredCreatorAboveXSpacingLine()) { + startY = hoverCreator.getY() + hoverCreator.getHeight(); + endY = selectedRec.y + selectedRec.height; + } else if (isHoveredCreatorBottomXSpacingLine()) { + startY = hoverCreator.getY(); + endY = selectedRec.y; + } + drawExtendedLine(g, startX, startY, endX, endY); + } + + private void drawSpacingText(Graphics g, String text, int x, int y) { + Graphics2D g2d = (Graphics2D) g.create(); + g2d.setColor(LINE_COLOR); + Font newFont = g2d.getFont().deriveFont(8F).deriveFont(Font.BOLD); + g2d.setFont(newFont); + FontMetrics metrics = g2d.getFontMetrics(); + int lineHeight = metrics.getAscent(); // 这里由于都是数字,要居中必须忽略掉leading和descent的高度 + int lineWidth = metrics.stringWidth(text); + + int labelPaneX = x - lineWidth / 2 - TEXT_PADDING_HORIZONTAL; + int labelPaneY = y - lineHeight / 2 - TEXT_PADDING_VERTICAL; + int labelPaneWidth = lineWidth + 2 * TEXT_PADDING_HORIZONTAL; + int labelPaneHeight = lineHeight + 2 * TEXT_PADDING_VERTICAL; + int labelPaneArc = Math.min(labelPaneWidth, labelPaneHeight); + GraphDrawHelper.fill(g2d, new RoundRectangle2D.Double(labelPaneX, labelPaneY, labelPaneWidth, labelPaneHeight, labelPaneArc, labelPaneArc)); + + g2d.setColor(TEXT_COLOR); + int labelX = x - lineWidth / 2; + int labelY = y + (lineHeight - 2) / 2; // 由于ascent里面包含了一小段空白,数字又没有大写的情况,相当于五线行第一行是空的,所以往上微调一点来居中 + GraphDrawHelper.drawString(g2d, text, labelX, labelY); + } + + private int[] calculateNearestXSide() { + return calculateNearestSide( + selectedRec.x, + selectedRec.x + selectedRec.width, + hoverCreator.getX(), + hoverCreator.getX() + hoverCreator.getWidth() + ); + } + + private int[] calculateNearestYSide() { + return calculateNearestSide(selectedRec.y, + selectedRec.y + selectedRec.height, + hoverCreator.getY(), + hoverCreator.getY() + hoverCreator.getHeight()); + } + + private int calculateNearestXGap() { + return calculateNearestGap( + selectedRec.x, + selectedRec.x + selectedRec.width, + hoverCreator.getX(), + hoverCreator.getX() + hoverCreator.getWidth() + ); + } + + private int calculateNearestYGap() { + return calculateNearestGap( + selectedRec.y, + selectedRec.y + selectedRec.height, + hoverCreator.getY(), + hoverCreator.getY() + hoverCreator.getHeight() + ); + } + + private int[] calculateNearestSide(int selectedRecSide1, int selectedRecSide2, int hoveredSide1, int hoveredSide2) { + int minGap = calculateNearestGap(selectedRecSide1, selectedRecSide2, hoveredSide1, hoveredSide2); + int[] nearestSides = new int[2]; + int[] selectedRecSides = new int[] {selectedRecSide1, selectedRecSide2}; + int[] hoveredSides = new int[] {hoveredSide1, hoveredSide2}; + for (int i = 0; i < selectedRecSides.length; i++) { + for (int j = 0; j < hoveredSides.length; j++) { + if (Math.abs(selectedRecSides[i] - hoveredSides[j]) == minGap) { + nearestSides[0] = selectedRecSides[i]; + nearestSides[1] = hoveredSides[j]; + } + } + } + return nearestSides; + } + + private int calculateNearestGap(int selectedRecSide1, int selectedRecSide2, int hoveredSide1, int hoveredSide2) { + int[] selectedRecSides = new int[] {selectedRecSide1, selectedRecSide2}; + int[] hoveredSides = new int[] {hoveredSide1, hoveredSide2}; + + int minDistance = 0; + for (int i = 0; i < selectedRecSides.length; i++) { + for (int j = 0; j < hoveredSides.length; j++) { + int distance = Math.abs(selectedRecSides[i] - hoveredSides[j]); + if (i == 0 && j == 0) { + minDistance = distance; + } else { + minDistance = Math.min(distance, minDistance); + } + } + } + return minDistance; + } + + private boolean isSelectedRootComponent() { + return designer.getSelectionModel().getSelection().size() == 1 && + designer.isRoot(designer.getSelectionModel().getSelection().getSelectedCreator()); + } + + private boolean isSelectedForm() { + return designer.getSelectionModel().getSelection().size() == 1 && + designer.getSelectionModel().getSelection().getSelectedCreator().getParent() == null; + } + + private boolean isHoveredRootComponent() { + return designer.isRoot(hoverCreator); + } + + private boolean isHoveredForm() { + return hoverCreator.getParent() == null; + } + + private boolean isNeedVerticalExtendedLine() { + return isHoveredCreatorAboveXSpacingLine() || isHoveredCreatorBottomXSpacingLine(); + } + + private boolean isHoveredCreatorAboveXSpacingLine() { + return hoverCreator.getY() + hoverCreator.getHeight() < selectedRec.y + selectedRec.height / 2; + } + + private boolean isHoveredCreatorBottomXSpacingLine() { + return hoverCreator.getY() > selectedRec.y + selectedRec.height / 2; + } + + private boolean isNeedHorizontalExtendedLine() { + return isHoveredCreatorLeftYSpacingLine() || isHoveredCreatorRightYSpacingLine(); + } + + private boolean isHoveredCreatorLeftYSpacingLine() { + return hoverCreator.getX() + hoverCreator.getWidth() < selectedRec.x + selectedRec.width / 2; + } + + private boolean isHoveredCreatorRightYSpacingLine() { + return hoverCreator.getX() > selectedRec.x + selectedRec.width / 2; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/MultiSelectionArrangement.java b/designer-form/src/main/java/com/fr/design/mainframe/MultiSelectionArrangement.java new file mode 100644 index 000000000..1b0962feb --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/MultiSelectionArrangement.java @@ -0,0 +1,218 @@ +package com.fr.design.mainframe; + +import com.fr.design.designer.creator.XCreator; + +import java.awt.Rectangle; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class MultiSelectionArrangement { + private FormDesigner designer; + private List selectedCreators; + private Rectangle rec; + + public MultiSelectionArrangement(FormDesigner designer) { + this.designer = designer; + update(); + } + + public void leftAlign() { + for (XCreator creator : selectedCreators) { + creator.setLocation(rec.x, creator.getY()); + } + repaint(); + } + + public void rightAlign() { + for (XCreator creator : selectedCreators) { + creator.setLocation(rec.x + rec.width - creator.getWidth(), creator.getY()); + } + repaint(); + } + + public void topAlign() { + for (XCreator creator : selectedCreators) { + creator.setLocation(creator.getX(), rec.y); + } + repaint(); + } + + public void bottomAlign() { + for (XCreator creator : selectedCreators) { + creator.setLocation(creator.getX(), rec.y + rec.height - creator.getHeight()); + } + repaint(); + } + + public void horizontalCenterAlign() { + for (XCreator creator : selectedCreators) { + creator.setLocation(rec.x + rec.width / 2 - creator.getWidth() / 2, creator.getY()); + } + repaint(); + } + + public void verticalCenterAlign() { + for (XCreator creator : selectedCreators) { + creator.setLocation(creator.getX(), rec.y + rec.height / 2 - creator.getHeight() / 2); + } + repaint(); + } + + // 水平分布,自动,间距由selectedCreators和border共同计算而来 + public void horizontalAutoDistribution() { + int gap = calculateHorizontalGap(); + horizontalDistribution(gap); + } + + // 水平分布,手动,传入一个间距,排列selectedCreators + public void horizontalManualDistribution(int gap) { + reSizeRecByHorizontal(gap); + horizontalDistribution(gap); + } + + private void horizontalDistribution(int gap) { + sortHorizontal(); + for (int i = 1; i < selectedCreators.size() - 1; i++) { + XCreator creator = selectedCreators.get(i); + XCreator preCreator = selectedCreators.get(i - 1); + creator.setLocation(preCreator.getX() + preCreator.getWidth() + gap, creator.getY()); + } + repaint(); + } + + private void reSizeRecByHorizontal(int gap) { + sortHorizontal(); + int width = 0; + for (XCreator creator : selectedCreators) { + width += creator.getWidth(); + } + width += (selectedCreators.size() - 1) * gap; + rec.x = rec.x + (rec.width - width) / 2; + rec.width = width; + XCreator first = selectedCreators.get(0); + first.setLocation(rec.x, first.getY()); + XCreator last = selectedCreators.get(selectedCreators.size() - 1); + last.setLocation(rec.x + rec.width - last.getWidth(), last.getY()); + } + + private void sortHorizontal() { + Collections.sort(selectedCreators, new Comparator() { + @Override + public int compare(XCreator o1, XCreator o2) { + int diffX = o1.getX() - o2.getX(); + if (diffX > 0) { + return 1; + } else if (diffX < 0) { + return -1; + } else { + int diffY = o1.getY() - o2.getY(); + if (diffY > 0) { + return 1; + } else if (diffY < 0) { + return -1; + } else { + int diffZOrder = o1.getParent().getComponentZOrder(o1) - o2.getParent().getComponentZOrder(o2); + if (diffZOrder > 0) { + return -1; + } else { + return 1; + } + } + } + } + }); + } + + // 计算selectedCreators的均分间距 + private int calculateHorizontalGap() { + int sum = 0; + for (XCreator creator : selectedCreators) { + sum += creator.getWidth(); + } + return (rec.width - sum) / (selectedCreators.size() - 1); + } + + public void verticalAutoDistribution() { + int gap = calculateVerticalGap(); + verticalDistribution(gap); + } + + public void verticalManualDistribution(int gap) { + reSizeRecByVertical(gap); + verticalDistribution(gap); + } + + private void verticalDistribution(int gap) { + sortVertical(); + for (int i = 1; i < selectedCreators.size() - 1; i++) { + XCreator creator = selectedCreators.get(i); + XCreator preCreator = selectedCreators.get(i - 1); + creator.setLocation(creator.getX(), preCreator.getY() + preCreator.getHeight() + gap); + } + repaint(); + } + + private void reSizeRecByVertical(int gap) { + sortVertical(); + int height = 0; + for (XCreator creator : selectedCreators) { + height += creator.getHeight(); + } + height += (selectedCreators.size() - 1) * gap; + rec.y = rec.y + (rec.height - height) / 2; + rec.height = height; + XCreator first = selectedCreators.get(0); + first.setLocation(first.getX(), rec.y); + XCreator last = selectedCreators.get(selectedCreators.size() - 1); + last.setLocation(last.getX(), rec.y + rec.height - last.getHeight()); + } + + private void sortVertical() { + Collections.sort(selectedCreators, new Comparator() { + @Override + public int compare(XCreator o1, XCreator o2) { + int diffY = o1.getY() - o2.getY(); + if (diffY > 0) { + return 1; + } else if (diffY < 0) { + return -1; + } else { + int diffX = o1.getX() - o2.getX(); + if (diffX > 0) { + return 1; + } else if (diffX < 0) { + return -1; + } else { + int diffZOrder = o1.getParent().getComponentZOrder(o1) - o2.getParent().getComponentZOrder(o2); + if (diffZOrder > 0) { + return -1; + } else { + return 1; + } + } + } + } + }); + } + + private int calculateVerticalGap() { + int sum = 0; + for (XCreator creator : selectedCreators) { + sum += creator.getHeight(); + } + return (rec.height - sum) / (selectedCreators.size() - 1); + } + + private void update() { + FormSelection selection = designer.getSelectionModel().getSelection(); + this.selectedCreators = Arrays.asList(selection.getSelectedCreators()); + this.rec = selection.getSelctionBounds(); + } + + private void repaint() { + designer.repaint(); + update(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java index fd64d3aab..b4fc1122b 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java @@ -5,25 +5,37 @@ import com.fr.design.ExtraDesignClassManager; import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; -import com.fr.design.designer.creator.*; +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.XWFitLayout; +import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.designer.properties.mobile.MobileBookMarkPropertyUI; import com.fr.design.designer.properties.mobile.MobileStylePropertyUI; import com.fr.design.form.util.FormDesignerUtils; import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.design.gui.controlpane.EventPropertyPane; +import com.fr.design.gui.ibutton.UIHead; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itable.AbstractPropertyTable; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.widget.ui.FormWidgetCardPane; +import com.fr.design.mainframe.widget.ui.FormWidgetCardPaneFactory; import com.fr.design.widget.ui.designer.mobile.MobileWidgetDefinePane; - import com.fr.stable.ArrayUtils; -import javax.swing.*; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.CardLayout; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -130,7 +142,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper * 创建属性表table */ private void createPropertyTable() { - formWidgetCardPane = new FormWidgetCardPane(designer); + formWidgetCardPane = FormWidgetCardPaneFactory.create(designer); designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(formWidgetCardPane)); psp = new UIScrollPane(formWidgetCardPane); // 用来装载属性表table psp.setBorder(null); @@ -141,6 +153,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper */ private void createEventTable() { eventTable = new EventPropertyPane(designer); + eventTable.setEnabled(false); designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable)); } @@ -235,6 +248,15 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Event"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Widget_Mobile_Terminal") }; + List uiHeads = new ArrayList(){ + private static final long serialVersionUID = -2456634893793575347L; + { + add(new UIHead(tabTitles[0], 0)); + add(new UIHead(tabTitles[1], 1, !designer.isMultiSelection())); + add(new UIHead(tabTitles[2], 2, !designer.isMultiSelection())); + } + + }; final CardLayout tabbedPane = new CardLayout(); final JPanel center = new JPanel(tabbedPane); center.add(formWidgetCardPane, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Properties")); @@ -242,7 +264,9 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper center.add(wsp, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Widget_Mobile_Terminal")); this.add(center, BorderLayout.CENTER); - tabsHeaderIconPane = new UIHeadGroup(tabTitles) { + tabsHeaderIconPane = new UIHeadGroup(uiHeads) { + private static final long serialVersionUID = -6739508210752677967L; + @Override public void tabChanged(int index) { //切换的时候再populate diff --git a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormMultiWidgetCardPane.java b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormMultiWidgetCardPane.java new file mode 100644 index 000000000..ba7c5156e --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormMultiWidgetCardPane.java @@ -0,0 +1,271 @@ +package com.fr.design.mainframe.widget.ui; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UIIntNumberField; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.MultiSelectionArrangement; +import com.fr.general.IOUtils; +import com.fr.stable.StableUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +public class FormMultiWidgetCardPane extends FormWidgetCardPane { + private static final int LEFT_ALIGN = 1; + private static final int RIGHT_ALIGN = 2; + private static final int HORIZONTAL_CENTER_ALIGN = 3; + private static final int TOP_ALIGN = 4; + private static final int BOTTOM_ALIGN = 5; + private static final int VERTICAL_CENTER_ALIGN = 6; + private static final int HORIZONTAL_AUTO_SPACING = 7; + private static final int VERTICAL_AUTO_SPACING = 8; + + private MultiSelectionArrangement arrangement; + + public FormMultiWidgetCardPane(FormDesigner designer) { + super(designer); + arrangement = new MultiSelectionArrangement(designer); + } + + public void initPropertyPane() { + content.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0)); + content.add(createArrangementLayoutPane(), BorderLayout.CENTER); + } + + // 整个排列分布面板的layout,可以看成一个三行一列的表格,第一行是分布,第二行是自动间距,第三行是手动间距 + private JPanel createArrangementLayoutPane() { + double[] rowSize = {TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED}; + double[] columnSize = {TableLayout.PREFERRED}; + Component[][] components = new Component[][] { + new Component[] { + createAlignmentPane() + }, + new Component[] { + createAutoSpacingPane() + }, + new Component[] { + createManualSpacingPane() + } + }; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, 0, 16); + } + + // 对齐 + private JPanel createAlignmentPane() { + double[] rowSize = {TableLayout.PREFERRED}; + double[] columnSize = { + TableLayout.PREFERRED, + TableLayout.PREFERRED, + TableLayout.PREFERRED, + TableLayout.PREFERRED, + TableLayout.PREFERRED, + TableLayout.PREFERRED + }; + Component[][] components = new Component[][] { + new Component[] { + createArrangementButton(LEFT_ALIGN), + createArrangementButton(HORIZONTAL_CENTER_ALIGN), + createArrangementButton(RIGHT_ALIGN), + createArrangementButton(TOP_ALIGN), + createArrangementButton(VERTICAL_CENTER_ALIGN), + createArrangementButton(BOTTOM_ALIGN) + } + }; + JPanel centerPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, 18, 0); + return createTitleLayout(Toolkit.i18nText("Fine-Design_Multi_Selection_Align"), centerPane); + } + + // 自动间距 + private JPanel createAutoSpacingPane() { + double[] rowSize = {TableLayout.PREFERRED}; + double[] columnSize = { + TableLayout.PREFERRED, + TableLayout.PREFERRED + }; + UIButton horizontalAutoSpacingBtn = createArrangementButton(HORIZONTAL_AUTO_SPACING); + UIButton verticalAutoSpacingBtn = createArrangementButton(VERTICAL_AUTO_SPACING); + if (designer.getSelectionModel().getSelection().size() < 3) { + horizontalAutoSpacingBtn.setEnabled(false); + verticalAutoSpacingBtn.setEnabled(false); + } + Component[][] components = new Component[][] { + new Component[] { + horizontalAutoSpacingBtn, + verticalAutoSpacingBtn + } + }; + JPanel centerPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, 18, 0); + + + UILabel tip = new UILabel(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_auto_spacing_tip.png")); + tip.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Auto_Spacing_Tip")); + Component[][] titleComponents = new Component[][] { + new Component[] { + new UILabel(Toolkit.i18nText("Fine-Design_Multi_Selection_Auto_Spacing")), + tip + } + }; + JPanel northPane = TableLayoutHelper.createGapTableLayoutPane(titleComponents, rowSize, columnSize, 5, 0); + + JPanel jPanel = new JPanel(); + jPanel.setLayout(new BorderLayout(0, 8)); + jPanel.add(northPane, BorderLayout.NORTH); + jPanel.add(centerPane, BorderLayout.CENTER); + return jPanel; + } + + // 手动间距 + private JPanel createManualSpacingPane() { + double[] rowSize = {TableLayout.PREFERRED, TableLayout.PREFERRED}; + double[] columnSize = { + TableLayout.PREFERRED, + TableLayout.FILL + }; + UITextField horizontalSpacingNumberField = new UIIntNumberField(); + horizontalSpacingNumberField.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + distributionDoChange(horizontalSpacingNumberField.getText(), false); + } + }); + UITextField verticalSpacingNumberField = new UIIntNumberField(); + verticalSpacingNumberField.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + distributionDoChange(verticalSpacingNumberField.getText(), true); + } + }); + Component[][] components = new Component[][] { + new Component[] { + new UILabel(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_horizontal_spacing.png")), + horizontalSpacingNumberField + }, + new Component[] { + new UILabel(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_vertical_spacing.png")), + verticalSpacingNumberField + } + }; + JPanel centerPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, 21, 9); + return createTitleLayout(Toolkit.i18nText("Fine-Design_Multi_Selection_Manual_Spacing"), centerPane); + } + + private void distributionDoChange(String text, boolean isVertical) { + if (StableUtils.isNumber(text)) { + if (isVertical) { + arrangement.verticalManualDistribution(Math.round(Float.parseFloat(text))); + } else { + arrangement.horizontalManualDistribution(Math.round(Float.parseFloat(text))); + } + } + } + + // 创建一个BorderLayout布局,上面是标题,例如“对齐”,下面是个容器 + private JPanel createTitleLayout(String title, JPanel centerPane) { + JPanel jPanel = new JPanel(); + jPanel.setLayout(new BorderLayout(0, 8)); + jPanel.add(new UILabel(title), BorderLayout.NORTH); + jPanel.add(centerPane, BorderLayout.CENTER); + return jPanel; + } + + private UIButton createArrangementButton(int btnType) { + UIButton btn = new UIButton(); + btn.setNormalPainted(false); + btn.setBorderPaintedOnlyWhenPressed(true); + switch (btnType) { + case LEFT_ALIGN: + btn.setIcon(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_left_align.png")); + btn.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Left_Align")); + btn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + arrangement.leftAlign(); + } + }); + break; + case RIGHT_ALIGN: + btn.setIcon(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_right_align.png")); + btn.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Right_Align")); + btn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + arrangement.rightAlign(); + } + }); + break; + case TOP_ALIGN: + btn.setIcon(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_top_align.png")); + btn.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Top_Align")); + btn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + arrangement.topAlign(); + } + }); + break; + case BOTTOM_ALIGN: + btn.setIcon(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_bottom_align.png")); + btn.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Bottom_Align")); + btn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + arrangement.bottomAlign(); + } + }); + break; + case HORIZONTAL_CENTER_ALIGN: + btn.setIcon(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_horizontal_center_align.png")); + btn.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Horizontal_Center_Align")); + btn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + arrangement.horizontalCenterAlign(); + } + }); + break; + case VERTICAL_CENTER_ALIGN: + btn.setIcon(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_vertical_center_align.png")); + btn.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Vertical_Center_Align")); + btn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + arrangement.verticalCenterAlign(); + } + }); + break; + case HORIZONTAL_AUTO_SPACING: + btn.setIcon(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_horizontal_auto_spacing.png")); + btn.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Auto_Horizontal_Spacing")); + btn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + arrangement.horizontalAutoDistribution(); + } + }); + break; + case VERTICAL_AUTO_SPACING: + btn.setIcon(IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_vertical_auto_spacing.png")); + btn.setToolTipText(Toolkit.i18nText("Fine-Design_Multi_Selection_Auto_Vertical_Spacing")); + btn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + arrangement.verticalAutoDistribution(); + } + }); + break; + default: break; + } + return btn; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormSingleWidgetCardPane.java b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormSingleWidgetCardPane.java new file mode 100644 index 000000000..a9e5e5d98 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormSingleWidgetCardPane.java @@ -0,0 +1,297 @@ +package com.fr.design.mainframe.widget.ui; + +import com.fr.design.data.DataCreatorUI; +import com.fr.design.designer.beans.events.DesignerEvent; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWAbsoluteBodyLayout; +import com.fr.design.designer.creator.XWAbsoluteLayout; +import com.fr.design.designer.creator.XWFitLayout; +import com.fr.design.designer.creator.XWParameterLayout; +import com.fr.design.designer.creator.XWScaleLayout; +import com.fr.design.designer.creator.XWTitleLayout; +import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.EastRegionContainerPane; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.JForm; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.widget.DataModify; +import com.fr.design.widget.FormWidgetDefinePaneFactoryBase; +import com.fr.design.widget.Operator; +import com.fr.design.widget.ui.designer.component.WidgetAbsoluteBoundPane; +import com.fr.design.widget.ui.designer.component.WidgetBoundPane; +import com.fr.design.widget.ui.designer.component.WidgetCardTagBoundPane; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WScaleLayout; +import com.fr.form.ui.container.WTitleLayout; +import com.fr.form.ui.widget.CRBoundsWidget; +import com.fr.general.ComparatorUtils; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import java.awt.BorderLayout; + +public class FormSingleWidgetCardPane extends FormWidgetCardPane { + private AttributeChangeListener listener; + + //当前的编辑器属性定义面板 + private DataModify currentEditorDefinePane; + private FormBasicPropertyPane widgetPropertyPane; + private JPanel attriCardPane; + + private XCreator xCreator; + private WidgetBoundPane widgetBoundPane; + + + public FormSingleWidgetCardPane(FormDesigner designer) { + super(designer); + } + + public void initPropertyPane() { + this.xCreator = findXcreator(designer); + initComponents(); + initDefinePane(); + } + + public XLayoutContainer getParent(XCreator source) { + XLayoutContainer container = XCreatorUtils.getParentXLayoutContainer(source); + if (source.acceptType(XWFitLayout.class) || source.acceptType(XWParameterLayout.class)) { + container = null; + } + return container; + } + + public WidgetBoundPane createWidgetBoundPane(XCreator xCreator) { + XLayoutContainer xLayoutContainer = getParent(xCreator); + if (xLayoutContainer == null || xCreator.acceptType(XWParameterLayout.class) || xCreator.acceptType(XWAbsoluteBodyLayout.class)) { + return null; + } else if (xLayoutContainer.acceptType(XWAbsoluteLayout.class)) { + return new WidgetAbsoluteBoundPane(xCreator); + } else if (xCreator.acceptType(XWCardTagLayout.class)) { + return new WidgetCardTagBoundPane(xCreator); + } + return new WidgetBoundPane(xCreator); + } + + public XCreator findXcreator(FormDesigner designer) { + XCreator creator = designer.getSelectionModel().getSelection().getSelectedCreator(); + return creator != null ? creator : designer.getRootComponent(); + } + + /** + * 后台初始化所有事件. + */ + @Override + public void initAllListeners() { + + } + + /** + * 后台初始化所有事件. + */ + public void reinitAllListeners() { + initListener(this); + } + + @Override + protected void initContentPane() { + + } + + private void initComponents() { + XCreator innerCreator = getXCreatorDedicated(); + + attriCardPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + content.add(attriCardPane, BorderLayout.CENTER); + content.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + + final boolean isExtraWidget = FormWidgetDefinePaneFactoryBase.isExtraXWidget(innerCreator.toData()); + this.listener = new AttributeChangeListener() { + @Override + public void attributeChange() { + if (!isExtraWidget) { + updateCreator(); + } + updateWidgetBound(); + firePropertyEdit(); + } + }; + + freshPropertyMode(innerCreator); + if (isExtraWidget) { + // REPORT-55603: 仅对于插件控件,将尺寸*位置面板放置在definePane下方,其余控件将尺寸*位置面板放置在definePane上方 + widgetBoundPane = createWidgetBoundPane(xCreator); + if (widgetBoundPane != null) { + attriCardPane.add(widgetBoundPane, BorderLayout.CENTER); + } + return; + } + + widgetPropertyPane = WidgetBasicPropertyPaneFactory.createBasicPropertyPane(innerCreator); + + UIExpandablePane uiExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), 280, 20, widgetPropertyPane); + + content.add(uiExpandablePane, BorderLayout.NORTH); + + widgetBoundPane = createWidgetBoundPane(xCreator); + if (widgetBoundPane != null) { + attriCardPane.add(widgetBoundPane, BorderLayout.NORTH); + } + } + + private static void freshPropertyMode(XCreator xCreator) { + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (!(jTemplate instanceof JForm) && jTemplate.isUpMode()) { + if (xCreator instanceof XWParameterLayout) { + EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT_PARA); + } else { + EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT_PARA_WIDGET); + } + } + } + + private void initDefinePane() { + currentEditorDefinePane = null; + XCreator creator = getXCreatorDedicated(); + FormWidgetDefinePaneFactoryBase.RN rn = FormWidgetDefinePaneFactoryBase.createWidgetDefinePane(creator, designer, creator.toData(), new Operator() { + @Override + public void did(DataCreatorUI ui, String cardName) { + //todo + } + }); + DataModify definePane = rn.getDefinePane(); + + JComponent definePaneComponent = definePane.toSwingComponent(); + boolean isExtraWidget = FormWidgetDefinePaneFactoryBase.isExtraXWidget(creator.toData()); + + if (isExtraWidget) { + // REPORT-55603: 仅对于插件控件,将尺寸*位置面板放置在definePane下方,其余控件将尺寸*位置面板放置在definePane上方 + attriCardPane.add(definePaneComponent, BorderLayout.NORTH); + } else { + // 使用单独的JPane和BorderLayout.North进行包装,避免出现CENTER嵌套CENTER后,内容高度变大的情况 + JPanel definePaneWrapContent = FRGUIPaneFactory.createBorderLayout_S_Pane(); + definePaneWrapContent.add(definePaneComponent, BorderLayout.NORTH); + attriCardPane.add(definePaneWrapContent, BorderLayout.CENTER); + } + currentEditorDefinePane = definePane; + } + + private XCreator getXCreatorDedicated() { + boolean dedicateLayout = xCreator.acceptType(XWScaleLayout.class) && xCreator.getComponentCount() > 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator() || xCreator.acceptType(XWTitleLayout.class); + return dedicateLayout ? (XCreator) xCreator.getComponent(0) : xCreator; + } + + @Override + public String title4PopupWindow() { + return "Widget"; + } + + public void populate() { + //populate之前先移除所有的监听 + removeAttributeChangeListener(); + Widget cellWidget = xCreator.toData(); + if (widgetBoundPane != null) { + widgetBoundPane.populate(); + } + Widget innerWidget = cellWidget; + if (cellWidget.acceptType(WScaleLayout.class)) { + Widget crBoundsWidget = ((WScaleLayout) cellWidget).getBoundsWidget(); + innerWidget = ((CRBoundsWidget) crBoundsWidget).getWidget(); + } else if (cellWidget.acceptType(WTitleLayout.class)) { + CRBoundsWidget crBoundsWidget = ((WTitleLayout) cellWidget).getBodyBoundsWidget(); + innerWidget = crBoundsWidget.getWidget(); + } + if (currentEditorDefinePane != null) { + currentEditorDefinePane.populateBean(innerWidget); + } + if (widgetPropertyPane != null) { + widgetPropertyPane.populate(innerWidget); + } + reinitAllListeners(); + this.addAttributeChangeListener(listener); + } + + + public void updateCreator() { + currentEditorDefinePane.setGlobalName(getGlobalName()); + Widget widget = currentEditorDefinePane.updateBean(); + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_Basic")) && widgetPropertyPane != null) { + UITextField widgetNameField = widgetPropertyPane.getWidgetNameField(); + String toSetWidgetName = widgetNameField.getText(); + String currentWidgetName = widget.getWidgetName(); + if (toSetWidgetName.isEmpty()) { + widgetNameField.setText(currentWidgetName); + return; + } + + boolean exist = designer.getTarget().isNameExist(toSetWidgetName, widget) && !ComparatorUtils.equals(toSetWidgetName, currentWidgetName); + if (exist) { + widgetNameField.setText(currentWidgetName); + showNameInvalidDialog(Toolkit.i18nText("Fine-Design_Form_Widget_Rename_Failure")); + return; + } + + //图表名称的合法性检查 + if (widget instanceof ChartEditor && toSetWidgetName.startsWith("Chart")) { + widgetNameField.setText(currentWidgetName); + showNameInvalidDialog(Toolkit.i18nText("Fine-Design_Form_Chart_Widget_Rename_Failure")); + return; + } + widgetPropertyPane.update(widget); + // 上面一行更新了组件 这里必须重新调用getWidgetName + xCreator.resetCreatorName(widget.getWidgetName()); + xCreator.resetVisible(widget.isVisible()); + designer.getEditListenerTable().fireCreatorModified(xCreator, DesignerEvent.CREATOR_RENAMED); + return; + } + fireValueChanged(); + } + + private void showNameInvalidDialog(String message) { + JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), message, Toolkit.i18nText("Fine-Design_Form_Joption_News"), JOptionPane.ERROR_MESSAGE, IOUtils.readIcon("com/fr/design/form/images/joption_failure.png")); + } + + public void updateWidgetBound() { + if (widgetBoundPane != null && ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size"))) { + widgetBoundPane.update(); + designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_RESIZED); + } + designer.refreshDesignerUI(); + } + + + @Override + /** + *检查 + */ + public void checkValid() throws Exception { + currentEditorDefinePane.checkValid(); + } + + public void fireValueChanged() { + XCreator creator = getXCreatorDedicated(); + creator.firePropertyChange(); + } + + @Override + public String getIconPath() { + return StringUtils.EMPTY; + } + + public void firePropertyEdit() { + designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java index a76c96902..c2d145983 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java @@ -1,49 +1,12 @@ package com.fr.design.mainframe.widget.ui; -import com.fr.design.data.DataCreatorUI; -import com.fr.design.designer.beans.events.DesignerEvent; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.designer.creator.XLayoutContainer; -import com.fr.design.designer.creator.XWAbsoluteBodyLayout; -import com.fr.design.designer.creator.XWAbsoluteLayout; -import com.fr.design.designer.creator.XWFitLayout; -import com.fr.design.designer.creator.XWParameterLayout; -import com.fr.design.designer.creator.XWScaleLayout; -import com.fr.design.designer.creator.XWTitleLayout; -import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.dialog.AttrScrollPane; import com.fr.design.dialog.BasicScrollPane; -import com.fr.design.file.HistoryTemplateListCache; -import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; -import com.fr.design.gui.frpane.AttributeChangeListener; -import com.fr.design.gui.itextfield.UITextField; -import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.JForm; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.widget.DataModify; -import com.fr.design.widget.FormWidgetDefinePaneFactoryBase; -import com.fr.design.widget.Operator; -import com.fr.design.widget.ui.designer.component.WidgetAbsoluteBoundPane; -import com.fr.design.widget.ui.designer.component.WidgetBoundPane; -import com.fr.design.widget.ui.designer.component.WidgetCardTagBoundPane; -import com.fr.form.ui.ChartEditor; -import com.fr.form.ui.Widget; -import com.fr.form.ui.container.WScaleLayout; -import com.fr.form.ui.container.WTitleLayout; -import com.fr.form.ui.widget.CRBoundsWidget; -import com.fr.general.ComparatorUtils; -import com.fr.general.IOUtils; -import com.fr.stable.StringUtils; import javax.swing.BorderFactory; -import javax.swing.JComponent; -import javax.swing.JOptionPane; import javax.swing.JPanel; import java.awt.BorderLayout; @@ -51,43 +14,18 @@ import java.awt.BorderLayout; * Created by ibm on 2017/7/25. */ public class FormWidgetCardPane extends AbstractAttrNoScrollPane { - private AttributeChangeListener listener; - private FormDesigner designer; - //当前的编辑器属性定义面板 - private DataModify currentEditorDefinePane; - private FormBasicPropertyPane widgetPropertyPane; - private JPanel attriCardPane; - - private XCreator xCreator; - private WidgetBoundPane widgetBoundPane; - + protected FormDesigner designer; + protected JPanel content; public FormWidgetCardPane(FormDesigner designer) { - super(); - this.xCreator = findXcreator(designer); this.designer = designer; - initComponents(); - initDefinePane(); + this.initLayout(); + this.initScrollPane(); + this.initPropertyPane(); } - public XLayoutContainer getParent(XCreator source) { - XLayoutContainer container = XCreatorUtils.getParentXLayoutContainer(source); - if (source.acceptType(XWFitLayout.class) || source.acceptType(XWParameterLayout.class)) { - container = null; - } - return container; - } + public void initPropertyPane() { - public WidgetBoundPane createWidgetBoundPane(XCreator xCreator) { - XLayoutContainer xLayoutContainer = getParent(xCreator); - if (xLayoutContainer == null || xCreator.acceptType(XWParameterLayout.class) || xCreator.acceptType(XWAbsoluteBodyLayout.class)) { - return null; - } else if (xLayoutContainer.acceptType(XWAbsoluteLayout.class)) { - return new WidgetAbsoluteBoundPane(xCreator); - } else if (xCreator.acceptType(XWCardTagLayout.class)) { - return new WidgetCardTagBoundPane(xCreator); - } - return new WidgetBoundPane(xCreator); } @Override @@ -95,219 +33,31 @@ public class FormWidgetCardPane extends AbstractAttrNoScrollPane { return null; } - public XCreator findXcreator(FormDesigner designer) { - XCreator creator = designer.getSelectionModel().getSelection().getSelectedCreator(); - return creator != null ? creator : designer.getRootComponent(); - } - - /** - * 后台初始化所有事件. - */ - @Override - public void initAllListeners() { - - } - - /** - * 后台初始化所有事件. - */ - public void reinitAllListeners() { - initListener(this); - } - - @Override - protected void initContentPane() { - } - - private void initComponents() { - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); - XCreator innerCreator = getXCreatorDedicated(); - - final JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + private void initScrollPane() { + final JPanel jPanel = this.createContentPaneInScrollPane(); BasicScrollPane basicScrollPane = new AttrScrollPane() { + private static final long serialVersionUID = 3117877968639659022L; + @Override protected JPanel createContentPane() { return jPanel; } }; this.add(basicScrollPane, BorderLayout.CENTER); - attriCardPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - jPanel.add(attriCardPane, BorderLayout.CENTER); - jPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); - - final boolean isExtraWidget = FormWidgetDefinePaneFactoryBase.isExtraXWidget(innerCreator.toData()); - this.listener = new AttributeChangeListener() { - @Override - public void attributeChange() { - if (!isExtraWidget) { - updateCreator(); - } - updateWidgetBound(); - firePropertyEdit(); - } - }; - - freshPropertyMode(innerCreator); - if (isExtraWidget) { - // REPORT-55603: 仅对于插件控件,将尺寸*位置面板放置在definePane下方,其余控件将尺寸*位置面板放置在definePane上方 - widgetBoundPane = createWidgetBoundPane(xCreator); - if (widgetBoundPane != null) { - attriCardPane.add(widgetBoundPane, BorderLayout.CENTER); - } - return; - } - - widgetPropertyPane = WidgetBasicPropertyPaneFactory.createBasicPropertyPane(innerCreator); - - UIExpandablePane uiExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), 280, 20, widgetPropertyPane); - - jPanel.add(uiExpandablePane, BorderLayout.NORTH); - - widgetBoundPane = createWidgetBoundPane(xCreator); - if (widgetBoundPane != null) { - attriCardPane.add(widgetBoundPane, BorderLayout.NORTH); - } - } - - private static void freshPropertyMode(XCreator xCreator) { - JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (!(jTemplate instanceof JForm) && jTemplate.isUpMode()) { - if (xCreator instanceof XWParameterLayout) { - EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT_PARA); - } else { - EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT_PARA_WIDGET); - } - } + this.content = jPanel; } - private void initDefinePane() { - currentEditorDefinePane = null; - XCreator creator = getXCreatorDedicated(); - FormWidgetDefinePaneFactoryBase.RN rn = FormWidgetDefinePaneFactoryBase.createWidgetDefinePane(creator, designer, creator.toData(), new Operator() { - @Override - public void did(DataCreatorUI ui, String cardName) { - //todo - } - }); - DataModify definePane = rn.getDefinePane(); - - JComponent definePaneComponent = definePane.toSwingComponent(); - boolean isExtraWidget = FormWidgetDefinePaneFactoryBase.isExtraXWidget(creator.toData()); - - if (isExtraWidget) { - // REPORT-55603: 仅对于插件控件,将尺寸*位置面板放置在definePane下方,其余控件将尺寸*位置面板放置在definePane上方 - attriCardPane.add(definePaneComponent, BorderLayout.NORTH); - } else { - // 使用单独的JPane和BorderLayout.North进行包装,避免出现CENTER嵌套CENTER后,内容高度变大的情况 - JPanel definePaneWrapContent = FRGUIPaneFactory.createBorderLayout_S_Pane(); - definePaneWrapContent.add(definePaneComponent, BorderLayout.NORTH); - attriCardPane.add(definePaneWrapContent, BorderLayout.CENTER); - } - currentEditorDefinePane = definePane; - } - - private XCreator getXCreatorDedicated() { - boolean dedicateLayout = xCreator.acceptType(XWScaleLayout.class) && xCreator.getComponentCount() > 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator() || xCreator.acceptType(XWTitleLayout.class); - return dedicateLayout ? (XCreator) xCreator.getComponent(0) : xCreator; + private void initLayout() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + // 跟上方tab标题“属性”那一栏间距10 + this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); } - @Override - public String title4PopupWindow() { - return "Widget"; + protected JPanel createContentPaneInScrollPane() { + return FRGUIPaneFactory.createBorderLayout_S_Pane(); } public void populate() { - //populate之前先移除所有的监听 - removeAttributeChangeListener(); - Widget cellWidget = xCreator.toData(); - if (widgetBoundPane != null) { - widgetBoundPane.populate(); - } - Widget innerWidget = cellWidget; - if (cellWidget.acceptType(WScaleLayout.class)) { - Widget crBoundsWidget = ((WScaleLayout) cellWidget).getBoundsWidget(); - innerWidget = ((CRBoundsWidget) crBoundsWidget).getWidget(); - } else if (cellWidget.acceptType(WTitleLayout.class)) { - CRBoundsWidget crBoundsWidget = ((WTitleLayout) cellWidget).getBodyBoundsWidget(); - innerWidget = crBoundsWidget.getWidget(); - } - currentEditorDefinePane.populateBean(innerWidget); - if (widgetPropertyPane != null) { - widgetPropertyPane.populate(innerWidget); - } - reinitAllListeners(); - this.addAttributeChangeListener(listener); - } - - - public void updateCreator() { - currentEditorDefinePane.setGlobalName(getGlobalName()); - Widget widget = currentEditorDefinePane.updateBean(); - if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_Basic")) && widgetPropertyPane != null) { - UITextField widgetNameField = widgetPropertyPane.getWidgetNameField(); - String toSetWidgetName = widgetNameField.getText(); - String currentWidgetName = widget.getWidgetName(); - if (toSetWidgetName.isEmpty()) { - widgetNameField.setText(currentWidgetName); - return; - } - - boolean exist = designer.getTarget().isNameExist(toSetWidgetName, widget) && !ComparatorUtils.equals(toSetWidgetName, currentWidgetName); - if (exist) { - widgetNameField.setText(currentWidgetName); - showNameInvalidDialog(Toolkit.i18nText("Fine-Design_Form_Widget_Rename_Failure")); - return; - } - - //图表名称的合法性检查 - if (widget instanceof ChartEditor && toSetWidgetName.startsWith("Chart")) { - widgetNameField.setText(currentWidgetName); - showNameInvalidDialog(Toolkit.i18nText("Fine-Design_Form_Chart_Widget_Rename_Failure")); - return; - } - widgetPropertyPane.update(widget); - // 上面一行更新了组件 这里必须重新调用getWidgetName - xCreator.resetCreatorName(widget.getWidgetName()); - xCreator.resetVisible(widget.isVisible()); - designer.getEditListenerTable().fireCreatorModified(xCreator, DesignerEvent.CREATOR_RENAMED); - return; - } - fireValueChanged(); - } - - private void showNameInvalidDialog(String message) { - JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), message, Toolkit.i18nText("Fine-Design_Form_Joption_News"), JOptionPane.ERROR_MESSAGE, IOUtils.readIcon("com/fr/design/form/images/joption_failure.png")); - } - - public void updateWidgetBound() { - if (widgetBoundPane != null && ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size"))) { - widgetBoundPane.update(); - designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_RESIZED); - } - designer.refreshDesignerUI(); - } - - - @Override - /** - *检查 - */ - public void checkValid() throws Exception { - currentEditorDefinePane.checkValid(); - } - - public void fireValueChanged() { - XCreator creator = getXCreatorDedicated(); - creator.firePropertyChange(); - } - - @Override - public String getIconPath() { - return StringUtils.EMPTY; - } - public void firePropertyEdit() { - designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPaneFactory.java b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPaneFactory.java new file mode 100644 index 000000000..6c4874536 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPaneFactory.java @@ -0,0 +1,13 @@ +package com.fr.design.mainframe.widget.ui; + +import com.fr.design.mainframe.FormDesigner; + +public class FormWidgetCardPaneFactory { + public static FormWidgetCardPane create(FormDesigner designer) { + if (designer.isMultiSelection()) { + return new FormMultiWidgetCardPane(designer); + } else { + return new FormSingleWidgetCardPane(designer); + } + } +}