Archive for the ‘SnapCode’ Category

SnapCode is the first and only pure JavaFX IDE

June 11, 2014

SnapCode is now the first and only pure JavaFX IDE! This allows SnapCode to easily implement page transitions, mouse over effects, animations and the SnapCode visual code editing that give SnapCode the feel of rich modern applications.

For the last two weeks we’ve been converting the remaining Swing parts of SnapCode to pure JavaFX. This includes the code editor, the runtime browser/player, the welcome panel and much more. We had some secret sauce in there that made the port happen remarkably quick.

This is just our first preview of the pure JavaFX world. We promise a balance of tasteful modern UI effects as we continue to polish SnapCode. But for now, we couldn’t resist some gratuitous effects that JavaFX makes so easy.

Check out the video overview and let us know what you think!

YouTube Video Overview: SnapCode is the First pure JavaFX IDE.



Getting the Visible Bounds of a Node

June 11, 2014

Today I set out to optimize a custom text node I have (for code editing) to only create nodes for lines of text that are visible – much like ListView only create cell nodes for visible items.

So the crux of this is that I needed a method similar to Swing’s JComponent.getVisibleRect() to tell me the visible bounds for my text node, which is usually in a ScrollPane. It seems there is currently no Node method for this and I couldn’t find previous work online, so I thought I would post my solution.

Here is a method that was sufficient for my purposes – it returns the visible bounds for a node based on the first ancestor clip (which could be from a ScrollPane, SplitPane or any Parent that clips its children):

 * Returns the visible bounds for a node based on first ancestor clip
 * (or null if no clipping found).
public static Bounds getVisibleBounds(Node aNode)
    // If node not visible, return empty bounds
    if(!aNode.isVisible()) return new BoundingBox(0,0,-1,-1);
    // If node has clip, return clip bounds in node coords
    if(aNode.getClip()!=null) return aNode.getClip().getBoundsInParent();
    // If node has parent, get parent visible bounds in node coords
    Bounds bounds = aNode.getParent()!=null? getVisibleBounds(aNode.getParent()) : null;
    if(bounds!=null && !bounds.isEmpty()) bounds = aNode.parentToLocal(bounds);
    return bounds;

I also wrote a version called getVisibleBoundsScene(node) which intersects the combined clips of every ancestor node all the way up to the scene. This version was only slightly more complicated, but it turned out to be overkill. In fact, if you have animations where panels are sliding in and out, of Parent containers, using the cumulative intersection of visible bounds can significantly slow things down.

So after I had my VisibleBounds solution, I had one more problem: if I only add child nodes for the visible bounds, I also need to rebuild when those visible bounds change. I achieved this by listening for bounds changes in ancestors up to the clip, a list that is updated every time the node is rebuilt. Below is the code I used for that.

 * Sets listeners for visible bounds.
void setVisibleBoundsListeners()
    // Get list of ancestors up to first clip (just return if same as last time)
    List pars = new ArrayList();
    for(Node p=this; p!=null && p.getClip()==null; p=p.getParent()) pars.add(p);
    if(pars.equals(_pars)) return;
    // Stop listening to old ancestors, start listening to new
    for(Node par : _pars) par.boundsInParentProperty().removeListener(_bcl);
    _pars = pars;
    for(Node par : _pars) par.boundsInParentProperty().addListener(_bcl);

// Listeners
List  _pars = new ArrayList();
ChangeListener _bcl = new ChangeListener() {
    public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
        resetChildNodes(); }}; 

Make ScrollPane Content fill Viewport Bounds

June 3, 2014

One of the most common issues I find when using ScrollPanes in JavaFX is that I need the Content to fill the width/height when the ScrollPane.ViewportBounds is larger than the Content.PrefWidth/PrefHeight.

My first thought was that the ScrollPane properties FitToWidth and FitToHeight were meant to solve this – but they force the Content to ViewportBounds even when the Content has a larger PrefWidth/PrefHeight (this is probably useful for things like a wrapped text view). I suppose it should be possible to create a conditional binding for these properties, but I haven’t looked into this.

My second thought was that maybe I could call HBox.setHgrow(content, Priority.Always) and VBox.setVGrow(content, Priority.Always), but that was ineffective.

The solution I settled on was to add a ChangeListener to ScrollPane.ViewportBoundsProperty to reset Content.MinWidth/MinHeight:

// Create ScrollPane
final ScrollPane spane = new ScrollPane(aTextArea);

