All Downloads are FREE. Search and download functionalities are using the official Maven repository.

core.com.jgoodies.binding.adapter.AbstractTableAdapter Maven / Gradle / Ivy

/*
 * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 *  o Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer. 
 *     
 *  o Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution. 
 *     
 *  o Neither the name of JGoodies Karsten Lentzsch nor the names of 
 *    its contributors may be used to endorse or promote products derived 
 *    from this software without specific prior written permission. 
 *     
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

package com.jgoodies.binding.adapter;

import javax.swing.ListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.table.AbstractTableModel;

/**
 * An abstract implementation of the {@link javax.swing.table.TableModel} 
 * interface that converts a {@link javax.swing.ListModel} of row elements.

* * This class provides default implementations for the TableModel * methods #getColumnCount() and #getColumnName(int). * To use these methods you must use the constructor that accepts an * array of column names and this array must not be null. * If a subclass constructs itself with the column names set to null * it must override the methods #getColumnCount() and * #getColumnName(int).

* * Example: API users subclass AbstractTableAdapter * and just implement the method TableModel#getValueAt(int, int).

* * The following example implementation is based on a list of customer rows * and exposes the first and last name as well as the customer ages:

 * public class CustomerTableModel extends AbstractTableAdapter {
 * 
 *     private static final String[] COLUMN_NAMES = 
 *         { "Last Name", "First Name", "Age" };
 * 
 *     public CustomerTableModel(ListModel listModel) {
 *         super(listModel, COLUMN_NAMES);
 *     }
 * 
 *     public Object getValueAt(int rowIndex, int columnIndex) {
 *         Customer customer = (Customer) getRow(rowIndex);
 *         switch (columnIndex) {
 *             case 0 : return customer.getLastName();
 *             case 1 : return customer.getFirstName();
 *             case 2 : return customer.getAge();
 *             default: return null;
 *         }
 *     }
 *            
 * }
 * 
* * @author Karsten Lentzsch * @version $Revision: 1.4 $ * * @see javax.swing.ListModel * @see javax.swing.JTable */ public abstract class AbstractTableAdapter extends AbstractTableModel { /** * Refers to the ListModel that holds the table row elements * and reports changes in the structure and content. The elements of * the list model can be requested using #getRow(int). * A typical subclass will use the elements to implement the * TableModel method #getValueAt(int, int). * * @see #getRow(int) * @see #getRowCount() * @see javax.swing.table.TableModel#getValueAt(int, int) */ private final ListModel listModel; /** * Holds an optional array of column names that is used by the * default implementation of the TableModel methods * #getColumnCount() and #getColumnName(int). * * @see #getColumnCount() * @see #getColumnName(int) */ private final String[] columnNames; // Instance Creation ****************************************************** /** * Constructs an AbstractTableAdapter on the given ListModel. * Subclasses that use this constructor must override the methods * #getColumnCount() and #getColumnName(int). * * @param listModel the ListModel that holds the row elements * @throws NullPointerException if the list model is null */ public AbstractTableAdapter(ListModel listModel) { this(listModel, null); } /** * Constructs an AbstractTableAdapter on the given ListModel using * the specified table column names. If the column names array is * non-null, it is copied to avoid external mutation.

* * Subclasses that invoke this constructor with a null column * name array must override the methods #getColumnCount() and * #getColumnName(int). * * @param listModel the ListModel that holds the row elements * @param columnNames an optional array of column names * @throws NullPointerException if the list model is null */ public AbstractTableAdapter(ListModel listModel, String[] columnNames) { this.listModel = listModel; if (listModel == null) throw new NullPointerException("The list model must not be null."); if (columnNames == null) { this.columnNames = null; } else { this.columnNames = new String[columnNames.length]; System.arraycopy(columnNames, 0, this.columnNames, 0, columnNames.length); } listModel.addListDataListener(createChangeHandler()); } // TableModel Implementation ********************************************** /** * Returns the number of columns in the model. A JTable uses * this method to determine how many columns it should create and * display by default.

* * Subclasses must override this method if they don't provide an * array of column names in the constructor. * * @return the number of columns in the model * @throws NullPointerException if the optional column names array * has not been set in the constructor. In this case API users * must override this method. * * @see #getColumnName(int) * @see #getRowCount() */ public int getColumnCount() { return columnNames.length; } /** * Returns the name of the column at the given column index. * This is used to initialize the table's column header name. * Note: this name does not need to be unique; two columns in a table * can have the same name.

* * Subclasses must override this method if they don't provide an * array of column names in the constructor. * * @param columnIndex the index of the column * @return the name of the column * @throws NullPointerException if the optional column names array * has not been set in the constructor. In this case API users * must override this method. * * @see #getColumnCount() * @see #getRowCount() */ public String getColumnName(int columnIndex) { return columnNames[columnIndex]; } /** * Returns the number of rows in the model. A * JTable uses this method to determine how many rows it * should display. This method should be quick, as it * is called frequently during rendering. * * @return the number of rows in the model * * @see #getRow(int) */ public final int getRowCount() { return listModel.getSize(); } // Misc ******************************************************************* /** * Returns the row at the specified row index. * * @param index row index in the underlying list model * @return the row at the specified row index. */ protected final Object getRow(int index) { return listModel.getElementAt(index); } // Event Handling ********************************************************* /** * Creates and returns a listener that handles changes * in the underlying list model. * * @return the listener that handles changes in the underlying ListModel */ protected ListDataListener createChangeHandler() { return new ListDataChangeHandler(); } /** * Listens to subject changes and fires a contents change event. */ private final class ListDataChangeHandler implements ListDataListener { /** * Sent after the indices in the index0,index1 * interval have been inserted in the data model. * The new interval includes both index0 and index1. * * @param evt a ListDataEvent encapsulating the * event information */ public void intervalAdded(ListDataEvent evt) { fireTableRowsInserted(evt.getIndex0(), evt.getIndex1()); } /** * Sent after the indices in the index0,index1 interval * have been removed from the data model. The interval * includes both index0 and index1. * * @param evt a ListDataEvent encapsulating the * event information */ public void intervalRemoved(ListDataEvent evt) { fireTableRowsDeleted(evt.getIndex0(), evt.getIndex1()); } /** * Sent when the contents of the list has changed in a way * that's too complex to characterize with the previous * methods. For example, this is sent when an item has been * replaced. Index0 and index1 bracket the change. * * @param evt a ListDataEvent encapsulating the * event information */ public void contentsChanged(ListDataEvent evt) { int firstRow = evt.getIndex0(); int lastRow = evt.getIndex1(); fireTableRowsUpdated(firstRow, lastRow); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy