Consider a slider/text-field:
When the user edits one, the other should update to match:
Can we express this in FRP-style?
val textField = new JTextField("50", 6)
val slider = new JSlider
val win = new JFrame("Test")
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
win.setLayout(new FlowLayout)
win.add(textField)
win.add(slider)
win.pack()
win.setLocationRelativeTo(null)
win.setVisible(true)
textField.text.foreachDelayed { text => implicit u =>
slider.value.updateLater(text map { text =>
Try(text.toInt) match {
case Failure(_) => slider.value.now
case Success(value) => value
}
})
} (slider.value.redoObserving)
slider.value.foreachDelayed { value => implicit u =>
textField.text.updateLater(value map (_.toString))
} (textField.text.redoObserving)
It turns out we can. But the code looks cyclical... how does it not produce an infinite loop?
foreachDelayed
comes to the rescue. It runs on the invalidation sweep. A signal can only be invalidated once before it is recalculated. So, the invalidation sweep can never produce an infinite loop; it simply traverses the graph of signals and invalidates each one it hits.
No comments:
Post a Comment