2016-04-25 15 views
6

Tôi đang cố gắng tìm cách sử dụng kéo và thả trong GUI MATLAB của mình. Tôi đã tìm thấy gần nhất là this.Kéo và thả tệp trong Matlab GUI

Tuy nhiên, tôi muốn kết quả tìm kiếm như thế này:

enter image description here

Khi một tập tin đã được giảm xuống, tất cả tôi cần là đường dẫn của tập tin và một cuộc gọi đến chức năng tải của tôi.

Tất cả đề xuất được đánh giá cao!

+1

Tôi đang sử dụng Matlab 2012, để don Không biết liệu các phiên bản mới hơn có thực hiện các sự kiện dragdrop hay không. Dù sao, bạn có thể sử dụng phương pháp sau: (http://de.mathworks.com/matlabcentral/answers/94681-how-do-i-implement-drag-and-drop-functionality-in-matlab) – Lati

+0

Trong ví dụ trong liên kết bạn cung cấp, bạn chỉ có thể kéo các mục trong một hình. Tôi muốn kéo các tập tin từ thám hiểm (hoặc công cụ tìm trên mac) và vào GUI, sau đó gọi một hàm để đọc tệp. – JCKaz

+0

@JZKaz, bạn vẫn có thể sử dụng cùng một phương pháp, chỉ điều bạn cần thêm là so sánh vị trí chuột và vị trí của phần tử bạn muốn thả (tôi đoán đó là bảng điều khiển trong trường hợp của bạn). – Lati

Trả lời

1

This submission bởi Maarten van der Seijs về trao đổi tệp dường như giải quyết được sự cố.

Nó tạo ra một chức năng gọi lại có thể được ghép nối với các thành phần GUI java swing, như được trình bày trong bản trình diễn kèm theo.

Nó sử dụng một lớp java, mà là một wrapper mỏng xung quanh java.awt.dnd.DropTarget:

import java.awt.dnd.*; 
import java.awt.datatransfer.*; 
import java.util.*; 
import java.io.File; 
import java.io.IOException; 

public class MLDropTarget extends DropTarget 
{ 
    /** 
    * Modified DropTarget to be used for drag & drop in MATLAB UI control. 
    */ 
    private static final long serialVersionUID = 1L; 
    private int droptype; 
    private Transferable t; 
    private String[] transferData; 

    public static final int DROPERROR = 0; 
    public static final int DROPTEXTTYPE = 1; 
    public static final int DROPFILETYPE = 2; 

    @SuppressWarnings("unchecked") 
    @Override 
    public synchronized void drop(DropTargetDropEvent evt) { 

     // Make sure drop is accepted 
     evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); 

     // Set droptype to zero 
     droptype = DROPERROR;   

     // Get transferable and analyze 
     t = evt.getTransferable(); 

     try { 
      if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { 
       // Interpret as list of files 
       List<File> fileList = (ArrayList<File>) t.getTransferData(DataFlavor.javaFileListFlavor); 
       transferData = new String[fileList.size()]; 
       for (int i = 0; i < fileList.size(); i++) 
        transferData[i] = fileList.get(i).getAbsolutePath(); 
       droptype = DROPFILETYPE; 
      } 
      else if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) { 
       // Interpret as string    
       transferData[0] = (String) t.getTransferData(DataFlavor.stringFlavor); 
       droptype = DROPTEXTTYPE; 
      } 

     } catch (UnsupportedFlavorException e) { 
      droptype = DROPERROR; 
      super.drop(evt);    
      return; 
     } catch (IOException e) { 
      droptype = DROPERROR; 
      super.drop(evt); 
      return; 
     } 

     // Call built-in drop method (fire MATLAB Callback)  
     super.drop(evt); 
    } 

    public int getDropType() { 
     return droptype; 
    } 
    public Transferable getTransferable() { 
     return t; 
    } 
    public String[] getTransferData() { 
     return transferData; 
    } 
} 

mà sau đó được khởi tạo và được gọi bằng một lớp MATLAB:

