![]() ![]() ![]() |
7
Events and Listeners
Displaying Cells
Editing Cells
Painting Tables
Printing Tables
Resizing Cells
Scrolling in Tables
Selecting Cells
Sorting Table Data
Table Data Changes
Traversing Cells
The following sections explain how to generate and receive events in your JClass LiveTable programs.
The descriptions are listed in sets of events and event listeners, with examples of when you would use the event and listener, and sample code.
In order to register an event listener in your program, it must implement the listener's interface.
7.1 Displaying Cells
JCCellDisplayEvent
This event is posted for every cell that is displayed in the table. When you receive a
JCCellDisplayEvent
object, you can call following methods:
getCellData()
returns the object to be passed to the renderer of the given cell.getRow()
retrieves the row number of the cell or label displayed.getColumn()
retrieves the column number of the cell or label displayed.setDisplayData()
lets you change the object that is displayed.getDisplayData()
retrieves the object to be displayed.A display request from
JCTable
generates aJCCellDisplayEvent
and notifies anyJCCellDisplayListeners
that they can customize the display object by callingsetDisplayData()
on the event.JCTable
does not generate the event if there are no listeners registered with the table.JCCellDisplayListener
To register the above event listener routine, use the following call (where
table.addCellDisplayListener(this);(this)
refers to the class, which implements theJCCellDisplayListener
interface):public void cellDisplay(JCCellDisplayEvent e)
JCCellDisplayListener
requires the following method to be implemented:Calling JCCellDisplayEvent and JCCellDisplayListener methods
JCCellDisplayListener
's method is called before each cell is rendered, and allJCCellDisplayEvent
methods are available at all times during the display process. For more information, please refer to Appendix A, which provides a complete event summary.Using JCCellDisplay Events and Listeners
JCCellDisplayListener
can be used to format the display String. Changing displayed data does not affect either data source values or values passed to editors. As such,JCCellDisplayEvent
does not provide any mechanism to store the displayed data in the data source. The following example (see examples/table/listeners/BooleanDisplay.java) displays objects as yes/no. Setting the display object does not have any effect during edit.
Figure 14 : Using JCCellDisplayEvent to display BooleanCellData objects as yes/no Strings.
import com.klg.jclass.table.JCTable;
import com.klg.jclass.table.JCTableEnum;
import com.klg.jclass.table.data.JCEditableVectorDataSource;
import com.klg.jclass.table.JCCellDisplayListener;
import com.klg.jclass.table.JCCellDisplayEvent;
import com.klg.jclass.util.swing.JCExitFrame;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JPanel;
public class BooleanDisplay extends JPanel implements JCCellDisplayListener {
// Table instance
protected JCTable table;
// Editable table data source
protected JCEditableVectorDataSource evds;
public BooleanDisplay() {
setBackground(Color.lightGray);
// Create table instance
table = new JCTable();
// Create and set up data source
evds = new JCEditableVectorDataSource();
evds.setNumRows(2);
evds.setNumColumns(2);
evds.setColumnLabel(0, "Original");
evds.setColumnLabel(1, "Formatted");
// Note that BooleanCellEditor will be automatically chosen by Table
evds.setCell(0, 0, new Boolean(false));
evds.setCell(0, 1, new Boolean(false));
evds.setCell(1, 0, new Boolean(true));
evds.setCell(1, 1, new Boolean(true));
// Connect table data source
table.setDataSource(evds);
// Turn off row labels because they are ugly.
table.setRowLabelDisplay(false);
// Add everything to the panel
setLayout(new GridLayout(1,1));
add(table);
// Add cell display listener.
table.addCellDisplayListener(this);
}
public void cellDisplay(JCCellDisplayEvent e) {
if(e.getColumn() == 1 && e.getRow() != JCTableEnum.LABEL) {
// Grab displayed data, in this case a boolean
Boolean dd = (Boolean)e.getDisplayData();
if(dd.equals(Boolean.TRUE)) {
e.setDisplayData("yes");
}
else {
e.setDisplayData("no");
}
}
}
public static void main(String args[]) {
JCExitFrame frame = new JCExitFrame("BooleanDisplay");
BooleanDisplay bd = new BooleanDisplay();
frame.getContentPane().add(bd);
frame.pack();
frame.setVisible(true);
}
}
7.2 Editing Cells
JCEditCellEvent
This event is posted whenever a user traverses into and edits a cell. When you receive a
JCEditCellEvent
object, you can call the following methods:
getRow()
- retrieves the row number of the cell that is being edited.getColumn()
- retrieves the column number of the cell that is being edited.getType()
- retrieves the type of edit event, where valid types areBEFORE_EDIT_CELL
,EDIT_CELL
, andAFTER_EDIT_CELL
.getEditingComponent()
- returns the editing component.isCancelled()
- retrieves the cancelled value.setCancelled()
- determines whether to allow an edit.JCEditCellListener
To register the above event listener routine, use the following call (where
table.addEditCellListener(this);(this)
refers to the class, which implements theJCEditCellListener
interface):public void beforeEditCell(JCEnterCellEvent e)
JCEditCellListener
requires the following methods to be implemented:
public void editCell(JCEnterCellEvent e)
public void afterEditCell(JCEnterCellEvent e)Calling JCCellDisplayEvent and JCCellDisplayListener methods
JCEditCellListener
'sbeforeEditCell()
method is used before any cell edits by the user occur. This is the only time an edit can be cancelled.editCell()
is used when the editor is displayed to the user, and at this point, you cannot cancel the edit.Once the user's edit action has been completed,
afterEditCell()
is used, committing the final changes on your part. For more information, please refer to Appendix A, which provides a complete event summary.Using JCEditCell Events and Listeners
The following example (see examples/table/listeners/EditCell.java) displays a status comment whenever a user edits a cell.
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import com.klg.jclass.table.JCTable;
import com.klg.jclass.table.JCEditCellListener;
import com.klg.jclass.table.JCEditCellEvent;
import com.klg.jclass.table.data.JCEditableVectorDataSource;
import com.klg.jclass.util.swing.JCExitFrame;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
public class EditCell extends JPanel implements JCEditCellListener {
// Table instance
protected JCTable table;
// Editable data source for table
protected JCEditableVectorDataSource evds;
// Label to track table column #
protected JLabel message;
// Messages to appear in the JLabel.
protected String messages[] = {
"This is the first column",
"This is the second column",
"This is the third column",
"This is the forth column" };
public EditCell() {
setBackground(Color.lightGray);
// Create table instance
table = new JCTable();
// Create and set up data source
evds = new JCEditableVectorDataSource();
evds.setNumRows(10);
evds.setNumColumns(4);
evds.setColumnLabel(0, "First");
evds.setColumnLabel(1, "Second");
evds.setColumnLabel(2, "Third");
evds.setColumnLabel(3, "Forth");
for(int r = 0; r < evds.getNumRows(); r++)
for(int c = 0; c < evds.getNumColumns(); c++)
evds.setCell(r, c, "R"+r+"C"+c);
// Connect table data source
table.setDataSource(evds);
// Turn off row labels because they are ugly
table.setRowLabelDisplay(false);
// Add everything to the panel
this.setLayout(new BorderLayout());
this.add("North", table);
this.add("South", message = new JLabel());
// Add cell Edit event listener
table.addEditCellListener(this);
}
public void beforeEditCell(JCEditCellEvent event) {
message.setText(messages[event.getColumn()]);
}
public void editCell(JCEditCellEvent event) {
// get the editing component and select all of the text if it
// is a JTextField component
Component c = event.getEditingComponent();
if(c instanceof JTextField) {
((JTextField)c).selectAll();
}
}
public void afterEditCell(JCEditCellEvent event) {
}
public static void main(String args[]) {
JCExitFrame frame = new JCExitFrame("EditCell");
EditCell ec = new EditCell();
frame.getContentPane().add(ec);
frame.pack();
frame.setVisible(true);
}
}
7.3 Painting Tables
JCPaintEvent
This event is posted before and after a portion of the table is painted. When you receive a
JCPaintEvent
object, you can call the following methods:
getStartRow()
- retrieves the start row of the repainted region.getStartColumn()
- retrieves the start column of the repainted region.getEndRow()
- retrieves the end row of the repainted region.getEndColumn()
- retrieves the end column of the repainted region.getType()
- retrieves the paint event type, where valid types areBEFORE_PAINT
andAFTER_PAINT
.getCellRange()
- returns aJCCellRange
containing the painted area.JCPaintListener
To register the above event listener routine, use the following call (where
table.addPaintListener(this);(this)
refers to the class, which implements theJCPaintListener
interface):public void beforePaint(JCPaintEvent e)
JCPaintListener
requires the following methods to be implemented:
public void afterPaint(JCPaintEvent e)Calling JCPaintEvent and JCPaintListener Methods
JCPaintListener
's methods,beforePaint()
andafterPaint()
, can callJCPaintEvent
methods at any time, as you are not able to interrupt the cell painting process. For more information, please refer to Appendix A, which provides a complete event summary.Using JCPaint Events and Listeners
JCPaintListener
allows you to monitor the repainting of table cells. Labels, frozen cells, and scrollable cells are painted independently.
7.4 Printing Tables
JCPrintEvent
This event is posted when your table is printed. When you receive a
JCPrintEvent
object, you can call the following methods:
getGraphics()
- retrieves the current graphics object.getPage()
- retrieves the page number.getPageDimensions()
- retrieves the page dimensions.getPageMargins()
- retrieves the page margins.getPageResolution()
- retrieves the page dpi resolution.getMarginUnits()
- retrieves the margin units (pixels or inches).getNumPages()
- retrieves the total number of pages (handy for page x of x footers).getNumHorizontalPages()
- retrieves the number of pages needed to print all of the columns in the table.getNumVerticalPages()
- retrieves the number of pages needed to print all of the rows in the table.getTableDimensions()
- retrieves the dimension needed to print the table on the current page.getType()
- retrieves the print event type, where valid types arePRINT_HEADER
,PRINT_BODY
, andPRINT_FOOTER
.JCPrintListener
To register the above event listener routine, use the following call (where
table.addPrintListener(this);(this)
refers to the class, which implements theJCPrintListener
interface):public void printPageHeader(JCPrintEvent e)
JCPrintListener
requires the following methods to be implemented:
public void printPageFooter(JCPrintEvent e)
public void printPageBody(JCPrintEvent e)Using JCPrint Events and Listeners
JCPrintListener
allows you to customize the header and footer regions for each page of the printout. Table Printing, in Chapter 8, has details and examples for using theJCPrintListener
.
7.5 Resizing Cells
JCResizeCellEvent
This event is posted when a cell or label is resized. When you receive a
JCResizeCellEvent
object, you can call the following methods:
getRow()
- retrieves the row being resized. ReturnsJCTableEnum.NOVALUE
if only a column is being resized.getColumn()
- retrieves the column being resized. ReturnsJCTableEnum.NOVALUE
if only a row is being resized.getCurrentRowHeight()
- retrieves the current row height. ReturnsJCTblEnum.NOVALUE
if only a column is being resized.getCurrentColumnWidth()
- retrieves the current column width. ReturnsJCTblEnum.NOVALUE
if only a row is being resized.getType()
- retrieves the type where valid types areBEFORE_RESIZE
,RESIZE
,RESIZE_DRAG
andAFTER_RESIZE
.getNewRowHeight()
- retrieves the new row height. ReturnsJCTableEnum.NOVALUE
if only a column is being resized.setNewRowHeight()
- sets the new row height.getNewColumnWidth()
- retrieves the new column width. ReturnsJCTblEnum.NOVALUE
if only a row is being resized.setNewColumnWidth()
- sets the new column width.isCancelled()
- retrieves the cancelled value.setCancelled()
- determines whether to allow an interactive resize.JCResizeCellListener
To register the above event listener routine, use the following call (where
table.addResizeCellListener(this);(this)
refers to the class, which implements theJCResizeCellListener
interface):public void beforeResizeCell(JCResizeCellEvent e)
JCResizeCellListener
requires the following methods to be implemented:
public void resizeCell(JCResizeCellEvent e)
public void afterResizeCell(JCResizeCellEvent e)JCResizeCellMotionListener
To register the above event listener routine, use the following call (where
table.addResizeCellMotionListener(this);(this)
refers to the class, which implements theJCResizeCellMotionListener
interface):public void resizeCellDragged(JCResizeCellEvent e)
JCResizeCellMotionListener
requires the following methods to be implemented:Calling JCResizeCellEvent and JCResizeCellListener Methods
JCResizeCellListener
'sbeforeResizeCell()
method is called once cell resizing begins, and allows the opportunity to programmatically cancel the resize.resizeCell()
is called once the user releases the mouse button, and the resize is complete from their perspective. Programmatically, you can cancel the resize, or set new column widths or row heights if the cell resize dimension is invalid, or outside the boundaries of predefined maximum/minimum cell sizes.Once the resize values have been set,
afterResizeCell()
is used, committing the final resize changes. For more information, please refer to Appendix A, which provides a complete event summary.Using JCResizeCell Events and Listeners
import com.klg.jclass.table.JCTable;
JCResizeCellListener
allows you to customize how table resizes on a per-cell basis. The following example (see examples/table/listeners/ResizeCell.java) restricts resize so that row labels cannot be resized and no cell can be less than 100 pixels or greater than 200 pixels.
import com.klg.jclass.table.JCTableEnum;
import com.klg.jclass.table.data.JCEditableVectorDataSource;
import com.klg.jclass.table.JCResizeCellListener;
import com.klg.jclass.table.JCResizeCellMotionListener;
import com.klg.jclass.table.JCResizeCellEvent;
import com.klg.jclass.util.swing.JCExitFrame;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JPanel;
public class ResizeCell extends JPanel implements JCResizeCellListener,
JCResizeCellMotionListener {
// Table instance
protected JCTable table;
// Editable table data source
protected JCEditableVectorDataSource evds;
public ResizeCell() {
setBackground(Color.lightGray);
// Create table instance
table = new JCTable();
// Create and set up data source
evds = new JCEditableVectorDataSource();
evds.setNumRows(100);
evds.setNumColumns(2);
evds.setColumnLabel(0, "End-Point");
evds.setColumnLabel(1, "Drag");
for(int r = 0; r < evds.getNumRows(); r++) {
evds.setRowLabel(r, "Row: "+r);
for(int c = 0; c < evds.getNumColumns(); c++) evds.setCell(r,c,"Cell: R"+r+"C"+c);
}
// Connect table data source
table.setDataSource(evds);
// Add everything to the panel
this.setLayout(new GridLayout(1,1));
this.add(table);
// Add resize cell listener
table.addResizeCellListener(this);
// Add resize cell motion listener
table.addResizeCellMotionListener(this);
}
public void beforeResizeCell(JCResizeCellEvent event) {
if (event.getColumn() == JCTableEnum.LABEL) {
event.setCancelled(true);
return;
}
}
public void resizeCell(JCResizeCellEvent event) {
// Width must be between 100 and 200
int width = event.getNewColumnWidth();
if (width < 100) {
event.setNewColumnWidth(100);
}
else if (width > 200) {
event.setNewColumnWidth(200);
}
// Height must be between 30 and 70
int height = event.getNewRowHeight();
if (height != JCTableEnum.NOVALUE && height < 30) {
event.setNewRowHeight(30);
}
else if (height > 70) {
event.setNewRowHeight(70);
}
}
public void afterResizeCell(JCResizeCellEvent event) {
}
public void resizeCellDragged(JCResizeCellEvent event) {
// restrict the range of motion for column 1 to 100 to 200
if(event.getColumn() == 1) {
int width = event.getNewColumnWidth();
if(width < 100) {
event.setNewColumnWidth(100);
}
else if(width > 200) {
event.setNewColumnWidth(200);
}
}
}
public static void main(String args[]) {
JCExitFrame frame = new JCExitFrame("ResizeCell");
ResizeCell rc = new ResizeCell();
frame.getContentPane().add(rc);
frame.pack();
frame.setSize(600, 400);
frame.setVisible(true);
}
}
7.6 Scrolling in Tables
JCScrollEvent
This event is posted when the table is scrolled by either the user or the application. When you receive a
JCScrollListener
object, you can call the following methods:
getAdjustable()
- retrieves the affected adjustable object.getDirection()
- retrieves the scrolling direction (eitherAdjustable.HORIZONTAL
orAdjustable.VERTICAL
).getEvent()
- retrieves the event that initiated the action.getType()
- retrieves the scroll event type, where valid types areJCScrollEvent.SCROLL
andJCScrollEvent.AFTER_SCROLL
.getValue()
- retrieves the scrollbar's current value.setValue()
- sets the scrollbar's current value.The
JCScrollListener
(registered withaddScrollListener(JCScrollListener)
) allows you to define a procedure to be called when the table scrolls; this is useful if your application is drawing into the table. The method is sent an instance ofJCScrollEvent
.JCScrollListener
To register the above event listener routine, use the following call (where (
table.addScrollListener(this);this)
refers to the class, which implements theJCScrollListener
interface):public void scroll(JCScrollEvent e)
JCScrollListener
requires the following methods to be implemented:
public void afterScroll(JCScrollEvent e)Calling JCScrollEvent and JCScrollListener Methods
JCScrollListener
'sscroll()
method is invoked when the user begins to scroll, during which allJCScrollEvent
methods are available.afterScroll()
is called when the user has finished scrolling. For more information, please refer to Appendix A, which provides a complete event summary.Using JCScroll Events and Listeners
JCScrollListener
allows you to synchronize table scrolling with another object. The following example (see examples/table/listeners/TwoTables.java) links two tables together with one scrollbar. This example uses two tables inside another table to simulate a splitter window.
Figure 15 : Example using JCScrollListener to synchronize scrolling between two tables.
import com.klg.jclass.table.JCTable;
import com.klg.jclass.table.JCTableEnum;
import com.klg.jclass.table.data.JCVectorDataSource;
import com.klg.jclass.table.data.JCEditableVectorDataSource;
import com.klg.jclass.table.JCScrollListener;
import com.klg.jclass.table.JCScrollEvent;
import com.klg.jclass.util.swing.JCExitFrame;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Adjustable;
import java.awt.Component;
import java.awt.Scrollbar;
import javax.swing.JPanel;
public class TwoTables extends JPanel implements JCScrollListener {
// First table
protected JCTable table1;
// Second table
protected JCTable table2;
// Common data source
protected JCEditableVectorDataSource evds1;
// Local variable used to avoid infinite loops in
// scroll event handler
protected boolean forcedScroll = false;
public TwoTables() {
setBackground(Color.lightGray);
// Create first table
table1 = new JCTable();
// Create and set up data source for first table
evds1 = new JCEditableVectorDataSource();
evds1.setNumRows(100);
evds1.setNumColumns(6);
for (int c = 0; c < evds1.getNumColumns(); c++)
evds1.setColumnLabel(c, "C"+c);
for (int r = 0; r < evds1.getNumRows(); r++) {
evds1.setRowLabel(r, "R"+r);
for (int c = 0; c < evds1.getNumColumns(); c++)
evds1.setCell(r,c,"R"+r+"C"+c);
}
// Connect data source to first table.
table1.setDataSource(evds1);
// Set up visuals and interactions for table 1.
table1.setAllowCellResize(JCTableEnum.RESIZE_NONE);
table1.setHorizSBDisplay(JCTableEnum.SBDISPLAY_NEVER);
table1.getDefaultCellStyle().setTraversable(false);
table1.setVisibleRows(2);
table1.setVisibleColumns(3);
// Create second table
table2 = new JCTable();
// Connect second table to same data source as first table.
table2.setDataSource(evds1);
// Set up visuals and interactions for table 2.
table2.setAllowCellResize(JCTableEnum.RESIZE_NONE);
table2.setColumnLabelDisplay(false);
table2.setTopRow(2);
table2.getDefaultCellStyle().setTraversable(false);
table2.setVisibleRows(5);
table2.setVisibleColumns(3);
// Add to panel
setLayout(new GridLayout(2,1));
add(table1);
add(table2);
// Add scroll listeners for both tables
table1.addScrollListener(this);
table2.addScrollListener(this);
}
public void scroll(JCScrollEvent event) {
// use forcedScroll to prevent an infinite loop, since
// calling setValue() on the scrollbar will generate another
// event.
if (event.getDirection() == Scrollbar.HORIZONTAL) {
if (forcedScroll == false) {
// Scroll event not forced by this method, okay
// to continue
// Grab adjustable object
Adjustable adj = event.getAdjustable();
// We need for it to be a component. Should be -
// scroll events come from LiveTable's scrollbar
if (adj != null && adj instanceof Component) {
Component c = (Component)adj;
if (c.getParent() == table2) {
// If table 2 scrolled, synchronize table 2
forcedScroll = true;
table1.getHorizSB().setValue(event.getValue());
}
else if (c.getParent() == table1) {
// If table 1 scrolled, synchronize table 2
forcedScroll = true;
table2.getHorizSB().setValue(event.getValue());
}
}
} else {
forcedScroll = false;
}
}
}
public void afterScroll(JCScrollEvent event) {
}
public static void main(String args[]) {
JCExitFrame frame = new JCExitFrame("TwoTables");
TwoTables tt = new TwoTables();
frame.getContentPane().add(tt);
frame.pack();
frame.setVisible(true);
}
}
7.7 Selecting Cells
This event is posted when the user selects cells, or cells are selected programmatically. When you receive a
JCSelectEvent
object, you can call the following methods:
getType()
- returns the type of selection event, where valid types areBEFORE_SELECTION
,SELECTION
, andAFTER_SELECTION
.getStartRow()
- retrieves the start row of the selected or deselected cell range.getStartColumn()
- retrieves the start column of the selected or deselected cell range.getEndRow()
- retrieves the end row of the selected or deselected cell range.getEndColumn()
- retrieves the end column of the selected or deselected cell range.isCancelled()
- returnstrue
if any listener has rejected the selection.setCancelled()
- determines if selection is allowed.getAction()
- returns the type of selection action, where valid types areSELECT
,ADD
,EXTEND
,DESELECT
, andEND
.getActionString()
- returns a String representation of the action.JCSelectListener
To register the above event listener routine, use the following call (where (
table.addSelectListener(this);this)
refers to the class, which implements theJCSelectListener
interface):public void beforeSelect(JCSelectEvent e)
JCSelectListener
requires the following methods to be implemented:
public void select(JCSelectEvent e)
public void afterSelect(JCSelectEvent e)Calling JCSelectEvent and JCSelectListener Methods
JCSelectListener
's methods are called when the user begins cell selection in a table.beforeSelect()
is invoked when the user selects or deselects a cell, and allJCSelectEvent
methods are available. For example, it is possible to cancel a selection inbeforeSelect()
by callingsetCancelled(true)
.The
select()
andafterSelect()
methods are called during and after the selection process, meaning that at that point, the cell is now visually selected from the user's perspective. For more information, please refer to Appendix A, which provides a complete event summary.Using JCSelect Events and Listeners
import java.awt.Color;
JCSelectListener
allows you to monitor scrolling actions in your table, either before or after the scrolling event. The following example (see examples/table/listeners/SelectListener.java) demonstrates the use ofJCSelectListener
notifications to cancel out cell selection.
import java.awt.GridLayout;
import java.applet.Applet;
import javax.swing.JPanel;
import com.klg.jclass.table.JCTable;
import com.klg.jclass.table.JCSelectListener;
import com.klg.jclass.table.JCSelectEvent;
import com.klg.jclass.table.JCTableEnum;
import com.klg.jclass.table.data.JCVectorDataSource;
import com.klg.jclass.util.swing.JCExitFrame;
public class SelectListener extends JPanel implements JCSelectListener {
// Table instance
protected JCTable table;
// Table data source
protected JCVectorDataSource ds;
public SelectListener() {
setBackground(Color.lightGray);
// Create table instance
table = new JCTable();
// Create and set up data source
ds = new JCVectorDataSource();
ds.setNumRows(10);
ds.setNumColumns(4);
for(int c = 0; c < ds.getNumColumns(); c++)
ds.setColumnLabel(c, "Column: "+c);
ds.setColumnLabel(1, "Non Selectable Column");
for(int r = 0; r < ds.getNumRows(); r++) {
ds.setRowLabel(r, "Row: "+r);
for(int c = 0; c < ds.getNumColumns(); c++)
ds.setCell(r,c,"Cell: R"+r+"C"+c);
}
// Connect table data source
table.setDataSource(ds);
table.setSelectionPolicy(JCTableEnum.SELECT_RANGE);
// Add everything to the panel
setLayout(new GridLayout(1,1));
add(table);
table.addSelectListener(this);
}
public void beforeSelect(JCSelectEvent e) {
if (e.getStartColumn() == 1) {
e.setCancelled(true);
System.out.println("We don't want selection starting from this column");
return;
}
System.out.println("beforeSelect: startRow="+e.getStartRow()+
", startColumn="+e.getStartColumn());
}
public void select(JCSelectEvent e) {
if (e.getAction() == JCSelectEvent.EXTEND &&
Math.abs(e.getStartRow()-e.getEndRow())>1) {
e.setCancelled(true);
System.out.println("We don't want selection extending for more than 2 rows");
return;
}
System.out.println("select: startRow="+e.getStartRow()+
", startColumn="+e.getStartColumn()+", endRow="+e.getEndRow()+
", endColumn="+e.getEndColumn());
}
public void afterSelect(JCSelectEvent e) {
System.out.println("afterSelect: startRow="+e.getStartRow()+
", startColumn="+e.getStartColumn()+", endRow="+e.getEndRow()+
", endColumn="+e.getEndColumn());
}
public static void main(String args[]) {
JCExitFrame frame = new JCExitFrame("SelectListener");
SelectListener sn = new SelectListener();
frame.getContentPane().add(sn);
frame.pack();
frame.setSize(600, 150);
frame.setVisible(true);
}
}
7.8 Sorting Table Data
JCSortEvent
This event is posted when the table is sorted. When you receive a
JCSortEvent
object, you can call the following methods:
getColumns()
- retrieves an array of column indices that were sorted.getNewRows()
- retrieves the newly sorted order.JCSortListener
To register the above event listener routine, use the following call (where
table.addSortListener(this);(this)
refers to the class, which implements theJCSortListener
interface):public void sort(JCSortEvent e)
JCSortListener
requires the following method to be implemented:Using JCSort Events and Listeners
JCSortListener
allows you to synchronize the sorted rows with another object (or to sort the data source). The following example (see examples/table/listeners/Sorter.java) uses the row sort array to pull out the top value.
Figure 16 : Sorter.java, illustrating how to use JCSort Events and Listeners.
import javax.swing.JLabel;
import com.klg.jclass.table.JCTable;
import com.klg.jclass.table.JCTableEnum;
import com.klg.jclass.table.data.JCEditableVectorDataSource;
import com.klg.jclass.table.JCSortListener;
import com.klg.jclass.table.JCSortEvent;
import com.klg.jclass.table.MouseActionInitiator;
import com.klg.jclass.util.swing.JCExitFrame;
import java.awt.Color;
import java.awt.event.InputEvent;
import java.awt.BorderLayout;
import javax.swing.JPanel;
public class Sorter extends JPanel implements JCSortListener {
// Table instance
protected JCTable table;
// Table data source
protected JCEditableVectorDataSource ds;
// Label that will display column top value
protected JLabel topItem;
public Sorter() {
setBackground(Color.lightGray);
// Create table instance
table = new JCTable();
// Create and set up data source
ds = new JCEditableVectorDataSource();
ds.setNumRows(5);
ds.setNumColumns(2);
// Column labels
ds.setColumnLabel(0, "INTEGER");
ds.setColumnLabel(1, "STRING");
// Populate data source with generated data.
int numrows = ds.getNumRows();
for(int r = 0; r < numrows; r++) {
ds.setCell(r, 0, new Integer(r+8));
ds.setCell(r, 1, "" + (r+8));
}
// Connect table data source
table.setDataSource(ds);
// Turn off row labels because they are ugly.
table.setRowLabelDisplay(false);
// Allow column sorting using a shift-click combination
table.addAction(new MouseActionInitiator(MouseActionInitiator.ANY_BUTTON_MASK, InputEvent.SHIFT_MASK), JCTableEnum.COLUMN_SORT_ACTION);
// Add everything to the panel
setLayout(new BorderLayout());
add(table, BorderLayout.CENTER);
add(topItem = new JLabel("Shift-click the label to sort numeric or string data"),
BorderLayout.SOUTH);
// Add sort listener
table.addSortListener(this);
}
public void sort(JCSortEvent event) {
int columns[] = event.getColumns();
int rows[] = event.getNewRows();
topItem.setText("The first item in the " +
ds.getTableColumnLabel(columns[0]) + " column is " +
ds.getTableDataItem(rows[0],columns[0]));
}
public static void main(String args[]) {
JCExitFrame frame = new JCExitFrame("Sorter");
Sorter s = new Sorter();
frame.getContentPane().add(s);
frame.pack();
frame.setVisible(true);
}
}
7.9 Table Data Changes
JCTableDataEvent
Unlike previous events,
JCTableDataEvent
objects are not thrown byJCTable
; instead, they come from the table's data source. This event is posted when theTableDataModel
object has been modified. When you receive aJCTableDataEvent
object, you can call the following methods:
getColumn()
- retrieves the column of the current cell.getRow()
- retrieves the row of the current cell.getNumAffected()
- retrieves the number of rows affected byTableDataModel
object changes.getDestination()
- indicates the destination location forMOVE
events.getCommand()
- returns the command that initiated the event. Valid commands include:
JCTableDataListener
To register the above event listener routine, use the following call (where
table.addTableDataListener(this);(this)
refers to the classMyClass
, which implements theJCTableDataListener
interface):public void dataChanged(JCTableDataEvent e)
JCDataTableListener
requires the following method to be implemented:Using JCTableData Events and Listeners
JCTableDataListener
allows you to monitor any changes made to theTableDataModel
object. Valid changes are listed above with thegetCommand()
method.There are examples included with your JClass LiveTable distribution that demonstrate the use of data with a table. See Creating your own Data Sources, in Chapter 3, to see descriptions of the included sample code.
7.10 Traversing Cells
JCTraverseCellEvent
This event is posted when cells in the table are traversed. When you receive a
JCTraverseCellEvent
object, you can call the following methods:
getColumn()
- retrieves the column of the current cell.getNextColumn()
- retrieves the targeted column for traversal.getRow()
- retrieves the row of the current cell.getNextRow()
- retrieves the targeted row for traversal.setNextRow()
- sets the row of the cell to which the user will traverse.setNextColumn()
- sets the column of the cell to which the user will traverse.getTraverseType()
- returns the action that caused the traverse. ValidJCTableEnum
action values are:TRAVERSE_POINTER
,TRAVERSE_DOWN
,TRAVERSE_UP
,TRAVERSE_LEFT
,TRAVERSE_RIGHT
,TRAVERSE_PAGEUP
,TRAVERSE_PAGEDOWN
,TRAVERSE_HOME
,TRAVERSE_END
,TRAVERSE_TOP
,TRAVERSE_BOTTOM
, andTRAVERSE_TO_CELL.
getTraverseTypeString()
- returns a String value for the traverse type.isCancelled()
- retrieves the cancelled value.setCancelled()
- determines whether to allow an interactive resize.getType()
- retrieves valid event types, which areTRAVERSE_CELL
andAFTER_TRAVERSE_CELL.
toString()
- returns a String representation of the event.JCTraverseCellListener
To register the above event listener routine, use the following call (where
table.addTraverseCellListener(this);(this)
refers to the class, which implements theJCTraverseCellListener
interface):public void traverseCell(JCTraverseCellEvent e)
JCTraverseCellListener
requires the following methods to be implemented:
public void afterTraverseCell(JCTraverseCellEvent e)Calling JCTraverseCellEvent and JCTraverseCellListener Methods
JCTraverseCellListener
'straverse()
method is invoked when the user begins to traverse to a neighboring cell. Since this method is called before the actual traversal, allJCTraverseCellEvent
methods are available. For example, ifsetCancelled()
is called, and is set totrue
, the cell traversal is cancelled. You can also call methods that permit cell skipping during traversal.
afterTraverseCell()
is invoked after valid cell traversal. ThesetNextRow()
,setNextColumn()
, andsetCancelled()
methods are unavailable duringafterTraverseCell()
. For more information, please refer to Appendix A, which provides a complete event summary.Using JCTraverse Events and Listeners
import com.klg.jclass.table.JCTable;
JCTraverseCellListener
allows you to control how cell traversal occurs in JClass LiveTable. The following example (see examples/table/listeners/SkipNavigation.java) uses aJCTraverseCellListener
to skip the second column if navigating from the first column. The column is not skipped if navigating from the third column.
import com.klg.jclass.table.JCTableEnum;
import com.klg.jclass.table.data.JCVectorDataSource;
import com.klg.jclass.table.JCTraverseCellListener;
import com.klg.jclass.table.JCTraverseCellEvent;
import com.klg.jclass.util.swing.JCExitFrame;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JPanel;
public class SkipNavigation extends JPanel implements JCTraverseCellListener {
// Table instance
protected JCTable table;
// Table data source
protected JCVectorDataSource ds;
public SkipNavigation() {
setBackground(Color.lightGray);
// Create table instance
table = new JCTable();
// Create and set up data source
ds = new JCVectorDataSource();
ds.setNumRows(10);
ds.setNumColumns(4);
for(int c = 0; c < ds.getNumColumns(); c++)
ds.setColumnLabel(c, "Column: "+c);
ds.setColumnLabel(1, "Skip from 0 to 2");
for(int r = 0; r < ds.getNumRows(); r++) {
ds.setRowLabel(r, "Row: "+r);
for(int c = 0; c < ds.getNumColumns(); c++)
ds.setCell(r,c,"Cell: R"+r+"C"+c);
}
// Connect table data source
table.setDataSource(ds);
// Add everything to the panel
setLayout(new GridLayout(1,1));
add(table);
// Add traverse cell listener
table.addTraverseCellListener(this);
}
public void traverseCell(JCTraverseCellEvent event) {
// Skip second column when approaching from the left
if (event.getColumn() == 0 && event.getNextColumn() == 1) {
event.setNextColumn(2);
}
// Skip second column in both directions.
// if(event.getNextColumn() == 1)
// event.setNextColumn(1 + event.getNextColumn() - event.getColumn());
}
public void afterTraverseCell(JCTraverseCellEvent e) {
}
public static void main(String args[]) {
JCExitFrame frame = new JCExitFrame("SkipNavigation");
SkipNavigation sn = new SkipNavigation();
frame.getContentPane().add(sn);
frame.pack();
frame.setSize(600, 150);
frame.setVisible(true);
}
}
![]() ![]() ![]() |