This discussion is archived
8 Replies Latest reply: Apr 8, 2013 8:50 AM by 1001443 RSS

Slider Listener

1001443 Newbie
Currently Being Moderated
I have 8 slider controls in an HBox and I want to add a listener to each one that will somehow let me know which slider it is. Each slider represents a channel for a device, and although I can add a listener that passes back a Number which represents the new value of the slider, it doesn't tell me which slider it is. Although I can add an int that represents the channel number of the slider to its user data, there doesn't seem to be a way of extracting it from the type returned (Number). The code looks like this:

HBox hbox = new HBox(8); // spacing
for(int i = 0; i < gain.length; i++) // for each output
{
gain[i] = SetLook(new Slider(0,100,0));
gain.setUserData(i+1); // the input number
hbox.getChildren().add(gain[i]);
gain[i].valueProperty().addListener(new ChangeListener<Number>()
{
@Override
public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue)
{
// makeGainChange((int)newValue.getUserData(),newValue.intValue());
makeGainChange(1, newValue.intValue());
}
});
}
  • 1. Re: Slider Listener
    James_D Guru
    Currently Being Moderated
    HBox hbox = new HBox(8); // spacing
    for(int i = 0; i < gain.length; i++) // for each output
    {
      gain = SetLook(new Slider(0,100,0));
      // gain.setUserData(i+1); // the input number
      hbox.getChildren().add(gain);
    
      // Add this:
      final int inputNumber = i+1 ;
     
      gain.valueProperty().addListener(new ChangeListener<Number>()
      {
        @Override
        public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue)
        {
          // now pass the input number to your method:
          makeGainChange(inputNumber, newValue.intValue());
        }
      });
    }
    Edited by: James_D on Apr 7, 2013 12:16 PM
  • 2. Re: Slider Listener
    shakir.gusaroff Expert
    Currently Being Moderated
    Hi. I would do it like this:
     final SimpleIntegerProperty  userD = new SimpleIntegerProperty(0);
            HBox hbox = new HBox(8); // spacing
            for (int i = 0; i < gain.length; i++) // for each output
            {
                gain = SetLook(new Slider(0, 100, 0));
                userD.set(i + 1);
           //     gain.setUserData(i + 1); // the input number
                hbox.getChildren().add(gain);
                gain.valueProperty().addListener(new ChangeListener<Number>() {
                    @Override
                    public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue) {
                       makeGainChange(userD.get(),newValue.intValue());
                       // makeGainChange(1, newValue.intValue());
                    }
                });
            }
  • 3. Re: Slider Listener
    James_D Guru
    Currently Being Moderated
    shakir.gusaroff wrote:
    Hi. I would do it like this:
    That doesn't actually work.
    import javafx.application.Application;
    import javafx.beans.property.SimpleIntegerProperty;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.geometry.Orientation;
    import javafx.scene.Scene;
    import javafx.scene.control.Slider;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;
    
    public class SliderListenerTest extends Application {
    
      @Override
      public void start(Stage primaryStage) {
        final SimpleIntegerProperty userD = new SimpleIntegerProperty(0);
        final Slider[] gain = new Slider[8];
        HBox hbox = new HBox(8); // spacing
        for (int i = 0; i < gain.length; i++) // for each output
        {
          gain[i] = setLook(new Slider(0, 100, 0));
          userD.set(i + 1);
          // gain.setUserData(i + 1); // the input number
          hbox.getChildren().add(gain);
    gain[i].valueProperty().addListener(new ChangeListener<Number>() {
    @Override
    public void changed(ObservableValue<? extends Number> ov,
    Number oldValue, Number newValue) {
    makeGainChange(userD.get(), newValue.intValue());
    // makeGainChange(1, newValue.intValue());
    }
    });
    }
    primaryStage.setScene(new Scene(hbox, 600, 600));
    primaryStage.show();
    }

    private void makeGainChange(int inputNumber, int value) {
    System.out.printf("Input %d changed to %d%n", inputNumber, value);
    }

    private Slider setLook(Slider slider) {
    slider.setOrientation(Orientation.VERTICAL);
    return slider;
    }

    public static void main(String[] args) {
    launch(args);
    }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
  • 4. Re: Slider Listener
    shakir.gusaroff Expert
    Currently Being Moderated
    Thank you John for pointing that out.
    The userD property should be inside the loop:
    for (int i = 0; i < gain.length; i++) // for each output
        {
         final SimpleIntegerProperty userD = new SimpleIntegerProperty(0);
          gain[i] = setLook(new Slider(0, 100, 0));
    The question was how to set the user data and retrieve later these data.
    User data can be set on the node. He is trying to get the user data from Number, which is illegal.
    I would prefer SimpleIntegerProperty as user data instead of int because you do not need to cast.
  • 5. Re: Slider Listener
    James_D Guru
    Currently Being Moderated
    You can use the cast with a Number; it would just require the correct cast. For example
    gain.setUserData(i+1);
    ...
    makeGainChange(((Number)newValue.getUserData()).intValue(),newValue.intValue());
    But why add that (admittedly small) overhead, and use up the userData slot, when you can solve the problem with a local variable?
  • 6. Re: Slider Listener
    1001443 Newbie
    Currently Being Moderated
    James,

    I tried your example to get the user data, but the compiler complains with:
    "The method getUserData() is undefined for the type Number"

    This emphasizes my lack of understanding about the mechanisms behind how the object is passed to the 'changed' method, and how the variable 'gainNumber' is unique for each call to the 'changed' method. Is this particular feature unique to JavaFX or part of the feature set introduced since Java 1.4?
  • 7. Re: Slider Listener
    James_D Guru
    Currently Being Moderated
    Oh, yeah, sorry; you need to call getUserData() on the Slider, not on the value if you want to use that mechanism.

    The control is not directly passed to the changed(...) method. You're listening for changes to an ObservableValue - in this case it's the valueProperty of the slider which is a DoubleProperty - and a reference to that ObservableValue is passed to the changed(...) method. You could get the slider from the ObservableValue parameter to the changed(...) method, but it's not very clean: cast the observableValue to a Property<Number>, call getBean() on the property, and cast the result of that to a Node. Then call getUserData() on the Node. But like I said, I wouldn't do it like that anyway. The point is you already have a reference to the slider, or any other data you need. Just arrange for that data to be available to your listener.

    In the solution
    for(int i = 0; i < gain.length; i++) // for each output
    {
      gain[i] = SetLook(new Slider(0,100,0));
      // gain.setUserData(i+1); // the input number
      hbox.getChildren().add(gain);
     
      // Add this:
      final int inputNumber = i+1 ;
     
      gain.valueProperty().addListener(new ChangeListener<Number>()
    {
    @Override
    public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue)
    {
    // now pass the input number to your method:
    makeGainChange(inputNumber, newValue.intValue());
    }
    });
    }
    each time you go through the loop, i holds the current loop index. You assign i+1 to a final variable inputNumber (declared for each iteration, so there is effectively a new final variable for each iteration of the loop). The anonymous inner class assigned as the listener to your value property (again, one listener each time you iterate through the loop) captures the final variable value. The way this works (as I understand it) is that the compiler effectively creates a class whose constructor takes a parameter corresponding to the final variable that is captured. There's nothing specific to JavaFX here (there's no specific JavaFX syntax, it's all standard Java code) and nothing "new" to Java 1.5.0; anonymous inner classes were introduced in Java 1.1 and have always been able to capture local final variables.
    
    If you need access to the control, you can do the same trick:
    for(int i = 0; i < gain.length; i++) // for each output
    {
    final Slider slider = new Slider(0, 100, 0);
    gain[i] = SetLook(slider); // I'm assuming SetLook(slider) configures the slider and returns a reference to it?
    hbox.getChildren().add(gain);

    // Add this:
    final int inputNumber = i+1 ;

    gain[i].valueProperty().addListener(new ChangeListener<Number>()
    {
    @Override
    public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue)
    {
    // You can access the control 'slider' if you need to...
    // now pass the input number to your method:
    makeGainChange(inputNumber, newValue.intValue());
    }
    });
    }
    If you prefer named classes, the equivalent would look something like this. I prefer anonymous classes but this might make what's happening clearer to you:
    for(int i = 0; i < gain.length; i++) // for each output
    {
    gain[i] = SetLook(new Slider(0,100,0));
    hbox.getChildren().add(gain);

    gain[i].valueProperty().addListener(new GainValueListener(i+1));

    }
    // ....

    // Inner class (inside the same class as the code above)
    private class GainValueListener implements ChangeListener<Number> {
    private final int gainNumber ;
    GainValueListener(int number) {
    this.gainNumber = number ;
    }
    @Override
    public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue) {
    makeGainChange(gainNumber, newValue.intValue());
    }
    }
    Edited by: James_D on Apr 8, 2013 8:16 AM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
  • 8. Re: Slider Listener
    1001443 Newbie
    Currently Being Moderated
    James,

    Thank you very much for clearing up my confusion with regards to final variables and anonymous inner classes. Your example replacing the anonymous inner class with an actual inner class was priceless. With regards to the gain variable, here's the actual code section:
        HBox hbox = new HBox(8); // spacing
        for(int i = 0; i < gain.length; i++) // for each output
        {
          gain[i] = SetLook(new Slider(0,100,0));
          hbox.getChildren().add(gain);
    final int gainNumber = i+1;
    gain[i].valueProperty().addListener(new ChangeListener<Number>()
    {
    @Override
    public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue)
    { makeGainChange(gainNumber, newValue.intValue());}
    });
    }
    ...
    }

    private Slider SetLook (Slider t)
    {
    t.setOrientation(Orientation.VERTICAL);
    t.setShowTickMarks(true);
    t.setShowTickLabels(true);
    t.setMajorTickUnit(10);
    t.setBlockIncrement(2);
    return t;
    }
    I'm using a gain array because I'll be implementing an IP server thread in order to allow clients to set the gain for each input. The array will make it easier to control the sliders in this case. Think of the UI here as a front panel to the device as well as a secondary means of controlling it. This application is a going to be a teaching aid where developing the client side (on a control system) using a touch panel is the real goal. This is merely a simulator of an IP controllable audio switcher.
    
    Edited by: LCubed on Apr 8, 2013 8:46 AM
    
    Edited by: LCubed on Apr 8, 2013 8:47 AM
    
    Edited by: LCubed on Apr 8, 2013 8:49 AM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points