Matlab从windows explorer拖放文件到图(gui)

时间:2014-12-31 10:54:24

标签: java matlab user-interface drag-and-drop matlab-figure

我想知道有一种方法可以将文件从Windows资源管理器拖放到我的GUI中。

目标应该是获取文件路径(或文件夹路径)并能够使用我自己的加载函数加载它。

我确切地知道我在Windows 10 64位中使用Matlab 2015b。

我编辑我的帖子给出了我想要做的代码示例(基于Yair Altman解决方案和Internet上的其他解决方案):

function demo

    % Set-up a figure droppable axis
    hFig = figure('name','DND example','numbertitle','off');
    hAx1 = axes('position',[.1,.1,.8,.8]);

    % Enable drop on the figure axis
    dnd = handle(java.awt.dnd.DropTarget(),'callbackProperties');
    jFrame = get(hFig,'JavaFrame');
    jAxis = jFrame.getAxisComponent;
    jAxis.setDropTarget(dnd);
    set(dnd,'DropCallback',{@dndCallbackFcn,hFig, hAx1});
    set(dnd,'DragOverCallback',@dndCallbackFcn);

end

function dndCallbackFcn(varargin)

   persistent transferable
   eventData = varargin{2};
   if eventData.isa('java.awt.dnd.DropTargetDropEvent') %nargin>2
       hFig = varargin{3}; % my figure is passed as the third argument

       try 
           eventData.acceptDrop(eventData.getDropAction);
           transferable = eventData.getTransferable; 
       catch
       end


       dataFlavorList = java.awt.datatransfer.DataFlavor.javaFileListFlavor;
       fileList = transferable.getTransferData(dataFlavorList);

       %{
          I want here to get back the file path and then call my loading function
       %}
    end
end

我总是在行中出错:

fileList = transferable.getTransferData(dataFlavorList); 

错误如下:

Java exception occurred:
java.awt.dnd.InvalidDnDOperationException: No drop current

at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(Unknown Source)

at sun.awt.datatransfer.TransferableProxy.getTransferData(Unknown Source)

at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(Unknown Source)

2 个答案:

答案 0 :(得分:1)

我尝试实现与您相同的功能,并在尝试获取可传输数据时遇到相同的异常。

由于在getTransferable 中实例化的默认FlavorMap%matlabroot%\sys\java\jre\...\lib\flavormap.properties是否失败,这一点尚不清楚(如Yair Altman's book中所述 在拖放部分)或其他一些奇怪的原因。无论如何,我在dndcontrol上遇到了这个file exchange对象,它通过直接管理java端的可传输数据,就像我们的目的一样有魅力。

我从中获得灵感,在java.awt.dnd.DropTarget之上编写了我自己的matlab代理,它更通用,更接近其java实现对等体(即它的工作方式与java DropTarget对象完全相同,除了所有数据类型都已转换为更标准和更方便的matlab类型。)

您可以从此处下载我的实施:

以下是一些用于执行所需操作的示例(从文件资源管理器中删除matlab轴):

%
% PURPOSE:
%
%   Show how to add drop support from file explorer to some matlab axis
%
% SYNTAX:
%
%   [] = DropListenerDemo();
%
% USAGE:
%
%   Simply drop files from file explorer into displayed axis.
%

%%
function [] = DropListenerDemo()
%[
    % Create a figure with some axis inside
    fig = figure(666); clf;
    axes('Parent', fig);

    % Get back the java component associated to the axis
    % NB1: See §3.7.2 of Undocumented Secrets of Matlab Java Programming
    % NB2: or use findjobj, or javaObjectEDT for drop support onto other component types
    jFrame = get(handle(fig), 'JavaFrame');
    jAxis = jFrame.getAxisComponent();

    % Add listener for drop operations
    DropListener(jAxis, ... % The component to be observed
                 'DropFcn', @(s, e)onDrop(fig, s, e)); % Function to call on drop operation    
%]
end
function [] = onDrop(fig, listener, evtArg) %#ok<INUSL>
%[
    % Get back the dropped data
    data = evtArg.GetTransferableData();

    % Is it transferable as a list of files
    if (data.IsTransferableAsFileList)       

        % Do whatever you need with this list of files
        msg = sprintf('%s\n', data.TransferAsFileList{:});
        msg = sprintf('Do whatever you need with:\n\n%s', msg);
        uiwait(msgbox(msg));

        % Indicate to the source that drop has completed 
        evtArg.DropComplete(true);

    elseif (data.IsTransferableAsString)

        % Not interested
        evtArg.DropComplete(false);

    else

        % Not interested
        evtArg.DropComplete(false);

    end
%]
end

该对象还支持捕获DragEnterDragOverDropActionChangedDragExit事件,因此您可以调整拖动操作的各个方面。只需很少的努力,它也可以扩展为支持图像拖动或其他数据类型拖动。

希望你喜欢它,并且你会发现它足够通用,可以想到其他用法。

答案 1 :(得分:-1)

Matlab Central有一个帖子,它使用已编译的java类。 stackoverflow answer包含了代码。使用该解决方案,您的演示可能如下所示:

function demo
    % Set-up a figure droppable axis
    hFig = figure('name','DND example','numbertitle','off');
    warning('off', 'MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
    jFrame = get(hFig,'JavaFrame');
    jAxis = jFrame.getAxisComponent;

    % dnccontrol class from above link
    dndcontrol.initJava();
    dndcontrol(jAxis, @dropCallbackFcn);
end

function dropCallbackFcn(~, evt)
    fileparts(evt.Data{1}) % show dropped file's path
end