001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2012 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.client.tide.collections.javafx;
022    
023    import org.granite.tide.data.model.SortInfo;
024    
025    import javafx.beans.property.ReadOnlyProperty;
026    import javafx.beans.value.ObservableValue;
027    import javafx.scene.control.TableColumn;
028    import javafx.scene.control.TableColumn.SortType;
029    import javafx.scene.control.TableView;
030    
031    /**
032     * @author William DRAI
033     */
034    public class TableViewSortAdapter<S> implements SortAdapter {
035            
036            private TableView<S> tableView;
037            private S exampleData;
038    
039            public TableViewSortAdapter(final TableView<S> tableView, final Class<S> exampleDataClass) {
040                    this.tableView = tableView;
041                    try {
042                            this.exampleData = exampleDataClass.newInstance();
043                    }
044                    catch (Exception e) {
045                            throw new RuntimeException("Could not instantiate example data class " + exampleDataClass, e);
046                    }
047            }
048            
049            public void apply(SortInfo sortInfo) {
050                    String[] order = sortInfo.getOrder();
051                    boolean[] desc = sortInfo.getDesc();
052                    
053                    if (order != null && desc != null) {
054                            // Apply current sort to attached TableView
055                            tableView.getSortOrder().clear();
056                            for (int i = 0; i < order.length; i++) {
057                                    for (TableColumn<S, ?> column : tableView.getColumns()) {
058                                            ObservableValue<?> property = column.getCellObservableValue(exampleData);
059                                            if (property instanceof ReadOnlyProperty<?> && ((ReadOnlyProperty<?>)property).getName().equals(order[i])) {
060                                                    tableView.getSortOrder().add(column);
061                                                    column.setSortType(desc[i] ? SortType.DESCENDING : SortType.ASCENDING);
062                                            }
063                                    }
064                            }
065                    }
066            }
067            
068            public void retrieve(SortInfo sortInfo) {
069                    int i = 0;
070                    String[] order = new String[tableView.getSortOrder().size()];
071                    boolean[] desc = new boolean[tableView.getSortOrder().size()];
072                    for (TableColumn<S, ?> column : tableView.getSortOrder()) {
073                            ObservableValue<?> property = column.getCellObservableValue(exampleData);
074                            if (property instanceof ReadOnlyProperty<?>) {
075                                    order[i] = ((ReadOnlyProperty<?>)property).getName();
076                                    desc[i] = column.getSortType() == SortType.DESCENDING;
077                                    i++;
078                            }
079                            else
080                                    throw new IllegalArgumentException("Sortable cell values must implement Property to apply TableViewSort adapter");
081                    }
082                    sortInfo.setOrder(order.length > 0 ? order : null);
083                    sortInfo.setDesc(desc.length > 0 ? desc : null);
084            }
085    }