java matlab user-interface drag-and-drop matlab-figure

java - Matlab arrastra y suelta el archivo desde el explorador de Windows hasta la figura(gui)



user-interface drag-and-drop (2)

Hay una publicación en Matlab Central que utiliza una clase java compilada. Una respuesta stackoverflow incluyó el código. Con esa solución, su demostración puede verse así:

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

Me gustaría saber que hay una forma de arrastrar un archivo desde el explorador de Windows y soltarlo en mi GUI.

El objetivo debe ser obtener la ruta del archivo (o la ruta de la carpeta) y poder cargarla con mi propia función de carga.

Preciso que estoy usando Matlab 2015b en Windows 10 64bits.

Edito mi publicación para dar un ejemplo de código de lo que estoy tratando de hacer (basado en la solución de Yair Altman y otros encontrados en 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

Siempre me sale un error en la línea:

fileList = transferable.getTransferData(dataFlavorList);

El error es el siguiente:

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)


Traté de implementar la misma funcionalidad que la tuya y caí en las mismas excepciones cuando trato de obtener datos transferibles.

No está claro si getTransferable falla debido a FlavorMap predeterminado instanciado en %matlabroot%/sys/java/jre/.../lib/flavormap.properties (como se señala en el libro de Yair Altman en la sección de arrastrar y soltar) o por algún otro extraño razón. De todos modos, encontré este objeto dndcontrol en el intercambio de archivos, que funciona como un encanto para nuestro propósito al administrar los datos transferibles en el lado de Java directamente.

Me inspiro para escribir mi propio proxy matlab encima de java.awt.dnd.DropTarget que es más genérico y más cercano a su par de implementación java (es decir, funciona exactamente de la misma manera que el objeto DropTarget java excepto que todos los tipos de datos tienen convertido a tipos de matlab más estándar y convenientes).

Puede descargar mi implementación desde aquí:

Y aquí hay algunos ejemplos de uso para hacer lo que necesita (colocar en el eje de matlab desde el explorador de archivos):

% % 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

El objeto también es compatible con la captura de DragOver , DragOver , DropActionChanged , DragExit evento para que pueda ajustar todos los aspectos de la operación de arrastre. Con poco esfuerzo, también se puede ampliar para admitir el arrastre de imágenes u otros tipos de datos al arrastrar.

Espero que te guste y lo encuentres lo suficientemente genérico como para pensar en otros usos.