samedi 20 mars 2010

More UI controls for the next release

I don’t know who is Sungmoon Cho, but according to linkedin he is JavaFX Product Line Manager at Sun Microsystems.
Some time ago, he has opened
Official JavaFX Feedback Forum to ask us what we are suggesting for JavaFX.
My answers were (the number before the item, is my number of vote for this item):

And recently (on Friday 19th), Sungmoon Cho updated the the JavaFX FeedBack Forum for the following items:
·         Create more native components, like form items, grids and menus.
with the status planned and the comment
"We are adding a lot more UI controls for the next release. Please stay tuned "
·         Quick application
with the status planned and the comment
"We have a dedicated team of people who work on startup performance. We see significant improvement so far, but we know that it should be much faster. We will update you when we have more data "
·         Quick application startup
with the status under review and the comment
"Many people asked this so we are reviewing this item "

lundi 15 mars 2010

JavaFX and JPA 2.0 with my custom component

In this third and last part, we are going to create a small application which dynamically updates the results in the result list when the user types the search word(s) in a text box.
To do that we will re-use the table and the entity created in the part one, the java class MusicServices.java created in the part two and my search text box that I've created some time ago (with a small correction).

Main.fx
package javafxjpa2searchtextbox;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import customcomponent.SearchTextBox;
import javafx.scene.control.ListView;
import paddy.domain.Music;
import paddy.service.MusicServices;

/**
 * @author Patrick
 */

var listMusic;

var seqMusic:Music[];

var musicServices:MusicServices = MusicServices{};

Stage {
    title: "Application title"
    width: 600
    height: 250
    scene: Scene {
        stylesheets : ["{__DIR__}resources/mac.css"]
        content: [
            Text {
                font: Font {
                    size: 16
                }
                x: 10
                y: 30
                content: "Search DB"
            }
            SearchTextBox {
                translateX: 10
                translateY: 40
                onResetSearch: function () {
                    println("reset !");
                        delete seqMusic;
                    }
                onSearch: function (s: String) {
                    println("Search of : {s}");

                    listMusic = musicServices.getArtisteNameBeginingBy(s);
                    delete seqMusic;
                    seqMusic = listMusic.toArray(seqMusic);

                    }
            }
            ListView {
                layoutY: 75
                width: 575
                height: 100
                items: bind seqMusic
            }
        ]
    }
}

The key points:
  • Delete the sequence on the onResetSearch event of the SearchTextBox component
    delete seqMusic;
  • Call the getArtisteNameBeginningBy method, delete the sequence and refill it on the onSearch event  of the SearchTextBox component
    listMusic = musicServices.getArtisteNameBeginningBy(s);
    delete seqMusic;
    seqMusic = listMusic.toArray(seqMusic);

Get the NetBeans project           
Note: don’t forget to create (in NetBeans) a library containing the jar DerbyClient.jar and being called DerbyClient.

mardi 2 mars 2010

JavaFX and the Databases with JPA 2.0

In the first part, we have seen how to access data with JPA. In this second part we are going to see how to get data from database with JPA 2.0 and to display them with JavaFX.


To do that we will re-use the table and the entity created in the part one, and we will create a Java class which contains the code to execute the JPA requests.
Let’s go and create the Java class.
The Java class contains one constructor to create the EntityManager and 2 methods:
findAll():
This method gets all the records from the table and uses the namedQuery findAllAlbum

getArtisteNameBeginningBy(String begining):
This method get all the records from the table where the field artisteName begin by the parameter
"begining"
For this second method, I use criteria API just because I wanted to test it…
Normally in this case, we don’t have to use criteria API because we don’t need to create dynamically a query and the criteria API was created to build dynamically and safely a query (without to concatenate strings to build a jpql request, like in JPA 1.0).
The best way to do that, is to use directly a jpql request like this


Query query = em.createQuery("select m from Music m where m.artisteName like :param");
query.setParameter("param", param);
List<Music> musics = query.getResultList();

Or, if you want, create another namedQuery in the Entity

@NamedQueries({
   @NamedQuery(name = "findAllAlbum", query= "select m from Music m"),
   @NamedQuery(name = "findAllAlbumWhereArtisteLike",query="select m from Music m where m.artisteName like :param")
})

And call it like that

Query  query = em.createNamedQuery("findAllAlbumWhereArtisteLike");
query.setParameter("param", param);
List<Music> musics = query.getResultList();

We will not use this method in this part but in the last part.

MusicServices.java
package paddy.service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import paddy.domain.Music;

