need help creating my own range slider class

3 views (last 30 days)
Andre Zeug
Andre Zeug on 5 Aug 2017
Edited: Yair Altman on 29 Sep 2017
Dear all,
would like to combine JRangeSlider and 'uipushbuttons' to allow single step value change. I think creating a class would be the appropriate way, however have no experience how to do.
I created some function as source for the class. The function itself however does not work correctly but I hope one can catch the idea.
Can anybody show how to create a class?
Or are there alternative solutions?
Thanks
Andre
.m:
function hObj = myRangeSlider(varargin)
%%parse Input
p = inputParser;
p.StructExpand = true; % if we allow parameter structure expanding
%p.CaseSensitivity = false; % enables or disables case-sensitivity when matching entries in the argument list with argument names in the schema. Default, case-sensitive matching is disabled (false).
p.KeepUnmatched = true; % controls whether MATLAB throws an error (false) or not (true) when the function being called is passed an argument that has not been defined in the inputParser schema for this file.
p.FunctionName = ['myRangeSlider']; % stores a function name that is to be included in error messages that might be thrown in the process of validating input arguments to the function.
addParameter(p,'Parent', gcf, @(x)(ishandle(x)));
addParameter(p,'Callback', '', @(x)~isempty(x));
addParameter(p,'Position', [10 10 100 16], @(x)isvector(x));
addParameter(p,'Min', 0, @(x)isscalar(x));
addParameter(p,'Max', 100, @(x)isscalar(x));
addParameter(p,'lowValue', 20, @(x)isscalar(x));
addParameter(p,'highValue', 70, @(x)isscalar(x));
parse(p,varargin{:});
p = p.Results;
pos = p.Position;
%Buttons only for horizontal slider
pos1 = [pos(1)+.00*pos(3) pos(2) .05*pos(3) pos(4)];
pos2 = [pos(1)+.05*pos(3) pos(2) .05*pos(3) pos(4)];
pos3 = [pos(1)+.10*pos(3) pos(2) .80*pos(3) pos(4)];
pos4 = [pos(1)+.90*pos(3) pos(2) .05*pos(3) pos(4)];
pos5 = [pos(1)+.95*pos(3) pos(2) .05*pos(3) pos(4)];
figure(p.Parent)
%%Range slider
% thanks Yair Altman: http://undocumentedmatlab.com/blog/sliders-in-matlab-gui
jRangeSlider = com.jidesoft.swing.RangeSlider(p.Min,p.Max,p.lowValue,p.highValue); % min,max,low,high
jRangeSlider = javacomponent(jRangeSlider, pos3, p.Parent);
set(jRangeSlider, 'PaintTicks',false, 'PaintLabels',false,'StateChangedCallback',@updateRangeSlider);
%%Buttons
hPB1 = uicontrol('Parent', p.Parent, 'Style', 'pushbutton', 'Units', 'Pixel', ...
'Position', pos1,'String', '<', 'HorizontalAlignment', 'left', 'Callback', {@myRangeSliderPushButton,1}, ...
'Tooltip','Lower lowValue');
hPB2 = uicontrol('Parent', p.Parent, 'Style', 'pushbutton', 'Units', 'Pixel', ...
'Position', pos2,'String', '>', 'HorizontalAlignment', 'left', 'Callback', {@myRangeSliderPushButton,2}, ...
'Tooltip','Lower lowValue');
hPB4 = uicontrol('Parent', p.Parent, 'Style', 'pushbutton', 'Units', 'Pixel', ...
'Position', pos4,'String', '<', 'HorizontalAlignment', 'left', 'Callback', {@myRangeSliderPushButton,4}, ...
'Tooltip','Lower lowValue');
hPB5 = uicontrol('Parent', p.Parent, 'Style', 'pushbutton', 'Units', 'Pixel', ...
'Position', pos5,'String', '>', 'HorizontalAlignment', 'left', 'Callback', {@myRangeSliderPushButton,5}, ...
'Tooltip','Lower lowValue');
hObj.lowValue = jRangeSlider.getLowValue;
hObj.highValue = jRangeSlider.getHighValue;
hObj.jRangeSlider = jRangeSlider;
function myRangeSliderPushButton(hObject, event, b)
switch b
case 1
if hObj.jRangeSlider.getLowValue > hObj.jRangeSlider.getMinimum
hObj.jRangeSlider.getLowValue = hObj.jRangeSlider.getLowValue-1;
end
case 2
if hObj.jRangeSlider.getLowValue < hObj.jRangeSlider.getLowValue
hObj.jRangeSlider.getLowValue = hObj.jRangeSlider.getLowValue+1;
end
case 4
if hObj.jRangeSlider.getHighValue > hObj.jRangeSlider.getLowValue
hObj.jRangeSlider.getHighValue = hObj.jRangeSlider.getHighValue-1;
end
case 5
if hObj.jRangeSlider.getHighValue < hObj.jRangeSlider.getMaximum
hObj.jRangeSlider.getHighValue = hObj.jRangeSlider.getHighValue+1;
end
end
hObj.jRangeSlider = jRangeSlider;
end
function updateRangeSlider(varargin)
hObj.lowValue = jRangeSlider.getLowValue;
hObj.highValue = jRangeSlider.getHighValue;
fprintf('min = %.2f \t max = %.2f \n',jRangeSlider.getLowValue, jRangeSlider.getHighValue)
hObj.jRangeSlider = jRangeSlider;
end
end
can be executed:
hFig = figure;
hObj = myRangeSlider('Parent', hFig, 'Callback', @myRangeSlider.updateRangeSlider, ... 'Units', 'Pixel',
'Position', [10 10 200 16], 'Min',0, 'Max', 100, 'Visible', 'on', ...
'lowValue',20,'highValue',70);

