Skip to content

Category: english

JavaFX, handling events with overlapping elements

Here is a problem I faced those days while programming with JavaFX.
When you perform a click in a JavaFX area, mouse events are called to all nodes through that position. You can see this behavior in this video.

Example 1.

Here is the code.

import javafx.application.*;
import javafx.scene.geometry.*;
import javafx.scene.geometry.Rectangle;
import javafx.scene.paint.Color;
import javafx.input.MouseEvent;
 
Frame {
    width: 200
    height: 200
    visible: true
    stage: Stage {
        content: [
            Rectangle {
                var color1 = Color.BLUE;
                x: 10, y: 10, width: 140, height: 90, fill: bind color1
                onMouseClicked: function( e: MouseEvent ):Void {
                    if (color1==Color.BLUE){
                        color1 = Color.GREEN;
                    } else {
                        color1 = Color.BLUE
                    }
                }
            },
            Circle {
                var color2 = Color.RED
                centerX: 100, centerY: 100, radius: 40, fill: bind color2
                onMouseClicked: function( e: MouseEvent ):Void {
                    if (color2==Color.YELLOW){
                        color2 = Color.RED;
                    } else {
                        color2 = Color.YELLOW
                    }
                }
            }
        ]
    }
}

This is the default behavior. All node are called with a mouse event. Is a expected and robust behavior but sometimes we just don’t want that. We want events called to just one node or a set of nodes.

Example 2.

Is exactly the same code but with blocksMouse: true in the circle node. When blocksMouse is true the mouse event will not be called to others node behind it.

package overlapping;
 
import javafx.application.*;
import javafx.scene.geometry.*;
import javafx.scene.geometry.Rectangle;
import javafx.scene.paint.Color;
import javafx.input.MouseEvent;
 
Frame {
    width: 200
    height: 200
    visible: true
    stage: Stage {
        content: [
            Rectangle {
                var color1 = Color.BLUE;
                x: 10, y: 10, width: 140, height: 90, fill: bind color1
                onMouseClicked: function( e: MouseEvent ):Void {
                    if (color1==Color.BLUE){
                        color1 = Color.GREEN;
                    } else {
                        color1 = Color.BLUE
                    }
                }
            },
            Circle {
                var color2 = Color.RED
                centerX: 100, centerY: 100, radius: 40, fill: bind color2
                blocksMouse: true
                onMouseClicked: function( e: MouseEvent ):Void {
                    if (color2==Color.YELLOW){
                        color2 = Color.RED;
                    } else {
                        color2 = Color.YELLOW
                    }
                }
            }
        ]
    }
}

Thanks guys on the OpenJDK user mail list and at OpenJFX Forum, specially this thread.

Script to Installing JavaFX Compiler

Right in this moment you can choose between three options to develop JavaFX:

I did this little script to download the last version of JavaFX continuos build and install it for you.

#!/bin/sh
envfile=$HOME/.bash_profile
 
#download and unpatch the last build of JavaFx
mkdir jfx
cd jfx
wget http://openjfx.java.sun.com/hudson/job/openjfx-compiler/lastBuild/artifact/openjfx-compiler/dist//*zip*/dist.zip
unzip dist.zip
rm dist.zip
 
#set files at bin folder as executable
chmod +x dist/bin/*
 
#add those executables to the path
echo "PATH=\$PATH:`pwd`/dist/bin" >> $envfile

Save this script as install_jfx.sh and execute it. Probably you want to execute it at you home directory. If you want to install JavaFX to root change envfile for /root/.bash_profile, if you want to install to all users change for /etc/profile. I tested this script successfully on my Ubuntu 8.04.

After that open a new terminal and try to see if javafx, javafxc and javafxdoc are available. You can test your enviroment with this simple program.

import javafx.ui.*;
import java.lang.*;
 
Frame {
  visible: true
  content: FlowPanel {
  content: Button {
      var n = 0
      text: bind Integer.toString(n)
      action: function() {
        n++;
      }
    }
  }
}

Save it as Counter.fx, compile with javafxc Counter.fx and so execute it with javafx Counter.fx.

To know more, take a look into the preliminary JavaFX API or in the article Using JavaFX GUI Toolkit.

Java Calendar Examples

import java.util.Calendar;
 
public class Main {
    public static void main(String[] args) {
        Calendar today = Calendar.getInstance();
        System.out.println("Today is  " + today.getTime());
    }
}

In this simplest example of Calendar, the output would be

Today is : Tue Jul 01 10:56:14 BRT 2008

In the next example how to get information about the day inside the year, month and week.

import java.util.Calendar;
 
public class Main {
    public static void main(String[] args) {
        Calendar today = Calendar.getInstance();
        int dof = today.get(Calendar.DAY_OF_YEAR);
        int dom = today.get(Calendar.DAY_OF_MONTH);
        int dow = today.get(Calendar.DAY_OF_WEEK);
        System.out.println("Today is the " + dof +"º day in this year,");
        System.out.println("the " + dom +"º day in this month");
        System.out.println("and the " + dow +"º day in this week.");
    }
}

The output could be

Today is the 183º day in this year,
the 1º day in this month
and the 3º day in this week.

The next example is about how to add (and subtract) a duration from a Calendar.

import java.util.Calendar;
 
public class Main {
    public static void main(String[] args) {
        Calendar today = Calendar.getInstance();
        System.out.println("Today is " + today.getTime());
 
        Calendar yesterday = (Calendar)today.clone();
        yesterday.add(Calendar.DATE, -1);
        System.out.println("Yesterday was " + yesterday.getTime());
 
        Calendar tomorow = (Calendar)today.clone();
        tomorow.add(Calendar.DATE, 1);
        System.out.println("Tomorow will be " + tomorow.getTime());
    }
}

A typical output would be

Today is Tue Jul 01 10:44:18 BRT 2008
Yesterday was Mon Jun 30 10:44:18 BRT 2008
Tomorow will be Wed Jul 02 10:44:18 BRT 2008

Event Review: Comsolid

This week I did another presentation outside my city. This time it was at Maracanau in the Comsolid, a open source and digital inclusion event.

IMG_0080

My first presentation was about ZFS filesystem and how you can take benefits from it like pooling storage and self healing. I used as base for examples my last post on it, Trying to corrupt data in a ZFS mirror.

Eu

IMG_0112
Eu
IMG_0114

My next talk was about OpenSolaris. We had a lot of questions and interesting about this. We burned some cds with OpenSolaris 2008.5 and also distributed others versions of OpenSolaris like Solaris 10.

IMG_0120

And my last presentation was a quick talk about high performance computing, a short version on that I already did before.

Was a interesting event mainly because the public was composed primarily by young students with few background on TI. It was a challenge to present some new concepts like pooling storage for those who aren’t familiar with filesystems management. I tried to keep my talk as simpler as I could and focus on daily problems and showing that you can avoid them with some open source technologies.

The full album is available at http://flickr.com/photos/silveiraneto/sets/72157605632001295/.