@ -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; |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 401 B |
After Width: | Height: | Size: 131 B |
After Width: | Height: | Size: 133 B |
After Width: | Height: | Size: 133 B |
After Width: | Height: | Size: 271 B |
After Width: | Height: | Size: 132 B |
After Width: | Height: | Size: 130 B |
After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 137 B |
After Width: | Height: | Size: 147 B |
After Width: | Height: | Size: 249 B |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |