Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Column sorting in Table view

804628Sep 6 2012 — edited Sep 7 2012
I have a issue with sorting in table view and seeing a weird behavior. I have a table with 3 columns (Column Zero, Column First, Column Second) and all columns are set to setSortable(true). When I click on the column header on column First or Column Second, it doesn't sort the rows properly.

- Each rows data is stored inside a Person Object.
- Each column data is stored inside a Hashmap with key as the column index. Column 1's data is stored with key as 1 and columns 2 data is stored with key as 2 and so on and so forth.

The problem I am facing is when I click on the header to sort alphabetically, it doesn't sort properly.
Also, Whenever I click on any column header, only column zero is sorted and not the other column.

Sample code attached.

Please help.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package test;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 *
 */
public class Sample1 extends Application {

    private TableView<Person> table = new TableView<>();
    private final ObservableList<Person> data = populatePersons();
    final HBox hb = new HBox();

    private ObservableList<Person> populatePersons() {
        Person p1 = new Person("alex john");
        VOBean<Integer> p1columnValues = p1.getValues();
        p1columnValues.addValue(0, "A13");
        p1columnValues.addValue(1, "alex john Column 1 value");
        p1columnValues.addValue(2, "alex");


        Person p2 = new Person("ethan williams");
        VOBean<Integer> p2columnValues = p2.getValues();
        p2columnValues.addValue(0, "A14");
        p2columnValues.addValue(1, "ethan williams Column 1 value");
        p2columnValues.addValue(2, "ethan");


        Person p3 = new Person("isabella johnson");
        VOBean<Integer> p3columnValues = p3.getValues();
        p3columnValues.addValue(0, "A15");
        p3columnValues.addValue(1, "isabella johnson Column 1 value");
        p3columnValues.addValue(2, "isabella");


        Person p4 = new Person("emma jones");
        VOBean<Integer> p4columnValues = p4.getValues();
        p4columnValues.addValue(0, "A115");
        p4columnValues.addValue(1, "emma jones Column 1 value");
        p4columnValues.addValue(2, "emma");


        Person p5 = new Person("michael brown");
        VOBean<Integer> p5columnValues = p5.getValues();
        p5columnValues.addValue(0, "A16");
        p5columnValues.addValue(1, "michael brown Column 1 value");
        p5columnValues.addValue(2, "michael");


        Person p6 = new Person("jacob smith");
        VOBean<Integer> p6columnValues = p6.getValues();
        p6columnValues.addValue(0, "A1");
        p6columnValues.addValue(1, "jacob smith Column 1 value");
        p6columnValues.addValue(2, "jacob");


        Person p7 = new Person("micheal clark");
        VOBean<Integer> p7columnValues = p7.getValues();
        p7columnValues.addValue(0, "A2");
        p7columnValues.addValue(1, "micheal clark Column 1 value");
        p7columnValues.addValue(2, "micheal");


        Person p8 = new Person("paul adam");
        VOBean<Integer> p8columnValues = p8.getValues();
        p8columnValues.addValue(0, "A3");
        p8columnValues.addValue(1, "paul adam Column 1 value");
        p8columnValues.addValue(2, "paul");


        Person p9 = new Person("peter scott");
        VOBean<Integer> p9columnValues = p9.getValues();
        p9columnValues.addValue(0, "Z4");
        p9columnValues.addValue(1, "peter scott Column 1 value");
        p9columnValues.addValue(2, "peter");


        Person p10 = new Person("scott tiger");
        VOBean<Integer> p10columnValues = p10.getValues();
        p10columnValues.addValue(0, "A5");
        p10columnValues.addValue(1, "scott tiger Column 1 value");
        p10columnValues.addValue(2, "scott");


        Person p11 = new Person("hello world");
        VOBean<Integer> p11columnValues = p11.getValues();
        p11columnValues.addValue(0, "A6");
        p11columnValues.addValue(1, "hello world Column 1 value");
        p11columnValues.addValue(2, "hello");


        Person p12 = new Person("james watson");
        VOBean<Integer> p12columnValues = p12.getValues();
        p12columnValues.addValue(0, "A7");
        p12columnValues.addValue(1, "james watson Column 1 value");
        p12columnValues.addValue(2, "james");


        Person p13 = new Person("harry watson");
        VOBean<Integer> p13columnValues = p13.getValues();
        p13columnValues.addValue(0, "W8");
        p13columnValues.addValue(1, "harry watson Column 1 value");
        p13columnValues.addValue(2, "harry");


        Person p14 = new Person("issac henry");
        VOBean<Integer> p14columnValues = p14.getValues();
        p14columnValues.addValue(0, "A9");
        p14columnValues.addValue(1, "issac henry Column 1 value");
        p14columnValues.addValue(2, "issac");
        p14.setValues(p14columnValues);

        Person p15 = new Person("daniel kate");
        VOBean<Integer> p15columnValues = p15.getValues();
        p15columnValues.addValue(0, "A10");
        p15columnValues.addValue(1, "daniel kate Column 1 value");
        p15columnValues.addValue(2, "daniel");


        Person p16 = new Person("james cameroon");
        VOBean<Integer> p16columnValues = p16.getValues();
        p16columnValues.addValue(0, "A11");
        p16columnValues.addValue(1, "james cameroon Column 1 value");
        p16columnValues.addValue(2, "james");


        Person p17 = new Person("victor adams");
        VOBean<Integer> p17columnValues = p17.getValues();
        p17columnValues.addValue(0, "A12");
        p17columnValues.addValue(1, "victor adams Column 1 value");
        p17columnValues.addValue(2, "victor");

        ObservableList<Person> allPersonsData = FXCollections.observableArrayList();
        allPersonsData.add(p1);
        allPersonsData.add(p2);
        allPersonsData.add(p3);
        allPersonsData.add(p4);
        allPersonsData.add(p5);
        allPersonsData.add(p6);
        allPersonsData.add(p7);
        allPersonsData.add(p8);
        allPersonsData.add(p9);
        allPersonsData.add(p10);
        allPersonsData.add(p11);
        allPersonsData.add(p12);
        allPersonsData.add(p13);
        allPersonsData.add(p14);
        allPersonsData.add(p15);
        allPersonsData.add(p16);
        allPersonsData.add(p17);
        return allPersonsData;

    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(800);
        stage.setHeight(500);

        final Label label = new Label("Table View Sorting");
        label.setFont(new Font("Arial", 20));

        table.setEditable(true);

        TableColumn<Person, VOBean<Integer>> column0 = new TableColumn<>("Column Zero");
        column0.setCellValueFactory(new PropertyValueFactory<Person, VOBean<Integer>>("values"));

        Callback<TableColumn<Person, VOBean<Integer>>, TableCell<Person, VOBean<Integer>>> myCellFactory0 =
                new Callback<TableColumn<Person, VOBean<Integer>>, TableCell<Person, VOBean<Integer>>>() {

                    @Override
                    public TableCell<Person, VOBean<Integer>> call(TableColumn<Person, VOBean<Integer>> p) {
                        CustomCellFactory cscellFactory = new CustomCellFactory(0, "zeroName");

                        return cscellFactory;
                    }
                };
        column0.setCellFactory(myCellFactory0);
        column0.setEditable(true);
        column0.setSortable(true);
        column0.setPrefWidth(200.0);


        TableColumn<Person, VOBean<Integer>> column1 = new TableColumn<>("Column First");
        column1.setCellValueFactory(new PropertyValueFactory<Person, VOBean<Integer>>("values"));

        Callback<TableColumn<Person, VOBean<Integer>>, TableCell<Person, VOBean<Integer>>> myCellFactory =
                new Callback<TableColumn<Person, VOBean<Integer>>, TableCell<Person, VOBean<Integer>>>() {

                    @Override
                    public TableCell<Person, VOBean<Integer>> call(TableColumn<Person, VOBean<Integer>> p) {
                        CustomCellFactory cscellFactory = new CustomCellFactory(1, "firstName");

                        return cscellFactory;
                    }
                };
        column1.setCellFactory(myCellFactory);
        column1.setEditable(true);
        column1.setSortable(true);
        column1.setPrefWidth(200.0);

        TableColumn<Person, VOBean<Integer>> column2 = new TableColumn<>("Column Second");
        column2.setCellValueFactory(new PropertyValueFactory<Person, VOBean<Integer>>("values"));

        Callback<TableColumn<Person, VOBean<Integer>>, TableCell<Person, VOBean<Integer>>> myCellFactory2 =
                new Callback<TableColumn<Person, VOBean<Integer>>, TableCell<Person, VOBean<Integer>>>() {

                    @Override
                    public TableCell<Person, VOBean<Integer>> call(TableColumn<Person, VOBean<Integer>> p) {
                        CustomCellFactory cscellFactory = new CustomCellFactory(2, "secondName");

                        return cscellFactory;
                    }
                };
        column2.setCellFactory(myCellFactory2);
        column2.setEditable(true);
        column2.setSortable(true);
        column2.setPrefWidth(200.0);

        table.setItems(data);
        table.getColumns().addAll(column0, column1, column2);

        hb.setSpacing(3);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(label, table, hb);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);

