|
|
|
package com.fr.design.mainframe;
|
|
|
|
|
|
|
|
import com.fr.base.BaseUtils;
|
|
|
|
import com.fr.design.designer.beans.AdapterBus;
|
|
|
|
import com.fr.design.designer.beans.HoverPainter;
|
|
|
|
import com.fr.design.designer.beans.Painter;
|
|
|
|
import com.fr.design.designer.beans.events.AddingWidgetListener;
|
|
|
|
import com.fr.design.designer.beans.models.DraggingModel;
|
|
|
|
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.XWFitLayout;
|
|
|
|
import com.fr.design.designer.creator.XWParameterLayout;
|
|
|
|
import com.fr.design.dialog.FineJOptionPane;
|
|
|
|
import com.fr.design.file.HistoryTemplateListPane;
|
|
|
|
import com.fr.design.form.util.XCreatorConstants;
|
|
|
|
import com.fr.design.gui.ibutton.UIButton;
|
|
|
|
import com.fr.design.icon.IconPathConstants;
|
|
|
|
import com.fr.design.utils.ComponentUtils;
|
|
|
|
import com.fr.log.FineLoggerFactory;
|
|
|
|
import com.fr.stable.Constants;
|
|
|
|
|
|
|
|
import javax.swing.BorderFactory;
|
|
|
|
import javax.swing.JOptionPane;
|
|
|
|
import javax.swing.JWindow;
|
|
|
|
import javax.swing.SwingUtilities;
|
|
|
|
import javax.swing.UIManager;
|
|
|
|
import java.awt.Color;
|
|
|
|
import java.awt.Component;
|
|
|
|
import java.awt.Point;
|
|
|
|
import java.awt.Rectangle;
|
|
|
|
import java.awt.dnd.DropTarget;
|
|
|
|
import java.awt.dnd.DropTargetDragEvent;
|
|
|
|
import java.awt.dnd.DropTargetDropEvent;
|
|
|
|
import java.awt.dnd.DropTargetEvent;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 添加模式下鼠标事件处理器。
|
|
|
|
*/
|
|
|
|
public class FormCreatorDropTarget extends DropTarget {
|
|
|
|
|
|
|
|
private FormDesigner designer;
|
|
|
|
/**
|
|
|
|
* 当前鼠标的设计组件
|
|
|
|
*/
|
|
|
|
private Component current;
|
|
|
|
private static final int GAP = 30;
|
|
|
|
|
|
|
|
private TabDragInner tabDragInner;
|
|
|
|
private XCreator creator;
|
|
|
|
private JWindow promptWindow = new JWindow();
|
|
|
|
private UIButton promptButton = new UIButton("", BaseUtils.readIcon(IconPathConstants.FORBID_ICON_PATH));
|
|
|
|
|
|
|
|
public FormCreatorDropTarget(FormDesigner designer, XCreator creator) {
|
|
|
|
this.designer = designer;
|
|
|
|
this.creator = creator;
|
|
|
|
this.promptWindow.add(promptButton);
|
|
|
|
this.tabDragInner = new TabDragInner(designer);
|
|
|
|
initAddingListener();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initAddingListener() {
|
|
|
|
designer.getAddingWidgetListeners().addListener(new AddingWidgetListener() {
|
|
|
|
@Override
|
|
|
|
public void beforeAdded() {
|
|
|
|
tabDragInner.setTabEditable();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void afterAdded(boolean addResult) {
|
|
|
|
if (addResult) {
|
|
|
|
tabDragInner.reset();
|
|
|
|
} else {
|
|
|
|
undoWhenAddingFailed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private void entering(int x, int y) {
|
|
|
|
// 将要添加的组件图标移动到鼠标下的位置
|
|
|
|
designer.updateDraggingPosition(x, y);
|
|
|
|
designer.repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void exiting() {
|
|
|
|
cancelPromptWidgetForbidEnter();
|
|
|
|
// 隐藏组件图标
|
|
|
|
designer.resetDraggingPosition();
|
|
|
|
designer.setPainter(null);
|
|
|
|
designer.repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void hovering(int x, int y) {
|
|
|
|
// 当前位置移植鼠标e所在的位置
|
|
|
|
designer.updateDraggingPosition(x, y);
|
|
|
|
// 获取e所在的焦点组件
|
|
|
|
XCreator hotspot = designer.getComponentAt(x, y);
|
|
|
|
// 获取焦点组件所在的焦点容器
|
|
|
|
XLayoutContainer container = XCreatorUtils.getHotspotContainer(hotspot);
|
|
|
|
//提示组件是否可以拖入
|
|
|
|
promptUser(x, y, container);
|
|
|
|
if (container != null) {
|
|
|
|
dealWithContainer(x, y, container);
|
|
|
|
} else {
|
|
|
|
// 如果鼠标不在任何组件上,则取消提示器
|
|
|
|
designer.setPainter(null);
|
|
|
|
current = null;
|
|
|
|
}
|
|
|
|
designer.repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void dealWithContainer(int x, int y, XLayoutContainer container) {
|
|
|
|
HoverPainter painter = null;
|
|
|
|
if (container != current || designer.getPainter() == null) {
|
|
|
|
// 如果焦点容器不是当前容器
|
|
|
|
if (current != null) {
|
|
|
|
// 取消前一个焦点容器的提示渲染器
|
|
|
|
designer.setPainter(null);
|
|
|
|
}
|
|
|
|
if (container == null) {
|
|
|
|
throw new IllegalArgumentException("container can not be null!");
|
|
|
|
}
|
|
|
|
//获取painter的时候要考虑布局之间嵌套的问题
|
|
|
|
XLayoutContainer xLayoutContainer = XCreatorUtils.getTopEditableContainer(container);
|
|
|
|
painter = AdapterBus.getContainerPainter(designer,
|
|
|
|
xLayoutContainer != null ? xLayoutContainer : container);
|
|
|
|
|
|
|
|
// 为界面设计器设置提示渲染提示器
|
|
|
|
designer.setPainter(painter);
|
|
|
|
|
|
|
|
// 将当前容器更新为新的容器
|
|
|
|
current = container;
|
|
|
|
} else {
|
|
|
|
// 获取当前设计界面的提示渲染器
|
|
|
|
Painter p = designer.getPainter();
|
|
|
|
if (p instanceof HoverPainter) {
|
|
|
|
painter = (HoverPainter) p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (painter != null) {
|
|
|
|
XLayoutContainer xLayoutContainer = XCreatorUtils.getTopEditableContainer(container);
|
|
|
|
// 为提示渲染器设置焦点位置、区域等渲染参数
|
|
|
|
Rectangle rect = ComponentUtils.getRelativeBounds(xLayoutContainer != null ? xLayoutContainer : container);
|
|
|
|
rect.x -= designer.getArea().getHorizontalValue();
|
|
|
|
rect.y -= designer.getArea().getVerticalValue();
|
|
|
|
painter.setRenderingBounds(rect);
|
|
|
|
painter.setHotspot(new Point(x, y));
|
|
|
|
painter.setCreator(creator);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void promptUser(int x, int y, XLayoutContainer container) {
|
|
|
|
if (!creator.canEnterIntoParaPane() && container.acceptType(XWParameterLayout.class)) {
|
|
|
|
promptButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Forbid_Drag_Into_Para_Pane"));
|
|
|
|
promptWidgetForbidEnter(x, y, container);
|
|
|
|
} else if (!creator.canEnterIntoAdaptPane() && container.acceptType(XWFitLayout.class)) {
|
|
|
|
promptButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Forbid_Drag_Into_Adapt_Pane"));
|
|
|
|
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 = designer.getArea().getLocationOnScreen().x;
|
|
|
|
int screenY = designer.getArea().getLocationOnScreen().y;
|
|
|
|
promptWindow.setLocation(screenX + x + GAP, screenY + y + GAP);
|
|
|
|
promptWindow.setVisible(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void cancelPromptWidgetForbidEnter() {
|
|
|
|
if (designer.getParaComponent() != null) {
|
|
|
|
designer.getParaComponent().setBorder(BorderFactory.createLineBorder(XCreatorConstants.LAYOUT_SEP_COLOR, Constants.LINE_THIN));
|
|
|
|
}
|
|
|
|
designer.getRootComponent().setBorder(BorderFactory.createLineBorder(XCreatorConstants.LAYOUT_SEP_COLOR, Constants.LINE_THIN));
|
|
|
|
promptWindow.setVisible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 拖拽进入
|
|
|
|
*
|
|
|
|
* @param dtde 事件
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public synchronized void dragEnter(DropTargetDragEvent dtde) {
|
|
|
|
Point loc = dtde.getLocation();
|
|
|
|
this.entering(designer.getRelativeX(loc.x), designer.getRelativeY(loc.y));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 拖拽移动经过
|
|
|
|
*
|
|
|
|
* @param dtde 事件
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public synchronized void dragOver(DropTargetDragEvent dtde) {
|
|
|
|
Point loc = dtde.getLocation();
|
|
|
|
int x = designer.getRelativeX(loc.x);
|
|
|
|
int y = designer.getRelativeY(loc.y);
|
|
|
|
hovering(x, y);
|
|
|
|
tabDragInner.setTabDragInAble(designer.getComponentAt(x, y), x, y);
|
|
|
|
|
|
|
|
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(creator);
|
|
|
|
if (parent!= null && parent.getLayoutAdapter()!=null){
|
|
|
|
parent.getLayoutAdapter().dragOver(creator, designer.getSelectionModel(), x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 触发状态添加模式事件
|
|
|
|
designer.repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 拖拽事件
|
|
|
|
*
|
|
|
|
* @param dtde 事件
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public synchronized void dropActionChanged(DropTargetDragEvent dtde) {
|
|
|
|
//do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 拖拽离开
|
|
|
|
*
|
|
|
|
* @param dte 事件
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public synchronized void dragExit(DropTargetEvent dte) {
|
|
|
|
this.exiting();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 拖拽释放
|
|
|
|
*
|
|
|
|
* @param dtde 事件
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public synchronized void drop(DropTargetDropEvent dtde) {
|
|
|
|
try {
|
|
|
|
dropXCreator(dtde);
|
|
|
|
} catch (Exception e) {
|
|
|
|
FineLoggerFactory.getLogger().error(e.getMessage(), e);
|
|
|
|
if (creator.isShared()) {
|
|
|
|
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),
|
|
|
|
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Drag_Component_Error_Info"),
|
|
|
|
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Error"),
|
|
|
|
JOptionPane.ERROR_MESSAGE,
|
|
|
|
UIManager.getIcon("OptionPane.errorIcon")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
dtde.rejectDrop();
|
|
|
|
}
|
|
|
|
designer.stopDragging();
|
|
|
|
designer.clearDropTarget();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void dropXCreator(DropTargetDropEvent dtde) {
|
|
|
|
DraggingModel model = designer.getDraggingModel();
|
|
|
|
|
|
|
|
if (model != null) {
|
|
|
|
cancelPromptWidgetForbidEnter();
|
|
|
|
Point loc = dtde.getLocation();
|
|
|
|
int x = designer.getRelativeX(loc.x);
|
|
|
|
int y = designer.getRelativeY(loc.y);
|
|
|
|
designer.addWidgetToForm(creator, x, y);
|
|
|
|
// 放到事件末尾执行
|
|
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
// 拖拽释放后标记未选中
|
|
|
|
for (XCreator xCreator : designer.getSelectionModel().getSelection().getSelectedCreators()) {
|
|
|
|
xCreator.setSelected(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
//针对在表单中拖入一个控件直接ctrl+s无反应
|
|
|
|
designer.requestFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public TabDragInner getTabDragInner() {
|
|
|
|
return this.tabDragInner;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void undoWhenAddingFailed() {
|
|
|
|
JTemplate<?, ?> jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
|
|
|
|
if (jt != null) {
|
|
|
|
jt.undoToCurrent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|