A Case Study: A JavaFX Widget Framework API

20 04 2013

A prototype of a widget container

A prototype of a widget container


Building a better mousetrap

In short I want to revisit the idea of a cross platform widget framework using JavaFX. In this article I’d like to share some ideas, concepts and prototypes that might invigorate this old but ingenious idea for the desktop and embedded world. An old idea you say? Does anyone remember WidgetFX?

In the early days of JavaFX there were a few Java Champions and community members who decided to create a cross platform JavaFX 1.x widget framework for the desktop (year 2008). I was fortunate enough to know many of those contributors involved.  I grew to love the capabilities the framework and widgets were able to provide.  However, as we all know JavaFX is now redone as Java APIs as opposed to the JavaFX script language. This eventually became apparent regarding to the future of most frameworks back then. Before I begin I would like to give credit to the folks who contributed to the WidgetFX framework project.  I want to thank them for their enthusiasm and their tireless efforts on building the community to what it is today. To see some of their cool widgets please visit the site
http://widgetfx.org
(catch them before they’re gone). Two of the original founders of the project are Stephen Chin and Keith Combs. Even though I did not partake in the fun during the height of the project I was quite inspired.

Inception phase

To fast forward just last year at the JavaOne 2012 conference I was able to catch up with Keith Combs (Silicon Valley JavaFX User Group organizer) and Stephen Chin (Java Technology Evangelist at Oracle) after his keynote speaking to inquire about the WidgetFX project now that JavaFX 1.x is no more. Steve kindly asked if anyone would be interested in giving it a reboot on the JavaFX 2.x platform (As he peered over towards Keith and me). I believe I said, “I don’t think, so… “. I thought it might be too much to bite off than I could possibly chew. So I politely declined the offer. During the conference I was later enamored by all things Java embedded which later fueled to some of my home automation project ideas using JavaFX with (Arduino, Raspberry Pi, and Beagle Board).

After returning home I was not only excited about the things I’ve learned at the conference but, I also was in the middle of transitioning to a new job and company. Working as a UI and Visualization developer for cloud based monitoring software I often encountered stakeholders/SMEs mentioning the term “SPOG” or single pane of glass.

What does the term “SPOG” mean?

According to Floyd Strimling a cloud technical evangelist at Zenoss explains how so many organizations will create desperate (silos) systems and he goes on to say, “The Holy Grail is a single pane of glass that provides IT managers with a single access point to make sense of their entire underlying infrastructure in real time”. (Searching for the Mythical Single Pane of Glass)

Isn’t “SPOG” an interesting concept for large operation centers? So, I continued to rethink of the old idea of a flexible widget framework that would provide richer interfaces that would allow better desktop integration, decoupled services, higher performance, and capable of empowering users with many of the modern UI metaphors that they’d expect on their favorite OS platform. I believe such a framework should also work on embedded devices for home automation.  Actually I got the idea of a widget framework for embedded devices from my good friend Gerrit Grunwald (Java Champion and author of the popular Steel Series API) while exchanging ideas about graphics performance and launching JavaFX applications on embedded devices.

Wow, with so many different problem domains and so many perspectives could such a widget framework truly exist? Could such a widget framework be able to make everyone happy? Is it possible to create a simple widget framework to rule them all? I believe it is possible.

eWidgetFX is born

In the back of my mind I noticed similar use cases with many customers wanting widget frameworks having this concept of a “SPOG”, but also provide a framework that I could use myself on my own desktop or touch device. So, I kept going back and forth on the possibility of rebooting the old project WidgetFX. Instead I wanted to throw a monkey wrench into the whole business of widget frameworks. Since there are so many kinds of ways to launch, display, and manage widgets it would also be a good idea to build a single widget framework SPI (service provider interface API) which would enable developers to build their own widget containers thus allowing widget developers to run their widgets in any widget container. There would basically be two developer perspectives: Container Developers and Widget Developers. So, I’d like to propose a new API called eWidgetFX (core) that would allow the developers to create widget containers and widgets.

For now I will defer the work of designing the core APIs and make it a future post. So, in this article I’ve decided to generate some prototypes of widget containers that would basically depend on the future eWidgetFX framework API.

Prototyping Widget Containers

Prototyping is probably the most fun part during any software development activity. Shown below are videos I recently uploaded to Youtube.com to kick some ideas around for different kinds of widget containers (Icon App tray) on a desktop environment.

