Adam Bien's Weblog

Monday Feb 21, 2011

Hello JavaFX 2! - A TableView Component

A table control was missed in JavaFX 1.3. JavaFX 2 comes with a new table component:

import javafx.application.Application;
import javafx.application.Launcher;
import javafx.collections.FXCollections;
import javafx.collections.Sequence;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.table.TableColumn;
import javafx.scene.control.table.TableView;
import javafx.scene.control.table.model.SequenceTableModel;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start() {

        Stage stage = new Stage();
        stage.setTitle("Hello Table");

        final Group root = new Group();
        Scene scene = new Scene(root);
        stage.setScene(scene);

        Sequence children = root.getChildren();
        children.add(getTableView());
        stage.setVisible(true);
    }

 	//TableView is a node...
    public static Node getTableView() {

        Sequence data = fetchDataFromServer();

        TableView tableView = new TableView();
        SequenceTableModel tableModel = new SequenceTableModel(data);
        tableView.setModel(tableModel);

        TableColumn[] columns = buildColumns(data);
        tableView.getColumns().addAll(columns);
        return tableView;
    }

    //sequence is an Observable java.util.List. It could come directly from e.g. JPA EntityManager.
    public static Sequence fetchDataFromServer() {
        return FXCollections.sequence(
                new Person("Duke", "Java"),
                new Person("DukeFX", "JavaFX"));

    }

    public static TableColumn[] buildColumns(final Sequence data) {
        TableColumn firstNameCol = new TableColumn();
        firstNameCol.setText("First");
        firstNameCol.setGetCellData(new TableColumn.GetCellData() {

            @Override
            public Object get(long row, int col) {
                return data.get((int) row).getFirstName();
            }
        });

        TableColumn lastNameCol = new TableColumn();
        lastNameCol.setText("Last");
        lastNameCol.setGetCellData(new TableColumn.GetCellData() {

            @Override
            public Object get(long row, int col) {
                return data.get((int) row).getLastName();
            }
        });

        return new TableColumn[]{firstNameCol, lastNameCol};

    }

    public static void main(String[] args) {
        Launcher.launch(Main.class, args);
    }
}


public class Person {

    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
//with getters.
}

A similar example comes with JavaFX 2 already. I just decomposed the origin example in several methods to see what happens behind the scenes.
Java FX 2 application can be compiled having jfxrt.jar in the classpath and launched like any other Java application: java -cp javafx-sdk2.0-ea/rt/jfxrt.jar com.abien.table.Main
Even in the case of the preview the startup performance is <1 sec and significantly faster, than 1.X version.
This post is based on Java FX 2 Early Access - the API and runtime can change any time.
Sees official JavaFX roadmap for more details.


Special Events: Java 8 with Java EE 7: "More Power with Less Code", 13th October, 2014 and Java EE 7: "Testing and Code Quality", 14th October, 2014

A book about rethinking Java EE Patterns

Comments:

Hi,

thanks for the introduction. What does the table look like? Could you add a screenshot?

Andreas

Posted by Andreas Ebbert-Karroum on February 21, 2011 at 12:16 PM CET #

Hi Adam,
Thanks for creating this useful, cannot live without, site.

We have recently had to ditch javafx for a new desktop project which uses services from some of our existing java applications. This was purely due to the issues raised here

http://javafx.uservoice.com/forums/33584-official-javafx-feedback-forum/suggestions/403105-allow-us-to-distribute-the-javafx-runtime-binary

Can you update us on whether this is being addressed or not.
Tx

NB
Anyway, must say I really like your Rethinking Java EE book especially the Session Facade section.

Posted by Farouk on February 21, 2011 at 12:22 PM CET #

I'm little pissed. I only read how it is nice and cool, but still no early access to JavaFX 2.

I wonder if, and how bindings work. What components are present. JavaFx 1.3 was interesting, but JavaFX 2 looks like Swing called JavaFx... I want to build fast and easily good looking applications that communicates fast with server, and use BigDecimal, DatePickers, TreeTables.

