Aportación Java México - PCJ - Tabla fácil en JavaFX

Esto es un pequeño ejemplo de como crear una tabla de manera sencilla en la tecnología JavaFX.

¿Esto por qué? Es una de las cosas que más se necesitan en programas sencillos, y resulta algo difícil de encontrar documentación o ejemplos de como crear una tabla con scroll y que responda a eventos del ratón.

Trate en este mismo ejemplo de poner muchas de las características importantes de la tecnología JavaFX, como 'bind', 'CustomNode', como usar un 'for' para regresar un matriz, como asignar datos en un 'for', como eliminar de una secuencia un elemento 'Node', si se le da click a una fila esta desaparece... como implementar un scroll, como usar un 'VBox' y un 'HBox', como usar un 'Group'... bueno en resumen creo que cubre muchas de las necesidades de un ejemplo muy completo de JavaFX.

package tablafx;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.Group;

/**
 * @author Rodrigo Salado Anaya
 */

/*nombres de la tabla*/
var nombres = ['luis', 'mago', 'lobo', 'musha', 'rodrigo'];
/*grupos*/
var grupos = ['freebsd.org', 'linuxmexico.org', 'javadu.org', 'underhub.net', 'javamexico.org'];
/*insertamos los datos necesarios para crear la tabla*/
var tabla: Tabla = Tabla { nombres: nombres, grupos: grupos };
/*un pequeño scroll*/
var scroll = ScrollBar {
            translateX: 222//posición a la derecha
            translateY: 0 //posición de inicio en lo alto
            height: 60//ancho del scroll
            blockIncrement: 10//incremento
            clickToPosition: true//si al dar un click con el raton se tralade el valor.
            vertical: true//para que sea vertical
        };
/*para mover toda la tabla con un grupo sale excelente... pero hay muchos metodos*/
var tablaConScroll: Group = Group {
            translateY: bind -scroll.value//negativo para que se vaya para arriba las filas
            content: [tabla.generarTabla()]//el contenido del grupo
        };

Stage {
    title: "Tabla facil en JavaFX"
    resizable: false
    scene: Scene {
        width: 220 + 2 + 13//el ancho de una fila es de 220 pero dejamos un poquito más
        height: 60;//el alto de la tabla
        content: [tablaConScroll, scroll]//mandamos a llamar la tabla creada
    }
}

package tablafx;

import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.LayoutInfo;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.layout.HBox;
import javafx.geometry.HPos;
import javafx.scene.input.MouseEvent;

/**
 * @author Rodrigo Salado Anaya
 */

public class FilaItem extends CustomNode {

    /*id. 'id' es una palabra reservada*/
    public var iD: Label = Label { text: "" layoutInfo: LayoutInfo { width: 20 } hpos: HPos.CENTER }
    /*nombre*/
    public var nombre: Label = Label { text: "" layoutInfo: LayoutInfo { width: 100 } hpos: HPos.CENTER }
    /*grupo*/
    public var grupo: Label = Label { text: "" layoutInfo: LayoutInfo { width: 100 } hpos: HPos.CENTER }
    /*marco en el fondo de la fila*/
    public var marco: Rectangle = Rectangle { width: 220 height: 15 fill: Color.WHITESMOKE stroke: Color.BLACK }
    /*caja horizontal. Sirbe para ordenar los datos contenidos en el*/
    var fila: HBox = HBox { content: [iD, nombre, grupo] }

    /*crea el nodo*/
    public override function create(): Node {
        /*posicionamos el marco*/
        marco.x = 0;
        marco.y = 0;
        /*posicionamos la fila*/
        fila.translateX = 0;
        fila.translateY = 0;
        /*regresamos los atributos de la fila como un grupo*/
        return Group {
                    content: [marco, fila]
                    /*cuando el raton pase por la fila se cambia de color*/
                    onMouseEntered: function (e: MouseEvent): Void {
                        marco.fill = Color.LIGHTBLUE;
                    }
                    /*cuando el raton sale regresa a su color original (el marco)*/
                    onMouseExited: function (e: MouseEvent): Void {
                        marco.fill = Color.WHITESMOKE;
                    }
                };
    }

}

package tablafx;

import javafx.scene.layout.VBox;

/**
 * @author Rodrigo Salado Anaya
 */

public class Tabla {

    /*nombres de las filas*/
    public var nombres: String[];
    /*grupos de las filas*/
    public var grupos: String[];

