Merge branch 'subtree'
[fanfix.git] / src / be / nikiroo / jexer / TTableModel.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2019 David "Niki" ROULET
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * @author David ROULET [niki@nikiroo.be]
27 * @version 1
28 */
29 package be.nikiroo.jexer;
30
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collection;
34
35 import javax.swing.event.TableModelListener;
36 import javax.swing.table.AbstractTableModel;
37 import javax.swing.table.TableModel;
38
39 /**
40 * The model of a {@link TTable}. It contains the data of the table and allows
41 * you access to it.
42 * <p>
43 * Note that you don't need to send it the representation of the data, but the
44 * data itself; {@link TTableCellRenderer} is the class responsible of
45 * representing that data (you can change the headers renderer on a
46 * {@link TTable} and the cells renderer on each of its {@link TTableColumn}).
47 * <p>
48 * It works in a similar way to the Java Swing version of it.
49 *
50 * @author niki
51 */
52 public class TTableModel implements TableModel {
53 private TableModel model;
54
55 /**
56 * Create a new {@link TTableModel} with the given data inside.
57 *
58 * @param data
59 * the data
60 */
61 public TTableModel(Object[][] data) {
62 this(convert(data));
63 }
64
65 /**
66 * Create a new {@link TTableModel} with the given data inside.
67 *
68 * @param data
69 * the data
70 */
71 public TTableModel(
72 final Collection<? extends Collection<? extends Object>> data) {
73
74 int maxItemsPerRow = 0;
75 for (Collection<? extends Object> rowOfData : data) {
76 maxItemsPerRow = Math.max(maxItemsPerRow, rowOfData.size());
77 }
78
79 int i = 0;
80 final Object[][] odata = new Object[data.size()][maxItemsPerRow];
81 for (Collection<? extends Object> rowOfData : data) {
82 odata[i] = new String[maxItemsPerRow];
83 int j = 0;
84 for (Object pieceOfData : rowOfData) {
85 odata[i][j] = pieceOfData;
86 j++;
87 }
88 i++;
89 }
90
91 final int maxItemsPerRowFinal = maxItemsPerRow;
92 this.model = new AbstractTableModel() {
93 private static final long serialVersionUID = 1L;
94
95 @Override
96 public Object getValueAt(int rowIndex, int columnIndex) {
97 return odata[rowIndex][columnIndex];
98 }
99
100 @Override
101 public int getRowCount() {
102 return odata.length;
103 }
104
105 @Override
106 public int getColumnCount() {
107 return maxItemsPerRowFinal;
108 }
109 };
110 }
111
112 @Override
113 public int getRowCount() {
114 return model.getRowCount();
115 }
116
117 @Override
118 public int getColumnCount() {
119 return model.getColumnCount();
120 }
121
122 @Override
123 public String getColumnName(int columnIndex) {
124 return model.getColumnName(columnIndex);
125 }
126
127 @Override
128 public Class<?> getColumnClass(int columnIndex) {
129 return model.getColumnClass(columnIndex);
130 }
131
132 @Override
133 public boolean isCellEditable(int rowIndex, int columnIndex) {
134 return model.isCellEditable(rowIndex, columnIndex);
135 }
136
137 @Override
138 public Object getValueAt(int rowIndex, int columnIndex) {
139 return model.getValueAt(rowIndex, columnIndex);
140 }
141
142 @Override
143 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
144 model.setValueAt(aValue, rowIndex, columnIndex);
145 }
146
147 @Override
148 public void addTableModelListener(TableModelListener l) {
149 model.addTableModelListener(l);
150 }
151
152 @Override
153 public void removeTableModelListener(TableModelListener l) {
154 model.removeTableModelListener(l);
155 }
156
157 /**
158 * Helper method to convert an array to a collection.
159 *
160 * @param <T>
161 *
162 * @param data
163 * the data
164 *
165 * @return the data in another format
166 */
167 static <T> Collection<Collection<T>> convert(T[][] data) {
168 Collection<Collection<T>> dataCollection = new ArrayList<Collection<T>>(
169 data.length);
170 for (T pieceOfData[] : data) {
171 dataCollection.add(Arrays.asList(pieceOfData));
172 }
173
174 return dataCollection;
175 }
176 }