Commit | Line | Data |
---|---|---|
8f34a795 NR |
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 | } |