    /*retorna filas ordenadas verticalmente*/
    public function generarTabla(): VBox {
        /*representa la tabla, solo su declaración*/
        var tabla: VBox;
        /*son las filas de la tabla*/
        var filas: FilaItem[] = for (n in nombres) {
                    /*se crea la fila*/
                    var fila: FilaItem = FilaItem { }
                    /*se asigna el iD de la fila, que no es lo mismo que el 'id' del nodo*/
                    fila.iD.text = "{indexof n}";
                    /*se asigna el nombre... contenido en 'n'*/
                    fila.nombre.text = n;
                    /*se asigna el grupo*/
                    fila.grupo.text = grupos[indexof n];
                    /*cuando el mouse de clic en la fila sera eliminada del conjunto*/
                    fila.onMouseClicked = function (MouseEvent): Void {
                        delete fila from tabla.content;
                    }
                    /*los items fila, se asignan a 'filas' de manera muy clara...*/
                    fila;
                }
        /*se insertan las filas a la tabla y les damos un espacionde 3 unidades entre cada una*/
        tabla = VBox { content: [filas] spacing: 3 }
        /*la falta de return es evidente, como en el caso del 'for'*/
        tabla;
    }

}

Adjunto imagen del muy sencillo ejemplo :)

Jajajaj voten por mi =P.

AdjuntoTamaño
tabla.png158.29 KB

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Shadonwk

Mucho codigo

Hola compa como estas: es un excelente tuto. pero mucho codigo jaja, sabes cual hubieras mandado? Distribuir una applicacion JavaFX aun sigo sin saber como hacerlo :X, en fin como siempre excelente material. espero y obtengas una de las 5 invitaciones cuentas con mi voto!

Imagen de rodrigo salado anaya

Muchos comentarios...

Si se ve mucho pero ... podría ser más. Por otro lado tiene muchos comentarios y quería ejemplificar varias características de JavaFX, la simple tabla se pudo haber hecho así:

package tablasimple;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.input.MouseEvent;

/**
 * @author Rodrigo Salado Anaya <xxxxx@xxx.xx>
 */

var tabla: VBox = VBox {
            spacing: 3
            content: [
                for (n in [0..5]) {
                    var rec: Rectangle = Rectangle {
                                width: 100, height: 10
                                fill: Color.rgb(222, indexof n*30, 255)
                                onMouseClicked: function (e: MouseEvent): Void {
                                    delete rec from tabla.content;
                                }
                            }
                }
            ]
        }

Stage {
    title: "Application title"
    scene: Scene {
        width: 101
        height: 80
        content: [tabla]
    }
}

pero gracias carnalito (Shadonwk), nos leemos pronto... =P

Ese si se ve simple :)

Ese si se ve simple :)

Imagen de rodrigo salado anaya

Puedes....

Usar estas paginas para ver como distribuir una aplicación...

http://java.sun.com/j2se/1.3/docs/tooldocs/win32/keytool.html
http://java.sun.com/j2se/1.3/docs/tooldocs/win32/jarsigner.html

nos leemos pronto va :)

Imagen de rugi

JNLP

Bueno.... lo de la distribución , dada las features de JavaFX, puedes rapidamente generar un JNLP para poder distribuirlo rapidamente.

Felicitaciones a Rodrigo por animarse a escribir algo sobre JavaFX.... mi voto, ya lo tienes ;)

Imagen de Jhanno

Revisado PCJ

Lo que realmente vale en ser "simples" es lograr una páctica constante. Gracias por tu aporte.

Imagen de rodrigo salado anaya

JavaFX 1.3, ListView, Cell API

Con la llegada de la versión 1.3 de JavaFX, se colaron nuevas chucherías, como las ListView, con un plus buenisimo, 'Cell', este es un ejemplo de como implementarlo... y no es una solución a una tabla para mostrar datos de una 'BD', pero a mi gusto es muy poderosa por que se puede listar muchisimos nodos y el rendimiento es muy bueno, como a los '9,999,999' aun trabaja bien... yo lo probé incluso con animaciones sencillas pero jalo muy bien, dejo pues un ejemplo usando la clase 'FilaItem' de este post:

ListView {
    items: [1..9999999]
    cellFactory: function () {
        var ep: FilaItem;
        def cell: ListCell = ListCell {
                    node: ep = FilaItem {visible: bind if (cell.empty) then false else true }
                    onMouseClicked: function (e) {
                        //println("{cell.listView.selectedItem }||{cell.listView.items}");
                        delete cell.listView.selectedItem from cell.listView.items;
                    }
                    blocksMouse: false
                }
        return cell;
    }
}