Conclusion

One of the main issue I found in UI development is that customers will often know what they want, but aren’t able to communicate what they ultimately want. It’s almost like playing a game of Charades or a game of Pictionary where guessing is a sought after skill in software design.  We are often faced with providing prototypes and end up settling on one particular view (one view, one way, one silo). The problem became pretty apparent where everyone had an opinion or philosophical stance on a particular GUI interface, usability aspect or UI metaphor. Sometimes it’s based on subjective personal preferences that can go into long discussions. No one person in the room was completely happy, but at the end of the day we compromised and we settled.

I believe that by creating a widget API it would allow organizations to build different single pane of glass instances (widget containers) and capable of sharing all widgets across other panes.

So, imagine seeing different types of widget containers in the wild. Some future widget containers could look like interfaces similar to the following movies: Avengers, Tron, or Minority Report

A final note: Many of of the ideas expressed and proposed are a collective effort from some of my friends (team members) of the JFXtras.org project (Mark Heckler, Hendrik Ebbers, and Gerrit Grunwald).

Would you like to see a talk regarding widget frameworks at JavaOne?

As always comments are welcome.

Carl ;-)

Resources

JavaFX:
http://www.oracle.com/technetwork/java/javafx/overview/index.html

Java Champions:
https://java.net/website/java-champions/bios.html

WidgetFX:
http://widgetfx.org

Keith Combs from the Silicon Valley JavaFX user group:
http://www.svjugfx.org/member/10394895/?op=&memberId=10394895

Steve on Java by Stephen Chin:
http://steveonjava.com

Arduino :
http://www.arduino.cc

Raspberry Pi:
http://www.raspberrypi.org

Beagle Board:
http://beagleboard.org

Guest Post: Searching for the Mythical Single Pane of Glass:
http://siliconangle.com/blog/2012/02/29/guest-post-searching-for-the-mythical-single-pane-of-glass

Anti-patterns:
http://en.wikibooks.org/wiki/Introduction_to_Software_Engineering/Architecture/Anti-Patterns

Google Images of Operation centers:
http://bit.ly/106p3h0

Avengers UI design:
http://cargocollective.com/jayse/Avengers

Tron UI design:
http://dlew.me/Tron-Legacy-Boardroom

Minority Report UI designer demos his tech at TED (video):
http://www.engadget.com/2010/06/03/minority-report-ui-designer-demos-his-tech-at-ted

The Java Jungle by Mark Heckler:
https://blogs.oracle.com/javajungle/entry/welcome_to_the_jungle

Gui Garage by Hendrik Ebbers:
http://www.guigarage.com

Harmonic Code by Gerrit Grunwald:
http://harmoniccode.blogspot.de

JFXtras.org :
http://jfxtras.org
Leap Motion:
https://www.leapmotion.com
Leap Motion:
https://www.leapmotion.com





JavaFX 2 GameTutorial Part 4

12 06 2012
JavaFX 2 Game Tutorial Part 4

Figure 1 JavaFX 2 Game Tutorial Part 4

 

Introduction

This is part four of a six part series related to a JavaFX 2 Game Tutorial. If you’ve missed Part 1, Part 2, or Part 3, I encourage you to go through them before beginning this tutorial. To recap, in Part 3 I gave you a little history of the many classic arcade style games and the different input devices that were used. I then showed you how to create a simple game similar to the famous arcade ‘Asteroids’. The controls (movement of the ship) were, however, more similar to those of the PC game ‘Star Craft’. In Part 3, you should have a good understanding of how to receive input from your keyboard and mouse.

This tutorial is about tweaking Part 2’s game engine and updating the existing ‘Asteroids’ style game from Part 3 to handle collision detection. In this tutorial, I will briefly talk about sprites and how to handle collision detection. The spaceship will now have the ability to generate a force field to protect itself from enemies and asteroids. This is reminiscent of the classic arcade ‘Asteroids Deluxe’.  If you want to run the demo, scroll down and click on the WebStart button below. Please read the requirements before launching the game.

What is a Sprite?