JavaFx has problems on 64 bit Linux Machines (doesn't started). Can it be used now?

And technical...
Below construct will create inner class, increasing size of client archive. We had used such concepts in JWS, but moved to use some EL libraries, because, at the end applet + EL, is smaller then applet + numbers of inner class, and code is "readable".

lastNameCol.setGetCellData(new TableColumn.GetCellData() {
@Override public Object get(long row, int col) {
....

Posted by rsmogura on February 21, 2011 at 02:14 PM CET #

Hello Adam,

First thank you very very much for giving us such useful information of javafx 2.0.I'm really happy to know that oracle has done very good by porting javafx to java.

I've some question please:
# In above tableview component example I'd like to know how will we be able to use TableCellRenderer(of Swing) in javafx?
# Can I user my custom renderer only by extending DefaultTableCellRenderer(as of Java Swing) or do i need to extend a seperate class ?Hope Javafx done very good for this.

Thanks.
Narayan Gopal Maharjan

Posted by Narayan Gopal Maharjan on February 21, 2011 at 03:45 PM CET #

Hopefully the SDK or the new site will contain extensive, in-depth samples and blueprints / best practices? A Table component is usually a complex beast (unless Jonathan pulled some black magic of design), so we can't really judge it from single-page code samples. (Where are generic types, are they supported extensively in the sequences, binding, UI widgets etc.?)

I just can't help with my prejudice - JavaFX Script spoiled GUI programming forever for me; reading this code immediately brings a negative impression of "OMG, how verbose and non-intuitive". Hopefully Visage will fix this back... although I'm a performance junkie so I'm sure my first FX2 programs will be pure-Java, as I will be interested in looking again at things like startup time, resource usage etc. And I wonder if the Visage people will have the resources (or will give priority) to the miles-long list of javafxc compiler&RT optimizations that were still necessary.

Posted by Osvaldo Doederlein on February 21, 2011 at 08:32 PM CET #

"OMG, how verbose and non-intuitive"

Osvaldo, we are in the same boat. I think that there should be an external file layout similar to Flex (mxml) or Silverlight (xaml) that caters to those who use the "pure java" approach.

Posted by javajoe@hotmail.com on February 21, 2011 at 10:01 PM CET #

@rsmogura
Please email me your suggestions regarding alternate approaches for specifying functionality to retrieve cell data. My email is jonathan.giles@oracle.com.

@Narayan
You can't use Swing TableCellRenderers in the JavaFX TableView, but you can use the Cell approach we first introduced in JavaFX 1.3 in a similar style for the TableView control.

@Osvaldo
We are planning to put considerable effort into samples and blueprints - even the very first EA release of JavaFX 2.0 has a number of very nice samples and blueprints apps.

There is only so much black magic one can come up with on their own for the TableView control, so your thoughts and suggestions would be much appreciated! Please, please, please email me anything on your mind - otherwise you have no right to complain once JavaFX 2.0 is released :-)

I can't speak to Visage directly, but yes, Java is verbose - there is no escaping that. However, on the other side, by basing ourselves on Java, we open up a whole new world of alternative language support, which I think is both exciting, and pays back the verbosity of being based in Java. People are now free to write great user interfaces with a powerful and clean API in the language of their choice (presuming it's on the JVM).

@javajoe
I'm fairly certain I've mentioned this to you already, but we are actively researching providing external layout file support. We have prototypes internally and will be making more noise as soon as we can.

Posted by Jonathan Giles on February 22, 2011 at 01:41 PM CET #

@Jonathan,

"black magic" sounds good - makes me guessing the tableView already has the complete flexibility and functionality of a J/X/Table plus ... <g>

"no right to complain"? We have all and every right to complain whenever we find something's wrong. Right now, it can't happen as there's nothing out in the open yet. ;-)

Cheers
Jeanette

Posted by Kleopatra on February 22, 2011 at 02:07 PM CET #

@Jonathan

"We have prototypes internally and will be making more noise as soon as we can"

very much looking forward to it!

Posted by javajoe@hotmail.com on February 22, 2011 at 06:07 PM CET #

I really hope that javafx 2 when release, contain at least the same rich set of ui components (eg jsplitpane, jlist, tree, menu, shortcut key) as present in swing demo app as I believe it's initial success lies on how well it can attract existing swing developers to develop conventional app with it. Without a rich ui library, it could easily be perceived as just another hobby technology. I believe that comprehensive ui lib should be main priority in next major release.

Posted by Geekycoder on February 23, 2011 at 02:13 AM CET #

@Geekycoder
I hear you, and couldn't agree more :-)

My fulltime job is cranking out UI Controls for JavaFX 2.0, and we're doing well. We're bringing across all controls from JavaFX 1.3.1, including the preview controls (so TreeView and menu related controls).

On top of that, we are adding TableView, TabbedPane, and SplitPane to the 2.0 release.

We've also got some work going on with TitledPane and Accordion controls, although they have not been committed to quite yet.

Finally, and possibly most excitingly, remember that all UI controls will be open sourced. Hopefully this will lead to bug reports, feature suggestions, code patches, and entirely new controls being developed at a faster pace.

Posted by Jonathan Giles on February 23, 2011 at 02:46 AM CET #

For those looking for a declarative XML approach, check out swixml2, which is actively maintained: http://code.google.com/p/swixml2/

Posted by JP on February 23, 2011 at 03:51 PM CET #

Jonathan,
that's sound great. I can't wait to use javafx 2. :) . Look like Javafx team is on the right track now.

In the past, I thought that Javafx team has lost focus making javafx to run on mobile and javafx TV which waste valuable time and effort, not forgetting they somehow endup designing javafx to run in lowest denominator of the platforms, or whatever it means to run in "all the screens of your life".

I glad that javafx now focusing solely on the desktop platform because if it succeeds, it can then expand to mobile or TV or whatever screens of your life with more conviction (Just like apple's success with MacOS X which later spring off iOS). At least, succeed in one area gives hope than to fail miserably in all areas with no hope. Glad that javafx takes the pragmatic approach.

By the way, the pervasive marketing term for javafx, "all the screens of your life", really give me gooseberry. I wonder if the JavaFX team feels the same... :)

Posted by Geekycoder on February 23, 2011 at 07:02 PM CET #

Hello
Pleased to see Oracle team making an effort to put a app/web interface that is a java option to Flex and SilverLight, as we like Java and know java, so script languages/xml are not the right way for the base of java programmers.

This JavaFx 2.0 puts me in a situation , Currently I´m working in a desktop/JWS project, and almost all layers below (Oracle , DAO´s, BO´s) are ready and now I should begin the GUI interface. As time is not a problem, the question is that I don´t know if I continue with swing and JGoodies or wait for JavaFx 2.0 rs rs

What´s the probably shedule for JavaFx 2.0 launch ?

Posted by Luiz Seadorf on February 24, 2011 at 07:13 PM CET #

Hello ! How about update this post using the recent JavaFX beta release and a data source like jpa ? We will apreciate this.
thanks!

Posted by Paulo alessandre on May 27, 2011 at 04:50 PM CEST #

Please give an example of how to edit table cells .. and update data into table.

thanks in advance. i ve been looking around but couldn't find it.

Posted by andrew on June 09, 2011 at 04:17 PM CEST #

This example doesnt work anymore... this work for me, using api documentation example and this one.

package testfx;

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import testfx.classes.Person;

/**
*
* @author edcaceres
*/
public class TestFX extends Application {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Application.launch(TestFX.class, args);
}

@Override
public void start(Stage primaryStage) {
Group root = new Group();
Scene scene = new Scene(root);
primaryStage.setScene(scene);

ObservableList children = root.getChildren();
children.add(getTableView());
primaryStage.setVisible(true);
}

public static Node getTableView() {

ObservableList data = fetchData();

TableView tableView = new TableView();
tableView.setItems(data);

TableColumn<String> firstNameColumn = new TableColumn<String>("First Name");
firstNameColumn.setProperty("firstName");
TableColumn<String> lastNameColumn = new TableColumn<String>("Last name");
lastNameColumn.setProperty("lastName");

tableView.getColumns().setAll(firstNameColumn, lastNameColumn);
return tableView;
}

private static ObservableList fetchData() {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Eduardo", "Caceres"));
personList.add(new Person("Alejandro", "Caceres"));
return FXCollections.observableList(personList);
}
}