Nota: JavaFX 1.3, mejoro su desempeño en 'binding'. Con este poco de código, me hubiera evitado una clase completa y un scroll, y etc, etc.

Se puede usar JavaFX en una aplicación Java?

¿Se puede ( ... más bien si se puede pero no sé como ) usar un front end en JavaFX con backend en Java?

Se me ocurre que se puede hacer una aplicación de escritorio, donde en vez de usar Swing, se pudiera usar JavaFX.

Existe algo tan fácil como:

public class MyApp {
      public static void main( String [] args ) {
            // JFrame frame  = .... ahh no mejor con JavaFX
            ObjetoXyz xyz  = metodoMagicoParaLlamarAJavaFXAquí();
            xyz.setEmployee( Employee.searchBy("etcetcet"));
      }
}
 

Donde el main es una aplicacoin Java, y el ObjetoXyz es un handler para el la pantalla en JavaFX?

?

EDIT

Doh!!! el primer resultado en google -> http://blogs.sun.com/javafx/entry/how_to_use_javafx_in

:P

Estaría bien ver un hola mundo con esto. Mhhh quizá después

Imagen de rodrigo salado anaya

Si OscarRyz

De echo esa es la finalidad de JavaFX.
Si quieres te ayudo con un post sencillisimo, tu haces la parte de core y te ayudo con detalle con lo lo gráfico (JavaFX), o echale un ojo a este ejemplo: http://theorymatters.wordpress.com/category/javafx/
puedes descargar el código para echarle el colmillo, incluso puedes usar sintaxis de java duro, y correrá igual.

Nota: no correrá con la versión 1.3... por que fue echa con una versión anterior, aun así el código dice mucho...

update :P: o mejor ve mi comentario en: http://www.javamexico.org/foros/java_enterprise/tratamiento_de_imagenes
y uso java y lo mando a llamar desde mi javafx....

@Rodrigo

Ah ya vi tu ejemplo en ese post, me saco mucho de onda por que el nombre de tu case está con minusculas y parecía un metodo sin tipo de retorno y etc.

Pero ya entendí, entonces desde JavaFX a Java se hace

    SomeClass {}

Y listo, pero y de Java como se llama a JavaFX? ( que era mi prgunta original )

Imagen de rodrigo salado anaya

ok @Oscar...

Ok, por fa.., aguantame en la noche, después del trabajo me doy a la tarea de pasarte como hacer el pequeño ejemplo en JavaFX, y con eso espero despejarte la duda, por lo mientras dale una leída a esto:

http://blog.netopyr.com/2008/03/15/writing-java-code-for-javafx-script/
y
http://blog.netopyr.com/2008/03/21/using-javafx-objects-in-java-code/

Nota: chin se me fue lo de poner las clases en mayúsculas, luego en la noche como que se me apaga en cerebro... :P, y soy malo explicando así que si te surgen dudas no te desesperes va, solo no dejes de preguntar, y ya le buscamos solución...

Imagen de rodrigo salado anaya

@Oscar, un pequeño avance...

Imagen de Fozzie

Llenar Tabla

Buenas compañeros, buen post, yo apenas comienzo a ver y usar JavaFx y pues intento hacer una aplicacion Desktop Bussines Application con BD que realice consultas y necesito hacer una tabla en una escena para mostrar registros y ya viendo el post pues vi que si se pueden usar tablas solo que no se como hacer mi tabla en mi aplicación, necesito ponerla en una de las escenas que tengo, porque ocupo un choiceBox de donde elijo a que escena ir, y ya que elija la escena donde debe estar la tabla que quiero poner pues mostrarla con los datos de la bd que tengo, pero en las condiciones ya que abro la escena no se como poner la tabla, alguna sugerencia, soy novato pero pues igual y pueden echarme la mano...

Intente hacer una tabla sencilla como la de rodrigo salado e intentar ponerla en el content pero me marca error si le agrego el content: [tabla], como lo tengo sin agregar la tabla esta asi:

javafx.stage.Stage {
title: "Query Management"
style: StageStyle.TRANSPARENT
scene: design.getDesignScene ()
}

entonces si agrego el content: [tabla] donde tabla es la var donde creo la tabla sencilla como la de rodrigo me marca error "cannot find simbol" y no se entonces como agregarle una tabla a mi aplicacion, arriba de este codigo tengo los if para el choiceBox y el de los botones y mi conexion.

De antemano les doy las gracias por la ayuda que puedan darme...

gracias