According to Wikipedia, “a sprite is a two-dimensional image or animation that is integrated into a larger scene.” From the Java gaming world view, a sprite is an object containing image frames and additional data based on the context of an actor to be animated onto the scene area. In the days of Walt Disney, when cartoons were drawn with a pencil and paper, the artist  produced many drawings that became animations. This example points to the creation of the flip book. I’m sure you’ve created flip books as a kid. I know I did. I used to doodle and make cool animations with all the corners of my notebooks. In our Asteroid type game, I created a sprite object which contains all of the images (ImageView) of the ship pre-rotated just like a flip book. To animate the ship turning, I made the current frame visible and the rest of the frames not visible. Similar to a flip book, it will appear to be rotated about its center (pivot) point. A sprite can also contain other information, such as velocity or health points.

Collision Detection

When actors or sprites animate across the scene, the game engine will check each sprite against other sprites to determine if they have collided into one another. This process should be very efficient especially when you have numerous sprites moving about the screen. There are tradeoffs when it comes to being efficient. Because each cycle in the game loop will check for collision, being more accurate usually degrades your performance. Many games will use the bounding region of the image to determine if two sprites have collided into one another.  Some games use rectangles as bounding regions. Shown below in figure 2 are two sprites colliding:

Bounding box as a rectangular collision region.

Figure 2 Bounding box as a rectangular collision region.

I’m sure you’ll know by now that most actors (images) in games don’t appear rectangular when pixels surrounding the actor are transparent. However, the actor or image is indeed rectangular even if the pixels are transparent or not.


Actor Image

Figure 3 depicts an actor image

Those games which use rectangular bounding regions usually make the bounding box inscribed in the sprite’s image. Shown below in figure 4 two rectangular bounding regions (orange and green) are inscribed in the spaceship image.

Two rectangles used as collision bounding boxes.

Figure 4 Two rectangles used as collision bounding boxes.

I’m sure you will notice that the nose tip of the ship and wings are not covered by either bounding box. This means that when an asteroid overlaps the unbounded region of the sprite the collision will not occur. Some games use this strategy; you will notice that the sprites’ rectangular bounding regions are small and placed in key areas of the sprite image.  Greater precision will be found with better algorithms for polygons and other non-rectangular shapes. In this blog entry, I basically use circles as bounding regions and not rectangles. I could have made each sprite contain an array of collision shapes, but instead, I chose to have only one collision region for each sprite. Each collision region will be a circle shape on the scene graph. For the spaceship, I inscribed the circle based on the center point of the ship with the radius extended to the cock pit of the ship. Shown below in figure 5 the bounded circular collision area of the ship is depicted as a red circle.

The ship's collision region.

Figure 5 The ship’s collision region.

I chose a circle as the bounding region because of the relative ease to determine the collision of two objects based on the distance formula (Pythagorean theorem) which only requires each sprite’s bounding region’s center point and their radii.  After calculating the distance based on the two center points, you will compare the result to see if it is less than or equal to the sum of the two radii. If the result does indeed come out to be less than or equal to the sum of the two radii then a collision has occurred.  Figure 6 depicts  how the distance formula relates to the two center points of circular bounding regions.

Distance formula

Figure 6 distance formula between two center points.

The following code creates the main game loop from the GameWorld class:

  @Override
  public void handle(javafx.event.ActionEvent event) {

     // update actors
     updateSprites();

     // check for collision
     checkCollisions();

     // removed dead things
     cleanupSprites();

  }

The code below creates the checkCollision() method from the GameWorld class:

    protected void checkCollisions() {
        // check other sprite's collisions
        spriteManager.resetCollisionsToCheck();
        // check each sprite against other sprite objects.
        for (Sprite spriteA : spriteManager.getCollisionsToCheck()) {
            for (Sprite spriteB : spriteManager.getAllSprites()) {
                if (handleCollision(spriteA, spriteB)) {
                    // The break helps optimize the collisions
                    //  The break statement means one object only hits another
                    // object as opposed to one hitting many objects.
                    // To be more accurate comment out the break statement.
                    break;
                }
            }
        }
    }

The derived Game World (TheExpanse) class’ implementation of its handleCollision() method:

    /**
     * How to handle the collision of two sprite objects.
     *
     * @param spriteA Sprite from the first list.
     * @param spriteB Sprite from the second list.
     * @return boolean returns a true if the two sprites have collided otherwise false.
     */
    @Override
    protected boolean handleCollision(Sprite spriteA, Sprite spriteB) {
        if (spriteA != spriteB) {
            if (spriteA.collide(spriteB)) {

                if (spriteA != myShip) {
                    spriteA.handleDeath(this);
                }
                if (spriteB != myShip) {
                    spriteB.handleDeath(this);
                }
            }
        }

        return false;
    }

