Saturday, May 3, 2008

JavaFX curly brace overdose

Have you seen code examples from JavaFX script? The language is very interesting. It contains many new features that may revolutionize the way people create user interfaces in Swing, such as triggers and binding. But one thing that always bothers me about the code examples that I have seen is the insane amount of curly braces that they have to use. Check out this example taken from James Weaver's Java FX blog:


/*
*  TetrisMain.fx - The main program for a compiled JavaFX Script Tetris game
*
*  Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
*  to serve as a compiled JavaFX Script example.
*/
package tetris_ui;

import javafx.ui.*;
import javafx.ui.canvas.*;
import java.lang.System;
import tetris_model.*;

Frame {
  var model = TetrisModel {}
  var canvas:Canvas
  width: 350
  height: 500
  title: "TetrisJFX"
  background: Color.LIGHTGREY
  content:
    StackPanel {
      content: [
        Canvas {
          content: [
            ImageView {
              image:
                Image {
                  url: "{__DIR__}images/background.jpg"
                }
            },
            Text {
              transform: bind [
                Translate.translate(30, 350),
                Rotate.rotate(290, 0, 0),
              ]
              content: "Game Over"
              fill: Color.WHITE
              opacity: bind if (model.timeline.running) 0
                            else 1
              font:
                Font {
                  face: FontFace.SANSSERIF
                  size: 60
                  style: FontStyle.BOLD
                }
            }
          ]
        },
        BorderPanel {
          center:
            FlowPanel {
              alignment: Alignment.LEADING
              vgap: 10
              hgap: 10
              content: [
                Canvas {
                  content:
                    TetrisPlayingField {
                      model: model
                    }
                }
              ]
            }
          right:
            GridPanel {
            var sansSerif24 =
              Font {
                face: FontFace.SANSSERIF
                size: 24
                style: FontStyle.BOLD
              }
              rows: 2
              columns: 1
              cells: [
                BorderPanel {
                  top:
                    FlowPanel {
                      vgap: 10
                      alignment: Alignment.LEADING
                      content:
                        Label {
                          foreground: Color.LIGHTBLUE
                          text: "NEXT:"
                          font: sansSerif24
                        }
                    }
                  center: 
                    Canvas {
                      content:
                        TetrisNextShapeNode {
                          model: model
                        }
                    }
                },
                BorderPanel {
                  top:
                    Label {
                      foreground: Color.LIGHTBLUE
                      text: "SCORE:"
                      font: sansSerif24
                    }
                  center:
                    FlowPanel {
                      alignment: Alignment.TRAILING
                      content:
                        Label {
                          foreground: Color.LIGHTBLUE
                          text: bind "{model.score}"
                          font: sansSerif24
                        }
                    }
                }
              ]
            }
          bottom:
            FlowPanel {
              alignment: Alignment.CENTER
              content: [
                Button {
                  text: bind
                    if (model.timeline.running)
                      "Stop"
                    else
                      "Play"
                  action:
                    function():Void {
                      if (model.timeline.running) {
                        model.stopGame();
                      }
                      else {
                        model.startGame();
                      }
                    }
                },
                Button {
                  text: "Rotate"
                  enabled: bind not model.stopDropping
                  action:
                    function():Void {
                      model.rotate90();
                    }
                },
                Button {
                  text: "Left"
                  enabled: bind not model.stopDropping
                  action:
                    function():Void {
                      model.moveLeft();
                    }
                },
                Button {
                  text: "Right"
                  enabled: bind not model.stopDropping
                  action:
                    function():Void {
                      model.moveRight();
                    }
                }
              ]
            }
        }
      ]
    }
  visible: true
  onClose:
    function():Void {
      System.exit(0);
    }
}


Wow... that code looks like a tower. So here goes a crazy idea: what if JavaFX Script used the same strategy as python: use the indentation to avoid the need of curly braces. Also, perhaps a different indentation scheme can help.

What do you think about the looks of JavaFX?

3 comments:

Chris P. said...

I see what they were trying to do with the language. I am a fan of Erlang where the use of tuples {} and lists [] are heavily used. to be honest once you get the style down pat it becomes easy to learn.

The problem with the code you posted is that each new attribute is on a new line. this is what makes it difficult to understand.

For instance:

[ form,
{type, MyFormType},
{event, {onexit, MyFunc}}
]

is alot easier to understand than:

[ form,
{
type, MyFormType
},
{
event,
{onexit, MyFunc
}
}
]

Indentation can be a problem especially when its coupled with syntax that is supposed to group values. However indentation alone can also get confusing, especially when you are "n" levels deep:

form,
type, MyFormType,
event,
onexit, MyFunc


Just my two cents.

Chris P. said...

Sorry my post above the indentation was lost. :(

Camilo A. said...

Thanks a lot for your comment. It makes a lot of sense.

Like this post? Digg it!