0 Replies Latest reply: Jun 6, 2011 3:56 PM by 865871 RSS

    How to position a custom control by its centerX/centerY values?

      I am working on a javafx scene for visualizing graph nodes. The position of each node is calculated by a graph layout library.
      Thats why I need to position the nodes with absolute values.

      I have a custom control, skin and behaviour fx class. The skin is an ellipse with a text. The text can be set in the control class and the ellipse adapts to the size of the text.
      Took me some time to figure it out how to do it so that getPrefWidth()/getPrefHeight() returns the correct size.

      What I want:
      I want to specify the absolute position of my custom control (from outside) with the value determined by the graph layout lib.
      AND the position should be the center of the ellipse.
      So far the position is just the top left corner of the node because of the stack.

      I experimented with overriding translateX/translateY which doesn't work if I put it in the scene which consists of a stack to center the whole graph.
      If overriding layoutX/layoutY I get an Exception. What is the trick?

      Furthermore I am not sure if implementing my own control and skin was the best way or if there is an easier way. Maybe there is a better way how to implement the skin class, too?

      Thanks a lot!

      Is there nobody who has a solution for that or is everyone busy trying JavaFX 2.0 beta?

      Custom control LVNode:
      import javafx.scene.control.Control;
      public class LVNode extends Control {
          public var nodeSkin = bind skin as LVNodeSkin;
          public var text: String;
          public var centerX: Number;
          public var centerY: Number;
          init {
              if (skin == null) {
                  skin = LVNodeSkin{};
      Custom skin LVSkin:
      public class LVNodeSkin extends Skin{
          public var nodeControl = bind control as LVNode;
          public var nodeBehavior = bind behavior as LVNodeBehavior;   
              var text = Text {
                  styleClass: "node-text";
                  content: bind 
                  if (nodeControl.text.length() < 20) then 
          var ellipseGroup = Group {
              styleClass: "node-ellipse-group";
              Ellipse {
                  styleClass: "node-ellipse";
                  radiusX: bind text.boundsInLocal.width / 2 + 6
                  radiusY: bind text.boundsInLocal.height / 2 + 12
          var ellipseWithText = Stack {
              width: bind nodeControl.width
              height: bind nodeControl.height
              content: [
          init {
              behavior = LVNodeBehavior{};
              node = Group {
                  content: [
                  onMouseClicked: function(me: MouseEvent) {
                  onMouseEntered: function(me: MouseEvent) {
                  onMouseExited: function(me: MouseEvent) {
          override function getPrefWidth(height: Number):Number {
          override function getPrefHeight(width: Number):Number {
          override function getMaxWidth() {
          override function getMaxHeight() {
          override function getMinWidth() {
          override function getMinHeight() {
          override function contains(localX: Number, localY: Number): Boolean {
              node.contains(localX, localY);
          override function intersects(localX: Number, localY: Number, localWidth: Number, localHeight: Number): Boolean {
              node.intersects(localX, localY, localWidth, localHeight);
      Example scene:
      import javafx.stage.Stage;
      import javafx.scene.layout.Stack;
      import javafx.scene.Scene;
      import javafx.scene.Group;
      var scene: Scene;
      var stack: Stack;
      def STYLE_SHEET_LOCATION : String = "file:META-INF/styles.css";
      var root: LVNode;
      var child1: LVNode;
      scene = Scene {
          stylesheets: [STYLE_SHEET_LOCATION]
          width: 500
          height: 400
          content: Stack {
              width: bind scene.width
              height: bind scene.height
              content: Group {
              child1 = LVNode {
                  text: "text1"
                  centerX: 0
                  centerY: 100
              root = LVNode {
                  text: "text very very very long"
                  centerX: 0
                  centerY: 250
      Stage {
          title: "Graph layout"
          scene: scene
      Edited by: 862868 on 04.06.2011 06:29

      Edited by: 862868 on 06.06.2011 13:54