The Sprite Class’ default implementation of its collide() method using the distance formula:

    public boolean collide(Sprite other) {

        if (collisionBounds == null || other.collisionBounds == null) {
            return false;
        }

        // determine it's size
        Circle otherSphere = other.collisionBounds;
        Circle thisSphere = collisionBounds;
        Point2D otherCenter = otherSphere.localToScene(otherSphere.getCenterX(), otherSphere.getCenterY());
        Point2D thisCenter = thisSphere.localToScene(thisSphere.getCenterX(), thisSphere.getCenterY());
        double dx = otherCenter.getX() - thisCenter.getX();
        double dy = otherCenter.getY() - thisCenter.getY();
        double distance = Math.sqrt(dx * dx + dy * dy);
        double minDist = otherSphere.getRadius() + thisSphere.getRadius();

        return (distance < minDist);
    }

The Sprite Class’ default implementation of its handleDeath() method:

    public void handleDeath(GameWorld gameWorld) {
        gameWorld.getSpriteManager().addSpritesToBeRemoved(this);
    }

The Atom (an asteroid or missile) class will override the handleDeath() method:


    public void handleDeath(GameWorld gameWorld) {
        implode(gameWorld);
        super.handleDeath(gameWorld);
    }

JavaFX 2 Sprite and Collision Demo

This simple demo game will be a mix between StarCraft and Asteroids. When using the mouse to navigate the ship, you will notice that the controls will resemble StarCraft’s Battle Cruiser. The objective is to fire your weapon at the spheres before they hit your spaceship or other spheres which implode upon impact. Because this is a simple tutorial or even a game in its early stages of development, the game doesn’t keep track of the score. I encourage you to go to GitHub to download the code and enhance the game. For the sake of brevity, I will not be showing all of the code changes, but I trust you will visit GitHub here: 
https://github.com/carldea/JFXGen
 for all the demos and source code.

Requirements:

  • Java 7 or later
  • JavaFX 2.1 or later
  • Windows XP or later (Should be available soon for Linux/MacOS)

A simple Asteroid type game called ‘The Expanse’.

Instructions:

  • Right mouse click (on Windows) to fly ship.
  • Left mouse click (left click on Windows mouse) to fire weapon.
  • Key press ’2′ to change to large missiles. (blue circular projectiles)
  • Other key press defaults to smaller missiles. (red circular projectiles)
  • Space bar key press will toggle a force field to protect the ship from enemies and asteroids.

Click on the Launch button below to start the demo:

Tutorial demo

Part 4 ‘The Expanse’ sprites/collision

Part 4 ‘Sprites/Collision’

Next up is Part 5 (Sound) where you will be using JavaFX to produce sound effects for your game.

References

Definition of a sprite:
http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29

Walt Disney:
http://en.wikipedia.org/wiki/Walt_Disney

How to make a flip book:
http://www.bitrebels.com/design/how-to-create-a-flip-book/

JavaFX’s ImageView :
http://docs.oracle.com/javafx/2/api/javafx/scene/image/ImageView.html

Collision detection:
http://zetcode.com/tutorials/javagamestutorial/collision/

AABBs Collision detection in Java:

Pythagorean theorem:
http://en.wikipedia.org/wiki/Pythagorean_theorem

Distance formula:
http://en.wikipedia.org/wiki/Distance

Serious game of Asteroids Deluxe (Youtube):





JavaFX 2.0 Introduction by Example book

19 12 2011

I recently finished writing a book on the new release of the JavaFX 2.0 SDK and it has already been placed on the shelves at a bookstore (Amazon) near you. The book will walk you through, step-by-step, giving you the ins and outs of JavaFX 2.0. When you encounter a chapter you will be presented recipes which will pose a problem (use case scenario) that will have an associated solution. After a proposed solution you will be shown an example source code listing and its display output after the program has been executed. Lastly you will be shown a section called “How it works” which will explain and discuss the examples and their details. To see more about this book, such as the source code and errata, please visit Apress Publishing (
http://www.apress.com/9781430242574
).

In this blog entry I also want to give you a sneak preview of a Java Webstart example of chapter 3 recipe 3-1 (JavaFX 2.0 MP3 Player). To launch the JavaFX MP3 player just jump down to Chapter 3 below.

