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!

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,180 views