www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/+mbcgui/+widget/Spinner.m
classdef Spinner < mbcgui.widget.BasicContainer %SPINNER Spinner editor component % mbcgui.widget.Spinner is a numeric scalar editor component that % presents the value to be altered in an edit box alongside arrow buttons % that increment and decrement the value. Default rules are provided for % limiting the value to a given range, integer values, prime numbers or a % predefined list of values. % % Spinner properties: % CData - N-by-M-by-3 array of uint8 values that represent an % image. Each page of the array contains the red, % green and blue values respectively. When the CData % property is set, the ImageFile property is cleared. % ImageFile - Name of an image file to load. When the ImageFile % property is set, the CData property is cleared. % TooltipString - String to display as a tooltip for the icon. % % See also BasicContainer, Component. % Copyright 2009-2013 The MathWorks, Inc. properties(SetObservable, AbortSet, Dependent) %VALUE Value to display in the spinner % The Value property contains a scalar double value that the spinner % is currently editing. % % See also Rule, Min, Max, Callback. Value = 0; end properties(SetObservable, AbortSet) %RULE Input validation rule to apply % The Rule property controls the validation behaviour of the spinner. % It may be set to one of the following strings: % % real - The value can be any number between the Min and Max % property values. % int - The value can be any integer between the Min and Max % property values. % list - The value can be any number that is contained in the % vector of values in the List property % prime - The value can be any prime number between the Min and % Max property values. % % See also Value, Min, Max, List. Rule = 'real'; %MIN Minimum value for spinner % The Min property sets a lower bound on the value allowed in the % spinner. This applies when the Rule is set to real, int or prime. % % See also Max, Value. Min = -inf; %MAX Maximum value for spinner % The Max property sets an upper bound on the value allowed in the % spinner. This applies when the Rule is set to real, int or prime. % % See also Min, Value. Max = inf; %LIST List of allowed spinner values % The List property specifies the set of allowed values when the % spinner Rule is set to 'list'. % % See also Rule, Value. List = []; end properties(AbortSet) %CLICKINCREMENTMODE Method of incrementing and decrementing % The ClickIncrementMode controls how values are increased and % decreased when the Rule property is set to int or real and an arrow % button is pressed. This property must be set to one of the % following strings: % % 'linear' - (Default) The value is increased or decreased by the % value of the ClickIncrement property, i.e. Value -> % Value +/- ClickIncrement. % % 'log' - The value is multiplied or divided but the value of % the ClickIncrement property, i.e. Value -> Value *// % ClickIncrement. % 'auto' - The value is changed in a linear fashion but the % increment size is automatically chosen. In general, % the increment will scale with the order of magnitude % of the value. % % See also: ClickIncrement, Rule, Value. ClickIncrementMode = 'linear'; %CLICKINCREMENT Magnitude of increment and decrement % The ClickIncrement property contains the value that is used to % increase or decrease the value when an arrow button is pressed. % This must be set to a scalar numeric value. See the help for % ClickIncrementMode for more details on how this value is used. % % See also: ClickIncrementMode, Rule, Value. ClickIncrement = 1; %FONTWEIGHT Set font weight for the Spinner. % The FontWeight property allows you to set the text in the edit box % to be either 'normal' or 'bold'. FontWeight = 'normal'; %TOOLTIPSTRING Tooltip to display over the icon % Setting the TooltipString will cause the specified string to be % displayed when the use hovers their mouse over the icon. TooltipString = ''; %CALLBACK Function to execute when the value is changed % The Callback property can be set to any standard callback array and % will be called when the ValueEdited event is fired. % % See also ValueEdited. Callback = []; end properties(AbortSet, Dependent) %UIContextMenu Handle to a uicontextmenu object % The UIContextMenu property allows you to set a context menu that % will appear when a Spinner is right-clicked. UIContextMenu end properties(Access='private') % Value that backs the dependent Value property. Having a separate % backing store gives us the option of value access without going % through get.Value. LocalValue = 0; % Flag that indicates whether the current value came from the user and % is hence not validated, or whether it came from the java peer and % hence has had the rules applied. LocalValueValidated = true; % Flag that signals the set.Value code not to pass on a new value to % the java peer. AllowPrivateValueSet = false; % Listener that executes the Callback property CallbackListener = []; end events ValueEdited end methods function obj = Spinner(varargin) %SPINNER Construct a new Spinner object % H = mbcgui.widget.Spinner(PROP, VAL, ...) constructs a new Spinner % object with its properties set to the values specified by the input % list of property-value pairs. obj@mbcgui.widget.BasicContainer(varargin{:}); P = com.mathworks.toolbox.mbc.gui.peer.SpinnerPeer; obj.ContentHandle = mbcwidgets.javacomponent(P, ... 'Parent', obj.Parent, ... 'Enable', obj.Enable, ... 'Visible', obj.Visible, ... 'Position', obj.Position); P.setTooltipText(obj.TooltipString); obj.createSpinnerModel; P.setStepMode(upper(obj.ClickIncrementMode)); P.setStepSize(obj.ClickIncrement); obj.updateFontWeight; cb =handle(obj.ContentHandle.Peer.getValueCallback); L = handle.listener(cb, 'delayed', {@iValueChange, obj}); obj.storeListeners(L); end function set.TooltipString(obj, tt) if obj.isConstructed obj.ContentHandle.Peer.setTooltipText(tt); end obj.TooltipString = tt; end function set.Value(obj, val) if ~isscalar(val) || ~isnumeric(val) error(message('mbc:widget:Spinner:InvalidPropertyValue')); end if ~obj.AllowPrivateValueSet && obj.isConstructed % Push the value to the java peer switch obj.Rule case 'int' obj.ContentHandle.Peer.setLongValue(val); case 'prime' obj.ContentHandle.Peer.setPrimeValue(val); otherwise obj.ContentHandle.Peer.setDblValue(val); end end % Store the value but mark it as not validated. obj.LocalValue = val; obj.LocalValueValidated = false; end function val = get.Value(obj) if obj.LocalValueValidated ... || ~obj.isConstructed ... || ~obj.ContentHandle.Peer.isComponentConstructed val = obj.LocalValue; else % Get value from java val = javaMethodEDT('getValue', obj.ContentHandle.Peer.getSpinner); end end function set.Rule(obj, rule) if ~any(strcmp(rule, {'real', 'int', 'list', 'prime'})); error(message('mbc:widget:Spinner:InvalidPropertyValue1')); end obj.Rule = rule; obj.LocalValueValidated = false; obj.createSpinnerModel; end function set.Min(obj, val) if ~isscalar(val) || ~isnumeric(val) error(message('mbc:widget:Spinner:InvalidPropertyValue2')); end obj.Min = val; obj.LocalValueValidated = false; obj.updateRange; end function set.Max(obj, val) if ~isscalar(val) || ~isnumeric(val) error(message('mbc:widget:Spinner:InvalidPropertyValue3')); end obj.Max = val; obj.LocalValueValidated = false; obj.updateRange; end function set.List(obj, val) if ~isvector(val) || ~isnumeric(val) error(message('mbc:widget:Spinner:InvalidPropertyValue4')); end obj.List = val; obj.LocalValueValidated = false; if obj.isConstructed obj.ContentHandle.Peer.setList(val); end end function set.ClickIncrementMode(obj, val) if ~any(strcmp(val, {'linear', 'log', 'auto'})); error(message('mbc:widget:Spinner:InvalidPropertyValue5')); end obj.ClickIncrementMode = val; if obj.isConstructed obj.ContentHandle.Peer.setStepMode(upper(val)); end end function set.ClickIncrement(obj, val) if ~isscalar(val) || ~isnumeric(val) error(message('mbc:widget:Spinner:InvalidPropertyValue6')); end obj.ClickIncrement = val; if obj.isConstructed obj.ContentHandle.Peer.setStepSize(val); end end function set.UIContextMenu(obj, val) if ~isempty(val) && (~isscalar(val) || ~isgraphics(val, 'uicontextmenu')) error(message('mbc:widget:Spinner:InvalidPropertyValue7')); end obj.ContentHandle.UIContextMenu = val; end function val = get.UIContextMenu(obj) val =obj.ContentHandle.UIContextMenu; end function set.FontWeight(obj, val) if ~any(strcmp(val, {'normal', 'bold'})); error(message('mbc:widget:Spinner:InvalidPropertyValue8')); end obj.FontWeight = val; obj.updateFontWeight; end function set.Callback(obj, val) if isempty(val) obj.CallbackListener = []; else obj.CallbackListener = event.listener(obj, 'ValueEdited', ... mbcutils.callback(@iCallBack, val)); end obj.Callback = val; end function increment(obj, N) %INCREMENT Increment the spinner by a single step % INCREMENT(OBJ) sets the spinner's value to that which would be % produced if the user clicked a single time on the "up" arrow % button. % % INCREMENT(OBJ, NUM) increments the spinner NUM times. if nargin<2 N = 1; end obj.ContentHandle.Peer.increment(N); obj.LocalValueValidated = false; end function decrement(obj, N) %DECREMENT Decrement the spinner by a single step % DECREMENT(OBJ) sets the spinner's value to that which would be % produced if the user clicked a single time on the "down" arrow % button. % % DECREMENT(OBJ, NUM) decrements the spinner NUM times. if nargin<2 N = 1; end obj.ContentHandle.Peer.decrement(N); obj.LocalValueValidated = false; end end methods(Hidden) % Debug helper method function P = getPeer(obj) P = obj.ContentHandle.Peer; end end methods(Access=protected) function setEnable(obj, En) % If the enable setting is 'inactive' we interpret this as 'off'. The % Java peer does not support 'inactive'. if strcmp(En, 'inactive') En = 'off'; end obj.setEnable@mbcgui.widget.BasicContainer(En); end end methods(Access=private) function createSpinnerModel(obj) if obj.isConstructed % Use the LocalValue cache - it does not matter if it is not % validated because the construction of a new model will do the % validation anyway. switch(obj.Rule) case 'real' obj.ContentHandle.Peer.createRealModel(obj.LocalValue, obj.Min, obj.Max); case 'int' obj.ContentHandle.Peer.createIntModel(obj.LocalValue, obj.Min, obj.Max); case 'list' obj.ContentHandle.Peer.createListModel(obj.LocalValue, obj.List); case 'prime' obj.ContentHandle.Peer.createPrimeModel(obj.LocalValue, obj.Min, obj.Max); otherwise error(message('mbc:widget:Spinner:InvalidPropertyValue9')); end end end function updateRange(obj) if obj.isConstructed switch(obj.Rule) case 'real' obj.ContentHandle.Peer.setDblRange(obj.Min, obj.Max); case 'int' obj.ContentHandle.Peer.setLongRange(obj.Min, obj.Max); case 'prime' obj.ContentHandle.Peer.setPrimeRange(obj.Min, obj.Max); otherwise % Range is not used by the list mode end end end function updateFontWeight(obj) if obj.isConstructed if strcmpi(obj.FontWeight, 'bold') W = java.awt.Font.BOLD; else W = java.awt.Font.PLAIN; end obj.ContentHandle.Peer.setFontStyle(W); end end function updateValue(obj, val, isUserEdit) % Update the Value property with a new validated value. This goes % through the public Value interface to ensure a property change % event is sent. % First validate the previous value so that get.Value does not go % to java. obj.LocalValueValidated = true; % Now set the value but do not push it back to the java peer. obj.AllowPrivateValueSet = true; obj.Value = val; obj.AllowPrivateValueSet = false; % Now re-mark the value as validated. obj.LocalValueValidated = true; % Fire a value edit event if the event actually came from a user % input action. Even though the value may not appear to have % changed, this often happens after a succession of non-input % events that *have* changed the value. if isUserEdit notify(obj, 'ValueEdited'); end end end end % Callback from the java peer function iValueChange(~, evt, obj) obj.updateValue(evt.JavaEvent.getValue, ... evt.JavaEvent.isUserGenerated && ~evt.JavaEvent.isValueChanging) end function iCallBack(src, ~, callback) xregcallback(callback, src, []); end