/**
 *
 * @author Patrick
 */
public class MusicServices {

    EntityManagerFactory emf;
    EntityManager em;

    public MusicServices(){
        emf = Persistence.createEntityManagerFactory("MusicAndLight");
        em = emf.createEntityManager();
    }

    public List<Music> findAll(){

        Query  query = em.createNamedQuery("findAllAlbum");
        List<Music> musics = query.getResultList();

        return musics;
    }

    public List<Music> getArtisteNameBeginningBy(String begining){

        String param = begining+"%";

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Music> query = cb.createQuery(Music.class);
        
        Root<Music> music = query.from(Music.class);
        query.where(cb.like(music.<String>get("artisteName"), param));
        List<Music> musics = em.createQuery(query).getResultList();

        return musics;
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            em.close();
            emf.close();
        } finally {
            super.finalize();
        }
    }
}

Now, let’s call this class from javaFX to get the data from the database and to display them in JavaFX

Main.fx
package javafxjpa2basic;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.Button;
import paddy.domain.Music;
import paddy.service.MusicServices;

/**
 * @author Patrick
 */

var listMusic;
var seqMusic:Music[];

var musicServices:MusicServices = MusicServices{};

Stage {
    title: "Application title"
    scene: Scene {
        width: 600
        height: 175
        content: [
            Button {
                text: "Find all the musics"
                action: function() {
                        delete seqMusic;

                        listMusic = musicServices.findAll();
                        seqMusic = listMusic.toArray(seqMusic);                        

                        println("seqMusic: {seqMusic} ");
                }
            }
            ListView {
                layoutY : 50
                 width: 575
                 height : 100
                 items: bind seqMusic
            }
        ]
    }
}
 
The key points :
  •  Creating an instance of the Java class in JavaFX
    var musicServices:MusicServices = MusicServices{};
  • Calling the findAll method
    listMusic = musicServices.findAll();
  • Converting the java list to a JavaFX sequence
    seqMusic = listMusic.toArray(seqMusic);
  • Binding the sequence to the JavaFX GUI List
    items: bind seqMusic
Note: don’t forget to create (in NetBeans) a library containing the jar DerbyClient.jar and being called DerbyClient.

mardi 23 février 2010

JavaFX Composer, the blog!

The JavaFX Composer Team has opened a new blog about…
JavaFX Composer, of course ;)

http://blogs.sun.com/javafxcomposer/

lundi 22 février 2010

Examples using JPA 2.0

This is the first part of 3 that shows you how to get data from database with JPA 2.0 and display them with JavaFX.
In this first part we are going:
  • to create the database and one table
  • to create the entity and the persistence.xml file
  • to use a namedQuery
  • to use criteria query API
Create the database and the table
  • Create a derby database with :
    • Database Name : javafxDB
    • UserName : APP
    • Password : paddy
  • Create the music table and fill it.
Execute this script to create the music table and fill it
The music table has 3 fields: an auto generated id, the name of the artist (artist_name) and the name of the album (album_title) …
And of course, it’s just for an example ;)
The Entity and the persistence unit
  • The Entity which is mapped to music table

Music.java
package paddy.domain;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQuery;

/**
 *
 * @author Patrick
 */
@Entity
@NamedQuery(name = "findAllAlbum", query= "select m from Music m")

public class Music implements Serializable {

    @Id
    @GeneratedValue
    private Long id;
    @Column(name = "artist_name")
    private String artisteName;
    @Column(name = "album_title")
    private String albumTitle;

    public Music() {
    }
    
    ...
    Getter and setter
    ...
    
    @Override
    public String toString(){

        StringBuffer sb = new StringBuffer();
        sb.append("id : ");sb.append(id);sb.append(" ; ");
        sb.append("artisteName : ");sb.append(artisteName);sb.append(" ; ");
        sb.append("albumTitle : ");sb.append(albumTitle);
        sb.append(" \n");

        return sb.toString();
    }

}
Full source here
The entity is just a plain old Java object (pojo) with some annotations.

@Entity:  designate my pojo as an entity so I can use it with JPA services.
@Id: designate the property as the entity's primary key
@GeneratedValue: used with @Id, it defines that this value is generated automatically
@Column: is used, in my example, to mapped the property of the entity with the field of the table
@NamedQuery(name = "findAllAlbum", query= "select m from Music m")  is used  to create pre-defined queries which get all record from music table.
  • The persistence.xml file
