1

I'm trying to use ScalaFX to draw tree diagrams - nodes with arrows between them.

To make the layout easy, I'm nesting each branch using standard ScalaFX layout containers (e.g. HBoxes and VBoxes).

I can't figure out a good way to draw the lines, in particular binding the line start and end properties to the properties of the nodes they connect. If they were in the same container, it would be easy, I could just do something like

startX <== start.centerX

However, if they are in different containers, it doesn't work - I need to find scene-relative components.

Minimal example attached - really, I'm looking for something to replace the bindings in Arrow with something that works. I'd like - if possible - to stay in the nice clean ScalaFX listener style of doing things.

EDIT: the current behaviour is to draw a horizontal line from the top node leftwards - coordinates aren't getting translated to match the scene coordinates of the containers they are in, and I can't figure out how to do that.

Current behaviour

package com.moseph.artifacts.visualisation

import scalafx.Includes._
import scalafx.scene.layout._
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.shape.Circle
import scalafx.scene.shape.Line
import javafx.geometry.Insets

object TestVisualiser extends JFXApp { self =>
  val nodes = new Nodes
  stage = new JFXApp.PrimaryStage {
    title = "Test Visualiser"; width = 500; height = 1000
    scene = new Scene {
      root = new StackPane {
      content = Seq( nodes , new Pane {
       content = Seq( new Arrow( nodes.a.circ, nodes.b.circ ), new Arrow( nodes.a.circ, nodes.b.circ )) 
      } ) 
      }
    }
  }
}

class Nodes extends VBox { nodes =>
  minWidth = 100
  val a = new TNode
  val b = new TNode
  val c = new TNode
  val d = new TNode
  content = Seq( a, new HBox{ content = Seq( b, c, d) } )
}

class TNode extends Pane { node =>
  val circ = new Circle { radius = 10; centerX <== node.width/2; centerY = 5}
  content = circ
  padding = new Insets(50)
}

class Arrow(from:Circle,to:Circle) extends Line {
  startX <== from.centerX + from.translateY + from.layoutY
  startY <== from.centerY + from.translateY + from.layoutY
  endX <== to.centerX + to.translateX + to.layoutX
  endY <== to.centerY + to.translateY + to.layoutY
}
mo-seph
  • 6,073
  • 9
  • 34
  • 35
  • Have a look at the `BoundLine` in the sample [Cubic Curve Manipulator](http://stackoverflow.com/questions/13056795/cubiccurve-javafx). – jewelsea Feb 04 '14 at 18:14
  • That would work if they were in the same container - it's essentially what the current Arrow class is doing. Unfortunately, I'm trying to connect nodes across different containers. It may be that this approach is flawed, and I'm better off doing the layout myself. – mo-seph Feb 04 '14 at 20:50

0 Answers0