⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table.java

📁 用applet实现很多应用小程序
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
package prefuse.data;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

import javax.swing.event.TableModelEvent;

import prefuse.data.column.Column;
import prefuse.data.column.ColumnFactory;
import prefuse.data.column.ColumnMetadata;
import prefuse.data.event.ColumnListener;
import prefuse.data.event.EventConstants;
import prefuse.data.event.TableListener;
import prefuse.data.expression.Expression;
import prefuse.data.expression.Predicate;
import prefuse.data.expression.parser.ExpressionParser;
import prefuse.data.tuple.AbstractTupleSet;
import prefuse.data.tuple.TableTuple;
import prefuse.data.tuple.TupleManager;
import prefuse.data.util.FilterIteratorFactory;
import prefuse.data.util.Index;
import prefuse.data.util.RowManager;
import prefuse.data.util.Sort;
import prefuse.data.util.TableIterator;
import prefuse.data.util.TreeIndex;
import prefuse.util.TypeLib;
import prefuse.util.collections.CopyOnWriteArrayList;
import prefuse.util.collections.IncompatibleComparatorException;
import prefuse.util.collections.IntIterator;


/**
 * <p>A Table organizes a collection of data into rows and columns, each row 
 * containing a data record, and each column containing data values for a
 * named data field with a specific data type. Table data can be accessed
 * directly using the row number and column name, or rows can be treated
 * in an object-oriented fashion using {@link prefuse.data.Tuple}
 * instances that represent a single row of data in the table. As such,
 * tables implement the {@link prefuse.data.tuple.TupleSet} interface.</p>
 * 
 * <p>Table rows can be inserted or deleted. In any case, none of the other
 * existing table rows are effected by an insertion or deletion. A deleted
 * row simply becomes invalid--any subsequent attempts to access the row
 * either directly or through a pre-existing Tuple instance will result
 * in an exception. However, if news rows are later added to the table,
 * the row number for previously deleted nodes can be reused. In fact, the
 * lower row number currently unused is assigned to the new row. This results
 * in an efficient reuse of the table rows, but carries an important side
 * effect -- rows do not necesarily maintain the order in which they were
 * added once deletions have occurred on the table. If not deletions
 * occur, the ordering of table rows will reflect the order in which
 * rows were added to the table.</p>
 * 
 * <p>Collections of table rows can be accessed using both iterators over
 * the actual row numbers and iterators over the Tuple instances that
 * encapsulate access to that row. Both types of iteration can also be
 * filtered by providing a {@link prefuse.data.expression.Predicate},
 * allowing tables to be queried for specific values.</p>
 * 
 * <p>Columns (alternativele referred to as data fields) can be added to
 * the Table using {@link #addColumn(String, Class)} and a host of
 * similar methods. This method will automatically determine the right
 * kind of backing column instance to use. Furthermore, Table columns
 * can be specified using a {@link Schema} instance, which describes
 * the column names, data types, and default values. The Table class
 * also maintains its own internal Schema, which be accessed (in a
 * read-only way) using the {@link #getSchema()} method.</p>
 * 
 * <p>Tables also support additional structures. The {@link ColumnMetadata}
 * class returned by the {@link #getMetadata(String)} method supports
 * calculation of different statistics for a column, including minimum
 * and maximum values, and the number of unique data values in the column.
 * {@link prefuse.data.util.Index} instances can be created and retrieved
 * using the {@link #index(String)} method and retrieved without triggering
 * creation using {@link #getIndex(String)} method. An index keeps a
 * sorted collection of all data values in a column, accelerating the creation
 * of filtered iterators by optimizing query calculations and also providing
 * faster computation of many of the {@link ColumnMetadata} methods. If
 * you will be issuing a number of queries (i.e., requesting filtered
 * iterators) dependent on the values of a given column, indexing that column
 * may result in a significant performance increase, though at the cost
 * of storing and maintaining the backing index structure.</p>  
 * 
 * @author <a href="http://jheer.org">jeffrey heer</a>
 */
public class Table extends AbstractTupleSet implements ColumnListener {
    
    /** Listeners for changes to this table */
    protected CopyOnWriteArrayList m_listeners;
    
    /** Locally stored data columns */
    protected ArrayList m_columns;
    /** Column names for locally store data columns */
    protected ArrayList m_names;
    
    /** Mapping between column names and column entries
     * containing column, metadata, and index references */ 
    protected HashMap m_entries;
    
    /** Manager for valid row indices */
    protected RowManager m_rows;
    
    /** manager for tuples, which are object representations for rows */
    protected TupleManager m_tuples;
    
    /** Tracks the number of edits of this table */
    protected int m_modCount = 0;
    
    /** Memoize the index of the last column operated on,
     * used to expedite handling of column updates. */
    protected int m_lastCol = -1;
    
    /** A cached schema instance, loaded lazily */
    protected Schema m_schema;
    
    // ------------------------------------------------------------------------
    // Constructors
    
    /**
     * Create a new, empty Table. Rows can be added to the table using
     * the {@link #addRow()} method.
     */
    public Table() {
        this(0, 0);
    }
    
    /**
     * Create a new Table with a given number of rows, and the starting
     * capacity for a given number of columns.
     * @param nrows the starting number of table rows
     * @param ncols the starting capacity for columns 
     */
    public Table(int nrows, int ncols) {
        this(nrows, ncols, TableTuple.class);
    }
    
    /**
     * Create a new Table.
     * @param nrows the starting number of table rows
     * @param ncols the starting capacity for columns 
     * @param tupleType the class of the Tuple instances to use
     */
    protected Table(int nrows, int ncols, Class tupleType) {
        m_listeners = new CopyOnWriteArrayList();
        m_columns = new ArrayList(ncols);
        m_names = new ArrayList(ncols);
        m_rows = new RowManager(this);
        m_entries = new HashMap(ncols+5);        
        m_tuples = new TupleManager(this, null, tupleType);

        if ( nrows > 0 )
            addRows(nrows);
    }
    
