帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

809 lines
32 KiB

package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fr.base.vcs.DesignerMode;
import com.fr.common.inputevent.InputEventBaseOnOS;
import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.ComponentAdapter;
import com.fr.design.designer.beans.events.DesignerEditor;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.beans.location.Direction;
import com.fr.design.designer.beans.location.Location;
import com.fr.design.designer.beans.models.SelectionModel;
import com.fr.design.designer.beans.models.StateModel;
import com.fr.design.designer.creator.XBorderStyleWidgetCreator;
import com.fr.design.designer.creator.XChartEditor;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
import com.fr.design.designer.creator.XEditorHolder;
import com.fr.design.designer.creator.XElementCase;
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.XWTitleLayout;
import com.fr.design.designer.creator.cardlayout.XCardAddButton;
import com.fr.design.designer.creator.cardlayout.XCardSwitchButton;
import com.fr.design.designer.creator.cardlayout.XWCardLayout;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.imenu.UIPopupMenu;
import com.fr.design.gui.xpane.ToolTipEditor;
import com.fr.design.icon.IconPathConstants;
import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.GUICoreUtils;
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;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputAdapter;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
/**
* 普通模式下的鼠标点击、位置处理器
*/
public class EditingMouseListener extends MouseInputAdapter {
private FormDesigner designer;
/**
* 普通模式下对应的model
*/
private StateModel stateModel;
private XLayoutContainer xTopLayoutContainer;
private XLayoutContainer clickTopLayout;
/**
* 获取表单设计器
*
* @return 表单设计器
*/
public FormDesigner getDesigner() {
return designer;
}
/**
* 选择模型,存储当前选择的组件和剪切板
*/
private SelectionModel selectionModel;
/**
* 获取选择模型
*
* @return 选择
*/
public SelectionModel getSelectionModel() {
return selectionModel;
}
private XCreator lastXCreator;
private MouseEvent lastPressEvent;
private DesignerEditor<? extends JComponent> currentEditor;
private XCreator currentXCreator;
//备份开始拖动的位置和大小
private Rectangle dragBackupBounds;
private int pressX;
private int pressY;
/**
* 获取最小移动距离
*
* @return 最小移动距离
*/
public int getMinMoveSize() {
return minMoveSize;
}
private int minDragSize = 5;
private int minMoveSize = 8;
private static final Insets DEEFAULT_INSETS = new Insets(0,0,0,0);
//报表块的编辑按钮不灵敏,范围扩大一点
private static final int GAP = 5;
private XElementCase xElementCase;
private XChartEditor xChartEditor;
private JWindow promptWindow = new JWindow();
public EditingMouseListener(FormDesigner designer) {
this.designer = designer;
stateModel = designer.getStateModel();
selectionModel = designer.getSelectionModel();
UIButton promptButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Forbid_Drag_Into_Adapt_Pane"), BaseUtils.readIcon(IconPathConstants.FORBID_ICON_PATH));
this.promptWindow.add(promptButton);
}
private void promptUser(int x, int y, XLayoutContainer container) {
if (!selectionModel.getSelection().getSelectedCreator().canEnterIntoAdaptPane() && container.acceptType(XWFitLayout.class)) {
promptWidgetForbidEnter(x, y, container);
} else {
cancelPromptWidgetForbidEnter();
}
}
private void promptWidgetForbidEnter(int x, int y, XLayoutContainer container) {
container.setBorder(BorderFactory.createLineBorder(Color.RED, Constants.LINE_MEDIUM));
int screenX = (int) designer.getArea().getLocationOnScreen().getX();
int screenY = (int) designer.getArea().getLocationOnScreen().getY();
this.promptWindow.setSize(promptWindow.getPreferredSize());
this.promptWindow.setPreferredSize(promptWindow.getPreferredSize());
promptWindow.setLocation(screenX + x + GAP, screenY + y + GAP);
promptWindow.setVisible(true);
}
private void cancelPromptWidgetForbidEnter() {
designer.getRootComponent().setBorder(BorderFactory.createLineBorder(XCreatorConstants.LAYOUT_SEP_COLOR, Constants.LINE_THIN));
promptWindow.setVisible(false);
}
/**
* 按下
*
* @param e 鼠标事件
*/
public void mousePressed(MouseEvent e) {
int oldX = e.getX();
int oldY = e.getY();
pressX = oldX;
pressY = oldY;
offsetEventPoint(e);
if (!stopEditing()) {
return;
}
if (!designer.isFocusOwner()) {
// 获取焦点,以便获取热键
designer.requestFocus();
}
if (e.getButton() == MouseEvent.BUTTON1 && !designer.checkIfBeyondValidArea(e)) {
Direction dir = selectionModel.getDirectionAt(e);
if (!DesignerMode.isAuthorityEditing()) {
stateModel.setDirection(dir);
}
if (dir == Location.outer) {
if (designer.isDrawLineMode()) {
designer.updateDrawLineMode(e);
} else {
if (selectionModel.hasSelectionComponent()
&& selectionModel.getSelection().getRelativeBounds().contains(
designer.getHorizontalScaleValue() + e.getX(),
designer.getVerticalScaleValue() + e.getY())) {
lastPressEvent = e;
lastXCreator = selectionModel.getSelection().getSelectedCreator();
} else {
stateModel.startSelecting(e);
}
}
} else {
stateModel.startResizing(e);
}
}
e.translatePoint(oldX - e.getX(), oldY - e.getY());
}
private void offsetEventPoint(MouseEvent e){
int x = designer.getRelativeX(e.getX());
int y = designer.getRelativeY(e.getY());
e.translatePoint(x - e.getX(), y - e.getY());
}
/**
* 释放
*
* @param e 鼠标事件
*/
public void mouseReleased(MouseEvent e) {
MouseEvent transEvent = new MouseEvent(e.getComponent(), MouseEvent.MOUSE_CLICKED, e.getWhen(), e.getModifiers(), e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e.getButton());
MouseEvent clickEvent = new MouseEvent(e.getComponent(), MouseEvent.MOUSE_CLICKED, e.getWhen(), e.getModifiers(), e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e.getButton());
int oldX = e.getX();
int oldY = e.getY();
offsetEventPoint(e);
if (e.isPopupTrigger()) {
if (stateModel.isDragging()) {
stateModel.draggingCancel();
}
} else {
if (designer.isDrawLineMode()) {
if (stateModel.prepareForDrawLining()) {
designer.getDrawLineHelper().setDrawLine(false);
designer.getDrawLineHelper().createDefalutLine();
}
} else if (stateModel.isSelecting()) {
// 如果当前是区域选择状态,则选择该区域所含的组件
designer.selectComponents(e);
}
if (stateModel.isDragging()) {
mouseDraggingRelease(e);
}
}
lastPressEvent = null;
lastXCreator = null;
e.translatePoint(oldX - e.getX(), oldY - e.getY());
if (isAutoFire(transEvent, clickEvent)) {
// click只有在mouseReleased和mousePressed前后x/y坐标相等时才会被触发在mouseReleased之后
// 但是当使用者来回点击切换时 存在mouseReleased和mousePressed前后x/y坐标不相等的情况 即鼠标按下去的位置和鼠标释放的位置不相等 存在偏移
// 当这种偏移很小时 看起来就好像是点击了 实际上是手抖了或者鼠标轻微滑动了 所以这里对这种情况要有容错处理
mouseClicked(clickEvent);
}
}
private boolean isAutoFire(MouseEvent transEvent, MouseEvent clickEvent ) {
offsetEventPoint(transEvent);
XCreator xCreator = designer.getComponentAt(transEvent);
return (pressX != clickEvent.getX() || pressY != clickEvent.getY())
&& xCreator != null && xCreator.acceptType(XCardSwitchButton.class);
}
private void mouseDraggingRelease(MouseEvent e) {
// 当前鼠标所在的组件
XCreator hoveredComponent = designer.getComponentAt(e.getX(), e.getY());
if (designer.isWidgetsIntersect() && dragBackupBounds != null && hoveredComponent != null) {
XCreator selectionXCreator = designer.getSelectionModel().getSelection().getSelectedCreator();
if (selectionXCreator != null) {
selectionXCreator.setBounds(dragBackupBounds.x, dragBackupBounds.y, dragBackupBounds.width, dragBackupBounds.height);
}
}
dragBackupBounds = null;
// 拉伸时鼠标拖动过快,导致所在组件获取会为空
if (hoveredComponent == null && e.getY() < 0) {
// bug63538
// 不是拖动过快导致的,而是纵坐标为负值导致的,这时参照横坐标为负值时的做法,取边界位置的组件,为鼠标所在点的组件
// 如果直接return,界面上已经进行了拖拽不能恢复
hoveredComponent = designer.getComponentAt(0, 0);
}
// 获取该组件所在的焦点容器
XLayoutContainer container = XCreatorUtils.getHotspotContainer(hoveredComponent);
if (container != null) {
boolean formSubmit2Adapt = !selectionModel.getSelection().getSelectedCreator().canEnterIntoAdaptPane()
&& container.acceptType(XWFitLayout.class);
if (!formSubmit2Adapt) {
// 如果是处于拖拽状态,则释放组件
stateModel.releaseDragging(e);
} else {
selectionModel.deleteSelection();
designer.setPainter(null);
}
cancelPromptWidgetForbidEnter();
}
}
/**
* TODO 激活上下文菜单,待完善
* 6.56暂时不支持右键 bugid 8777
*/
private void triggerPopup(MouseEvent e) {
XCreator creator = selectionModel.getSelection().getSelectedCreator();
if (creator == null) {
return;
}
JPopupMenu popupMenu = null;
ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, creator);
popupMenu = adapter.getContextPopupMenu(e);
if (popupMenu != null) {
popupMenu.show(designer, e.getX(), e.getY());
}
// 通知组件已经被选择了
designer.getEditListenerTable().fireCreatorModified(creator, DesignerEvent.CREATOR_SELECTED);
}
/**
* 移动
*
* @param e 鼠标事件
*/
public void mouseMoved(MouseEvent e) {
int oldX = e.getX();
int oldY = e.getY();
offsetEventPoint(e);
XCreator component = designer.getComponentAt(e);
setCoverPaneNotDisplay(component, e, false);
if (processTopLayoutMouseMove(component, e)) {
return;
}
if (component instanceof XEditorHolder) {
XEditorHolder xcreator = (XEditorHolder) component;
Rectangle rect = xcreator.getBounds();
int min = rect.x + rect.width / 2 - minMoveSize;
int max = rect.x + rect.width / 2 + minMoveSize;
if (e.getX() > min && e.getX() < max) {
if (designer.getCursor().getType() != Cursor.HAND_CURSOR) {
designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
return;
} else {
if (designer.getCursor().getType() == Cursor.HAND_CURSOR) {
designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
}
Direction dir = selectionModel.getDirectionAt(e);
if (designer.isDrawLineMode() && stateModel.getDirection() == Location.outer) {
designer.updateDrawLineMode(e);
}
if (!DesignerMode.isAuthorityEditing()) {
stateModel.setDirection(dir);
}
if (component.isReport()) {
elementCaseMouseMoved(e, component);
designer.repaint();
return;
}
processChartEditorMouseMove(component, e);
e.translatePoint(oldX - e.getX(), oldY - e.getY());
designer.repaint();
}
private void processCoverPane(XCreator component) {
// selected状态 不展示封面
XCreator xCreator = selectionModel.getSelection().getSelectedCreator();
boolean accept = xCreator == null || !ComparatorUtils.equals(xCreator.toData().getWidgetName(), component.toData().getWidgetName()) ||!xCreator.isSelected();
if (accept) {
component.displayCoverPane(true);
}
}
private boolean isShareConfigButton(MouseEvent e, XCreator component, Insets insets) {
if (component.isShared()) {
int minX = getParentPositionX(component, component.getX()) + component.getWidth() - insets.right - CoverReportPane.SHARE_CONF_BTN_W - designer.getHorizontalScaleValue();
int maxX = minX + CoverReportPane.SHARE_CONF_BTN_W;
int minY = getParentPositionY(component, component.getY()) + insets.top - designer.getVerticalScaleValue();
int maxY = minY + CoverReportPane.SHARE_CONF_BTN_H;
if ((e.getX() > minX - GAP) && e.getX() < maxX + GAP) {
if (e.getY() > minY - GAP && e.getY() < maxY + GAP) {
return true;
}
}
}
return false;
}
private boolean isEditButton(MouseEvent e, XCreator component, Insets insets) {
// 不显示编辑按钮 鼠标格式
if (component.getParent() instanceof XCreator) {
XCreator parent = (XCreator) component.getParent();
if (parent.acceptType(XWTitleLayout.class) || component.acceptType(XWCardMainBorderLayout.class, XWAbsoluteLayout.class)) {
return false;
}
}
int innerWidth = component.getWidth() - insets.left - insets.right;
int innerHeight = component.getHeight() - insets.top - insets.bottom;
int minX = getParentPositionX(component, component.getX()) + insets.left + (innerWidth - CoverReportPane.EDIT_BTN_W) / 2 - designer.getHorizontalScaleValue();
int maxX = minX + CoverReportPane.EDIT_BTN_W;
int minY = getParentPositionY(component, component.getY()) + insets.top + (innerHeight - CoverReportPane.EDIT_BTN_H) / 2 - designer.getVerticalScaleValue();
int maxY = minY + CoverReportPane.EDIT_BTN_H;
if (e.getX() > minX - GAP && e.getX() < maxX + GAP) {
if (e.getY() > minY - GAP && e.getY() < maxY + GAP) {
return true;
}
}
return false;
}
private void elementCaseMouseMoved(MouseEvent e, XCreator component) {
xElementCase = (XElementCase) component;
processCoverPane(component);
processCoverMouseMove(component, e);
}
private void setCoverPaneNotDisplay(XCreator component, MouseEvent e, boolean isLinkedHelpDialog) {
if (xChartEditor != null) {
xChartEditor.displayCoverPane(false);
}
component.displayCoverPane(false);
if (xTopLayoutContainer != null) {
xTopLayoutContainer.setMouseEnter(false);
}
//不知道为什么要对XElementCase进行判断,但是直接return会有bug,所以把他放在最后
if (xElementCase != null) {
int x = getParentPositionX(xElementCase, 0) - designer.getArea().getHorizontalValue();
int y = getParentPositionY(xElementCase, 0) - designer.getArea().getVerticalValue();
Rectangle rect = new Rectangle(x, y, xElementCase.getWidth(), xElementCase.getHeight());
if (!rect.contains(e.getPoint())) {
xElementCase.displayCoverPane(false);
}
}
designer.repaint();
}
private boolean processTopLayoutMouseMove(XCreator component, MouseEvent e) {
XLayoutContainer parent = XCreatorUtils.getHotspotContainer(component).getTopLayout();
if (parent != null) {
xTopLayoutContainer = parent;
xTopLayoutContainer.setMouseEnter(true);
designer.repaint();
if (!xTopLayoutContainer.isEditable()) {
processCoverMouseMove(parent, e);
return true;
}
}
return false;
}
private void processChartEditorMouseMove(XCreator component, MouseEvent e) {
if (component instanceof XChartEditor) {
xChartEditor = (XChartEditor) component;
processCoverPane(component);
processCoverMouseMove(component, e);
}
}
private void processCoverMouseMove(XCreator component, MouseEvent e) {
component.setHelpBtnOnFocus(false);
Insets insets;
if (component instanceof XBorderStyleWidgetCreator) {
insets = ((XBorderStyleWidgetCreator) component).getInsets();
} else {
insets = DEEFAULT_INSETS;
}
if (designer.getCursor().getType() == Cursor.HAND_CURSOR) {
designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
if (isEditButton(e, component, insets)) {
designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
}
private int getParentPositionX(XCreator comp, int x) {
return comp.getParent() == null ?
x : getParentPositionX((XCreator) comp.getParent(), comp.getParent().getX() + x);
}
private int getParentPositionY(XCreator comp, int y) {
return comp.getParent() == null ?
y : getParentPositionY((XCreator) comp.getParent(), comp.getParent().getY() + y);
}
/**
* 拖拽
*
* @param e 鼠标事件
*/
public void mouseDragged(MouseEvent e) {
int oldX = e.getX();
int oldY = e.getY();
offsetEventPoint(e);
if (DesignerMode.isAuthorityEditing()) {
return;
}
boolean shiftSelecting = e.isShiftDown();
boolean ctrlSelecting = InputEventBaseOnOS.isControlDown(e);
int currentCursorType = this.designer.getCursor().getType();
boolean shiftResizing = e.isShiftDown() && ( Cursor.SW_RESIZE_CURSOR <= currentCursorType && currentCursorType <= Cursor.E_RESIZE_CURSOR);
if ((shiftSelecting || ctrlSelecting) && !shiftResizing && !stateModel.isSelecting()) {
stateModel.startSelecting(e);
}
// 如果当前是左键拖拽状态,拖拽组件
if (stateModel.dragable()) {
if (SwingUtilities.isRightMouseButton(e)) {
return;
} else {
stateModel.dragging(e);
// 获取e所在的焦点组件
XCreator hotspot = designer.getComponentAt(e.getX(), e.getY());
if (dragBackupBounds == null) {
XCreator selectingXCreator = designer.getSelectionModel().getSelection().getSelectedCreator();
if (selectingXCreator != null) {
dragBackupBounds = new Rectangle(selectingXCreator.getX(), selectingXCreator.getY(), selectingXCreator.getWidth(), selectingXCreator.getHeight());
}
}
// 拉伸时鼠标拖动过快,导致所在组件获取会为空
if (hotspot == null) {
return;
}
// 获取焦点组件所在的焦点容器
XLayoutContainer container = XCreatorUtils.getHotspotContainer(hotspot);
//提示组件是否可以拖入
promptUser(e.getX(), e.getY(), container);
}
} else if (designer.isDrawLineMode()) {
if (stateModel.prepareForDrawLining()) {
stateModel.drawLine(e);
}
} else if (stateModel.isSelecting() && (selectionModel.getHotspotBounds() != null)) {
// 如果是拖拽选择区域状态,则更新选择区域
stateModel.changeSelection(e);
} else {
if ((lastPressEvent == null) || (lastXCreator == null)) {
return;
}
if (e.getPoint().distance(lastPressEvent.getPoint()) > minDragSize) {
//参数面板和自适应布局不支持拖拽
if (lastXCreator.isSupportDrag()) {
designer.startDraggingComponent(lastXCreator, lastPressEvent, e.getX(), e.getY());
}
e.consume();
lastPressEvent = null;
}
}
e.translatePoint(oldX - e.getX(), oldY - e.getY());
designer.repaint();
}
//当前编辑的组件是在布局中,鼠标点击布局外部,需要一次性将布局及其父布局都置为不可编辑
private void setTopLayoutUnEditable(XLayoutContainer clickedTopLayout, XLayoutContainer clickingTopLayout) {
//双击的前后点击click为相同对象,过滤掉
if (clickedTopLayout == null || clickedTopLayout == clickingTopLayout) {
return;
}
//位于同一层级的控件,父布局相同,过滤掉
if (clickingTopLayout != null && clickedTopLayout.getParent() == clickingTopLayout.getParent()) {
return;
}
//前后点击的位于不同层级,要置为不可编辑
XLayoutContainer xLayoutContainer = (XLayoutContainer) clickedTopLayout.getParent();
if (xLayoutContainer == clickingTopLayout) {
return;
}
if (xLayoutContainer != null) {
xLayoutContainer.setEditable(false);
setTopLayoutUnEditable((XLayoutContainer) clickedTopLayout.getParent(), clickingTopLayout);
}
}
private boolean isCreatorInLayout(XCreator creator, XCreator layout) {
if (creator.equals(layout)) {
return true;
}
if (layout.getParent() != null) {
return isCreatorInLayout(creator, (XCreator) layout.getParent());
}
return false;
}
// 点击控件树,会触发此方法。如果在设计器中选中组件,则直接走 processTopLayoutMouseClick
public void stopEditTopLayout(XCreator creator) {
boolean isTabpaneSelected = creator instanceof XWCardLayout && creator.getParent().equals(clickTopLayout);
if (clickTopLayout != null && (isTabpaneSelected || clickTopLayout.equals(creator))) {
clickTopLayout.setEditable(false);
}
processTopLayoutMouseClick(creator);
}
public XCreator processTopLayoutMouseClick(XCreator creator) {
XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer(creator).getTopLayout();
if (topLayout != null) {
if (clickTopLayout != null && !clickTopLayout.equals(topLayout) && !isCreatorInLayout(clickTopLayout,
topLayout)) {
clickTopLayout.setEditable(false);
setTopLayoutUnEditable(clickTopLayout, topLayout);
}
clickTopLayout = topLayout;
if (!topLayout.isEditable()) {
creator = topLayout;
}
} else {
if (clickTopLayout != null) {
clickTopLayout.setEditable(false);
setTopLayoutUnEditable(clickTopLayout, null);
}
}
return creator;
}
/**
* 点击
*
* @param e 鼠标事件
*/
public void mouseClicked(MouseEvent e) {
int oldX = e.getX();
int oldY = e.getY();
offsetEventPoint(e);
selectionModel.getSelection().getTabList().clear();
XCreator creator = designer.getComponentAt(e);
boolean isValidButton = e.getButton() == MouseEvent.BUTTON1 || e.getButton() == MouseEvent.BUTTON3;
if (!isValidButton && !creator.acceptType(XCardSwitchButton.class)) {
return;
}
XCreator oldCreator = creator;
creator = processTopLayoutMouseClick(creator);
if (creator != null) {
// tab块处于未编辑状态
boolean uneditedTab = designer.getCursor().getType() != Cursor.HAND_CURSOR && creator.acceptType(XWCardMainBorderLayout.class) && !((XWCardMainBorderLayout) creator).isEditable();
// 点击不在tab块的button中
boolean clickedNonCardButton = !creator.acceptType(XCardAddButton.class, XCardSwitchButton.class);
if (clickedNonCardButton && e.getClickCount() == 1 && designer.getCursor().getType() != Cursor.HAND_CURSOR) {
setCoverPaneNotDisplay(creator, e, false);
selectionModel.selectACreatorAtMouseEvent(e);
refreshTopXCreator();
XCreator[] xCreators = selectionModel.getSelection().getSelectedCreators();
// 放到事件队尾执行
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
for (XCreator xCreator : xCreators) {
xCreator.setSelected(true);
}
}
});
} else if (clickedNonCardButton && uneditedTab && responseTabLayout(oldCreator, e)) {
// do nothing
} else {
creator.respondClick(this, e);
}
if (e.getButton() == MouseEvent.BUTTON3) {
UIPopupMenu cellPopupMenu = creator.createPopupMenu(designer);
if (cellPopupMenu != UIPopupMenu.EMPTY) {
GUICoreUtils.showPopupMenu(cellPopupMenu, designer, oldX, oldY);
}
}
creator.doLayout();
}
e.translatePoint(oldX - e.getX(), oldY - e.getY());
LayoutUtils.layoutRootContainer(designer.getRootComponent());
}
private boolean responseTabLayout(XCreator creator, MouseEvent e) {
LinkedList<XCreator> list = selectionModel.getSelection().getTabList();
if (creator.acceptType(XWCardMainBorderLayout.class)) {
list.add(creator);
}
while (creator.getParent() instanceof XCreator) {
creator = (XCreator) creator.getParent();
if (creator.acceptType(XWCardMainBorderLayout.class)) {
list.add(creator);
}
}
// 至少存在一层以上tab块的嵌套
if (list.size() > 1) {
XWCardMainBorderLayout firstCreator = (XWCardMainBorderLayout) list.getFirst();
XWCardMainBorderLayout lastCreator = (XWCardMainBorderLayout) list.getLast();
// 内层tab响应事件
firstCreator.respondClick(this, e);
setCoverPaneNotDisplay(firstCreator, e, false);
final XCreator xCreator = selectionModel.getSelection().getSelectedCreator();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
xCreator.setSelected(true);
// 外层tab展示阴影边框效果
lastCreator.setShowOuterShadowBorder(true);
}
});
return true;
} else {
return false;
}
}
/**
* 离开
*
* @param e 鼠标事件
*/
public void mouseExited(MouseEvent e) {
int oldX = e.getX();
int oldY = e.getY();
offsetEventPoint(e);
if (designer.getCursor().getType() != Cursor.DEFAULT_CURSOR && !(e.isShiftDown() || InputEventBaseOnOS.isControlDown(e))) {
designer.setCursor(Cursor.getDefaultCursor());
}
cancelPromptWidgetForbidEnter();
e.translatePoint(oldX - e.getX(), oldY - e.getY());
}
/**
* 开始编辑
*
* @param creator 容器
* @param designerEditor 设计器
* @param adapter 适配器
*/
public void startEditing(XCreator creator, DesignerEditor<? extends JComponent> designerEditor, ComponentAdapter adapter) {
if (designerEditor != null) {
Rectangle rect = ComponentUtils.getRelativeBounds(creator);
currentEditor = designerEditor;
currentXCreator = creator;
Rectangle bounds = new Rectangle(1, 1, creator.getWidth() - 2, creator.getHeight() - 2);
bounds.x += (rect.x - designer.getArea().getHorizontalValue());
bounds.y += (rect.y - designer.getArea().getVerticalValue());
designerEditor.getEditorTarget().setBounds(bounds);
designer.add(designerEditor.getEditorTarget());
designer.invalidate();
designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
designerEditor.getEditorTarget().requestFocus();
designer.repaint();
}
}
/**
* 停止编辑
*
* @return 是否编辑成功
*/
public boolean stopEditing() {
if (currentEditor != null) {
designer.remove(currentEditor.getEditorTarget());
currentEditor.fireEditStoped();
Container container = currentXCreator.getParent();
if (container != null) {
LayoutUtils.layoutRootContainer(container);
}
designer.invalidate();
designer.repaint();
currentXCreator.stopEditing();
currentXCreator = null;
currentEditor = null;
refreshTopXCreator();
return true;
}
return true;
}
/**
* 重置编辑控件大小
*/
public void resetEditorComponentBounds() {
if (currentEditor == null) {
return;
}
if (currentXCreator.getParent() == null) {
stopEditing();
return;
}
Rectangle rect = ComponentUtils.getRelativeBounds(currentXCreator);
Rectangle bounds = new Rectangle(1, 1, currentXCreator.getWidth() - 2, currentXCreator.getHeight() - 2);
bounds.x += (rect.x - designer.getHorizontalScaleValue());
bounds.y += (rect.y - designer.getVerticalScaleValue());
if (currentXCreator instanceof XEditorHolder) {
ToolTipEditor.getInstance().resetBounds((XEditorHolder) currentXCreator, bounds, currentEditor.getEditorTarget().getBounds());
}
currentEditor.getEditorTarget().setBounds(bounds);
}
/**
* 刷新顶层组件
* */
public void refreshTopXCreator(boolean isEditing){
designer.refreshTopXCreator(isEditing);
}
/**
* 刷新顶层组件
* */
public void refreshTopXCreator(){
refreshTopXCreator(false);
}
}