JavaFX Sequences and Predicates

9 02 2009


Introduction

JavaFX script has array list like structures called sequences. Deriving new sequences from existing sequences can be done with predicates. One could think of it as a filter on a collection of objects that produces a new collection or sequence. In the past I’ve used Apache Commons Collection API to achieve this behavior in the Java world. So, instead of using for loops to generate new sequences you would use predicates. In JavaFX predicates are built into the language to achieve this behavior. So, I would like explore this cool facility.
Playing Cards

The Problem

With a deck of cards randomly shuffled generate four sequences with each sequence based on the one of the four suits.

Example: one pile of clubs, one pile of hearts, one pile of spades and one pile of diamonds.

Click here to see playing cards

The Solution


var deck: PlayingCard[];


// Predicates for each suit
var clubs = deck[c | c.suit == "Club"];
var hearts = deck[c | c.suit == "Heart"];
var spades = deck[c | c.suit == "Spade"];
var diamonds = deck[c | c.suit == "Diamond"];

Conclusion:

The ability to use predicates to filter nested object are quite easy.  No messy for loops. If anyone is willing to convert SVG files to JavaFX may take a look at http://commons.wikimedia.org/wiki/Category:SVG_Playing_cards . Creating all 52 cards! (Desktop to Mobile in a snap).

Below is the full source code:

/*
 * Main.fx
 *
 * Created on Feb 7, 2009, 5:24:05 PM
 */

package carlfx;

import javafx.scene.CustomNode;
import javafx.scene.effect.Reflection;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * @author cdea
 */

def kinds = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
def suits = ["Club", "Heart", "Spade", "Diamond"];

// building a deck of cards.
var deck:PlayingCard[];
var x = 0;
var y = 0;

function retrieveImage(name, x:Number, y:Number){
    println("{__DIR__}{name}.gif");
    return ImageView {
        x:x
        y:y
        image: Image {
            url: "{__DIR__}{name}.gif"
        }
    }
}

class PlayingCard extends CustomNode{
    var kind:String;
    var suit:String;
    var root:Group;
    var lastX:Number = 25 + x;
    var lastY:Number = 55;

    protected override function create() : Node {

        if (root == null) {
            initializeCustomNode();
        }
        return root;
    }

    function initializeCustomNode():Void {
        root = Group {
            content: [
                Rectangle {
                    stroke: Color.DARKRED
                    x: lastX
                    y: lastY
                    width: 50
                    height: 70
                    arcWidth: 16
                    arcHeight: 16
                    fill: LinearGradient {
                        startX: 0.0,
                        startY: 0.0,
                        endX: 0.0,
                        endY: 1.0,
                        proportional: true
                        stops: [
                            Stop {
                                offset: 0.0
                            color: Color.WHITE},
                            Stop {
                                offset: 1.0
                            color: Color.BLACK}
                        ]
                    }
                    effect: Reflection {
                        fraction: 0.9
                        topOpacity: 0.5
                        topOffset: 2.5
                    }

                },
                Text{
                    x:25 + x + 3
                    y:55 + 10
                    font:Font{
                        size:10
                    }
                    content:kind
                },
                retrieveImage(suit, 25 + x + 3, 55 + 20)
            ]
        } // Group

    } // initializeCustomNode
}

// Build 52 playing cards
for (suit in suits) {
    for(kind in kinds){
        var card = PlayingCard {
            kind:kind
            suit:suit
        };
        x = x + 12;
        insert card into deck;
    }
}

// Predicates for each suit
var clubs = deck[c | c.suit == "Club"];
var hearts = deck[c | c.suit == "Heart"];
var spades = deck[c | c.suit == "Spade"];
var diamonds = deck[c | c.suit == "Diamond"];

// display deck in text format
println ("the deck displayed ");
for(card in hearts){
    println("card {card.kind} of {card.suit}");
}

// Display Playing Cards
Stage {
    title: "Playing Cards"
    width: 725
    height: 300
    scene: Scene {
        content:[clubs, hearts, spades, diamonds]
    }
}

Actions

Information

7 responses

10 02 2009
Jim Weaver

Nice post! Can you please provide a link to the project (or at least the graphical assets) as well as a Web Start link?

Thanks,
Jim Weaver

11 02 2009
carldea

Thanks, it should be ready. If anyone is having trouble just let me know. I will try to self sign it later.
Carl

11 02 2009
Jim Weaver

No reason to sign, because the app doesn’t need to play outside of the sandbox. Please see:
http://javafxpert.com/weblog/2009/01/absence-of-malice-in-javafx.html

Also, recommend removing desktop icon prompt by removing the following lines from the JNLP file:

The less dialogs that the user needs to interact with before the app starts the better :-)

Thanks,
Jim Weaver

11 02 2009
Jim Weaver

What is the RSS feed URL for your blog?

Thanks,
Jim Weaver

12 02 2009
carldea

Jim,

Thanks for the suggestion. I just fixed it.

-Carl Dea

12 02 2009
carldea

Jim,
I’m not really sure. I’m new on WordPress, so I’m trying to figure this option out.

Ah, figured it out… http://carlfx.wordpress.com/feed/

I really want to know how to do proper syntax code highlighting too.

My next demo is going to be fun.

-Carl Dea

15 02 2009
Java Desktop links of the week, February 16th | Jonathan Giles

[...] Dea posts about JavaFX sequences and predicates. His post is clear but very code-heavy, so for those of you that learn by reading code, dive right [...]

Leave a comment