Imagen de rodrigo salado anaya

javafx script || visage

Pues ya no usaria JavaFx Script por que pues.... pues nomas por que ya no le dan soporte mejor ve los ejemplos que vienen en el beta de javafx 2.0, encontraras que usan un par de tablas y SORPRESA que no son precisamente de JavaFX si no las implementan con Swing.

http://www.javamexico.org/blogs/rodrigo_salado_anaya/javafx_20_beta_tip_1

Bueno checa los ejemplos y si surgen dudas solo pregunta (primero lees esto)

Imagen de Fozzie

Tabla Swing en JavaFx Desktop Business App

Hey buenas, gracias por tu repuesta Rodrigo, he leido lo que me decías, vi los ejemplos y la verdad me parecieron un poco complejos el entenderlos, pude notar que usan tablas en swing, aunque usan varias clases y todo, como les mencione soy muy nuevo en esto y estoy aprendiendo pero no pude entender mucho de estos ejemplos, aunque ahora intente hacer mi tabla pero vuelvo al mismo problema de antes, lo que pasa es que yo estoy trabajando con una aplicación JavaFx Desktop Business Application y el ejemplo de donde intente guiarme es de JavaFx Script Application, entonces al crear la tabla en mi aplicación el código no me da ningún error, el problema es al asignar la tabla y/o su contenido al stage, porque en el ejemplo de Javafx script va así:

Stage {
title: "Query Management"
scene: Scene {
width: 600
height: 400
content: ContactEditor{
contacts: bind contacts with inverse
}
}

entonces en el content me marca error y en la linea de contacts: bind...

esto porque en mi aplicación esta esta parte de esta manera:

javafx.stage.Stage { ----------------------------> esto es lo que tiene de diferente, no se como hacerlo entonces
title: "Query Management"
style: StageStyle.TRANSPARENT
scene: design.getDesignScene ()
content: stageContactEditor{ -----------------------> aquí me marca el error
contacts: bind contacts with inverse -------------/
}
}

Entonces no puedo hasta ahora hacer mi tabla para intentar llenarla con información desde una bd, se que tal vez sea un tanto cuanto tonto, pero la verdad no entiendo mucho y hago lo que puedo, espero puedan echarme una mano y disculpen mi ignorancia...

Gracias de antemano

Imagen de rodrigo salado anaya

Que onda :)

Que onda Fozzie, no te compliques la vida usando JavaFX Script, has de saber que ya no le dan soporte a esa tecnología, lo que ahora se tiene que hacer es usar JavaFX como si de un API se tratara y pues puedes usar tablas swing y javafx como en el ejemplo SwingJavaFXChart, te dejo una liga que te ayudara:

http://download.oracle.com/javase/tutorial/uiswing/components/table.html
http://www.java2s.com/Code/Java/Swing-JFC/TableModelExample.htm

La verdad ando apurado estos días pero con gusto te ayudare en el ratito que pueda...

Solo como tip debes de agregar la librería jfxrt.jar a tus proyectos JavaFX...

Imagen de Fozzie

Añadir Tabla a Scene