classdef (CaseInsensitiveProperties) dndcontrol < handle 
%DNDCONTROL Class for Drag & Drop functionality. 
% obj = DNDCONTROL(javaobj) creates a dndcontrol object for the specified 
% Java object, such as 'javax.swing.JTextArea' or 'javax.swing.JList'. Two 
% callback functions are available: obj.DropFileFcn and obj.DropStringFcn, 
% that listen to drop actions of respectively system files or plain text. 
% 
% The Drag & Drop control class relies on a Java class that need to be 
% visible on the Java classpath. To initialize, call the static method 
% dndcontrol.initJava(). The Java class can be adjusted and recompiled if 
% desired. 
% 
% DNDCONTROL Properties: 
%  Parent   - The associated Java object. 
%  DropFileFcn  - Callback function for system files. 
%  DropStringFcn  - Callback function for plain text. 
% 
% DNDCONTROL Methods: 
%  dndcontrol  - Constructs the DNDCONTROL object. 
% 
% DNDCONTROL Static Methods: 
%  defaultDropFcn - Default callback function for drop events. 
%  demo    - Runs the demonstration script. 
%  initJava   - Initializes the Java class. 
%  isInitialized  - Checks if the Java class is visible. 
% 
% A demonstration is available from the static method dndcontrol.demo(). 
% 
% Example: 
%  dndcontrol.initJava(); 
%  dndcontrol.demo(); 
% 
% See also: 
%  uicontrol, javaObjectEDT.  
% 
% Written by: Maarten van der Seijs, 2015. 
% Version: 1.0, 13 October 2015. 


    properties (Hidden) 
     dropTarget;     
    end 

    properties (Dependent) 
     %PARENT The associated Java object. 
     Parent; 
    end 

    properties 
     %DROPFILEFCN Callback function executed upon dropping of system files. 
     DropFileFcn;   
     %DROPSTRINGFCN Callback function executed upon dropping of plain text. 
     DropStringFcn;   
    end 

    methods (Static) 
     function initJava() 
     %INITJAVA Initializes the required Java class. 

      %Add java folder to javaclasspath if necessary 
      if ~dndcontrol.isInitialized(); 
       classpath = fileparts(mfilename('fullpath'));     
       javaclasspath(classpath);     
      end 
     end 

     function TF = isInitialized()    
     %ISINITIALIZED Returns true if the Java class is initialized. 

      TF = (exist('MLDropTarget','class') == 8); 
     end       
    end 

    methods 
     function obj = dndcontrol(Parent,DropFileFcn,DropStringFcn) 
     %DNDCONTROL Drag & Drop control constructor. 
     % obj = DNDCONTROL(javaobj) contstructs a DNDCONTROL object for 
     % the given parent control javaobj. The parent control should be a 
     % subclass of java.awt.Component, such as most Java Swing widgets. 
     % 
     % obj = DNDCONTROL(javaobj,DropFileFcn,DropStringFcn) sets the 
     % callback functions for dropping of files and text. 

      % Check for Java class 
      assert(dndcontrol.isInitialized(),'Javaclass MLDropTarget not found. Call dndcontrol.initJava() for initialization.') 

      % Construct DropTarget    
      obj.dropTarget = handle(javaObjectEDT('MLDropTarget'),'CallbackProperties'); 
      set(obj.dropTarget,'DropCallback',{@dndcontrol.DndCallback,obj}); 
      set(obj.dropTarget,'DragEnterCallback',{@dndcontrol.DndCallback,obj}); 

      % Set DropTarget to Parent 
      if nargin >=1, Parent.setDropTarget(obj.dropTarget); end 

      % Set callback functions 
      if nargin >=2, obj.DropFileFcn = DropFileFcn; end 
      if nargin >=3, obj.DropStringFcn = DropStringFcn; end 
     end 

     function set.Parent(obj, Parent) 
      if isempty(Parent) 
       obj.dropTarget.setComponent([]); 
       return 
      end 
      if isa(Parent,'handle') && ismethod(Parent,'java') 
       Parent = Parent.java; 
      end 
      assert(isa(Parent,'java.awt.Component'),'Parent is not a subclass of java.awt.Component.') 
      assert(ismethod(Parent,'setDropTarget'),'DropTarget cannot be set on this object.') 

      obj.dropTarget.setComponent(Parent); 
     end 

     function Parent = get.Parent(obj) 
      Parent = obj.dropTarget.getComponent(); 
     end 
    end 

    methods (Static, Hidden = true) 
     %% Callback functions 
     function DndCallback(jSource,jEvent,obj) 

      if jEvent.isa('java.awt.dnd.DropTargetDropEvent') 
       % Drop event  
       try 
        switch jSource.getDropType() 
         case 0 
          % No success. 
         case 1 
          % String dropped. 
          string = char(jSource.getTransferData()); 
          if ~isempty(obj.DropStringFcn) 
           evt = struct(); 
           evt.DropType = 'string'; 
           evt.Data = string;         
           feval(obj.DropStringFcn,obj,evt); 
          end 
         case 2 
          % File dropped. 
          files = cell(jSource.getTransferData());        
          if ~isempty(obj.DropFileFcn) 
           evt = struct(); 
           evt.DropType = 'file'; 
           evt.Data = files;         
           feval(obj.DropFileFcn,obj,evt); 
          end 
        end 

        % Set dropComplete 
        jEvent.dropComplete(true); 
       catch ME 
        % Set dropComplete 
        jEvent.dropComplete(true); 
        rethrow(ME) 
       end        

      elseif jEvent.isa('java.awt.dnd.DropTargetDragEvent') 
       % Drag event        
       action = java.awt.dnd.DnDConstants.ACTION_COPY; 
       jEvent.acceptDrag(action); 
      end    
     end 
    end 

    methods (Static) 
     function defaultDropFcn(src,evt) 
     %DEFAULTDROPFCN Default drop callback. 
     % DEFAULTDROPFCN(src,evt) accepts the following arguments: 
     %  src - The dndcontrol object. 
     %  evt - A structure with fields 'DropType' and 'Data'. 

      fprintf('Drop event from %s component:\n',char(src.Parent.class())); 
      switch evt.DropType 
       case 'file' 
        fprintf('Dropped files:\n'); 
        for n = 1:numel(evt.Data) 
         fprintf('%d %s\n',n,evt.Data{n}); 
        end 
       case 'string' 
        fprintf('Dropped text:\n%s\n',evt.Data); 
      end 
     end    

     function [dndobj,hFig] = demo() 
     %DEMO Demonstration of the dndcontrol class functionality. 
     % dndcontrol.demo() runs the demonstration. Make sure that the 
     % Java class is visible in the Java classpath. 

      % Initialize Java class 
      dndcontrol.initJava(); 

      % Create figure 
      hFig = figure(); 

      % Create Java Swing JTextArea 
      jTextArea = javaObjectEDT('javax.swing.JTextArea', ... 
       sprintf('Drop some files or text content here.\n\n')); 

      % Create Java Swing JScrollPane 
      jScrollPane = javaObjectEDT('javax.swing.JScrollPane', jTextArea); 
      jScrollPane.setVerticalScrollBarPolicy(jScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 

      % Add Scrollpane to figure 
      [~,hContainer] = javacomponent(jScrollPane,[],hFig); 
      set(hContainer,'Units','normalized','Position',[0 0 1 1]); 

      % Create dndcontrol for the JTextArea object 
      dndobj = dndcontrol(jTextArea); 

      % Set Drop callback functions 
      dndobj.DropFileFcn = @demoDropFcn; 
      dndobj.DropStringFcn = @demoDropFcn; 

      % Callback function 
      function demoDropFcn(~,evt) 
       switch evt.DropType 
        case 'file' 
         jTextArea.append(sprintf('Dropped files:\n')); 
         for n = 1:numel(evt.Data) 
          jTextArea.append(sprintf('%d %s\n',n,evt.Data{n})); 
         end 
        case 'string' 
         jTextArea.append(sprintf('Dropped text:\n%s\n',evt.Data)); 
       end 
       jTextArea.append(sprintf('\n')); 
      end 
     end 
    end  
end 
+0

Rody Oldgenius, cảm ơn rất nhiều! – JCKaz