Dave
Dave

Reputation: 2386

Range Based Slider (Control both Ends)

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

Answers (2)

Dave
Dave

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:

Slider Example

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

pragmatist1
pragmatist1

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

Related Questions