JAL-3438 spotless for 2.11.2.0
[jalview.git] / src / jalview / fts / core / FTSDataColumnPreferences.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.fts.core;
22
23 import jalview.fts.api.FTSDataColumnI;
24 import jalview.fts.api.FTSDataColumnI.FTSDataColumnGroupI;
25 import jalview.fts.api.FTSRestClientI;
26 import jalview.fts.api.StructureFTSRestClientI;
27 import jalview.fts.service.pdb.PDBFTSRestClient;
28
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Comparator;
32 import java.util.HashMap;
33 import java.util.LinkedHashSet;
34 import java.util.List;
35
36 import javax.swing.JScrollPane;
37 import javax.swing.JTable;
38 import javax.swing.RowSorter;
39 import javax.swing.SortOrder;
40 import javax.swing.table.AbstractTableModel;
41 import javax.swing.table.TableModel;
42 import javax.swing.table.TableRowSorter;
43
44 /**
45  * Helps render GUI allowing control of which columns to show for entries
46  * returned from an FTS query. TODO: push down FTSClient specific code
47  * 
48  * @author tcofoegbu
49  *
50  */
51 @SuppressWarnings("serial")
52 public class FTSDataColumnPreferences extends JScrollPane
53 {
54   protected JTable tbl_FTSDataColumnPrefs = new JTable();
55
56   protected JScrollPane scrl_pdbDocFieldConfig = new JScrollPane(
57           tbl_FTSDataColumnPrefs);
58
59   private HashMap<String, FTSDataColumnI> map = new HashMap<String, FTSDataColumnI>();
60
61   private Collection<FTSDataColumnI> structSummaryColumns = new LinkedHashSet<FTSDataColumnI>();
62
63   private Collection<FTSDataColumnI> allFTSDataColumns = new LinkedHashSet<FTSDataColumnI>();
64
65   public enum PreferenceSource
66   {
67     SEARCH_SUMMARY, STRUCTURE_CHOOSER, PREFERENCES;
68   }
69
70   private PreferenceSource currentSource;
71
72   private FTSRestClientI ftsRestClient;
73
74   public FTSDataColumnPreferences(PreferenceSource source,
75           FTSRestClientI ftsRestClient)
76   {
77     this.ftsRestClient = ftsRestClient;
78     if (source.equals(PreferenceSource.STRUCTURE_CHOOSER)
79             || source.equals(PreferenceSource.PREFERENCES))
80     {
81       structSummaryColumns = ((StructureFTSRestClientI) ftsRestClient)
82               .getAllDefaultDisplayedStructureDataColumns();
83     }
84     allFTSDataColumns.addAll(ftsRestClient.getAllFTSDataColumns());
85
86     tbl_FTSDataColumnPrefs.setAutoCreateRowSorter(true);
87     this.getViewport().add(tbl_FTSDataColumnPrefs);
88     this.currentSource = source;
89
90     String[] columnNames = ftsRestClient.getPreferencesColumnsFor(source);
91
92     Object[][] data = new Object[allFTSDataColumns.size()][3];
93
94     int x = 0;
95     for (FTSDataColumnI field : allFTSDataColumns)
96     {
97       // System.out.println("allFTSDataColumns==" + allFTSDataColumns);
98       if (field.getName().equalsIgnoreCase("all"))
99       {
100         continue;
101       }
102
103       switch (source)
104       {
105       case SEARCH_SUMMARY:
106         data[x++] = new Object[] { ftsRestClient
107                 .getAllDefaultDisplayedFTSDataColumns().contains(field),
108             field.getName(), field.getGroup() };
109         // System.out.println(" PUIS " + field.getName() + " ET AUSSI " +
110         // field.getGroup() + "X = " + x);
111         break;
112       case STRUCTURE_CHOOSER:
113         data[x++] = new Object[] { structSummaryColumns.contains(field),
114             field.getName(), field.getGroup() };
115         break;
116       case PREFERENCES:
117         data[x++] = new Object[] {
118             field.getName(), ftsRestClient
119                     .getAllDefaultDisplayedFTSDataColumns().contains(field),
120             structSummaryColumns.contains(field) };
121         break;
122       default:
123         break;
124       }
125       map.put(field.getName(), field);
126     }
127
128     FTSDataColumnPrefsTableModel model = new FTSDataColumnPrefsTableModel(
129             columnNames, data);
130     tbl_FTSDataColumnPrefs.setModel(model);
131
132     switch (source)
133     {
134     case SEARCH_SUMMARY:
135     case STRUCTURE_CHOOSER:
136       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(0)
137               .setPreferredWidth(30);
138       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(0).setMinWidth(20);
139       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(0).setMaxWidth(40);
140       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(1)
141               .setPreferredWidth(150);
142       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(1).setMinWidth(150);
143       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(2)
144               .setPreferredWidth(150);
145       tbl_FTSDataColumnPrefs.getColumnModel().getColumn(2).setMinWidth(150);
146
147       TableRowSorter<TableModel> sorter = new TableRowSorter<>(
148               tbl_FTSDataColumnPrefs.getModel());
149       tbl_FTSDataColumnPrefs.setRowSorter(sorter);
150       List<RowSorter.SortKey> sortKeys = new ArrayList<>();
151       int columnIndexToSort = 2;
152       sortKeys.add(new RowSorter.SortKey(columnIndexToSort,
153               SortOrder.ASCENDING));
154       sorter.setComparator(columnIndexToSort,
155               new Comparator<FTSDataColumnGroupI>()
156               {
157                 @Override
158                 public int compare(FTSDataColumnGroupI o1,
159                         FTSDataColumnGroupI o2)
160                 {
161                   return o1.getSortOrder() - o2.getSortOrder();
162                 }
163               });
164       sorter.setSortKeys(sortKeys);
165       // BH 2018 setSortKeys does a sort sorter.sort();
166
167       tbl_FTSDataColumnPrefs
168               .setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
169       break;
170     case PREFERENCES:
171     default:
172       break;
173     }
174
175   }
176
177   public Collection<FTSDataColumnI> getStructureSummaryFields()
178   {
179     return structSummaryColumns;
180   }
181
182   class FTSDataColumnPrefsTableModel extends AbstractTableModel
183   {
184
185     public FTSDataColumnPrefsTableModel(String[] columnNames,
186             Object[][] data)
187     {
188       this.data = data;
189       this.columnNames = columnNames;
190     }
191
192     private Object[][] data;
193
194     private String[] columnNames;
195
196     @Override
197     public int getColumnCount()
198     {
199       return columnNames.length;
200     }
201
202     @Override
203     public int getRowCount()
204     {
205       return data.length;
206     }
207
208     @Override
209     public String getColumnName(int col)
210     {
211       return columnNames[col];
212     }
213
214     @Override
215     public Object getValueAt(int row, int col)
216     {
217       return data[row][col];
218     }
219
220     /*
221      * JTable uses this method to determine the default renderer/ editor for
222      * each cell. If we didn't implement this method, then the last column would
223      * contain text ("true"/"false"), rather than a check box.
224      */
225     @Override
226     public Class getColumnClass(int c)
227     {
228       return getValueAt(0, c).getClass();
229     }
230
231     /*
232      * Don't need to implement this method unless your table's editable.
233      */
234     @Override
235     public boolean isCellEditable(int row, int col)
236     {
237       // Note that the data/cell address is constant,
238       // no matter where the cell appears onscreen.
239       // !isPDBID(row, col) ensures the PDB_Id cell is never editable as it
240       // serves as a unique id for each row.
241       // return (col == 1 || col == 2) && !isPDBID(row, col);
242       switch (currentSource)
243       {
244       case SEARCH_SUMMARY:
245       case STRUCTURE_CHOOSER:
246         return (col == 0) && !isPrimaryKeyCell(row, 1);
247       case PREFERENCES:
248         return (col == 1 || col == 2) && !isPrimaryKeyCell(row, 0);
249       default:
250         return false;
251       }
252
253     }
254
255     /**
256      * Determines whether the data in a given cell is a PDB ID.
257      * 
258      * @param row
259      * @param col
260      * @return
261      */
262
263     public boolean isPrimaryKeyCell(int row, int col)
264     {
265       String name = getValueAt(row, col).toString();
266       FTSDataColumnI pdbField = map.get(name);
267       return pdbField.isPrimaryKeyColumn();
268     }
269
270     /*
271      * Don't need to implement this method unless your table's data can change.
272      */
273     @Override
274     public void setValueAt(Object value, int row, int col)
275     {
276       data[row][col] = value;
277       fireTableCellUpdated(row, col);
278
279       String name = null;
280       switch (currentSource)
281       {
282       case SEARCH_SUMMARY:
283       case STRUCTURE_CHOOSER:
284         name = getValueAt(row, 1).toString();
285         break;
286       case PREFERENCES:
287         name = getValueAt(row, 0).toString();
288         break;
289       default:
290         break;
291       }
292       boolean selected = ((Boolean) value).booleanValue();
293
294       FTSDataColumnI ftsDataColumn = map.get(name);
295
296       if (currentSource == PreferenceSource.SEARCH_SUMMARY)
297       {
298         updatePrefs(ftsRestClient.getAllDefaultDisplayedFTSDataColumns(),
299                 ftsDataColumn, selected);
300       }
301       else if (currentSource == PreferenceSource.STRUCTURE_CHOOSER)
302       {
303         updatePrefs(structSummaryColumns, ftsDataColumn, selected);
304       }
305       else if (currentSource == PreferenceSource.PREFERENCES)
306       {
307         if (col == 1)
308         {
309           updatePrefs(ftsRestClient.getAllDefaultDisplayedFTSDataColumns(),
310                   ftsDataColumn, selected);
311         }
312         else if (col == 2)
313         {
314           updatePrefs(structSummaryColumns, ftsDataColumn, selected);
315         }
316       }
317     }
318
319     private void updatePrefs(Collection<FTSDataColumnI> prefConfig,
320             FTSDataColumnI dataColumn, boolean selected)
321     {
322       if (prefConfig.contains(dataColumn) && !selected)
323       {
324         prefConfig.remove(dataColumn);
325       }
326
327       if (!prefConfig.contains(dataColumn) && selected)
328       {
329         prefConfig.add(dataColumn);
330       }
331     }
332
333   }
334 }