Below is a brief overview of the chapters in the book:

Chapter 1: JavaFX Fundamentals

I begin by instructing you on how to get your environment set-up to rapidly develop rich internet applications using Java and JavaFX.

JavaFX Swiss army knife

After reading this chapter you will be able to answer questions such as:

  • How do I create GUI applications?
  • What is the Scene graph?
  • How do I display text onto the scene graph?
  • How do I incorporate UI controls into my application?
  • How do I bind expressions?
  • How do I draw shapes?
  • How do I generate a background process?
  • How do I associate keyboard sequences to applications?

Chapter 2: Graphics with JavaFX
In chapter 2 there are recipe examples which delve into JavaFX’s graphics and animation capabilities. I begin by explaining some of the basics of JavaFX’s Graphics such as rendering images and animating nodes. I then go on to more advanced topics such as animating with transitions, manipulating layouts, and enhancing nodes using JavaFX CSS.
The following picture, taken from Recipe 2-2, depicts an image viewer application with a custom news ticker control at the bottom.

Photo Viewer and News Ticker application

Photo Viewer and News Ticker application

Chapter 3: Media with JavaFX
Chapter 3 covers all things media related. Here I reveal JavaFX’s media APIs which allows you to integrate audio and video into your applications. I begin by showing you how to create a JavaFX MP3 player and a video player. Then I will walk you through the different ways to enhance the video player with additional features to control media actions and events, mark positions in a video, and synchronize animations.

The illustration below, taken from Recipe 3-1, depicts a JavaFX 2.0 MP3 player with a graphical visualization (using the AudioSpectrumListener API). Before launching the example you will need to know the requirements and instructions to run the demo example.

JavaFX 2.0 MP3 Player

JavaFX MP3 Player

Simple requirements and instructions to run the JavaFX 2.0 MP3 Player:

Requirements

  • Java 6 update 24 JRE or greater (Java 7 is preferred)
  • JavaFX 2.0 or greater (JavaFX 2.0.2 is preferred)
  • Windows XP SP 3 or greater. (I will update the jnlp as JavaFX becomes available on other OSes)

Instructions

  1. Click the Webstart launch button below.
  2. By using your file explorer on your host operating system “drag and drop” a music mp3 file onto the surface of the application.
  3. Use the controls to the bottom right of the application to pause, play, and stop the music.
  4. You may use your mouse to drag the application around your desktop.
  5. To close the application click on the ‘X’ in the upper right hand corner.

To launch the application click on the Java Webstart button below:

Demo JavaFX 2.0 MP3 Player

Chapter 4: JavaFX on the Web
In chapter 4 you will be able to take advantage of the interoperability between JavaFX and HTML5.

For starters I will cover how to embed JavaFX applications into a Web page. I then will demonstrate JavaFX’s powerful WebView and WebEngine APIs. Below are the recipe examples from chapter 4 which utilize the  WebView and WebEngine APIs:

  • Displaying HTML5 Content (animated analog clock application)
  • Loading data from a Web service (weather application)
  • Handling Web events
  • Storing and displaying data using an embedded database (RSS reader application)

Depicted below is an animated analog clock application, taken from Recipe 4-2, demonstrating the ability to render HTML5 content.

JavaFX 2.0 Analog Clock

JavaFX 2.0 Analog Clock (HTML5)

I assume you know the Java programming language and some web development concepts. I hope you will enjoy these examples which can be used freely in your own projects. I’ve tested the examples with the latest Java 7 update 2 and JavaFX 2.0.2 runtime and SDK. If you have any questions or comments feel free to ask them here or on my Twitter account @carldea .

Thanks!

Carl





JavaFX – Java Applets Making a Comeback?

15 02 2010

Pedal to the metal

Petal to the metal

Introduction

In 2008 JavaWorld had written a great article by Jeff Friesen called “Are applets making a comeback?“. Jeff Friesen poses this question to leading thinkers and doers in the Java developer community. Although the question posed to readers may seem rhetorical, and difficult to answer with an emphatic “Yes“.  I want to try to answer this question in the year 2010.  Right after Oracle has finalized its acquisition of Sun Microsystems, Larry Ellison CEO of Oracle had  an Oracle + Sun Product Strategy Webcast announcing it would invest heavily in JavaFX. So, currently there are lots of things going on with the JavaFX platform. As the JavaFX platform matures the community should mature. So, hopefully I can encourage you to stay more involved in helping the JavaFX community grow.

