2

Background:

I'm working on a visualizer for real-time planning algorithms. The 'world' is provided in a text file, where '_' is a free cell, and '#' is a blocked cell. The following is an example:

41
21
___________________@_____________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_#######################################_
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
_________________________________________
___________________*_____________________

It is very important that the window has the exact same number of cells in every row and the exact same number of cells in every column.

I have to visualize in Kotlin, which is 100% interoperable with Java. I decided to try javafx, version 8.0.60. After doing some research on javafx layouts, I decided TilePane was my best bet.

What I have so far:

This is what I have so far. If you look closely, you can see a very small amount of padding within each node of the TilePane. As the robot goes from tile to tile, this small amount of padding introduces a slight error, because the robot moves using the width and height of the tile, not accounting for the padding. This causes the robot to not be in the center of the tile as it traverses the maze.

Additionally, my solution is very dependent on the size of the window. If I adjust it slightly, the world is displayed incorrectly because each row and column do not have the same number of fixed cells.

Questions:

These questions are in order of importance.

  1. Is there a layout or setting that will provide me with a fixed number of cells per row and per column? Displaying the world depends on that.
  2. How do I get rid of the padding between each node in the layout?
  3. If possible, I would like to resize the layout, while maintaining the first two invariants. Does anyone know of a way to do this?

Relevant parts of my code:

Note: robot.fill is the same as calling robot.setFill, and Kotlin omits types and the keyword new when instantiating objects.

val root = TilePane(0.0, 0.0)

/* The robot */
val robotWidth = TILE_WIDTH / 4.0
val robot = Rectangle(robotWidth, robotWidth)
robot.fill = Color.ORANGE

/* The robots starting location, needs to be drawn later */
var startX: Double? = null
var startY: Double? = null


for (y in 0..rowCount - 1) {
    val line = inputScanner.nextLine()

    for (x in 0..columnCount - 1) {
        when (line[x]) {
            '#' -> {
                val blocked = Rectangle(TILE_WIDTH, TILE_HEIGHT)
                blocked.fill = Color.BLACK
                //blocked.stroke = Color.BLACK
                root.children.add(blocked)
            }
            '_' -> {
                val free = Rectangle(TILE_WIDTH, TILE_HEIGHT)
                free.fill = Color.LIGHTSLATEGRAY
                free.opacity = .5
                root.children.add(free)
            }
            '*' -> {
                val radius = TILE_WIDTH / 10.0
                val dirtyCell = Circle(radius)
                //dirtyCell.stroke = Color.BLUE
                dirtyCell.fill = Color.BLUE
                root.children.add(dirtyCell)
            }
            '@' -> {
                startX = x * 1.0
                startY = y * 1.0
                root.children.add(robot)
            }
        }
    }
}
  • What does the robot do? Is it supposed to be animated at some point? Or do you just want to display it in the center of the various other cells? – James_D Feb 20 '16 at 21:54
  • @James_D I need to animate the robot. Ideally I would animate it to the goal (the bottom of the screen in this example) and then have the animation restart. I currently animate the robot now, but the padding issue that I described above makes it not work that well. For example, the robot doesn't always stay in the center of his cell. – Stephen Chambers Feb 21 '16 at 01:00
  • I didn't actually ask the right question. I should have asked: is the animation smoothly transitioning between the centers of different cells, or is it "hopping" from the center of one cell to another? If it's the first, it's probably easier just to use a plain `Pane` and basically manage the layout yourself. There would just be some basic calculations to compute the location and size of the rectangles, and you could bind those to the pane's width and height. If it's the second, I would use a `GridPane` with `StackPane`s in each cell. You can then add and remove the robot from the stack panes. – James_D Feb 21 '16 at 01:16
  • Thank you! That worked perfectly. However, I'm not sure how to bind the rectangles width/height to the pane's width/height. I tried setting each rectangles heightProperty and widthProperty, but I'm encountering odd behavior. Some rectangles are longer than others, some are taller than others. How exactly should I bind the width/height properties to my new pane? – Stephen Chambers Feb 21 '16 at 05:21
  • Either [edit] your question, or perhaps post a new one, to show the code you are now using that is causing that not to work properly. In Java I would just do `rect.widthProperty().bind(pane.widthProperty().divide(columnCount));`. – James_D Feb 21 '16 at 14:27
  • Everything's fine now. Thanks for your help! – Stephen Chambers Feb 23 '16 at 18:05

0 Answers0