Browse Source

Pull request #5250: REPORT-54885 【10.0.19】FRM布局推荐之布局优化部分

Merge in DESIGN/design from ~FANGLEI/design10.0:feature/10.0 to feature/10.0

* commit '897230cfaa4f3156df586bb5436cac407f07f09a':
  REPORT-54885 添加注释,便于理解
  REPORT-54885 优化获取延长线方法的实现
  REPORT-54885 优化方法命名
  REPORT-54885 优化api命名
  REPORT-54885 优化重复代码
  REPORT-54885 【10.0.19】FRM布局推荐之布局优化部分
  REPORT-54885 【10.0.19】FRM布局推荐之布局优化部分
feature/10.0
fanglei 3 years ago
parent
commit
d25d4c2461
  1. 2
      designer-base/src/main/java/com/fr/design/dialog/BasicPane.java
  2. 2
      designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java
  3. 63
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIHead.java
  4. 129
      designer-base/src/main/java/com/fr/design/gui/ibutton/UIHeadGroup.java
  5. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_auto_spacing_tip.png
  6. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_bottom_align.png
  7. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_auto_spacing.png
  8. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_center_align.png
  9. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_spacing.png
  10. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_left_align.png
  11. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_right_align.png
  12. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_top_align.png
  13. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_auto_spacing.png
  14. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_center_align.png
  15. BIN
      designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_spacing.png
  16. 3
      designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java
  17. 70
      designer-form/src/main/java/com/fr/design/mainframe/AbstractFormParallelLine.java
  18. 3
      designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java
  19. 20
      designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java
  20. 13
      designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java
  21. 45
      designer-form/src/main/java/com/fr/design/mainframe/FormHorizontalParallelLine.java
  22. 198
      designer-form/src/main/java/com/fr/design/mainframe/FormSpacingLineDrawer.java
  23. 45
      designer-form/src/main/java/com/fr/design/mainframe/FormVerticalParallelLine.java
  24. 218
      designer-form/src/main/java/com/fr/design/mainframe/MultiSelectionArrangement.java
  25. 36
      designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java
  26. 23
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/AbstractMultiSelectionArrangementButton.java
  27. 35
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/BottomAlignButton.java
  28. 35
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/HorizontalCenterButton.java
  29. 35
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/HorizontalDistributionButton.java
  30. 35
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/LeftAlignButton.java
  31. 16
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/MultiSelectionArrangementButton.java
  32. 35
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/RightAlignButton.java
  33. 35
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/TopAlignButton.java
  34. 35
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/VerticalCenterButton.java
  35. 35
      designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/VerticalDistributionButton.java
  36. 178
      designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormMultiWidgetCardPane.java
  37. 297
      designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormSingleWidgetCardPane.java
  38. 284
      designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java
  39. 13
      designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPaneFactory.java

2
designer-base/src/main/java/com/fr/design/dialog/BasicPane.java

@ -410,6 +410,4 @@ public abstract class BasicPane extends JPanel {
}
}
}

2
designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java

@ -46,9 +46,11 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane {
protected void initContentPane() {
leftContentPane = createContentPane();
if (leftContentPane != null) {
leftContentPane.setBorder(BorderFactory.createMatteBorder(10, 10, 0, 0, original));
this.add(leftContentPane, BorderLayout.CENTER);
}
}
protected abstract JPanel createContentPane();

63
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;
}
}