Are Applets Making a Comeback?

Many Java Developers who have used Applets in the past, have often felt inadequate when competing with the new Web Order due to all the AJAX and Adobe Flash craze.  One of the main complaints about Java Applets was its start-up time. In my opinion ‘Perception‘ is key and when it comes to user experience, it is often said that “If it looks and feels slow, the application is probably not worth running“.  I believe that our society has this urge of instant gratification, so being patient is a hard thing to do these days. During years past Java developers have been longing for that day when Java Applets will make its big comeback. While many Sun engineers are working tirelessly solving this problem it always seems on going (It should).  Sometimes I’ll come across Java developers still feeling unconvinced whenever an update is released. I also have heard people get quite flustered and a little threatening.  I don’t mind if you complain, but do something about it. Then some will say, “What can I do about it?“. Well, the obvious things are forums, blogs and filing bugs. I normally am an early adopter when it comes to Java/JavaFX updates relating to performance increases. Just like folks who decide to buy a new game (Like StarCraft 2) off the shelf they’ll take a look at the graphics requirements such as video ram, etc in hopes their computer can handle it. If not they will likely upgrade their video card or buy a new computer all together. So, upgrading your Java Runtime Environment (JRE) is a snap. So, you are probably wondering where is the part where I encourage you? Well, let me just say with the recent release of JRE 1.6 update 18, I was pretty impressed  with the start-up and reload performance increases. To really see how fast Applets start-up I recommend installing the latest JRE (1.6 update 18), and to please visit Oracle/Sun engineer Rakesh Menon‘s blog entry called “JavaFX – Applet Startup Time“. On his site you will see a list of many folks taking some time to record metrics and describing their browser, OS, and hardware (Please note: make sure your Java Console is set to display so that a text dump outputting  the metrics can later be cut and pasted). I also suggest posting your results if you have a different configuration than the others on the list.

*Note: When clearing the cache (from the Java Control Panel) while having Firefox open be sure to restart Firefox or close tab before re-running the applet.

Conclusion

Once you will notice the start-up time increased you should be able to answer the question yourself  “Are Applets Making a Comeback?“. I know I can see the difference and I’m sure you will too. The Java/JavaFX community with tons of libraries and very good boosts in performance, I truly believe it is safe to say with an emphatic “Yes, Applets are making a comeback!”.  I also want to mention about two very cool sites to test drive your new JRE w/start-up/reload enhanced:

Lastly, I want to applaud and thank the Java/JavaFX engineers (Rakesh and company) for making these great strides.

References

Are applets making a comeback? by Jeff Friesen:
http://www.javaworld.com/javaworld/jw-05-2008/jw-05-applets.html

Larry Ellison CEO of Oracle:
http://en.wikipedia.org/wiki/Larry_Ellison

Interactive Pulp – JavaFX, startup time, and security dialogs :
http://www.interactivepulp.com/blog/2008/12/javafx-startup-time-and-security-dialogs

Oracle invests in JavaFX:
http://learnjavafx.typepad.com/weblog/2010/01/oracle-we-will-invest-heavily-in-javafx.html

Oracle/Sun strategy Webcast:
http://www.oracle.com/events/productstrategy/index.html

New Applet Experience by Jeff Friesen:
http://www.javaworld.com/javaworld/jw-05-2008/jw-05-newapplet.html

JavaFX forums:
http://forums.sun.com/category.jspa?categoryID=132

The JavaFX Journey filing bugs:
http://piliq.com/javafx/?p=1144

The Vancouver 2010 Olympics:
http://www.vancouver2010.com/olympic-medals/geo-view/

JavaFX – Applet Startup Time:
http://rakeshmenonp.wordpress.com/2009/08/31/javafx-applet-startup-time/

Star Cannon:
http://www.freearcade.com/StarCannon.jav/StarCannon.html





Does JavaFX have Multiple Inheritance?

29 06 2009

CatDog cartoon from Nickodean

CatDog cartoon from Nickelodeon

Introduction

