0

I am trying to write an event handler for a dynamically created button in a FXML-defined form controller and it seems to work ok but as soon as I try accessing another element it fails.

For example this code works fine:

import java.util
import java.net.URL
import javafx.{scene => jfxs, fxml => jfxf}
import javafx.event.{EventHandler, ActionEvent}
import scalafx.Includes._

class  MainFormFxmlController extends jfxf.Initializable{
  @jfxf.FXML
  private var anchorPane: jfxs.layout.AnchorPane = _

  @jfxf.FXML
  private var slider: jfxs.control.Slider = _

  def initialize(url: URL, rb: util.ResourceBundle) {
    // the slider variable becomes null at this point if I observe it in the button event handler below and is not null id I don't
    slider.valueProperty.addListener{ (o: javafx.beans.value.ObservableValue[_ <: Number], oldVal: Number, newVal: Number) =>
      // ...
    }

    //...

    val button = new jfxs.control.Button("Button")

    jfxs.layout.AnchorPane.setRightAnchor(button, 63.0)

    jfxs.layout.AnchorPane.setTopAnchor(button, 14.0)

    anchorPane.getChildren.add(button)

   button.setOnAction(new EventHandler[ActionEvent]() {
      @Override
      def handle(event: ActionEvent) {
        println("123") // trying to access the slider variable here makes the whole app fail on load
      }
    })
  }
}

But it is enough to replace println("123") with if(slider != null) println("123") to make the application fail through throwing NullPointerException at the initialize function beginning.

What I am trying to reach is to adjust the slider value on the button press (while creating this particular button dynamically having the rest of the form loaded from FXML) and I thought that my mistake is in using a wrong way to do that but I have found out that a mere null check made with the slider variable causes the fail, not necessarily its value adjustment.

This looks quite curious to me as if the slider variable would be null I'd get just this fact with the check and if it would be inaccessible the application would fail to get compiled but what I get is different.

Ivan
  • 63,011
  • 101
  • 250
  • 382
  • Strange! Can we see the stack trace that you're getting. – ggovan May 07 '14 at 00:40
  • First of all it is better in all the aspects, @xiefei. Second - I write functional wherever I can (and where it does not make the logic more complex). Also this is not a real project, I am just exploring JavaFX in this case (and needless to say I don't want to code Java when there is Scala which is, as I have said, simply better). Also it is worth mentioning that using vars (rather than vals) is enforced by JavaFX. – Ivan May 07 '14 at 10:06
  • The first line which throws the actual exception is `slider.valueProperty.addListener` adding a listener to the slider value change event. The funny thing is that it works ok if I don't access slider as I have shown in the question code and breaks (slider happens to be null) if I do. Looks a lot like the quantum physics trick: the variable is changed to null by the fact that we are going to observe it in the future. – Ivan May 07 '14 at 10:45
  • I have found out that the effect takes place in any case if I access the slider variable anywhere after or inside the `slider.valueProperty.addListener` declaration. And the case of accessing it before it is even more weird: if I pass it to a function ads an argument then it (the argument) is not null but it's value can't be accessed (nothig happens), if I call a function that addresses the slider by name (not through an argument) then it is does not get executed, `speedSlider.valueProperty` gets reached and fails with NullPointerException. – Ivan May 07 '14 at 11:50
  • It seems like the FXMLLoader is not injecting the slider control. Check that you are using `fx:id="slider"` in your FXML. Otherwise please post your FXML, the problem may be in there. – ggovan May 08 '14 at 00:30

0 Answers0