Que onda Rodrigo, ya lei los tutos de las ligas que dejaste... pero sigo con problemas :( ...

En mi proyecto Desktop App de JavaFx tengo varias escenas, donde me logeo según una BD y abre otra escena y así sucesivamente y en una de estas la penúltima escena, tengo un botón donde al dar clic tiene que llevarme a una ultima escena y mostrarme la tan ansiada tabla cargada con datos desde una bd.... pero no puedo mostrarla!! ;( en ese proyecto hecho en desktop application no en Javafx Scrip agrege una clase *.java donde creo una tabla, y en el main de la Desktop App tengo las validaciones de las escenas y la conexión a la bd para el login y demás, y en el código del botón que abrira la escena donde quiero mostrar la tabla, aquí creo un objeto de la clase donde hago mi tabla y después la intento mostrar como en swing y no me marca error pero no me muestra la tabla y me salen 8 warnings, me imagino que así no se asigna a la escena pero no se como mostrarla, o asignársela a la escena final... necesito terminarlo, yo se que se puede pero no lo logro hacer!!... disculpa mi ignorancia :(

algo así hago
function buttonActionAtLoginY(): Void {

var IP: String = "";
var company: String = "";

var tabla = new TablasG(); ------> Aquí hago el objeto de la clase donde creo mi tabla
tabla.setVisible(true);-------------> así intento mostrarla, pero no es así :( y no se como mostrar la tabla en la escena que quiero

var rs1: ResultSet = null;

var dbase: database = database {
driverName: 'com.mysql.jdbc.Connection'
jdbcUrl: 'jdbc:mysql://{IP}/clientes'
user: {us}//user: 'root' ---Esta es la conexión que uso nada que importe ahora
password: {pss}//password: 'pupus'
};

dbase.connect();

try {
rs1 = dbase.consultar("SELECT task FROM todos WHERE id = 1");
if (rs1.next()) {
var resultado: String = rs1.getString(1);
java.lang.System.out.println("Resultset");
java.lang.System.out.println(resultado);}else{java.lang.System.out.println("Pendejo!!!");} ----- una selección para probar la conexión
} catch (e: SQLException) {
JOptionPane.showMessageDialog(null, "No se pudo Conectar Wey!! Revisa el Cod");
}

Esto es lo que hay al final de todo el código en mis validaciones y demás que omití por no ser de interés para lo que intento:

function run (): Void {
var design = Main {};
//var tabla = new TablasG();

javafx.stage.Stage {
title: "Query Management"
style: StageStyle.TRANSPARENT
scene: design.getDesignScene ()
}
}
una
yo pensé que podría ser como JavaFx Scrip que se asignara la tabla no se en el content del stage o la escena y ahí agregar la tabla de alguna forma, lo intente poniendo el content así:

function run (): Void {
var design = Main {};
//var tabla = new TablasG();

javafx.stage.Stage {
title: "Query Management"
style: StageStyle.TRANSPARENT
scene: design.getDesignScene ()
content: VBox{
content: [tabla]
}
}
}

pero tampoco y no encuentro como podria hacerlo....

ah y así es el código de la clase de mi tabla

public class TablasG extends JFrame{

public TablasG(){

Object[ ][ ] data = {
{"Cesar","Julio","Manuel","Prueba", new Integer(5)},
{"Tabla","Columna","Fila","Java", new Integer(6)},
{"JavaFx","Codigo","Intento","Try", new Integer(7)},
{"Tablas2","Tres","cuatro","cinco", new Integer(8)}
};
String[] columnNam = {"Colum1", "Colum2", "Colum3", "Colum4"};

final JTable table = new JTable(data, columnNam);
table.setPreferredScrollableViewportSize(new Dimension(300, 80));
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane, BorderLayout.CENTER);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}

Gracias de antemano :(

@fozzie Puedes editar tu

@fozzie Puedes editar tu post y reformatearlo incluyendo los tags <code> y </code> ? Por cierto, JavaFX script está descontinuado no crees que valdría la pena averiguar como se hace lo que quieres usando JavaFX 2.0 ?

Imagen de Fozzie

!!!!

Oh! no lo sabia gracias por el aviso, mmmm y pues si lo se, que ya no le dan soporte, y lo de JavaFx 2.0 pues no lo había pensado... pero entonces tendría que usar netbeans 7 mas el plugin de JavaFx 2.0?.... veré también a ver que encuentro... deseo terminar esto, yo se que se puede pero pues haber que pasa, lo checare...

No necesariamente ( aunque

No necesariamente ( aunque honestamente no he usado Netbeans )

Solo tienes que bajar el SDK, instalarlo y luego desde tu netbeans usarlo como cualquier otra biblioteca ( como java.util.* o javax.swing.* )

Tengo una duda ¿por que usas netbeans? Sucede que durante mucho tiempo no conocí nadie que lo usara y ahora van apareciendo muchos.

En fin..

Imagen de Fozzie

Netbeans

Ammm orale va, pues ya lo estoy descargando junto con Netbeans 7....

y pues uso netbeans porque fue el IDE con el que comence a ver este show de la programacion, se que existe tambien eclipse pero pues no lo he usado... ¿tiene o hay algun problema con Netbeans? o ¿por que la pregunta y sopresa de que uso netbeans? ¿tu que IDE utilizas o me recomiendas usar y por que?

¿no tienes idea de como hacer lo que quiero con lo de mi tabla swing en javafx?

Gracias por la ayuda...

Por que cuando salio

Por que cuando salio inicialmente ( hace muchos años ) era malísimo. Pero veo que en años recientes ( como desde la v5+ ) mejoró bastante lo cual me prece genial.

Lo que me estaba preguntando es si estaría asociado a que en el downloads de Java viene como bundled.

Y no, no le veo nada malo ( no lo he usado ). Yo uso Intellj IDEA desde la v2.6, pero tampoco lo uso para cosas muy rudas ni nada.