129
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<UIHead> uiHeads = new ArrayList<>();
protected List<UIToggleButton> labelButtonList;
private boolean isNeedLeftRightOutLine = true;
protected int selectedIndex = -1;
@ -29,77 +30,47 @@ public class UIHeadGroup extends JPanel {
}
public UIHeadGroup(String[] textArray) {
labelButtonList = new ArrayList<UIToggleButton>(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();
uiHeads.add(new UIHead(textArray[i], i));
}
};
}
};
initButton(labelButton);
}
setSelectedIndex(0);
initUIHeadGroup(uiHeads);
}
public UIHeadGroup(Icon[] iconArray) {
labelButtonList = new ArrayList<UIToggleButton>(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();
uiHeads.add(new UIHead(iconArray[i], i));
}
};
initUIHeadGroup(uiHeads);
}
};
initButton(labelButton);
public UIHeadGroup(Icon[] iconArray, String[] textArray) {
int length = Math.min(textArray.length, iconArray.length);
for (int i = 0; i < length; i++) {
uiHeads.add(new UIHead(textArray[i], iconArray[i], i));
}
setSelectedIndex(0);
initUIHeadGroup(uiHeads);
}
public UIHeadGroup(Icon[] iconArray, String[] textArray) {
labelButtonList = new ArrayList<UIToggleButton>(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();
public UIHeadGroup(List<UIHead> uiHeads) {
initUIHeadGroup(uiHeads);
}
};
public void initUIHeadGroup(List<UIHead> uiHeads) {
if (uiHeads != null) {
labelButtonList = new ArrayList<UIToggleButton>(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);
}
}
@Override
public Dimension getPreferredSize() {
@ -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);

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_auto_spacing_tip.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_bottom_align.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_auto_spacing.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_center_align.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_horizontal_spacing.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_left_align.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_right_align.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_top_align.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_auto_spacing.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_center_align.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

BIN
designer-base/src/main/resources/com/fr/design/images/buttonicon/multi_selection_vertical_spacing.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

3
designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java

@ -862,4 +862,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo
}
}
public boolean isParentAbsolute() {
return ((XCreator) this.getParent()).acceptType(XWAbsoluteLayout.class);
}
}

70
designer-form/src/main/java/com/fr/design/mainframe/AbstractFormParallelLine.java

@ -0,0 +1,70 @@
package com.fr.design.mainframe;
import java.awt.Point;
public abstract class AbstractFormParallelLine {
protected int parallelValue;
protected int startPosition;
protected int endPosition;
public AbstractFormParallelLine(int parallelValue, int startPosition, int endPosition) {
this.parallelValue = parallelValue;
this.startPosition = startPosition;
this.endPosition = endPosition;
}
public int getCenterPosition() {
return (startPosition + endPosition) / 2;
}
/**
* 获取当前直线的中垂线起点位置
* @return 中垂线起点位置
*/
abstract public Point getStartPointOnVerticalCenterLine();
/**
* 获取当前直线的中垂线的重点位置重点位置即为重垂线与另一条平行线相交的点
* @param parallelValue 平行线
* @return 中垂线重点位置
*/
abstract public Point getEndPointOnVerticalCenterLine(int parallelValue);
public boolean isVerticalCenterLineBeforeTheParallelLine(AbstractFormParallelLine parallelLine) {
return this.getCenterPosition() < parallelLine.getStartPosition();
}
public boolean isVerticalCenterLineBehindTheParallelLine(AbstractFormParallelLine parallelLine) {
return this.getCenterPosition() > parallelLine.getEndPosition();
}
/**
* 传一个平行线 当前直线和平行线中心点位置无平行相交的部分的时候需要绘制一条延长线一直延长到平行线边界位置
* @param parallelLine 平行线
* @return 延长线的起点位置
*/
abstract public Point getExtendedLineStartPoint(AbstractFormParallelLine parallelLine);
/**
* 传一个平行线 当前直线和平行线中心点位置无平行相交的部分的时候需要绘制一条延长线一直延长到平行线边界位置
* @param parallelLine 平行线
* @return 延长线的重点位置
*/
abstract public Point getExtendedLineEndPoint(AbstractFormParallelLine parallelLine);
public int getDistanceWithLine(AbstractFormParallelLine parallelLine) {
return Math.abs(this.getParallelValue() - parallelLine.getParallelValue());
}
public int getParallelValue() {
return parallelValue;
}
public int getStartPosition() {
return startPosition;
}
public int getEndPosition() {
return endPosition;
}
}

3
designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java

