Reputation: 2386
Hi I'm looking for a clean way to produce a slider in matlab that allows me to adjust both ends of the range. Rather than dragging a single value I would like to be able to control the end points of the slider.
I can accomplish this using two sliders with Matlab but am wondering if there is any way that this can be combined into a single control
Example showing slider that I would like.
http://demos.jquerymobile.com/1.3.0-rc.1/docs/demos/widgets/sliders/rangeslider.html
Upvotes: 2
Views: 1526
Reputation: 2386
This can be accomplished through the use of a third party java jar using Swing along with Matlabs handle
and javacomponent
functions. I've adapted this from the JIDE Common Layer (Open Source)
Apparently Matlab can use standard Swing components. This is discussed on Undocumented Matlab.
You will end up with a slider that looks like so:
Here is the code:
function [hcomponent, hcontainer] = createSlider
% Add the 3rd Party Jar, should use static path but for the example, we
% use dynamic
javaaddpath('C:\PathToJars\jide_demo.jar')
import com.jidesoft.plaf.LookAndFeelFactory;
import com.jidesoft.swing.JideButton;
import com.jidesoft.swing.JideSwingUtilities;
import com.jidesoft.swing.RangeSlider;
import com.jidesoft.swing.SelectAllUtils;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
minField = JTextField();
maxField = JTextField();
SelectAllUtils.install(minField);
SelectAllUtils.install(maxField);
rangeSlider = RangeSlider(-100, 100, -100, 100);
rangeSlider.setPaintTicks(true);
rangeSlider.setPaintLabels(true);
rangeSlider.setPaintTrack(true);
rangeSlider.setRangeDraggable(false);
rangeSlider.setMajorTickSpacing(25);
rangeSlider = handle(rangeSlider, 'CallbackProperties');
function updateValues(~, ~)
minField.setText(num2str(rangeSlider.getLowValue()));
maxField.setText(num2str(rangeSlider.getHighValue()));
end
rangeSlider.StateChangedCallback = @updateValues;
minField.setText(num2str(rangeSlider.getLowValue()));
maxField.setText(num2str(rangeSlider.getHighValue()));
minPanel = JPanel(BorderLayout());
minPanel.add(JLabel('Min'), BorderLayout.BEFORE_FIRST_LINE);
minField.setEditable(false);
minPanel.add(minField);
maxPanel = JPanel(BorderLayout());
maxPanel.add(JLabel('Max', SwingConstants.TRAILING), BorderLayout.BEFORE_FIRST_LINE);
maxField.setEditable(false);
maxPanel.add(maxField);
textFieldPanel = JPanel(GridLayout(1, 3));
textFieldPanel.add(minPanel);
textFieldPanel.add(JPanel());
textFieldPanel.add(maxPanel);
panel = JPanel(BorderLayout());
panel.add(rangeSlider, BorderLayout.CENTER);
panel.add(textFieldPanel, BorderLayout.AFTER_LAST_LINE);
% hcontainer can be used to interact with panel like uicontrol
[hcomponent, hcontainer] = javacomponent(panel, [50, 50, 200, 100], gcf);
end
Upvotes: 2
Reputation: 919
First you need to create edit boxes on either side of your slider. Assuming that f
is the handle for the figure and h
is the handle for the slider you can do something like this:
endval1 = uicontrol('Parent',f,'Style','Edit','Position',[180,10,200,23],'String','Your number here', 'Callback', @(src,event)callback(src,event,h));
Of course change the position to what suits your needs and create two of them for top and bottom.
Notice how I have a callback with the following @(src,event)callback(src,event,h)
. Here I'm passing in the handle for the slider (h
) so I can modify it when I need.
Now for the callback:
function callback(src, event, h)
n = num2str(src.String);
set(h, 'Min', n);
end
That's an example of a callback. You will need another for the other end of course. Keep in mind that if your new min
value is larger than either the current slider value or max
value, it will not render until the remaining two are updated accordingly. The same of course applies to the max value.
Hope this helps.
Upvotes: 0