Slider usage questions

I have 2 questions about setting up sliders.

  1. Is there a way to define the background image for the slider button other than through a style? Slider doesn’t appear to expose the button created in order to set the background.

  2. Is there a way to add a Command to the slider so that the application can perform some action when the user presses the slider? For a normal button, the button.addCommands is available, but it doesn’t appear to be available for sliders. When the user selects the slider, I would like to display some other objects on the screen and then hide them when the slider is released.

Adding a mouseListener to the slider works when the user clicks on the slider background, but when the user clicks on the button in the slider, it looks like the button consumes the event and the slider mouseListener doesn’t receive the event.

I don’t think there is a way to retrieve the slider button so that I could add a command to it.

I think I need to provide a way to get the buttons for the slider. I just hadn’t needed it yet but it will be trivial to add and I can see a few use-cases for it.

Latest version (SVN and I’ve uploaded a new release to the release dir) has accessors for all of Slider’s sub-parts.

Do note: another change to IconComponent may break your code (I think from other conversations) because the scale is now a Vector2f.

@pspeed

With the access to the slider’s sub-parts, the setBackground on the thumb button doesn’t appear to work. The increment button works fine, but not thumb. Maybe because it is simply added to the range node and not actually a Lemur child in the layout?

If I use styles to define the background of the thumb, it works fine.

Also, in the code below, I expected the DynamicInsetsComponent to center the slider, but it actually fills the entire width. Any idea why?

Code below is what I was using to test the thumb background and the slider width.

[java]
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.math.Vector3f;
import com.simsilica.lemur.Axis;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Command;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.DefaultRangedValueModel;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Slider;
import com.simsilica.lemur.component.BorderLayout;
import com.simsilica.lemur.component.DynamicInsetsComponent;
import com.simsilica.lemur.component.IconComponent;
import com.simsilica.lemur.component.TbtQuadBackgroundComponent;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SliderTest extends SimpleApplication {
private static final Logger logger = Logger.getLogger(SliderTest.class.getName());

public static void main(String[] args) {
    SliderTest app = new SliderTest();
    app.start();
}

@Override
public void simpleInitApp() {
    GuiGlobals.initialize(this);

    Container mainContainer = new Container(new BorderLayout());
    mainContainer.setLocalTranslation(0f, settings.getHeight(), 0f);
    mainContainer.setPreferredSize(
            new Vector3f(settings.getWidth(), settings.getHeight(), 0f));
    getGuiNode().attachChild(mainContainer);

    float sliderBackgroundWidth = (float)(settings.getWidth()) / 2f;
    float sliderBackgroundHeight = (float)(settings.getHeight()) / 10f;

    Slider slider = new Slider(new DefaultRangedValueModel(-10, 10, 0), Axis.X);
    slider.setPreferredSize(
            new Vector3f(sliderBackgroundWidth, sliderBackgroundHeight, 0f));
    slider.setInsetsComponent(new DynamicInsetsComponent(0.5f, 0.5f, 0.5f, 0.5f));

    slider.setBackground(
            TbtQuadBackgroundComponent.create(
            "Interface/SliderBackground.png", 1f,
            10, 20, 246, 10,
            0f, false));

    slider.getThumbButton().setText("");
    slider.getThumbButton().setBackground(
            new IconComponent("Interface/SliderPosition.png"));

    slider.getIncrementButton().setText("");
    slider.getIncrementButton().setBackground(
            new IconComponent("Interface/SliderPosition.png"));

    slider.getThumbButton().addCommands(Button.ButtonAction.Down, new Command() {
        public void execute(Object source) {
            logger.log(Level.INFO, "spinSlider Button Down");
        }
    });
    slider.getThumbButton().addCommands(Button.ButtonAction.Up, new Command() {
        public void execute(Object source) {
            logger.log(Level.INFO, "spinSlider Button Up");
        }
    });

    mainContainer.addChild(slider, BorderLayout.Position.South);

}

}
[/java]

Sorry it took me so long to answer this… I parked it in my to-do pile but forgot to look at the pile. :slight_smile:

@iwgeric said: @pspeed

With the access to the slider’s sub-parts, the setBackground on the thumb button doesn’t appear to work. The increment button works fine, but not thumb. Maybe because it is simply added to the range node and not actually a Lemur child in the layout?

If I use styles to define the background of the thumb, it works fine.

Very strange… the layout (or lack thereof) shouldn’t be an issue because a) it works when you do it through styles, and b) you can set the background of a Button added directly to the guiNode without issue.

Oooh… though I looked at the code and there is a comment where I force layout the button because it isn’t managed by a layout. I should probably add a special method for these cases but in the mean time, you might try:
b.setSize(b.getSize());
…to force it to update itself.

I may look into ways to get it to at least automatically reset its component stack (I thought it already should).

@iwgeric said: Also, in the code below, I expected the DynamicInsetsComponent to center the slider, but it actually fills the entire width. Any idea why?

Not sure. You might try swapping the line adding the dynamic insets for the one setting the preferred size. I’m kind of grasping at straws, though.

Another point of interest would be what the preferred size was before you overrode it and what exact values you are setting it to.

@pspeed said: b.setSize(b.getSize());

Regarding this… I will point out that normally you’d do something like:
b.setSize(b.getPreferredSize());
…but in this case, I’ve already done that so resetting the size to itself should be enough to trigger a recalculation of the component stack.

@pspeed

Sorry for the late response. I ended using the code below to make it work. b.getsize() was returning all 0’s and wasn’t forcing the background to be displayed, but the code below works.

[java]
spinSlider.getThumbButton().setText(null);
spinSlider.getThumbButton().setBackground(
LemurHelpers.createScaledIcon(“Interface/SliderPosition.png”,
sliderThumbWidth, sliderThumbHeight));
spinSlider.getThumbButton().setPreferredSize(
new Vector3f(sliderThumbWidth, sliderThumbHeight, 0f));
spinSlider.getThumbButton().setSize(
spinSlider.getThumbButton().getPreferredSize());
[/java]

Returned all 0s before or after you set the preferred size?

Anyway, glad you found a way to make it work.