@ -36,7 +36,6 @@ import com.fr.design.utils.gui.LayoutUtils;
import com.fr.general.ComparatorUtils;
import com.fr.stable.Constants;
import java.util.LinkedList;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPopupMenu;
@ -49,6 +48,7 @@ import java.awt.Cursor;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.LinkedList;
/**
* 普通模式下的鼠标点击位置处理器
@ -353,6 +353,7 @@ public class EditingMouseListener extends MouseInputAdapter {
return;
}
designer.getSpacingLineDrawer().updateMouseEvent(e, true);
processChartEditorMouseMove(component, e);
e.translatePoint(oldX - e.getX(), oldY - e.getY());
designer.repaint();

20
designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java

@ -38,7 +38,6 @@ import com.fr.design.designer.creator.XWAbsoluteLayout;
import com.fr.design.designer.creator.XWBorderLayout;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
import com.fr.design.designer.creator.cardlayout.XWTabFitLayout;
import com.fr.design.designer.properties.FormWidgetAuthorityEditPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.event.DesignerOpenedListener;
@ -126,6 +125,7 @@ public class FormDesigner extends TargetComponent<Form> 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<Form> implements TreeSelection
// 必须刷新"参数/控件树"面板,否则,若最近一次打开模版为 cpt,重启设计器,打开 frm,控件树消失
populateParameterPropertyPane();
spacingLineDrawer = new FormSpacingLineDrawer(this);
}
@ -1764,4 +1766,20 @@ public class FormDesigner extends TargetComponent<Form> 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].isParentAbsolute()) {
return false;
}
}
return creators[creators.length - 1].isParentAbsolute();
}
return false;
}
public FormSpacingLineDrawer getSpacingLineDrawer() {
return spacingLineDrawer;
}
}

13
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() {
}
}

45
designer-form/src/main/java/com/fr/design/mainframe/FormHorizontalParallelLine.java

@ -0,0 +1,45 @@
package com.fr.design.mainframe;
import java.awt.Point;
public class FormHorizontalParallelLine extends AbstractFormParallelLine {
public FormHorizontalParallelLine(int parallelValue, int startPosition, int endPosition) {
super(parallelValue, startPosition, endPosition);
}
@Override
public Point getStartPointOnVerticalCenterLine() {
Point point = new Point();
point.setLocation(getCenterPosition(), parallelValue);
return point;
}
@Override
public Point getEndPointOnVerticalCenterLine(int parallelValue) {
Point point = new Point();
point.setLocation(getCenterPosition(), parallelValue);
return point;
}
@Override
public Point getExtendedLineStartPoint(AbstractFormParallelLine parallelLine) {
Point point = new Point();
if (parallelLine.isVerticalCenterLineBeforeTheParallelLine(this)) {
point.setLocation(getStartPosition(), getParallelValue());
} else if (parallelLine.isVerticalCenterLineBehindTheParallelLine(this)) {
point.setLocation(getEndPosition(), getParallelValue());
}
return point;
}
@Override
public Point getExtendedLineEndPoint(AbstractFormParallelLine parallelLine) {
Point point = new Point();
if (parallelLine.isVerticalCenterLineBeforeTheParallelLine(this)) {
point.setLocation(parallelLine.getStartPosition(), getParallelValue());
} else if (parallelLine.isVerticalCenterLineBehindTheParallelLine(this)) {
point.setLocation(parallelLine.getEndPosition(), getParallelValue());
}
return point;
}
}

198
designer-form/src/main/java/com/fr/design/mainframe/FormSpacingLineDrawer.java

@ -0,0 +1,198 @@
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 (!isDrawSpacingLine()) {
return;
}
if (!hoverCreator.isParentAbsolute()) {
return;
}
drawHorizontalSpacingLine(g);
drawVerticalSpacingLine(g);
}
private void drawHorizontalSpacingLine(Graphics g) {
AbstractFormParallelLine[] lines = getNearestHorizontalSide();
drawSpacingLine(g, lines);
}
private void drawVerticalSpacingLine(Graphics g) {
AbstractFormParallelLine[] lines = getNearestVerticalSide();
drawSpacingLine(g, lines);
}
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 drawSpacingLine(Graphics g, AbstractFormParallelLine[] nearestSides) {
if (nearestSides.length != 2) {
return;
}
int gap = nearestSides[0].getDistanceWithLine(nearestSides[1]);
if (gap <= MIN_SPACING) {
return;
}
int startX = (int) nearestSides[0].getStartPointOnVerticalCenterLine().getX();
int startY = (int) nearestSides[0].getStartPointOnVerticalCenterLine().getY();
int endX = (int) nearestSides[0].getEndPointOnVerticalCenterLine(nearestSides[1].getParallelValue()).getX();
int endY = (int) nearestSides[0].getEndPointOnVerticalCenterLine(nearestSides[1].getParallelValue()).getY();
drawSpacingLine(g, startX, startY, endX, endY);
drawSpacingText(g, String.valueOf(gap), (startX + endX) / 2, (startY + endY) / 2);
drawExtendedLine(g, nearestSides);
}
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 drawExtendedLine(Graphics g, AbstractFormParallelLine[] nearestSides) {
if (isNeedExtendedLine(nearestSides)) {
int startX = (int) nearestSides[1].getExtendedLineStartPoint(nearestSides[0]).getX();
int startY = (int) nearestSides[1].getExtendedLineStartPoint(nearestSides[0]).getY();
int endX = (int) nearestSides[1].getExtendedLineEndPoint(nearestSides[0]).getX();
int endY = (int) nearestSides[1].getExtendedLineEndPoint(nearestSides[0]).getY();
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 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 isNeedExtendedLine(AbstractFormParallelLine[] nearestSides) {
return nearestSides[0].isVerticalCenterLineBeforeTheParallelLine(nearestSides[1]) || nearestSides[0].isVerticalCenterLineBehindTheParallelLine(nearestSides[1]);
}
private boolean isSelectedRootPane() {
return isSelectedForm() || isSelectedRootComponent();
}
private boolean isHoveredRootPane() {
return isHoveredForm() || isHoveredRootComponent();
}
private boolean isDrawSpacingLine() {
return !isSelectedRootPane() && !isHoveredRootPane() && isMouseMoveEvent;
}
private AbstractFormParallelLine[] getNearestHorizontalSide() {
AbstractFormParallelLine[] selectedRecSides = new AbstractFormParallelLine[] {
new FormHorizontalParallelLine(selectedRec.y, selectedRec.x, selectedRec.x + selectedRec.width),
new FormHorizontalParallelLine(selectedRec.y + selectedRec.height, selectedRec.x, selectedRec.x + selectedRec.width)
};
AbstractFormParallelLine[] hoveredCreatorSides = new AbstractFormParallelLine[] {
new FormHorizontalParallelLine(hoverCreator.getY(), hoverCreator.getX(), hoverCreator.getX() + hoverCreator.getWidth()),
new FormHorizontalParallelLine(hoverCreator.getY() + hoverCreator.getHeight(), hoverCreator.getX(), hoverCreator.getX() + hoverCreator.getWidth())
};
return getNearestSide(selectedRecSides, hoveredCreatorSides);
}
private AbstractFormParallelLine[] getNearestVerticalSide() {
AbstractFormParallelLine[] selectedRecSides = new AbstractFormParallelLine[] {
new FormVerticalParallelLine(selectedRec.x, selectedRec.y, selectedRec.y + selectedRec.height),
new FormVerticalParallelLine(selectedRec.x + selectedRec.width, selectedRec.y, selectedRec.y + selectedRec.height)
};
AbstractFormParallelLine[] hoveredCreatorSides = new AbstractFormParallelLine[] {
new FormVerticalParallelLine(hoverCreator.getX(), hoverCreator.getY(), hoverCreator.getY() + hoverCreator.getHeight()),
new FormVerticalParallelLine(hoverCreator.getX() + hoverCreator.getWidth(), hoverCreator.getY(), hoverCreator.getY() + hoverCreator.getHeight())
};
return getNearestSide(selectedRecSides, hoveredCreatorSides);
}
private AbstractFormParallelLine[] getNearestSide(AbstractFormParallelLine[] lines1, AbstractFormParallelLine[] lines2) {
AbstractFormParallelLine[] nearestSides = new AbstractFormParallelLine[2];
int minDistance = lines1[0].getDistanceWithLine(lines2[0]);
for (int i = 0; i < lines1.length; i++) {
for (int j = 0; j < lines2.length; j++) {
int distance = lines1[i].getDistanceWithLine(lines2[j]);
if (distance <= minDistance) {
nearestSides[0] = lines1[i];
nearestSides[1] = lines2[j];
}
}
}
return nearestSides;
}
}

45
designer-form/src/main/java/com/fr/design/mainframe/FormVerticalParallelLine.java

@ -0,0 +1,45 @@
package com.fr.design.mainframe;
import java.awt.Point;
public class FormVerticalParallelLine extends AbstractFormParallelLine {
public FormVerticalParallelLine(int parallelValue, int startPosition, int endPosition) {
super(parallelValue, startPosition, endPosition);
}
@Override
public Point getStartPointOnVerticalCenterLine() {
Point point = new Point();
point.setLocation(parallelValue, getCenterPosition());
return point;
}
@Override
public Point getEndPointOnVerticalCenterLine(int parallelValue) {
Point point = new Point();
point.setLocation(parallelValue, getCenterPosition());
return point;
}
@Override
public Point getExtendedLineStartPoint(AbstractFormParallelLine parallelLine) {
Point point = new Point();
if (parallelLine.isVerticalCenterLineBeforeTheParallelLine(this)) {
point.setLocation(getParallelValue(), getStartPosition());
} else if (parallelLine.isVerticalCenterLineBehindTheParallelLine(this)) {
point.setLocation(getParallelValue(), getEndPosition());
}
return point;
}
@Override
public Point getExtendedLineEndPoint(AbstractFormParallelLine parallelLine) {
Point point = new Point();
if (parallelLine.isVerticalCenterLineBeforeTheParallelLine(this)) {
point.setLocation(getParallelValue(), parallelLine.getStartPosition());
} else if (parallelLine.isVerticalCenterLineBehindTheParallelLine(this)) {
point.setLocation(getParallelValue(), parallelLine.getEndPosition());
}
return point;
}
}

218
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<XCreator> 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<XCreator>() {
@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<XCreator>() {
@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();
}
}

36
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<UIHead> uiHeads = new ArrayList<UIHead>(){
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

23
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/AbstractMultiSelectionArrangementButton.java

@ -0,0 +1,23 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.mainframe.MultiSelectionArrangement;
public abstract class AbstractMultiSelectionArrangementButton implements MultiSelectionArrangementButton {
protected MultiSelectionArrangement arrangement;
public AbstractMultiSelectionArrangementButton(MultiSelectionArrangement arrangement) {
this.arrangement = arrangement;
}
@Override
public UIButton create() {
UIButton btn = new UIButton();
btn.setNormalPainted(false);
btn.setBorderPaintedOnlyWhenPressed(true);
btn.setIcon(getIcon());
btn.setToolTipText(getTipText());
btn.addActionListener(getActionListener());
return btn;
}
}

35
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/BottomAlignButton.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.MultiSelectionArrangement;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BottomAlignButton extends AbstractMultiSelectionArrangementButton {
public BottomAlignButton(MultiSelectionArrangement arrangement) {
super(arrangement);
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_bottom_align.png");
}
@Override
public String getTipText() {
return Toolkit.i18nText("Fine-Design_Multi_Selection_Bottom_Align");
}
@Override
public ActionListener getActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrangement.bottomAlign();
}
};
}
}

35
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/HorizontalCenterButton.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.MultiSelectionArrangement;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class HorizontalCenterButton extends AbstractMultiSelectionArrangementButton {
public HorizontalCenterButton(MultiSelectionArrangement arrangement) {
super(arrangement);
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_horizontal_center_align.png");
}
@Override
public String getTipText() {
return Toolkit.i18nText("Fine-Design_Multi_Selection_Horizontal_Center_Align");
}
@Override
public ActionListener getActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrangement.horizontalCenterAlign();
}
};
}
}

35
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/HorizontalDistributionButton.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.MultiSelectionArrangement;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class HorizontalDistributionButton extends AbstractMultiSelectionArrangementButton {
public HorizontalDistributionButton(MultiSelectionArrangement arrangement) {
super(arrangement);
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_horizontal_auto_spacing.png");
}
@Override
public String getTipText() {
return Toolkit.i18nText("Fine-Design_Multi_Selection_Auto_Horizontal_Spacing");
}
@Override
public ActionListener getActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrangement.horizontalAutoDistribution();
}
};
}
}

35
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/LeftAlignButton.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.MultiSelectionArrangement;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LeftAlignButton extends AbstractMultiSelectionArrangementButton {
public LeftAlignButton(MultiSelectionArrangement arrangement) {
super(arrangement);
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_left_align.png");
}
@Override
public String getTipText() {
return Toolkit.i18nText("Fine-Design_Multi_Selection_Left_Align");
}
@Override
public ActionListener getActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrangement.leftAlign();
}
};
}
}

16
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/MultiSelectionArrangementButton.java

@ -0,0 +1,16 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.gui.ibutton.UIButton;
import javax.swing.Icon;
import java.awt.event.ActionListener;
public interface MultiSelectionArrangementButton {
Icon getIcon();
String getTipText();
ActionListener getActionListener();
UIButton create();
}

35
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/RightAlignButton.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.MultiSelectionArrangement;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class RightAlignButton extends AbstractMultiSelectionArrangementButton {
public RightAlignButton(MultiSelectionArrangement arrangement) {
super(arrangement);
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_right_align.png");
}
@Override
public String getTipText() {
return Toolkit.i18nText("Fine-Design_Multi_Selection_Right_Align");
}
@Override
public ActionListener getActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrangement.rightAlign();
}
};
}
}

35
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/TopAlignButton.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.MultiSelectionArrangement;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TopAlignButton extends AbstractMultiSelectionArrangementButton {
public TopAlignButton(MultiSelectionArrangement arrangement) {
super(arrangement);
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_top_align.png");
}
@Override
public String getTipText() {
return Toolkit.i18nText("Fine-Design_Multi_Selection_Top_Align");
}
@Override
public ActionListener getActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrangement.topAlign();
}
};
}
}

35
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/VerticalCenterButton.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.MultiSelectionArrangement;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class VerticalCenterButton extends AbstractMultiSelectionArrangementButton {
public VerticalCenterButton(MultiSelectionArrangement arrangement) {
super(arrangement);
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_vertical_center_align.png");
}
@Override
public String getTipText() {
return Toolkit.i18nText("Fine-Design_Multi_Selection_Vertical_Center_Align");
}
@Override
public ActionListener getActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrangement.verticalCenterAlign();
}
};
}
}

35
designer-form/src/main/java/com/fr/design/mainframe/widget/arrangement/buttons/VerticalDistributionButton.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.widget.arrangement.buttons;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.MultiSelectionArrangement;
import com.fr.general.IOUtils;
import javax.swing.Icon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class VerticalDistributionButton extends AbstractMultiSelectionArrangementButton {
public VerticalDistributionButton(MultiSelectionArrangement arrangement) {
super(arrangement);
}
@Override
public Icon getIcon() {
return IOUtils.readIcon("/com/fr/design/images/buttonicon/multi_selection_vertical_auto_spacing.png");
}
@Override
public String getTipText() {
return Toolkit.i18nText("Fine-Design_Multi_Selection_Auto_Vertical_Spacing");
}
@Override
public ActionListener getActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrangement.verticalAutoDistribution();
}
};
}
}

178
designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormMultiWidgetCardPane.java

@ -0,0 +1,178 @@
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.design.mainframe.widget.arrangement.buttons.BottomAlignButton;
import com.fr.design.mainframe.widget.arrangement.buttons.HorizontalCenterButton;
import com.fr.design.mainframe.widget.arrangement.buttons.HorizontalDistributionButton;
import com.fr.design.mainframe.widget.arrangement.buttons.LeftAlignButton;
import com.fr.design.mainframe.widget.arrangement.buttons.RightAlignButton;
import com.fr.design.mainframe.widget.arrangement.buttons.TopAlignButton;
import com.fr.design.mainframe.widget.arrangement.buttons.VerticalCenterButton;
import com.fr.design.mainframe.widget.arrangement.buttons.VerticalDistributionButton;
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.FocusAdapter;
import java.awt.event.FocusEvent;
public class FormMultiWidgetCardPane extends FormWidgetCardPane {
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[] {
new LeftAlignButton(arrangement).create(),
new HorizontalCenterButton(arrangement).create(),
new RightAlignButton(arrangement).create(),
new TopAlignButton(arrangement).create(),
new VerticalCenterButton(arrangement).create(),
new BottomAlignButton(arrangement).create()
}
};
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 = new HorizontalDistributionButton(arrangement).create();
UIButton verticalAutoSpacingBtn = new VerticalDistributionButton(arrangement).create();
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;
}
}

297
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<Widget> 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<Widget> 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);
}
}

284
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<Widget> 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<Widget> 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);
}
}

13
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);
}
}
}
Loading…
Cancel
Save