我正在实施一个EMF + GEF编辑器,也想支持Drag&从Package / Project Explorer中删除。 到目前为止,我在本教程后取得了很好的进展:https://eclipse.org/articles/Article-GEF-dnd/GEF-dnd.html
然而,现在我被困在这里: 我需要根据文件类型创建不同的对象。 例如,当我删除一个XML文件时,我想创建一个A类型的对象,当我删除一个TXT文件时,我想创建一个B类型的对象。
我可以访问handleDrop()
事件的文件名,但问题是在createTargetRequest()
,当我设置工厂类型时,有关扩展名的信息不可用。
即。访问isComponentXML()
的函数((String[])getCurrentEvent().data)[0]
会导致异常。
protected Request createTargetRequest() {
CreateRequest request = new CreateRequest();
if(isComponentXML()){
request.setFactory(componentfactory);
} else if (isControlFile()){
request.setFactory(filefactory);
}
}
在createTargetRequest()
期间,有人可以建议我可以访问文件名或树对象吗?
答案 0 :(得分:0)
您是否将所有内容设置为FileTransfer而非TextTransfer? 如果您从其中一个Eclipse视图(如PackageExplorer或ProjectExplorer)执行DND,那么转移可能是StructuredSelection。因此,请考虑以下两个代码段>:
for Files:
if (getCurrentEvent().data instanceof String[]) {
insertFileNamesFromStringArray(filesList, (String[]) getCurrentEvent().data);
}
对于结构化选择:
if (getCurrentEvent().data instanceof IStructuredSelection) {
Object[] array = ((IStructuredSelection)getCurrentEvent().data).toArray();
for (int j = 0; j < array.length; j++) {
if (array[j] instanceof IFile) {
IFile dropFile = (IFile)array[j];
filesList.add(dropFile.getLocation().toOSString());
}
}
}
答案 1 :(得分:0)
所以,我现在确实创建了自己的解决方案,虽然它可能不是最好的解决方案,我仍然希望有人提出其他的东西并在这里分享。但是,如果其他人有这个问题,并且不知道如何继续这个问题:
我基本上创建了自己的Request
和TargetDropListener
,然后将其添加到Policies
的{{1}}。确定正确对象的逻辑(根据文件扩展名)被添加到EditPart
中的getCommand(...)
。对于那些仍然不知道我一直在做什么的人,下面有一个循序渐进的指南。
第1步:创建自己的请求对象:
Policy
第2步:创建TargetDropListener
public class FileTransferRequest extends Request implements DropRequest {
public static final String TYPE = "FILE_TRANSFER"; // for comparison
private Point location; // stores where the new Object should be displayed
private String filepath; // this is the data bit...
public FileTransferRequest() {
setType(TYPE); // set the type of the request so we can recognise it later
}
/* GETTERS AND SETTERS */
@Override public Point getLocation() { return this.location; }
public void setLocation(Point location) { this.location = location; }
public void setFilePath(String filepath){ this.filepath = filepath; }
public String getFilePath(){ return this.filepath; }
}
第3步:在public class ResourceTransferDropTargetListener extends AbstractTransferDropTargetListener{
public ResourceTransferDropTargetListener(EditPartViewer viewer, Transfer xfer) {
super(viewer, xfer);
}
public ResourceTransferDropTargetListener(EditPartViewer viewer) {
super(viewer, FileTransfer.getInstance());
}
@Override public boolean isEnabled(DropTargetEvent event) {
return true; // maybe you want some smarter code here
}
// creates a new Request, will be called by getTargetRequest() if necessary
@Override protected Request createTargetRequest() {
return new FileTransferRequest();
}
// this routine is called repeatedly and sets the x/y coordinates of the mouse pointer
@Override protected void updateTargetRequest() {
((FileTransferRequest)getTargetRequest()).setLocation(getDropLocation());
}
// prevent moving, we want to copy the file...
@Override protected void handleDragOver() {
getCurrentEvent().detail = DND.DROP_COPY;
super.handleDragOver();
}
// called on drop. THIS IS WHERE WE GET ACCESS TO THE FILE NAME (for the first time)
@Override protected void handleDrop() {
((FileTransferRequest)getTargetRequest()).setFilePath(getFilepath());
super.handleDrop();
}
// a helper for the function above... returns only one element (for multiple selections you will have to change something here and above)
private String getFilepath(){
return ((String[])getCurrentEvent().data)[0];
}
}
MyEditor.java
第4步:这是重要的部分。
TargetDropListener将尝试查找实现与....
@Override
protected void initializeGraphicalViewer() {
super.initializeGraphicalViewer();
getGraphicalViewer().setContents(/* whatever you are displaying */);
// add the TransferDropTargetListener to the Editor
getGraphicalViewer().addDropTargetListener(new
ResourceTransferDropTargetListener(getGraphicalViewer()));
}
.....
对应的策略的EditPolicy。因此,我们需要创建一个新的YourRequest.TYPE
或扩展旧的EditPolicy
。
(我选择扩展现有的,因为我想保持简单,不要弄乱许多文件......)
步骤4a :将请求类型添加到EditPolicy。如果'被问到'它能处理什么,它将返回其EditPart
public class MyXYLayoutPolicy extends XYLayoutEditPolicy {
// This function will be called to find out what types it can handle.
// We need to return an EditPart to signal that we can.
// FileTransferRequest.TYPE serves as the identifier
@Override public EditPart getTargetEditPart(Request request) {
if(request.getType().equals(FileTransferRequest.TYPE)){
return getHost();
}
// if the previous didn't trigger, return what it would have done normally
return super.getTargetEditPart(request);
}
....
}
第4b步 :在返回正确的EditPart后,将调用getCommand(...)
,因此我们需要返回一个命令...
我会将Command实现保留给您自己的研究,但如果您正在寻求帮助:
here是查找信息的好地方。 (也适用于其他GEF的事情)
提示:扩展Command
并实施execute()
和undo()
!
public class MyXYLayoutPolicy extends XYLayoutEditPolicy {
....
@Override public Command getCommand(Request request) {
if(request.getType().equals(FileTransferRequest.TYPE)){ // for file DND
return handleFileTransferRequest(request);
}
return super.getCommand(request);
}
private Command handleFileTransferRequest(Request request){
FileTransferRequest req = (FileTransferRequest) request;
if(req.getFilePath().endsWith(".xml")){ // XML file
System.out.println("XML");
XMLCreateCommand command = new XMLCreateCommand();
command.setLocation(req.getLocation());
command.setParent((Graph)(getHost().getModel()));
Component c = GraphFactory.eINSTANCE.createComponent();
c.setName(req.getFilePath);
command.setComponent(c);
return command;
} else if(((FileTransferRequest) request).getFilePath().endsWith(".txt")){
System.out.println("TXT");
TXTCreateCommand command = new TXTCreateCommand();
command.setLocation(req.getLocation());
command.setParent((Graph)(getHost().getModel()));
TXTFile f = GraphFactory.eINSTANCE.createTXTFile();
f.setName(req.getFilePath());
command.setFile(f);
return command;
} else {
return null; // a FileTransferRequest, but not a type we know...
}
}
....
}