// Add listener to set content min width/height from viewport bounds
spane.viewportBoundsProperty().addListener(new ChangeListener() {
  public void changed(ObservableValue<? extends Bounds> arg0, Bounds arg1, Bounds arg2) {
    if(spane.getContent() instanceof Region) {
      Region content = (Region)spane.getContent();

Please comment if you have a better solution.

SplitPane Animation with DoubleTransition

May 29, 2014

Today I added a nice effect to SnapCode which slides a SplitPane item onscreen when a button is clicked. This functionality was actually ported over from Swing where it required a significant amount of code, but in JavaFX, I was able to achieve the same effect with just a few lines of code.

So when I click on the “Add Support Pane” button, this code adds the SupportPane to the SplitPane and triggers the animation:

  DoubleProperty dprop = mySplitPn.getDividers().get(0).positionProperty();
  DoubleTransition dt = new DoubleTransition(Duration.millis(500), dprop);
  dt.setFromValue(1); dt.setToValue(500);;

When I click the button again (to remove), similar code is called, except that the item is removed OnFished:

  DoubleProperty dprop = mySplitPn.getDividers().get(0).positionProperty();
  DoubleTransition dt = new DoubleTransition(Duration.millis(500), dprop);
  dt.setOnFinished(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent e) {
      getBrowserBox().getItems().remove(1); }});

So it is very simple to add such a nice animated effect. Now the only slight complication is that there is no “DoubleTransition” class in JavaFX. It turns out that this class is trivial to implement with just a slight modification to something like FadeTransition. And this DoubleTransition class will undoubtedly come in handy in other places as well.

Here is a link to the source:

And a link to a simple video demo as well: SplitPane Animation Video

SuperMario JavaFX in SnapCode

May 15, 2014

This week I flushed out more SnapCode JavaFX sprite functionality using a version of Super Mario written for Greenfoot. This required new SnapScene API to control the order of painting: setPaintOrder(classes) and some touch up to the hit detection code. Check out the two minute video below.

YouTube Video: SuperMario JavaFX in SnapCode


JavaFX PacMan in SnapCode with Greenfoot

May 6, 2014

This week I flushed out a set of classes to emulate Greenfoot in JavaFX and  SnapCode. My test case was a nice version of PacMan written by Dan Post. For this I had to add a number of drawing methods to SnapImage (which uses JavaFX Canvas) and I had to add support for playing MP3 sound files (which uses JavaFX Media and MediaPlayer).

Check out the screenshot and 3 minute video of the game in action with some custom/silly JavaFX modding thrown in for fun.

YouTube Video: JavaFX PacMan in SnapCode with Greenfoot


SnapCode Update April 25: Added SnapImage

April 27, 2014

This week I added a class to SnapCode to facilitate “sprite” programming with SnapActor. The class is called SnapImage and it has methods to load an image from a file name, and methods to do all kinds of drawing and basic image manipulation: flipImage, rotateImage, sizeImage, setColor (for a pixel), etc.

SnapActor now has a primary attribute that is a SnapImage, so you can easily create actors with custom drawing and you can easily change the look of an actor on the fly by resetting or manipulating the SnapActor.Image.

Additionally, I added a new SnapActor subclass to make it possible to have compound or nested actors. This class is called SnapParent, and it basically has a list attribute called Actors that lets you add/remove child actors, and it has methods to do hit detection on those child actors and/or retrieve subsets of the actors by class. Since this essentially what SnapScene does, I made SnapScene a SnapParent subclass to get more consistency and code re-use.

Here is a full list of the week’s changes:

- SnapImage: Added class to add rendering and drawing functionality to Actors
– SnapImage: Added flipImageX/flipImageY/rotateImage() to get current image in new orientation
– SnapImage: Added getColor(int,int) and setColor(int,int,color)
– SnapImage: Added Opacity attribute
– SnapImage: Added fillRoundRect, strokeLine, strokeRect, strokeRoundRect
– SnapImage: Added drawImage(image, x,y)
– SnapScene: Added start/stop methods
– SnapParent: Created Actor subclass that can have child actors
– SnapScene: Made this a subclass of SnapParent so it gets same Actor/Image management

SnapCode is available here.

JavaFX Asteroids with Greenfoot and SnapCode

April 21, 2014

This week I wrote a simple emulation library (4 classes) to run Greenfoot applications without modification in JavaFX and SnapCode. My test case is Asteroids for Greenfoot from their wonderful programming book.

The following 2 minute video shows loading the Asteroids project from a simple HTTP repository at and running Asteroids. At the end, there is even some Asteroids modding. :-)

I haven’t done any performance work yet, but the game runs fine – even when I mod the game to fill the screen with asteroids. Check out the video below.



JavaFX Asteroids with Greenfoot and SnapCode


SnapCode Update April 18: Added Hit Detection

April 19, 2014

This week added some hit detection methods to the SnapActor class:


This makes it possible to determine whether a given actor overlaps (or “hit”) another actor and will be useful for most games. Additionally, we updated the KeyDown and KeyClicked functionality to handle multiple down/clicked keys at once – because it turns out that real gameplay often involves this (head-smack).

Early next week I’ll release our test case – a JavaFX/SnapCode version of asteroids. Below is the full list of improvements made to SnapCode this week.

- SnapActor: Added getIntersectingActor/getIntersectingActors
– SnapActor: Added getActorsInRange
– SnapScene: Fixed KeyDown to be a Set of KeyCodes instead of just one
– SnapActor: Fixed to have X/Y be at center of actor
– SnapAnimator: Fixed to animate X/Y instead of LayoutX/Y
– SnapAnimator: Added moveTo()
– SnapScene: Made default scene have main() and act() methods
– SnapPartStmt: Fixed dropNode on bottom of block statement
– SnapActor: Fixed setWidth/setHeight to preserve x/y
– SnapActor: Added getDistance(actor)
– SnapScene: Added removeActor()
– SnapScene: Made playSound() check /sounds directory
– SnapScene, SnapActor: Renamed MousePressed/KeyPressed methods to be MouseDown/KeyDown.

SnapCode Update April 11: Added ShowCoords and more

April 11, 2014

This week added a nice SnapCode feature for working with the standard graphics coordinate system: a new method on the Scene class called setShowCoords(boolean) to have the scene draw the coordinate system along with the current mouse point. This makes it easier to plot coordinates in the scene.

Additionally, there are a couple new methods to customize the scene and console. The Scene class has a getColor()/setColor() method. And you can now ask the Scene for the Console, which has new methods to set the Font and FontSize.

Finally, there are a couple of new actor methods to get the angle and distance to the mouse or another actor: getAngle(“Mouse/Actor-Name”), getDistance(“Mouse/Actor-Name”). These make it easy to have an actor point or move to the mouse or another actor.

Here is an image of the scene with ShowCoords enabled.



Get every new post delivered to your Inbox.