gusucode.com > vision工具箱matlab源码程序 > vision/+vision/+internal/+uitools/ImageStrip.m
classdef ImageStrip < handle properties JImageStrip JImageList MaxNumIcons = 13; % Cache for java objects Misc % variables needed to control HG/Java synchronization IsInteractionDisabledByScrollCallback = false; IsBrowserInteractionEnabled = true; ToolGroup Session % image strip helps manage this, is there a way to abstract this better? end %---------------------------------------------------------------------- % Properties to store callback function handles for image strip events. %---------------------------------------------------------------------- properties % SelectionCallback Callback for selecting an image with the mouse. % Typically, apps will use this callback to draw the image in the % app's main display. SelectionCallback = [] % MousePressedCallback Callback for dealing with other events such % as right-click context menus. MousePressedCallback = [] % KeyPressedCallback Callback for dealing with keyboard events in % the image strip, e.g. delete, up/down arrow, etc. KeyPressedCallback = [] % MouseMovedCallback Callback for dealing with mouse motion over % the image list, e.g. updating status text when mouse hovers over % an image. MouseMovedCallback = [] end %====================================================================== % Public methods %====================================================================== methods %------------------------------------------------------------------ function this = ImageStrip(tool, session) this.ToolGroup = tool; this.Session = session; end %------------------------------------------------------------------ % Set up image strip and attach callbacks. %------------------------------------------------------------------ function update(this) this.JImageStrip = javaObject('com.mathworks.toolbox.vision.ImageStrip'); this.JImageList = javaMethod('getImageList', this.JImageStrip); jfirstVisibleIndex = this.JImageList.getFirstVisibleIndex(); jlastVisibleIndex = this.JImageList.getLastVisibleIndex(); if jfirstVisibleIndex == -1 jfirstVisibleIndex = 0; end if jlastVisibleIndex == -1 % By default, a full sized viewport can hold approx 13 % icons, if the number of images selected is lesser than % that set it as the last visible index. jlastVisibleIndex = min(getNumel(this.Session.ImageSet)-1,... this.MaxNumIcons); end for ind = jfirstVisibleIndex:jlastVisibleIndex this.Session.ImageSet.updateImageListEntry(ind); javaMethodEDT('setListData', this.JImageList, ... getIcons(this.Session.ImageSet)) end dataPanel = this.JImageStrip.getImagePanel(); this.ToolGroup.setDataBrowser(dataPanel); % moved to parent % Add a listener for handling file selections this.addSelectionListener(); if isempty(this.MousePressedCallback) popupListener = []; else popupListener = addlistener(this.JImageList, 'MousePressed', ... this.MousePressedCallback); end if isempty(this.KeyPressedCallback) keyListener = []; else keyListener = addlistener(this.JImageList, 'KeyPressed', ... this.KeyPressedCallback); end % Use the handle command to convert the Java object to a % handle object. scrollCallback = handle(this.JImageStrip.getScrollCallback); % Connect the callback to a nested function. The callback % class requires 'delayed' as the listener type. scrollListener = handle.listener(scrollCallback, 'delayed', @doScroll); if isempty(this.MouseMovedCallback) mouseMotionListener = []; else mouseMotionListener = addlistener(this.JImageList, 'MouseMoved', ... this.MouseMovedCallback); end % Store handles to prevent going out of scope this.Misc.PopupListener = popupListener; this.Misc.KeyListener = keyListener; this.Misc.DataPanel = dataPanel; this.Misc.ScrollListener = scrollListener; this.Misc.MouseMotionListener = mouseMotionListener; %-------------------------------------------------------------- function doScroll(~, ~) if this.Session.ImageSet.areAllIconsGenerated() return; end drawnow(); % update Java UI components before proceeding this.setBrowserInteractionEnabled(false); this.IsInteractionDisabledByScrollCallback = true; jfirstVisibleIndex = this.JImageList.getFirstVisibleIndex(); jlastVisibleIndex = this.JImageList.getLastVisibleIndex(); for index = jfirstVisibleIndex:jlastVisibleIndex doUpdate = this.Session.ImageSet.updateImageListEntry(index); if doUpdate % Do not move the "setWaiting" outside of the for loop! % It will cause the down/up arrows on the scrollbar % to misbehave setWaiting(this.ToolGroup, true); % turn on waiting pointer selectedIndex = this.getSelectedImageIndex(); javaMethodEDT('setListData', this.JImageList, ... getIcons(this.Session.ImageSet)); this.setSelectedImageIndex(selectedIndex); drawnow(); end end this.setBrowserInteractionEnabled(true); this.IsInteractionDisabledByScrollCallback = false; setWaiting(this.ToolGroup, false); % turn off waiting pointer drawnow(); end end % updateImageStrip %------------------------------------------------------------------ function updateListItems(this, idx) this.Session.IsChanged = true; if this.Session.hasAnyItems() javaMethodEDT('setListData', ... this.JImageList, getIcons(this.Session.ImageSet)); % conditionally update selected image. Setting the selected to allow for % dynamic insertion into the list without forcing the % selection callback to be trigg %jLowestIdx = this.getSelectedImageIndex(); if idx ~= 0 newIdx = idx; else newIdx = 1; end this.setSelectedImageIndex(newIdx); drawnow(); end % Update the UI before proceeding further drawnow; end %------------------------------------------------------------------ % Removes selected images from the strip. A pop-up dialog is % displayed for user confirmation. %------------------------------------------------------------------ function wasCanceled = removeSelectedItems(this, showConfirmationDialog) if nargin == 1 showConfirmationDialog = true; end idxMultiselect = this.getSelectedImageIndices(); if showConfirmationDialog % Display different warnings based on whether multiple images % are selected or just a single image is selected. cancelString = getString(message('MATLAB:uistring:popupdialogs:Cancel')); if numel(idxMultiselect) > 1 choice = questdlg(vision.getMessage('vision:trainingtool:RemoveImagesPrompt'),... vision.getMessage('vision:trainingtool:RemoveImagesTitle'),... vision.getMessage('vision:uitools:Remove'), cancelString, cancelString); elseif (numel(idxMultiselect) == 1) choice = questdlg(vision.getMessage('vision:trainingtool:RemoveImagePrompt'),... vision.getMessage('vision:trainingtool:RemoveImageTitle'),... vision.getMessage('vision:uitools:Remove'), cancelString, cancelString); end % Handle of the dialog is destroyed by the user % closing the dialog or the user pressed cancel wasCanceled = isempty(choice) || strcmp(choice, cancelString); if wasCanceled return; end end this.Session.ImageSet.removeItem(idxMultiselect); this.Session.IsChanged = true; jLowestIdx = idxMultiselect(1)-1; if this.Session.hasAnyItems() javaMethodEDT('setListData', ... this.JImageList, getIcons(this.Session.ImageSet)); if jLowestIdx ~= 0 newIdx = jLowestIdx; else newIdx = 1; end this.setSelectedImageIndex(newIdx); drawnow(); end % Update the UI before proceeding further drawnow; end %------------------------------------------------------------------ % Puts the image strip in focus %------------------------------------------------------------------ function setFocus(this) %drawnow; if ishandle(this.JImageList) javaMethodEDT('requestFocus', this.JImageList); end end %------------------------------------------------------------------ % Key pressed callback wrapper provides synchronisation and invokes % user defined key press callback functions. %------------------------------------------------------------------ function processKeyPressedCallback(this, es, ed) if this.IsBrowserInteractionEnabled this.KeyPressedCallback(es,ed); end end %------------------------------------------------------------------ % Moves up and down the image strip. %------------------------------------------------------------------ function changeImage(this, direction) currentIndex = this.getSelectedImageIndex(); this.setSelectedImageIndex(currentIndex+direction); this.makeSelectionVisible(currentIndex+direction); end %------------------------------------------------------------------ % returns index of the selected Image %------------------------------------------------------------------ function idx = getSelectedImageIndex(this) idx = double(javaMethodEDT('getSelectedIndex', this.JImageList)); idx = idx+1; % make it one based end %------------------------------------------------------------------ function setSelectedImageIndex(this, index) % assumes 1-based index javaMethodEDT('setSelectedIndex', this.JImageList, index-1); end %------------------------------------------------------------------ function makeSelectionVisible(this, index) javaMethodEDT('ensureIndexIsVisible', this.JImageList, index-1); end %------------------------------------------------------------------ function [idx, jIdx] = getSelectedImageIndices(this) idx = double(this.JImageList.getSelectedIndices); jIdx = idx; % 0-based java index idx = idx+1; % make it one based end %------------------------------------------------------------------ function wipeFigure(this, fig) if ishandle(fig) set(fig,'HandleVisibility','on'); clf(fig); % clean out figure content zoom(fig, 'off'); pan(fig, 'off'); resetCallbacks(); % turn off the visibility set(fig,'HandleVisibility','off'); end %---------------------------------------- function resetCallbacks % remove any hanging callbacks set(fig,'WindowButtonMotionFcn',[]) set(fig,'WindowButtonUpFcn',[]) set(fig,'WindowButtonDownFcn',[]) set(fig,'WindowKeyPressFcn',[]) set(fig,'WindowKeyReleaseFcn',[]) % install listeners that temporarily block use of the % image browser iptaddcallback(fig,'WindowButtonDownFcn',@mouseClick); iptaddcallback(fig,'WindowButtonUpFcn',@mouseRelease); %---------------------------------------- function mouseClick(~,~) if ~this.IsInteractionDisabledByScrollCallback this.setBrowserInteractionEnabled(false); end end %---------------------------------------- function mouseRelease(~,~) if ~this.IsInteractionDisabledByScrollCallback this.setBrowserInteractionEnabled(true); drawnow(); end end end % end of resetCallbacks end % end of wipeFigure %------------------------------------------------------------------ % This function can suspend and resume interaction with the % image browser. This is particularly useful for synchronizing % Java UI with MATLAB's functions. %------------------------------------------------------------------ function setBrowserInteractionEnabled(this, isEnabled) scrollPane = this.JImageStrip.getImageScrollPane(); this.IsBrowserInteractionEnabled = isEnabled; if isEnabled javaMethod('enableImageScrolling', this.JImageStrip); else javaMethod('disableImageScrolling', this.JImageStrip); end javaMethodEDT('setEnabled', scrollPane, isEnabled); javaMethodEDT('setWheelScrollingEnabled', scrollPane, isEnabled); end end %====================================================================== % Methods for processing selection callback. %====================================================================== methods(Access = protected) %------------------------------------------------------------------ % Add image selection callback to the image browser to handle the % update of the image display when a user selects an image from the % list. %------------------------------------------------------------------ function addSelectionListener(this) if isempty(this.SelectionCallback) selectionListener = []; else selectionCallback = handle(this.JImageStrip.getSelectionCallback); % Connect the callback to a class function. The callback % class requires 'delayed' as the listener type. selectionListener = handle.listener(selectionCallback, ... 'delayed', @this.processImageSelectionCallBack); end % Cache the java object to prevent it from going out of scope. this.Misc.SelectionListener = selectionListener; end %------------------------------------------------------------------ % Processes user defined image selection callback. Uses % synchronization guards to prevent issues between JAVA and MATLAB % UI elements. %------------------------------------------------------------------ function processImageSelectionCallBack(this, es, ed) if this.Session.hasAnyItems this.preSelectionSyncGuard(); this.SelectionCallback(es,ed); % execute user defined callback this.postSelectionSyncGuard(); end end %------------------------------------------------------------------ % Sync guard for executing selection callback. %------------------------------------------------------------------ function preSelectionSyncGuard(this) if ~this.IsInteractionDisabledByScrollCallback drawnow(); setWaiting(this.ToolGroup, true); this.setBrowserInteractionEnabled(false); end end %------------------------------------------------------------------ % Sync guard for executing selection callback. %------------------------------------------------------------------ function postSelectionSyncGuard(this) if ~this.IsInteractionDisabledByScrollCallback drawnow(); this.setBrowserInteractionEnabled(true); setWaiting(this.ToolGroup, false); end end end end