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.
247 lines
7.2 KiB
247 lines
7.2 KiB
/* |
|
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved. |
|
*/ |
|
package com.fr.poly.hanlder; |
|
|
|
import com.fr.base.ScreenResolution; |
|
import com.fr.base.chart.BaseChartCollection; |
|
import com.fr.base.vcs.DesignerMode; |
|
import com.fr.chart.chartattr.ChartCollection; |
|
import com.fr.chartx.attr.ChartProvider; |
|
import com.fr.design.mainframe.DesignerContext; |
|
import com.fr.design.mainframe.chart.info.ChartInfoCollector; |
|
import com.fr.grid.Grid; |
|
import com.fr.log.FineLoggerFactory; |
|
import com.fr.poly.PolyDesigner; |
|
import com.fr.poly.PolyUtils; |
|
import com.fr.poly.creator.BlockCreator; |
|
import com.fr.poly.creator.ChartBlockCreator; |
|
import com.fr.poly.model.AddingData; |
|
import com.fr.report.poly.PolyChartBlock; |
|
import com.fr.stable.unit.UnitRectangle; |
|
|
|
import javax.swing.JScrollBar; |
|
import java.awt.Point; |
|
import java.awt.Rectangle; |
|
import java.awt.datatransfer.DataFlavor; |
|
import java.awt.datatransfer.Transferable; |
|
import java.awt.dnd.DropTarget; |
|
import java.awt.dnd.DropTargetAdapter; |
|
import java.awt.dnd.DropTargetDragEvent; |
|
import java.awt.dnd.DropTargetDropEvent; |
|
import java.awt.dnd.DropTargetEvent; |
|
|
|
/** |
|
* @author richer |
|
* @since 6.5.4 创建于2011-4-1 |
|
*/ |
|
public class PolyDesignerDropTarget extends DropTargetAdapter { |
|
|
|
private static final double SCROLL_POINT = 100; |
|
private static final int SCROLL_DISTANCE = 15; |
|
|
|
private PolyDesigner designer; |
|
private AddingData addingData; |
|
private int resolution = ScreenResolution.getScreenResolution(); |
|
//禁止重叠提示窗口 |
|
private BlockForbiddenWindow forbiddenWindow = new BlockForbiddenWindow(); |
|
|
|
public PolyDesignerDropTarget(PolyDesigner designer) { |
|
this.designer = designer; |
|
new DropTarget(designer, this); |
|
} |
|
|
|
/** |
|
* 拖拽进入事件 |
|
* |
|
* @param dtde 鼠标事件 |
|
* |
|
*/ |
|
public void dragEnter(DropTargetDragEvent dtde) { |
|
|
|
if (DesignerMode.isAuthorityEditing()) { |
|
return; |
|
} |
|
// richer:避免在一次拖拽过程中重复查找 |
|
if (designer.getAddingData() != null) { |
|
return; |
|
} |
|
try { |
|
Transferable tr = dtde.getTransferable(); |
|
DataFlavor[] flavors = tr.getTransferDataFlavors(); |
|
for (int i = 0; i < flavors.length; i++) { |
|
if (!tr.isDataFlavorSupported(flavors[i])) { |
|
continue; |
|
} |
|
Object obj = tr.getTransferData(flavors[i]); |
|
BlockCreator creator = null; |
|
if (obj instanceof Class) { |
|
Class clazz = (Class) obj; |
|
creator = PolyUtils.createCreator(clazz); |
|
} else if (obj instanceof BaseChartCollection) { |
|
creator = PolyUtils.createCreator((BaseChartCollection) obj); |
|
} |
|
if (creator == null) { |
|
return; |
|
} |
|
|
|
addingData = new AddingData(creator); |
|
designer.setAddingData(addingData); |
|
} |
|
} catch (Exception e) { |
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
|
} |
|
Point loc = dtde.getLocation(); |
|
addingData.moveTo(loc); |
|
designer.repaint(); |
|
} |
|
|
|
/** |
|
* 拖拽悬浮事件 |
|
* |
|
* @param dtde 鼠标事件 |
|
* |
|
*/ |
|
public void dragOver(DropTargetDragEvent dtde) { |
|
if (addingData != null) { |
|
Point loc = dtde.getLocation(); |
|
addingData.moveTo(loc); |
|
//检测是否跟别的组件重叠 |
|
setForbiddenWindowVisibility(loc); |
|
//检测是否到达角落 |
|
scrollWhileDropCorner(dtde); |
|
|
|
designer.repaint(); |
|
} |
|
} |
|
|
|
private void scrollWhileDropCorner(final DropTargetDragEvent dtde){ |
|
Thread tt = new Thread(new Runnable() { |
|
|
|
@Override |
|
public void run() { |
|
Point location = dtde.getLocation(); |
|
//当block的右下角小于当前面板的-SCROLL_POINT时, 开始滚动 |
|
if(location.x > designer.getWidth() - SCROLL_POINT){ |
|
JScrollBar horizonBar = designer.getHorizontalScrollBar(); |
|
horizonBar.setValue(horizonBar.getValue() + SCROLL_DISTANCE); |
|
} |
|
|
|
if(location.y> designer.getHeight() - SCROLL_POINT){ |
|
JScrollBar verticalBar = designer.getVerticalScrollBar(); |
|
verticalBar.setValue(verticalBar.getValue() + SCROLL_DISTANCE); |
|
} |
|
|
|
} |
|
}); |
|
tt.start(); |
|
} |
|
|
|
//设置是否显示 禁止组件重叠 窗口 |
|
private void setForbiddenWindowVisibility(Point loc){ |
|
BlockCreator creator = addingData.getCreator(); |
|
Rectangle pixRec = getCreatorPixRectangle(creator, loc); |
|
UnitRectangle rec = new UnitRectangle(pixRec, resolution); |
|
|
|
if(designer.intersectsAllBlock(rec, creator.getValue().getBlockName())){ |
|
int x = (int) (designer.getAreaLocationX() + pixRec.getCenterX() - designer.getHorizontalValue()); |
|
int y = (int) (designer.getAreaLocationY() + pixRec.getCenterY() - designer.getVerticalValue()); |
|
forbiddenWindow.showWindow(x, y); |
|
}else{ |
|
forbiddenWindow.hideWindow(); |
|
} |
|
} |
|
|
|
/** |
|
* 放下事件 |
|
* |
|
* @param dtde 鼠标事件 |
|
* |
|
*/ |
|
public void drop(DropTargetDropEvent dtde) { |
|
if (addingData != null) { |
|
designer.stopAddingState(); |
|
BlockCreator creator = addingData.getCreator(); |
|
Point location = dtde.getLocation(); |
|
Rectangle pixRec = getCreatorPixRectangle(creator, location); |
|
if(!intersectLocation(pixRec, creator)){ |
|
return; |
|
} |
|
|
|
designer.addBlockCreator(creator); |
|
//图表埋点 |
|
dealChartBuryingPoint(creator); |
|
designer.stopEditing(); |
|
designer.setSelection(creator); |
|
//在重新设置了选择之后,要对菜单和工具进行target的重新设置 |
|
DesignerContext.getDesignerFrame().resetToolkitByPlus(DesignerContext.getDesignerFrame().getSelectedJTemplate()); |
|
focusOnSelection(); |
|
designer.fireTargetModified(); |
|
// richer:拖拽完成后需要把addingData重置 |
|
addingData = null; |
|
} |
|
} |
|
|
|
//聚焦选中块 |
|
private void focusOnSelection(){ |
|
if (designer.getSelection().getEditingElementCasePane() == null) { |
|
return; |
|
} |
|
Grid grid = designer.getSelection().getEditingElementCasePane().getGrid(); |
|
if (!grid.hasFocus() && grid.isRequestFocusEnabled()) { |
|
grid.requestFocus(); |
|
} |
|
} |
|
|
|
//检测新加入的creator位置是否与老的重叠, 重叠返回false |
|
private boolean intersectLocation(Rectangle pixRec, BlockCreator creator){ |
|
if (pixRec.getX() < 0 || pixRec.getY() < 0) { |
|
forbiddenWindow.hideWindow(); |
|
designer.repaint(); |
|
return false; |
|
} |
|
UnitRectangle rec = new UnitRectangle(pixRec, resolution); |
|
if(designer.intersectsAllBlock(rec, creator.getValue().getBlockName())){ |
|
//停止移动后要隐藏掉禁止重叠的标志 |
|
forbiddenWindow.hideWindow(); |
|
designer.repaint(); |
|
return false; |
|
} |
|
|
|
creator.getValue().setBounds(rec); |
|
|
|
return true; |
|
} |
|
|
|
private Rectangle getCreatorPixRectangle(BlockCreator creator, Point location){ |
|
int width = creator.getWidth(); |
|
int height = creator.getHeight(); |
|
int resx = location.x - width / 2 + designer.getHorizontalValue(); |
|
int resy = location.y - height / 2 + designer.getVerticalValue(); |
|
return new Rectangle(resx, resy, width, height); |
|
} |
|
|
|
/** |
|
* 拖拽移出去事件 |
|
* |
|
* @param dte 拖拽事件 |
|
* |
|
*/ |
|
public void dragExit(DropTargetEvent dte) { |
|
if (addingData != null) { |
|
addingData.reset(); |
|
designer.repaint(); |
|
} |
|
|
|
forbiddenWindow.hideWindow(); |
|
} |
|
|
|
private void dealChartBuryingPoint(BlockCreator creator) { |
|
if (creator instanceof ChartBlockCreator) { |
|
PolyChartBlock value = ((ChartBlockCreator) creator).getValue(); |
|
ChartCollection chartCollection = (ChartCollection) value.getChartCollection(); |
|
ChartInfoCollector.getInstance().collection(chartCollection.getSelectedChartProvider(ChartProvider.class), null); |
|
} |
|
} |
|
|
|
} |