Jtable: Open Computing Institute, Inc
Jtable: Open Computing Institute, Inc
• Basic Tables
• Overview of Related Classes
• JTable Class in Detail
• Table Data Models
– interface, abstract, default, listener, event
• Table Columns
– class, model, listener, event
• Table Headers
• Selection of Rows, Columns, and Cells
• Cell Renderers and Editors
• Row Sorting
• Database Access
– code can
• change cell values
• add/remove/move columns
• customize cell rendering
• customize cell editing
• Supported by
– JTable class in javax.swing package
– many classes and interfaces in
javax.swing.table and javax.swing.event
private BasicMovieApp() {
super("Movies!");
String[] columnNames =
{"Title", "Rating", "On Video?"};
Object[][] data = {
{"A Bug's Life", "G", new Boolean(false)},
{"A Civil Action", "PG13", new Boolean(false)},
// ... more movies omitted ...
};
JTable
1 1
TableModel JTableHeader
1 1
AbstractTableModel TableColumnModel
DefaultTableModel
DefaultTable-
ColumnModel
1
*
dataVector Vector
TableColumn
1 1
*
ListSelectionModel
TableCellRenderer
DefaultListSelectionModel
DefaultTableCellRenderer
CellEditor
* dataVector is a Vector of
Vectors. The inner Vectors
TableCellEditor represent the data in each row.
DefaultCellEditor
italic indicates interface
• Method highlights
– getting fundamental helper objects
TableColumnModel getColumnModel() knows column selections
TableModel getModel()
ListSelectionModel getSelectionModel() knows row selections
TableHeader getTableHeader()
– other methods
void addColumn(TableColumn aColumn)
void editCellAt(int row, int column)
void setAutoResizeMode(int mode) - explained later
void setSelectionMode(int selectionMode)
SINGLE_SELECTION, SINGLE_INTERVAL_SELECTION,
MULTIPLE_INTERVAL_SELECTION
void setValueAt(Object aValue, int row, int column)
void addTableModelListener
(TableModelListener l)
• to be notified of changes to the table data and structure
void removeTableModelListener(TableModelListener l)
• Implements TableModel
• Must define these methods
int getRowCount();
int getColumnCount();
Object getValueAt(int rowIndex, int columnIndex);
void fireTableDataChanged()
– can be called even if the number of rows changes
less
specific
void fireTableStructureChanged()
– call this when the number, names, or types of the columns changes
void fireTableChanged(TableModelEvent e)
– you describe the change in the TableModelEvent
– using the other "fire" methods is easier
• Extends AbstractTableModel
• Stores cell data in a Vector of Vectors
– one Vector per row
• Override methods to change
default behavior
– supplies these defaults
• the class of all cells is reported as Object
– class-specific renderers and editors aren't used
• columns are named like in spreadsheets
– unless the column names are passed to the contructor, setDataVector(),
or setColumnIdentifiers()
• cells are editable
– to make some or all cells read-only, override isCellEditable()
import java.util.*;
import javax.swing.table.*;
try {
switch (columnIndex) {
case TITLE_COLUMN:
movie.setTitle((String) aValue);
break;
case RATING_COLUMN:
movie.setRatingString((String) aValue);
break;
case ON_VIDEO_COLUMN:
movie.setOnVideo
(((Boolean) aValue).booleanValue());
break;
}
fireTableCellUpdated(rowIndex, columnIndex);
} catch (ClassCastException cce) {
cce.printStackTrace();
}
}
}
myJFrame.getContentPane().add
(new JScrollPane(table), BorderLayout.CENTER);
import javax.swing.event.*;
• Implemented by DefaultTableColumnModel
• Holds a collection of TableColumns
• Supports adding, removing, and moving
columns
To get the one
• Supports column selections associated with
a JTable, call
– controls whether they are allowed getColumnModel().
• TableColumnModelListener interface
methods
void columnAdded(TableColumnModelEvent e)
void columnRemoved(TableColumnModelEvent e)
void columnMoved(TableColumnModelEvent e)
void columnMarginChanged(ChangeEvent e)
void columnSelectionChanged(ListSelectionEvent e)
• Implemented by DefaultListSelectionModel
• One for rows and one for columns
• To be notified of table row selections
table.getSelectionModel(). a ListSelectionListener
addListSelectionListener(l);
• ListSelectionEvent class
– getFirstIndex()
• returns index of first row/column selected
– getLastIndex()
• returns index of last row/column selected
– getValueIsAdjusting()
• indicates whether this event is part of a series of
ListSelectEvents and it is not the last one
setText(rating);
setFont(isSelected ? SELECTED_FONT : NORMAL_FONT);
setForeground(color);
return this;
}
}
• implements TableCellEditor
• cells edited using this should contain one of the strings in Movie.RATINGS
• if not then the first string in the JComboBox is selected
• TableCellEditor interface
– only one method
Component getTableCellEditorComponent
(JTable table,
Object value,
boolean isSelected,
int row,
int column)
import java.awt.Component;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.TableCellEditor;
/**
* @return the Component to be used for editing.
*/
public Component getTableCellEditorComponent
(JTable table, Object value,
boolean isSelected, int row, int column) {
savedValue = ((Integer) value).intValue();
setValue(savedValue);
return this;
}
/**
* Can editing begin based on the event passed in?
*/
public boolean isCellEditable(EventObject anEvent) {
return true;
}
/**
* Should the cell be selected based on the event passed in?
*/
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
/**
* Cancels editing and discards the edited value.
*/
public void cancelCellEditing() {
setValue(savedValue); // revert to last saved value
/**
* Stops editing and accepts the edited value.
* Returns false if editing wasn't stopped.
* Useful for editors that validate and
* can't accept invalid entries.
*/
public boolean stopCellEditing() {
ChangeEvent ce = new ChangeEvent(this);
Vector copy = (Vector) listeners.clone();
Enumeration e = copy.elements();
while (e.hasMoreElements()) {
CellEditorListener l =
(CellEditorListener) e.nextElement();
l.editingStopped(ce);
}
return true;
}
}
static {
for (int i = Movie.NR; i <= Movie.R; i++) {
addLabel(i);
}
}
public MovieRatingEditor() {
super(Movie.NR, Movie.R);
setPaintTicks(true);
setMinorTickSpacing(1);
setMajorTickSpacing(1);
setSnapToTicks(true);
setPaintLabels(true);
setLabelTable(labelTable);
}
• Modify MovieTableModel
– getValueAt() must return an Integer for ratings
instead of a String
– getColumnClass() must return Integer.class
instead of String.class
– setValueAt() must accept an Integer for ratings
instead of a String
• To request this editor for the
Rating column
TableColumnModel tcm = table.getColumnModel();
TableColumn tc =
tcm.getColumn(MovieTableModel.RATING_COLUMN);
tc.setCellEditor(new MovieRatingEditor());
table.setRowHeight(40); // so the editor will fit