View Javadoc
1   /*******************************************************************************
2    * jhunters: Pool League
3    * Copyright 2015 Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   ********************************************************************************/
17  package net.sourceforge.jhunters.pool.ui;
18  
19  import java.util.Iterator;
20  
21  import org.w3c.dom.Element;
22  
23  import javafx.beans.value.ObservableValue;
24  import javafx.collections.FXCollections;
25  import javafx.collections.ObservableList;
26  import javafx.geometry.Pos;
27  import javafx.scene.control.TableCell;
28  import javafx.scene.control.TableColumn;
29  import javafx.scene.control.TableColumn.CellDataFeatures;
30  import javafx.util.Callback;
31  import net.sourceforge.jhunters.pool.data.Competition;
32  import net.sourceforge.jhunters.pool.data.CompetitionFixtures;
33  import net.sourceforge.jhunters.pool.data.CompetitionFixtures.FixtureRecord;
34  import net.sourceforge.jhunters.pool.data.CompetitionFixtures.PlayerFixtureField;
35  import net.sourceforge.jhunters.pool.data.DataParser;
36  import net.sourceforge.jhunters.pool.data.DataSet;
37  import net.sourceforge.jhunters.pool.data.Player.PlayerField;
38  import net.sourceforge.jhunters.pool.data.Result;
39  import net.sourceforge.jhunters.pool.ui.ReportPanel.TableSource;
40  import net.sourceforge.jhunters.pool.ui.TableUtils.FieldTableColumn;
41  import net.sourceforge.jhunters.pool.ui.TableUtils.FieldTableView;
42  
43  /**
44   * Matrix Table.
45   */
46  public class ResultsTable
47          extends FieldTableView<CompetitionFixtures, PlayerFixtureField>
48          implements TableSource {
49      /**
50       * Width for player.
51       */
52      protected static final int WIDTH_PLAYER = 100;
53  
54      /**
55       * Width for value.
56       */
57      protected static final int WIDTH_VALUE = 32;
58  
59      /**
60       * Width for fixture.
61       */
62      private static final int WIDTH_FIXTURE = 72;
63  
64      /**
65       * Results format.
66       */
67      private static final String RESULTS_FORMAT = GuiResource.REPORT_RESULTS_TITLE.getValue();
68  
69      /**
70       * Fixture cell factory.
71       */
72      private final Callback<TableColumn<CompetitionFixtures, FixtureRecord>, TableCell<CompetitionFixtures, FixtureRecord>> theFixtureCellFactory;
73  
74      /**
75       * Current dataSet.
76       */
77      private DataSet theDataSet;
78  
79      /**
80       * Current analysis list.
81       */
82      private ObservableList<CompetitionFixtures> theList;
83  
84      /**
85       * Current # of fixture columns.
86       */
87      private int theNumColumns = 0;
88  
89      /**
90       * Constructor.
91       */
92      protected ResultsTable() {
93          /* Disallow editing */
94          setEditable(false);
95  
96          /* Access column list */
97          ObservableList<TableColumn<CompetitionFixtures, ?>> myColumns = getColumns();
98  
99          /* Create the player column */
100         TableColumn<CompetitionFixtures, String> myPlayerCol = new FieldTableColumn<CompetitionFixtures, PlayerFixtureField, String>(PlayerFixtureField.NAME);
101         myPlayerCol.setCellValueFactory(p -> p.getValue().getPlayer().nameProperty());
102         myPlayerCol.setCellFactory(TableUtils.itemCellFactory(Pos.CENTER_RIGHT));
103         myPlayerCol.setMinWidth(WIDTH_PLAYER);
104         myColumns.add(myPlayerCol);
105 
106         /* Create the id column */
107         TableColumn<CompetitionFixtures, String> myIdCol = new FieldTableColumn<CompetitionFixtures, PlayerFixtureField, String>(PlayerFixtureField.ID);
108         myIdCol.setCellValueFactory(p -> p.getValue().idProperty());
109         myIdCol.setCellFactory(TableUtils.itemCellFactory(Pos.CENTER));
110         myIdCol.setMinWidth(WIDTH_VALUE);
111         myColumns.add(myIdCol);
112 
113         /* Create the fixture cell factory */
114         theFixtureCellFactory = TableUtils.itemCellFactory(Pos.CENTER);
115     }
116 
117     /**
118      * Adjust columns.
119      */
120     private void adjustColumns() {
121         /* Determine required columns */
122         int myNumColumns = theList.size();
123         ObservableList<TableColumn<CompetitionFixtures, ?>> myColumns = getColumns();
124 
125         /* If we need to add columns */
126         while (myNumColumns > theNumColumns) {
127             /* Create the fixture column */
128             TableColumn<CompetitionFixtures, FixtureRecord> myFixCol = new FieldTableColumn<CompetitionFixtures, PlayerFixtureField, FixtureRecord>(PlayerFixtureField.FIXTURE,
129                     CompetitionFixtures.getIdForIndex(theNumColumns));
130             myFixCol.setCellValueFactory(new FixtureCellValueFactory(theNumColumns));
131             myFixCol.setCellFactory(theFixtureCellFactory);
132             myFixCol.setMinWidth(WIDTH_FIXTURE);
133             myColumns.add(myFixCol);
134             theNumColumns++;
135         }
136 
137         /* If we need to remove columns */
138         while (myNumColumns < theNumColumns) {
139             /* Remove last column */
140             int iSize = myColumns.size();
141             myColumns.remove(iSize - 1);
142             theNumColumns--;
143         }
144     }
145 
146     /**
147      * Set dataSet.
148      * @param pData the dataSet
149      */
150     protected void setData(final DataSet pData) {
151         /* Store the DataSet */
152         theDataSet = pData;
153     }
154 
155     /**
156      * Set table data.
157      * @param pCompetition the competition
158      */
159     protected void setCompetition(final Competition pCompetition) {
160         /* Access the fixture list */
161         theList = pCompetition != null
162                                        ? pCompetition.getMatrix().getMatrix()
163                                        : FXCollections.observableArrayList();
164 
165         /* Declare the list */
166         setItems(theList);
167 
168         /* adjust the columns */
169         if (pCompetition != null) {
170             adjustColumns();
171         }
172     }
173 
174     @Override
175     public void buildReport(final ReportBuilder pBuilder) {
176         /* Build the main report */
177         buildMainReport(pBuilder);
178     }
179 
180     @Override
181     public void createWeb(final ReportBuilder pBuilder) {
182         /* Build the main report */
183         buildRotatedReport(pBuilder);
184     }
185 
186     /**
187      * build the main report.
188      * @param pBuilder the builder
189      */
190     private void buildMainReport(final ReportBuilder pBuilder) {
191         /* Create a new table */
192         pBuilder.newTinyTable();
193 
194         /* Set caption */
195         pBuilder.setTableCaption(RESULTS_FORMAT, DataParser.formatDate(theDataSet.getLastChange()));
196 
197         /* Set the column headings */
198         pBuilder.setColumnHeading(PlayerField.NAME.toString());
199         pBuilder.setColumnHeading(PlayerFixtureField.ID.toString());
200 
201         /* Create the fixture columns */
202         for (int i = 0; i < theNumColumns; i++) {
203             /* Create the fixture column */
204             pBuilder.setColumnHeading(CompetitionFixtures.getIdForIndex(i));
205         }
206 
207         /* Loop through the players */
208         boolean bFirst = true;
209         Iterator<CompetitionFixtures> myIterator = theList.iterator();
210         while (myIterator.hasNext()) {
211             CompetitionFixtures myFixtures = myIterator.next();
212 
213             /* Create a new row */
214             Element myRow = pBuilder.newRow();
215 
216             /* Add separator for first row */
217             if (bFirst) {
218                 pBuilder.addClassAttribute(myRow, ReportBuilder.CLASS_SEPARATOR);
219                 bFirst = false;
220             }
221 
222             /* Set the column headings */
223             pBuilder.setCellPlayerRight(myFixtures.playerProperty().getValue());
224             pBuilder.setCellId(myFixtures.idProperty().getValue());
225 
226             /* Create the fixture cells */
227             for (int i = 0; i < theNumColumns; i++) {
228                 /* Create the fixture column */
229                 pBuilder.setCellObject(myFixtures.fixtureProperty(i).getValue());
230             }
231         }
232     }
233 
234     /**
235      * build the main report.
236      * @param pBuilder the builder
237      */
238     private void buildRotatedReport(final ReportBuilder pBuilder) {
239         /* Create a new table */
240         pBuilder.newSmallTable();
241 
242         /* Set caption */
243         pBuilder.setTableCaption(RESULTS_FORMAT, DataParser.formatDate(theDataSet.getLastChange()));
244 
245         /* Set the column headings */
246         Element myHeader = pBuilder.setColumnHeading(PlayerField.NAME.toString());
247         pBuilder.addClassAttribute(myHeader, "jhp-row-rotate-header");
248 
249         /* Create the fixture columns */
250         Iterator<CompetitionFixtures> myIterator = theList.iterator();
251         while (myIterator.hasNext()) {
252             CompetitionFixtures myFixtures = myIterator.next();
253 
254             /* Create the fixture column */
255             pBuilder.setRotatedColumnHeading(myFixtures.playerProperty().getValue().getName());
256         }
257 
258         /* Loop through the players */
259         boolean bFirst = true;
260         myIterator = theList.iterator();
261         while (myIterator.hasNext()) {
262             CompetitionFixtures myFixtures = myIterator.next();
263 
264             /* Create a new row */
265             Element myRow = pBuilder.newRow();
266 
267             /* Add separator for first row */
268             if (bFirst) {
269                 pBuilder.addClassAttribute(myRow, ReportBuilder.CLASS_SEPARATOR);
270                 bFirst = false;
271             }
272 
273             /* Set the column headings */
274             pBuilder.setCellPlayerRight(myFixtures.playerProperty().getValue());
275 
276             /* Create the fixture cells */
277             for (int i = 0; i < theNumColumns; i++) {
278                 /* Create the fixture column */
279                 FixtureRecord myFixture = myFixtures.fixtureProperty(i).getValue();
280                 Result myResult = myFixture == null
281                                                     ? null
282                                                     : myFixture.getResult();
283                 pBuilder.setCellNullResult(myResult);
284             }
285         }
286     }
287 
288     /**
289      * FixtureCellValue factory.
290      */
291     private static final class FixtureCellValueFactory
292             implements Callback<CellDataFeatures<CompetitionFixtures, FixtureRecord>, ObservableValue<FixtureRecord>> {
293         /**
294          * Field value.
295          */
296         private final int theIndex;
297 
298         /**
299          * Constructor.
300          * @param pIndex the index
301          */
302         private FixtureCellValueFactory(final int pIndex) {
303             theIndex = pIndex;
304         }
305 
306         @Override
307         public ObservableValue<FixtureRecord> call(final CellDataFeatures<CompetitionFixtures, FixtureRecord> p) {
308             return p.getValue().fixtureProperty(theIndex);
309         }
310     }
311 }