and person class:

package testfx.classes;

import javafx.beans.property.StringProperty;

/**
*
* @author edcaceres
*/
public class Person {

private StringProperty firstName;

public Person(StringProperty firstName, StringProperty lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

public Person(String fname, String lname) {
this.firstName = new StringProperty(fname);
this.lastName = new StringProperty(lname);
}

public void setFirstName(String value) {
firstNameProperty().set(value);
}

public String getFirstName() {
return firstNameProperty().get();
}

public StringProperty firstNameProperty() {
if (firstName == null) {
firstName = new StringProperty();
}
return firstName;
}
private StringProperty lastName;

public void setLastName(String value) {
lastNameProperty().set(value);
}

public String getLastName() {
return lastNameProperty().get();
}

public StringProperty lastNameProperty() {
if (lastName == null) {
lastName = new StringProperty();
}
return lastName;
}
}

Posted by Eduardo on July 21, 2011 at 10:29 PM CEST #

can you please help me to get a javafx2.0 code of carousel
i can't convert a code in javafx 1.3 to javafx 2.0
thanks

Posted by cedric sipa on July 25, 2011 at 08:27 PM CEST #

can you please help me to get a javafx2.0 code of carousel
i can't convert a code in javafx 1.3 to javafx 2.0
thanks

Posted by cedric sipa on July 25, 2011 at 08:28 PM CEST #

Hi,
I would like to build a table of objects having number of attributes contained into a list. The number of attributes can vary but all objects have the same number of attributes.
Does someone knows how to do this ?
Thanks.

Posted by Nicolas Albarello on October 28, 2011 at 08:23 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
realworldpatterns.com
...the last 150 posts
...the last 10 comments
Links
License