META-INF\persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="MusicAndLight" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>paddy.domain.Music</class>
    <properties>
      <property name="eclipselink.target-database" value="DERBY"/>
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/javafxDB"/>
      <property name="javax.persistence.jdbc.user" value="APP"/>
      <property name="javax.persistence.jdbc.password" value="paddy"/>
    </properties>
  </persistence-unit>
</persistence>
The persistence.xml file defined:
    • the persistence unit named MusicAndLight
    • the entity (paddy.domain.Music) managed by the persistence unit
    • and how the persistence unit connects to the database
Execute query by using a namedQuery
namedQuery
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MusicAndLight");
        EntityManager em = emf.createEntityManager();

        //get and create the namedQuery findAllBum
        Query  query = em.createNamedQuery("findAllAlbum");
        //execute the query
        List<Music> musics = query.getResultList();

        for (Music music : musics){
            System.out.println(music);
        }

        em.close();
        emf.close();
    
Execute query by using a criteria API
Criteria Api
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MusicAndLight");
        EntityManager em = emf.createEntityManager();

        String param = "Arc%";

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Music> query2 = cb.createQuery(Music.class);
        //select * from Music
        Root<Music> music2 = query2.from(Music.class);
        //where artisteName like param
        //in my example where artisteName like Arc% (begining by Arc)
        query2.where(cb.like(music2.<String>get("artisteName"), param));
        //execute the query
        List<Music> musics2 = em.createQuery(query2).getResultList();

        for (Music music : musics2){
            System.out.println(music);
        }

        em.close();
        emf.close();
    

Note: don’t forget to create (in NetBeans) a library containing the jar DerbyClient.jar and being called DerbyClient.

lundi 25 janvier 2010

Eclipse et Ubuntu 9.10 …

Au départ, je voulais juste installer le plugin Android avec la dernière version d’Eclipse(3.5.1) sur mon Ubuntu 9.10. 
La chose parait assez simple de premier abord…
Mais impossible d’installer le plugin, les boutons ne produisent aucune action, les listes ne s’affichent pas, etc…
La cause du problème provient d’Eclipse qui utilise la bibliothèque UI SWT se basant les composants UI natif  GTK+
et comme le comportement interne de GTK+ a changé dans la version de GTK+ (2.18) utilisée dans Ubuntu 9.10 et que SWT utilise très mal et bidouille trop GTK+, ca ne marche plus.
https://bugs.launchpad.net/ubuntu/+source/gtk+2.0/+bug/442078/comments/28

Heureusement les créateurs on prévu le coup et il existe une variable pour redonner le comportement d’avant avec cette version de GTK+.
La solution est donc de créer un script  pour lancer Eclipse avec la variable GDK_NATIVE_WINDOWS positionnée à  1
launch_eclipse.sh
#!/bin/bash
export  GDK_NATIVE_WINDOWS=1
/home/patrick/patrick/program/eclipse.org/eclipse-javaEE-galileo/eclipse/eclipse
Ou /home/patrick/patrick/program/eclipse.org/eclipse-javaEE-galileo/eclipse/eclipse est l’emplacement de votre exécutable Eclipse

Sinon NetBeans fonctionne très bien ;)
Note : Le problème existe aussi avec toutes les applications Eclipse RCP et je pense SWT

dimanche 10 janvier 2010

Scrolling with DisplacementMap effect

Bonne Année ! , Happy New Year !

For beginning this New Year, I added a sinusoidal effect to my scroll.
To do that, I added a
DisplacementMap effect to the scroll line.

DisplacementMap Effect
                    effect: DisplacementMap { mapData: map
                                              input:Reflection {
                                                   fraction: 0.75
                                                   topOffset: 0.0
                                                   topOpacity: 0.5
                                                   bottomOpacity: 0.0
                                               } 
                  } 

And I created a FloatMap to make the sinusoidal effect

FloatMap
var widthScroll = letterWidth * 10;    // 10 chars
var map = FloatMap { width: widthScroll height: letterHeight }
for (i:Integer in [0..<widthScroll]) {
    var v = (Math.sin(i/35.0*Math.PI)-0.5)/30.0;
    for (j:Integer in [0..<letterHeight]) {
        map.setSamples(i, j, 0.0, v);
    }
}
As you see in the code, the DisplacementMap effect take a FloatMap as parameter. And each individual entry in the FloatMap contains per-pixel offset information in the x and y direction.

For example if you have this image

My FloatMap contains offsets x and y to have

Download full Main.fx

Download StringConverter.fx