Answers (1)

Chris Perkins
Chris Perkins on 8 Aug 2017
Hi Andre,
There seem to be two separate questions.
First, regarding MATLAB classes.
The following link provides a good introduction, with an example, on how to make classes in MATLAB. https://www.mathworks.com/help/matlab/matlab_oop/create-a-simple-class.html
You can integrate this function, along with any others you might want, into your custom class as shown in the example.
Second, regarding the code provided - there seems to be two issues.
A) In function "myRangeSliderPushButton", you seem to be trying to set the low and high values of hObj with the function call "getLowValue" and "getHighValue". However, these methods return the current number, rather than setting that number. If you change the four lines of the form
hObj.jRangeSlider.getLowValue = hObj.jRangeSlider.getLowValue-1;
to the form
hObj.jRangeSlider.setLowValue (hObj.jRangeSlider.getLowValue-1);
It will update the current high and low values, and you should no longer get the error message "No public property getLowValue exists for class ..."
For more information, see the documentation link for the Java class RangeSlider: http://www.jidesoft.com/javadoc/com/jidesoft/swing/RangeSlider.html
B) Also in function "myRangeSliderPushButton", in case 2, you are checking if a value is less than itself (both left and right hand sides are the same value, 'hObj.jRangeSlider.getLowValue'), which can never be true.
Instead of the conditional check
if hObj.jRangeSlider.getLowValue < hObj.jRangeSlider.getLowValue
you should have the conditional check
if hObj.jRangeSlider.getLowValue < hObj.jRangeSlider.getHighValue
Once I made these changes, your slider seems to work fine.
  2 Comments
Andre Zeug
Andre Zeug on 8 Aug 2017
Dear Chris,
thanks a lot correcting my code. Indeed I mixed up 'get' and 'set'.
Will have a look how to 'convert' the function to a class. From a brief look to your link two questions araise:
  1. how to handle Matlab's 'propertyName'/'propertyValue' concept, when defining classes.
  2. how to inherit (e.g. uicontrol) properties and methods such that I do not need to handle all properties by my new class.
I had the hope 'maintaning' properties from uicontrol as:
hObj = myRangeSlider(...,'BackgroundColor', 'w',...)
without specifically handle the property 'BackgroundColor' in my class.
same for
set(hObj, 'BackgroundColor', [.9 .9 .9])
Is this possible at all?
Sorry for asking such basic questions
Andre
Yair Altman
Yair Altman on 29 Sep 2017
Edited: Yair Altman on 29 Sep 2017
Andre - take a look at my uicomponent utility on the File Exchange, that might do what you want: https://www.mathworks.com/matlabcentral/fileexchange/14583-uicomponent-expands-uicontrol-to-all-java-classes

Sign in to comment.

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!