        stage.setScene(scene);
        stage.show();
    }

    public class Person {

        private String personName;

        public Person() {
            super();
        }
        private VOBean<Integer> values = new VOBean<>();

        private Person(String personName) {
            this.personName = personName;
        }

        public String getPersonName() {
            return personName;
        }

        public void setPersonName(String personName) {
            this.personName = personName;
        }

        public VOBean<Integer> getValues() {
            return values;
        }

        public void setValues(VOBean<Integer> values) {
            this.values = values;
        }
    }

    public class VOBean<T> implements Serializable {

        private static final long serialVersionUID = 1L;

        public VOBean() {
            super();
        }
        private Map<T, Object> values;

        public Map<T, Object> getValues() {
            return values;
        }

        public void setValues(Map<T, Object> values) {

            this.values = values;

        }

        public Object getValue(T key) {
            if (getValues() != null) {
                return getValues().get(key);
            }
            return null;
        }

        public void addValue(T key, Object value) {
            if (getValues() == null) {
                setValues(new HashMap<T, Object>());
            }
            getValues().put(key, value);
        }

        public Object removeValue(T key) {
            if (getValues() == null || getValues().isEmpty()) {
                return null;
            }
            return getValues().remove(key);
        }

        public boolean isEmpty() {
            if (getValues() == null || getValues().isEmpty()) {
                return true;
            }
            return false;
        }

        @Override
        public String toString() {
            return "VOBean{" + "values=" + values + '}';
        }
    }

    public class CustomCellFactory extends TableCell<Person, VOBean<Integer>> {

        private static final long serialVersionUID = 1L;

        public CustomCellFactory() {
            super();
        }

        public CustomCellFactory(Integer columnIndex, String columnName) {
            super();
            this.columnIndex = columnIndex;
            this.columnName = columnName;
        }
        private String columnName;
        private Text inputText;
        private Integer columnIndex;

        @Override
        public void updateItem(VOBean<Integer> item, boolean empty) {
            super.updateItem(item, empty);

            if (item != null) {
                Object cellData = null;
                cellData = ((VOBean) item).getValues().get(getColumnIndex());
                if (cellData != null) {
                    inputText = new Text(cellData.toString());
                } else {
                    inputText = new Text("");
                }
                setGraphic(inputText);
            }
        }

        public Integer getColumnIndex() {
            return columnIndex;
        }

        public void setColumnIndex(Integer columnIndex) {
            this.columnIndex = columnIndex;
        }

        public String getColumnName() {
            return columnName;
        }

        public void setColumnName(String columnName) {
            this.columnName = columnName;
        }
    }
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Oct 5 2012
Added on Sep 6 2012
5 comments
3,133 views