Eclipse GEF drag& drop区分文件扩展名

时间:2014-09-12 13:13:07

标签: eclipse events drag-and-drop eclipse-gef

我正在实施一个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()期间,有人可以建议我可以访问文件名或树对象吗?

2 个答案:

答案 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)

所以,我现在确实创建了自己的解决方案,虽然它可能不是最好的解决方案,我仍然希望有人提出其他的东西并在这里分享。但是,如果其他人有这个问题,并且不知道如何继续这个问题:

我基本上创建了自己的RequestTargetDropListener,然后将其添加到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...
        }
    }

    ....

}