/*
 * This file is part of lanterna (http://code.google.com/p/lanterna/).
 *
 * lanterna is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright (C) 2010-2020 Martin Berglund
 */
package com.googlecode.lanterna.gui2.table;

import java.util.*;

A TableModel contains the data model behind a table, here is where all the action cell values and header labels are stored.
Author:Martin
/** * A {@code TableModel} contains the data model behind a table, here is where all the action cell values and header * labels are stored. * * @author Martin */
public class TableModel<V> {
Listener interface for the TableModel class which can be attached to a TableModel to be notified of changes to the table model.
Type parameters:
  • <V> – Value type stored in the table
/** * Listener interface for the {@link TableModel} class which can be attached to a {@link TableModel} to be notified * of changes to the table model. * @param <V> Value type stored in the table */
public interface Listener<V> {
Called when a new row has been added to the model
Params:
  • model – Model the row was added to
  • index – Index of the new row
/** * Called when a new row has been added to the model * @param model Model the row was added to * @param index Index of the new row */
void onRowAdded(TableModel<V> model, int index);
Called when a row has been removed from the model
Params:
  • model – Model the row was removed from
  • index – Index of the removed row
  • oldRow – Content of the row that was removed
/** * Called when a row has been removed from the model * @param model Model the row was removed from * @param index Index of the removed row * @param oldRow Content of the row that was removed */
void onRowRemoved(TableModel<V> model, int index, List<V> oldRow);
Called when a new column has been added to the model
Params:
  • model – Model the column was added to
  • index – Index of the new column
/** * Called when a new column has been added to the model * @param model Model the column was added to * @param index Index of the new column */
void onColumnAdded(TableModel<V> model, int index);
Called when a column has been removed from the model
Params:
  • model – Model the column was removed from
  • index – Index of the removed column
  • oldHeader – Header the removed column had
  • oldColumn – Values in the removed column
/** * Called when a column has been removed from the model * @param model Model the column was removed from * @param index Index of the removed column * @param oldHeader Header the removed column had * @param oldColumn Values in the removed column */
void onColumnRemoved(TableModel<V> model, int index, String oldHeader, List<V> oldColumn);
Called when an existing cell had its content updated
Params:
  • model – Model that was modified
  • row – Row index of the modified cell
  • column – Column index of the modified cell
  • oldValue – Previous value of the cell
  • newValue – New value of the cell
/** * Called when an existing cell had its content updated * @param model Model that was modified * @param row Row index of the modified cell * @param column Column index of the modified cell * @param oldValue Previous value of the cell * @param newValue New value of the cell */
void onCellChanged(TableModel<V> model, int row, int column, V oldValue, V newValue); } private final List<String> columns; private final List<List<V>> rows; private final List<Listener<V>> listeners;
Default constructor, creates a new model with same number of columns as labels supplied
Params:
  • columnLabels – Labels for the column headers
/** * Default constructor, creates a new model with same number of columns as labels supplied * @param columnLabels Labels for the column headers */
public TableModel(String... columnLabels) { this.columns = new ArrayList<String>(Arrays.asList(columnLabels)); this.rows = new ArrayList<List<V>>(); this.listeners = new ArrayList<Listener<V>>(); }
Returns the number of columns in the model
Returns:Number of columns in the model
/** * Returns the number of columns in the model * @return Number of columns in the model */
public synchronized int getColumnCount() { return columns.size(); }
Returns number of rows in the model
Returns:Number of rows in the model
/** * Returns number of rows in the model * @return Number of rows in the model */
public synchronized int getRowCount() { return rows.size(); }
Returns all rows in the model as a list of lists containing the data as elements
Returns:All rows in the model as a list of lists containing the data as elements
/** * Returns all rows in the model as a list of lists containing the data as elements * @return All rows in the model as a list of lists containing the data as elements */
public synchronized List<List<V>> getRows() { List<List<V>> copy = new ArrayList<List<V>>(); for(List<V> row: rows) { copy.add(new ArrayList<V>(row)); } return copy; }
Returns all column header label as a list of strings
Returns:All column header label as a list of strings
/** * Returns all column header label as a list of strings * @return All column header label as a list of strings */
public synchronized List<String> getColumnLabels() { return new ArrayList<String>(columns); }
Returns a row from the table as a list of the cell data
Params:
  • index – Index of the row to return
Returns:Row from the table as a list of the cell data
/** * Returns a row from the table as a list of the cell data * @param index Index of the row to return * @return Row from the table as a list of the cell data */
public synchronized List<V> getRow(int index) { return new ArrayList<V>(rows.get(index)); }
Adds a new row to the table model at the end
Params:
  • values – Data to associate with the new row, mapped column by column in order
Returns:Itself
/** * Adds a new row to the table model at the end * @param values Data to associate with the new row, mapped column by column in order * @return Itself */
public synchronized TableModel<V> addRow(V... values) { addRow(Arrays.asList(values)); return this; }
Adds a new row to the table model at the end
Params:
  • values – Data to associate with the new row, mapped column by column in order
Returns:Itself
/** * Adds a new row to the table model at the end * @param values Data to associate with the new row, mapped column by column in order * @return Itself */
public synchronized TableModel<V> addRow(Collection<V> values) { insertRow(getRowCount(), values); return this; }
Inserts a new row to the table model at a particular index
Params:
  • index – Index the new row should have, 0 means the first row and row count will append the row at the end
  • values – Data to associate with the new row, mapped column by column in order
Returns:Itself
/** * Inserts a new row to the table model at a particular index * @param index Index the new row should have, 0 means the first row and <i>row count</i> will append the row at the * end * @param values Data to associate with the new row, mapped column by column in order * @return Itself */
public synchronized TableModel<V> insertRow(int index, Collection<V> values) { ArrayList<V> list = new ArrayList<V>(values); rows.add(index, list); for(Listener<V> listener: listeners) { listener.onRowAdded(this, index); } return this; }
Removes a row at a particular index from the table model
Params:
  • index – Index of the row to remove
Returns:Itself
/** * Removes a row at a particular index from the table model * @param index Index of the row to remove * @return Itself */
public synchronized TableModel<V> removeRow(int index) { List<V> removedRow = rows.remove(index); for(Listener<V> listener: listeners) { listener.onRowRemoved(this, index, removedRow); } return this; }
Removes all rows from the table, this will trigger listeners for each row
Returns:Itself
/** * Removes all rows from the table, this will trigger listeners for each row * @return Itself */
public synchronized TableModel<V> clear() { while (rows.size() > 0) { removeRow(0); } return this; }
Returns the label of a column header
Params:
  • index – Index of the column to retrieve the header label for
Returns:Label of the column selected
/** * Returns the label of a column header * @param index Index of the column to retrieve the header label for * @return Label of the column selected */
public synchronized String getColumnLabel(int index) { return columns.get(index); }
Updates the label of a column header
Params:
  • index – Index of the column to update the header label for
  • newLabel – New label to assign to the column header
Returns:Itself
/** * Updates the label of a column header * @param index Index of the column to update the header label for * @param newLabel New label to assign to the column header * @return Itself */
public synchronized TableModel<V> setColumnLabel(int index, String newLabel) { columns.set(index, newLabel); return this; }
Adds a new column into the table model as the last column. You can optionally supply values for the existing rows through the newColumnValues.
Params:
  • label – Label for the header of the new column
  • newColumnValues – Optional values to assign to the existing rows, where the first element in the array will be the value of the first row and so on...
Returns:Itself
/** * Adds a new column into the table model as the last column. You can optionally supply values for the existing rows * through the {@code newColumnValues}. * @param label Label for the header of the new column * @param newColumnValues Optional values to assign to the existing rows, where the first element in the array will * be the value of the first row and so on... * @return Itself */
public synchronized TableModel<V> addColumn(String label, V[] newColumnValues) { return insertColumn(getColumnCount(), label, newColumnValues); }
Adds a new column into the table model at a specified index. You can optionally supply values for the existing rows through the newColumnValues.
Params:
  • index – Index for the new column
  • label – Label for the header of the new column
  • newColumnValues – Optional values to assign to the existing rows, where the first element in the array will be the value of the first row and so on...
Returns:Itself
/** * Adds a new column into the table model at a specified index. You can optionally supply values for the existing * rows through the {@code newColumnValues}. * @param index Index for the new column * @param label Label for the header of the new column * @param newColumnValues Optional values to assign to the existing rows, where the first element in the array will * be the value of the first row and so on... * @return Itself */
public synchronized TableModel<V> insertColumn(int index, String label, V[] newColumnValues) { columns.add(index, label); for(int i = 0; i < rows.size(); i++) { List<V> row = rows.get(i); //Pad row with null if necessary for(int j = row.size(); j < index; j++) { row.add(null); } if(newColumnValues != null && i < newColumnValues.length && newColumnValues[i] != null) { row.add(index, newColumnValues[i]); } else { row.add(index, null); } } for(Listener<V> listener: listeners) { listener.onColumnAdded(this, index); } return this; }
Removes a column from the table model
Params:
  • index – Index of the column to remove
Returns:Itself
/** * Removes a column from the table model * @param index Index of the column to remove * @return Itself */
public synchronized TableModel<V> removeColumn(int index) { String removedColumnHeader = columns.remove(index); List<V> removedColumn = new ArrayList<V>(); for(List<V> row : rows) { removedColumn.add(row.remove(index)); } for(Listener<V> listener: listeners) { listener.onColumnRemoved(this, index, removedColumnHeader, removedColumn); } return this; }
Returns the cell value stored at a specific column/row coordinate.
Params:
  • columnIndex – Column index of the cell
  • rowIndex – Row index of the cell
Returns:The data value stored in this cell
/** * Returns the cell value stored at a specific column/row coordinate. * @param columnIndex Column index of the cell * @param rowIndex Row index of the cell * @return The data value stored in this cell */
public synchronized V getCell(int columnIndex, int rowIndex) { if(rowIndex < 0 || columnIndex < 0) { throw new IndexOutOfBoundsException("Invalid row or column index: " + rowIndex + " " + columnIndex); } else if (rowIndex >= getRowCount()) { throw new IndexOutOfBoundsException("TableModel has " + getRowCount() + " rows, invalid access at rowIndex " + rowIndex); } if(columnIndex >= getColumnCount()) { throw new IndexOutOfBoundsException("TableModel has " + columnIndex + " columns, invalid access at columnIndex " + columnIndex); } return rows.get(rowIndex).get(columnIndex); }
Updates the call value stored at a specific column/row coordinate.
Params:
  • columnIndex – Column index of the cell
  • rowIndex – Row index of the cell
  • value – New value to assign to the cell
Returns:Itself
/** * Updates the call value stored at a specific column/row coordinate. * @param columnIndex Column index of the cell * @param rowIndex Row index of the cell * @param value New value to assign to the cell * @return Itself */
public synchronized TableModel<V> setCell(int columnIndex, int rowIndex, V value) { getCell(columnIndex, rowIndex); List<V> row = rows.get(rowIndex); //Pad row with null if necessary for(int j = row.size(); j < columnIndex; j++) { row.add(null); } V existingValue = row.get(columnIndex); if(existingValue == value) { return this; } row.set(columnIndex, value); for(Listener<V> listener: listeners) { listener.onCellChanged(this, rowIndex, columnIndex, existingValue, value); } return this; }
Adds a listener to this table model that will be notified whenever the model changes
Params:
  • listener – Listener to register with this model
Returns:Itself
/** * Adds a listener to this table model that will be notified whenever the model changes * @param listener {@link Listener} to register with this model * @return Itself */
public TableModel<V> addListener(Listener<V> listener) { listeners.add(listener); return this; }
Removes a listener from this model so that it will no longer receive any notifications when the model changes
Params:
  • listener – Listener to deregister from this model
Returns:Itself
/** * Removes a listener from this model so that it will no longer receive any notifications when the model changes * @param listener {@link Listener} to deregister from this model * @return Itself */
public TableModel<V> removeListener(Listener<V> listener) { listeners.remove(listener); return this; } }