Often when we learn about object oriented programming we try to find out if a particular language contains a dirty little phrase called multiple inheritance. Of course there are good reasons to try to avoid it (Diamond Problem) but sometimes you can’t.  I believe that it can be used in certain contexts which can be done safely (fearing and trembling from angry purists). In Java when asked if multiple inheritance is supported the answer is “Well, Sort of” or “Yes, but…“. Java has interfaces which follows the Design by Contract concept which forces the developer to implement the interface methods. Fundamentally when we think of abstraction we think of what behavior is common across classes. Abstract classes help but tend to get bloated and some folks resort to creating NOP (No operation performed) methods. One of the major principles of object oriented programming is re-use not un-re-use while rendering an object very coupled-ygoop. It would be wonderful if you could have method re-use from an abstract data type. Well, JavaFX has this ability to do this very thing! So, to ask the question again “Does JavaFX have multiple inheritance?“. I would answer it like this: “Yes, its similar to Java’s Interfaces but with implementation details“. JavaFX uses a concept called Mixin classes which allows the developer to inherit multiple classes. Sweet!

Example

I couldn’t help but think about all kinds of cats when thinking about multiple inheritance (not to be confused with these types of cats I Can Has Cheezburger ). In a nutshell there are Big cats and Small cats.

Requirements:

  • Some Big cats can roar, but all big cats can’t meow.
  • Similarly small cats can meow, but all small cats can’t roar.
  • All cats can purr.

In this example we will model reusable behavior as Mixins and we will also create the standard abstract classes such as “Animal” and “Cat“.

Step 1: Create Abstract Classes

abstract class Animal {
    public var name:String;
    public function eat(food:String){
        println("munchin on {food}");
    }
}

abstract public class Cat extends Animal {
    public function purr(volume:Integer){
        println("Purrrr...level({volume})");
    }
    public function scratch(){
        println("Scratching...")
    }

}

Step 2: Create Mixin Classes

public mixin class Roarer {
    public var bass:Integer = 20;
    public function roar(){
        println("Roar...");
    }
}

public mixin class Meower {
    public var pitch:Integer = 5;
    public function meow(){
        println("Meow...");
    }
}

Step 3: Create Derived Classes Inheriting Mixin Classes

// Cheetah's can't roar and can't meow
class Cheetah extends Cat {
}

class Lion extends Cat, Roarer{
    public override var bass = 50;
    public override function roar() {
        println("(ROAR) I'm King of the land!!!");
    }
}

class HouseCat extends Cat, Meower {
    public override var pitch = 10;
    public override function meow(){
        println("Meow...");
    }
}

Step 4: Create instances of the types of Cats

var fluffy:Cat = HouseCat{name:'fluffy'}; // regular house cat
var simba:Cat = Lion{name:'Simba'};      // Lion King cat
var chester:Cat = Cheetah{name:'Chester'}; // Cheetos' Chester

var cats:Cat[] = [fluffy, simba, chester]; // cat bus

Step 5: Create a script level function

Cat will ask to come into your house. Notice the down cast to Meower and Roarer type cats.

function letMeIntoHouse(cat:Cat){
        print("LET ME IN! ");
        if (cat instanceof Meower){
            var meower = (cat as Meower);
            meower.meow();
        }
        if (cat instanceof Roarer){
            var roarer = (cat as Roarer);
            roarer.roar();
        }
        cat.scratch();
}

Step 6: run() function like Java’s main()

This will loop through a sequence of cats by:

  • Cat asking in your house
  • Introduces cat
  • Feeds cat
  • Cat will purr
  • function run(){
        def food:String = "tender vittles";
        for (cat:Cat in cats){
            letMeIntoHouse(cat);
            print("The cat named {cat.name} is ");
            cat.eat(food);
            cat.purr(5);
        }
    }

    Output

    LET ME IN! Meow...
    Scratching...
    The cat named fluffy is munchin on tender vittles
    Purrrr...level(5)
    LET ME IN! (ROAR) I'm King of the land!!!
    Scratching...
    The cat named Simba is munchin on tender vittles
    Purrrr...level(5)
    LET ME IN! Scratching...
    The cat named Chester is munchin on tender vittles
    Purrrr...level(5)

    Conclusion

    Although this example doesn’t use Mixins in an RIA context, instead its used with simple domain objects to show multiple inheritance. Hopefully we can now answer the question when asked, “Does JavaFX have multiple inheritance?“. Is it ever a quick answer?

    References:








    Follow

    Get every new post delivered to your Inbox.

    Join 51 other followers