Open Source JavaFX Now!

JFXtras Core Logo

XSwingTable

XSwingTable uses javax.swing.JTable to display and edit regular two-dimensional tables of cells. This makes it easy to use your existing javax.swing.table.TableModel implementations within a JavaFX GUI. We also provide table model implementations for JavaFX sequences; these table models provide binding support to enable you to keep your model data in sync with the table.

Sample Code

Example 1: string sequence.
import org.jfxtras.ext.swing.XSwingTable;
import org.jfxtras.ext.swing.table.StringSequenceTableModel;

import javafx.ext.swing.SwingScrollPane;

var names = ["Joe", "Fred", "Jane"];

SwingScrollPane {
    view: XSwingTable {
        tableModel: StringSequenceTableModel {
            sequence: bind names with inverse
            columnLabel: "Names"
            editable: true
        }
    }
}

Example 2: object sequence.

import org.jfxtras.ext.swing.XSwingTable;
import org.jfxtras.ext.swing.table.IntegerCell;
import org.jfxtras.ext.swing.table.Row;
import org.jfxtras.ext.swing.table.ObjectSequenceTableModel;
import org.jfxtras.ext.swing.table.StringCell;

import javafx.ext.swing.SwingScrollPane;

class Person {
    var forename:String;
    var surname:String;
    var age:Integer;
}

var employees = [
    Person {
        forename: "Joe"
        surname: "Bloggs"
        age: 45
    }
    Person {
        forename: "Fred"
        surname: "Bloggs"
        age: 60
    }
];

SwingScrollPane {
    view: XSwingTable {
        tableModel: ObjectSequenceTableModel {
            override function transformEntry(entry) {
                def person:Person = entry as Person;
                return Row {
                    cells: [
                        StringCell { value: bind person.forename }
                        StringCell {
                            value: bind person.surname with inverse
                            editable: true
                        }
                        IntegerCell { value: bind person.age }
                    ]
                }
            }
            columnLabels: ["Forename", "Surname", "Age"]
            sequence: bind employees
        }
     }
}

Example 3: table with form.

import org.jfxtras.ext.swing.XSwingTable;
import org.jfxtras.ext.swing.table.ListSelectionMode;
import org.jfxtras.ext.swing.table.ObjectSequenceTableModel;
import org.jfxtras.ext.swing.table.Row;
import org.jfxtras.ext.swing.table.StringCell;
import org.jfxtras.ext.swing.table.TableResizeMode;
import org.jfxtras.ext.swing.table.TableSelectionMode;
import org.jfxtras.scene.layout.MigNodeLayoutInfo;
import org.jfxtras.scene.layout.MigLayout;
import org.jfxtras.scene.XScene;

import javafx.ext.swing.SwingButton;
import javafx.ext.swing.SwingLabel;
import javafx.ext.swing.SwingScrollPane;
import javafx.ext.swing.SwingTextField;
import javafx.stage.Stage;

class Person {
    var forename:String;
    var surname:String;

    function copyTo(to:Person) {
        to.forename = forename;
        to.surname = surname;
    }
}

var people = [
  Person {
      forename: "Joe"
      surname: "Bloggs"
  }
  Person {
      forename: "Jane"
      surname: "Doe"
  }
  Person {
      forename: "Fred"
      surname: "Bloggs"
  }
];

var selectedPerson:Person = null on replace {
    if (selectedPerson == null) {
        Person{}.copyTo(detailPerson);
    } else {
        selectedPerson.copyTo(detailPerson);
    }
}

// unfortunatly we can't use selectedPerson directly because
// you can't bind with inverse to the property of a var
def detailPerson = Person {}

var editPanel:MigLayout;
var swingTable:XSwingTable;
Stage {
    width: 350
    height: 300
    title: ##[app_title]"XSwingTable Demo"
    scene: XScene  {
        content: MigLayout {
            constraints: "wrap 1"
            rows: "[]unrel[]"
            content: [
                SwingScrollPane {
                    view: swingTable = XSwingTable {
                        autoResizeMode: TableResizeMode.AUTO_RESIZE_OFF
                        tableModel: ObjectSequenceTableModel {
                            override function transformEntry(entry) {
                                def person:Person = entry as Person;
                                return Row {
                                    cells: [
                                        StringCell { value: bind person.forename }
                                        StringCell { value: bind person.surname }
                                    ]
                                }
                            }
                            columnLabels: [##[forename_label]"Forename", ##[surname_label]"Surname"]
                            sequence: bind people
                        }
                        tableSelectionMode: TableSelectionMode.ROW;
                        rowSelectionMode: ListSelectionMode.SINGLE_SELECTION;
                        onSelectedRowChanged: function(selectedRowIndex) {
                            selectedPerson = if (selectedRowIndex == null)
                                then null
                                else people[selectedRowIndex];
                        }
                    }
                }
                editPanel = MigLayout {
                    constraints: "insets 0, wrap 2"
                    rows: "[]unrel[]"
                    content: [
                        SwingLabel {
                            text: ##[forename_label]"Forename"
                        }
                        SwingTextField {
                            text: bind detailPerson.forename with inverse
                            columns: 12
                        }

                        SwingLabel {
                            text: ##[surname_label]"Surname"
                        }
                        SwingTextField {
                            text: bind detailPerson.surname with inverse
                            columns: 12
                        }

                        SwingButton {
                            layoutInfo: MigNodeLayoutInfo {
                                constraints: "spanx 2, split 3"
                            }
                            disable: bind selectedPerson == null
                            text: ##[update_button]"Update"
                            action: function () {
                                detailPerson.copyTo(selectedPerson);
                            }
                        }
                        SwingButton {
                            text: ##[add_button]"Add"
                            action: function () {
                                def newPerson = Person {}
                                detailPerson.copyTo(newPerson);
                                insert newPerson into people;

                                // select new row
                                var newSelectionIndex = sizeof people - 1;
                                var jTable = swingTable.getJTable();
                                var selectionModel = jTable.getSelectionModel();
                                selectionModel.setSelectionInterval(newSelectionIndex, newSelectionIndex);
                                // scroll to new row
                                jTable.scrollRectToVisible(jTable.getCellRect(newSelectionIndex, 0, true));
                            }
                        }
                        SwingButton {
                            text: ##[delete_button]"Delete"
                            disable: bind selectedPerson == null
                            action: function () {
                                delete selectedPerson from people;
                            }
                        }
                    ]
                }
            ]
        }
    }
}

0 Attachments 0 Attachments
1424 Views