Title: JTable and MVC
1JTable and MVC
- SOFTENG 251
- Object Oriented Software Construction
2A world without models
- All Swing components can be used without
knowledge of their separate models - When any Swing component is created without
specifying a particular model, some kind of
default model is created and associated with the
component - As discussed previously, creating a JTextField
component without an explicit model causes the
component to create and bind to a PlainDocument
model - When a JTable component is created without
specifying a particular model, it creates and
uses a new DefaultTableModel instance
3A world without models
Object tableData "NestingShape",
10, 10, 2, 2, 200, 250, null, "Black" ,
"RectangleShape", 10, 10, 3, 2, 70, 40, null,
"Blue" , "RectangleShape", 0, 0, 1, 1, 80,
35, "Simple rectangle", "White" ,
"GemShape", 0, 0, -1, 10, 45, 35, "I'm a Gem",
"Cyan" , "NestingShape", 0, 0, 10, 10,
100, 100, "I'm a Nest", "White" ,
"DynamicRectangleShape", 10, 2, -1, -1, 110, 60,
null, "Cyan" , "OvalShape", 10, 10, 5, 5,
110, 60, null, "Red" , "RectangleShape",
1, 1, 3, 3, 80, 50, null, "Cyan" ,
"DynamicRectangleShape", 50, 50, 5, -5, 120, 40,
"I change colour", "Green" String
columnNames "Type", "X-pos", "Y-pos",
"X-delta", "Y-delta", "Width", "Height", "Text",
"Color JTable table new JTable( tableData,
columnNames )
4Aside autoboxing
Object tableData "NestingShape",
10, 10, 2, 2, 200, 250, null, "Black" ,
- As from Java 1.5, primitive values are
automatically boxed and unboxed as necessary - Note that every primitive data type has an
associated wrapper class
Automatically boxes x into a new instance of
Integer. Automatically unboxes the int value
contained in the Integer object referred to by y.
int x 10 Integer y x int z y
5A world without models
- Getting data out of a JTable component that was
created with an implicit model is unnatural and
cumbersome
JTable table Shape s new RectangleShape(
( ( Integer )table.getValueAt( 1, 1 )
).intValue( ), // X-pos ( ( Integer
)table.getValueAt( 1, 2 ) ).intValue( ), //
Y-pos ( ( Integer )table.getValueAt( 1, 3 )
).intValue( ), // Delta X ( ( Integer
)table.getValueAt( 1, 4 ) ).intValue( ), // Delta
Y ( ( Integer )table.getValueAt( 1, 5 )
).intValue( ), // Width ( ( Integer
)table.getValueAt( 1, 6 ) ).intValue( ), //
Height ( ( String )table.getValueAt(1, 7 )
), // Text )
When retrieving data from a JTable component, the
data has no meaning. Each cell simply stores some
sort of Object.
6A world without models
- Without using an explicit model
- Every cell in a JTable is editable by default
- Any sequence of characters can be entered into
any cell - Each cell is rendered as a (left-justified)
String - toString( ) is called on the Object stored in a
cell - There is an undesirable need to convert between
application objects and table data when
populating a JTable and extracting its content - Application and GUI code is heavily intertwined,
resulting in complex and inflexible code
7Use of explicit models
setValueAt( ltobjgt, row, col )
Model
Component
- Creating a JTable component with a custom model
(a TableModel implementation) has many
advantages - Clear separation between GUI and application
logic/data - The model can specify the type of data stored in
each column - The JTable uses this knowledge to render cell
data appropriately - The model can specify which data are editable and
which are not - The JTable only allows users to edit editable
cells - The model takes responsibility for
accepting/vetoing change requests - In response to a cell edit, the model is informed
and only if it accepts the edit and changes its
state does it notify its views - The model can have many views not just a single
(visual) JTable
tableChanged( lteventgt )
JTable
TableModel
JTable
TableModelListener
8(No Transcript)
9Interaction
10Interaction
11AbstractTableModel
- AbstractTableModel implements all but the
getRowCount( ), getColumnCount( ), and
getValueAt( ) methods of the TableModel interface - AbstractTableModel also implements event handling
which is intended to be reused by subclasses - The fire( ) methods create TableModelEvent
objects and broadcast them to all registered
views - E.g. fireTableCellUpdated( ) creates an event
which describes a change made to a particular
cell - E.g. fireTableRowsUpdated( ) creates an event
which describes a change that has effected
multiple rows
AbstractTableModel is a good abstract class. It
implements the TableModel interface and adds
additional beaviour that is useful to subclasses.
To implement your own TableModel, all you need do
(minimally) is inherit from AbstractTableModel
and implement 3 methods.
12Cell rendering editing
- JTable is configured by default with a particular
cell renderer for given data types - Boolean gt JCheckBox
- Number gt JLabel, right aligned
- ImageIcon gt JLabel, image centered
- Object gt String
- To edit cell data, JTextFields are used by
default - Based on knowledge of a cells data type,
inappropriate inputs are discarded - A JTables view can be customised by specifying a
new renderer for a given type of data - Similarly, a JTables controller can be
customised by specifying a cell editor for a data
type
See interfaces TableCellEditor and
TableCellRenderer plus class TableColumnModel.
13Shape editor
14Shape editor
- Key responsibilities
- ShapeModelAdapter
- Forwards change requests to individual shapes if
successfully processed notify views - Disallow column Type to be edited
- Implement methods to support JTable
- Shape
- Provide an interface to allow shape state to be
changed - Ensure state changes are valid
- JTable
- Using a new CellEditor, restrict inputs to
columns X-pos, Y-pos, width and height to be
non-negative integers - Using a new CellEditor and Renderer, allow a
shapes colour to be rendered and edited
Customised controller
Customised view
15update( )
JTree (VIEW)
update( )
ShapeModel (MODEL)
AnimationView (VIEW)
update( )
setColor( )
JTable (VIEW)
16Trees in Swing