    // ------------------------------------------------------------------------
    // Table Metadata
    
    /**
     * Get the number of columns / data fields in this table.
     * @return the number of columns 
     */
    public int getColumnCount() {
        return m_columns.size();
    }

    /**
     * Get the data type of the column at the given column index.
     * @param col the column index
     * @return the data type (as a Java Class) of the column
     */
    public Class getColumnType(int col) {
        return getColumn(col).getColumnType();
    }

    /**
     * Get the data type of the column with the given data field name.
     * @param field the column / data field name
     * @return the data type (as a Java Class) of the column
     */
    public Class getColumnType(String field) {
        Column c = getColumn(field); 
        return (c==null ? null : c.getColumnType());
    }

    /**
     * Get the number of rows in the table.
     * @return the number of rows
     */
    public int getRowCount() {
        return m_rows.getRowCount();
    }
    
    /**
     * Get the minimum row index currently in use by this Table.
     * @return the minimum row index
     */
    public int getMinimumRow() {
        return m_rows.getMinimumRow();
    }

    /**
     * Get the maximum row index currently in use by this Table.
     * @return the maximum row index
     */
    public int getMaximumRow() {
        return m_rows.getMaximumRow();
    }
    
    /**
     * Indicates if the value of the given table cell can be changed. 
     * @param row the row number
     * @param col the column number
     * @return true if the value can be edited/changed, false otherwise
     */
    public boolean isCellEditable(int row, int col) {
        if ( !m_rows.isValidRow(row) ) {
            return false;
        } else {
            return getColumn(col).isCellEditable(row);
        }
    }
    
    /**
     * Get the number of times this Table has been modified. Adding rows,
     * deleting rows, and updating table cell values all contribute to
     * this count.
     * @return the number of modifications to this table
     */
    public int getModificationCount() {
        return m_modCount;
    }
    
    /**
     * Sets the TupleManager used by this Table. Use this method
     * carefully, as it will cause all existing Tuples retrieved
     * from this Table to be invalidated.
     * @param tm the TupleManager to use
     */
    public void setTupleManager(TupleManager tm) {
        m_tuples.invalidateAll();
        m_tuples = tm;
    }
    
    /**
     * Returns this Table's schema. The returned schema will be
     * locked, which means that any attempts to edit the returned schema
     * by adding additional columns will result in a runtime exception.
     * 
     * If this Table subsequently has columns added or removed, this will not
     * be reflected in the returned schema. Instead, this method will need to
     * be called again to get a current schema. Accordingly, it is not
     * recommended that Schema instances returned by this method be stored
     * or reused across scopes unless that exact schema snapshot is
     * desired.
     * 
     * @return a copy of this Table's schema
     */
    public Schema getSchema() {
        if ( m_schema == null ) {
            Schema s = new Schema();
            for ( int i=0; i<getColumnCount(); ++i ) {
                s.addColumn(getColumnName(i), getColumnType(i), 
                            getColumn(i).getDefaultValue());
            }
            s.lockSchema();
            m_schema = s;
        }
        return m_schema;
    }
    
    /**
     * Invalidates this table's cached schema. This method should be called
     * whenever columns are added or removed from this table.
     */
    protected void invalidateSchema() {
        m_schema = null;
    }
    
    // ------------------------------------------------------------------------
    // Row Operations
    
    /**
     * Get the row value for accessing an underlying Column instance,
     * corresponding to the given table cell. For basic tables this just
     * returns the input row value. However, for tables that inherit
     * data columns from a parent table and present a filtered view on
     * this data, a mapping between the row numbers of the table and
     * the row numbers of the backing data column is needed. In those cases,
     * this method returns the result of that mapping. The method
     * {@link #getTableRow(int, int)} accesses this map in the reverse
     * direction.
     * @param row the table row to lookup
     * @param col the table column to lookup
     * @return the column row number for accessing the desired table cell
     */
    public int getColumnRow(int row, int col) {
        return m_rows.getColumnRow(row, col);
    }
    
    /**
     * Get the row number for this table given a row number for a backing
     * data column and the column number for the data column. For basic
     * tables this just returns the column row value. However, for tables that
     * inherit data columns from a parent table and present a filtered view on
     * this data, a mapping between the row numbers of the table and
     * the row numbers of the backing data column is needed. In those cases,
     * this method returns the result of this mapping, in the direction of
     * the backing column rows to the table rows of the cascaded table. The
     * method {@link #getColumnRow(int, int)} accesses this map in the reverse
     * direction.
     * @param colrow the row of the backing data column
     * @param col the table column to lookup.
     * @return the table row number for accessing the desired table cell
     */
    public int getTableRow(int colrow, int col) {
        return m_rows.getTableRow(colrow, col);
    }
    
    /**
     * Add a row to this table. All data columns will be notified and will
     * take on the appropriate default values for the added row.
     * @return the row number of the newly added row
     */
    public int addRow() {
        int r = m_rows.addRow();
        updateRowCount();
        
        fireTableEvent(r, r, TableModelEvent.ALL_COLUMNS,
                       TableModelEvent.INSERT);        
        return r;
    }
    
    /**
     * Add a given number of rows to this table. All data columns will be
     * notified and will take on the appropriate default values for the
     * added rows.
     * @param nrows the number of rows to add.
     */
    public void addRows(int nrows) {
        for ( int i=0; i<nrows; ++i ) {
            addRow();
        }
    }
    
    /**
     * Internal method that updates the row counts for local data columns.
     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -