package org.openpnp.gui.components;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.Vector;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.text.JTextComponent;
/**
* From http://tips4java.wordpress.com/2008/10/20/table-select-all-editor/
*
* The RXTable provides some extensions to the default JTable
*
* 1) Select All editing - when a text related cell is placed in editing mode the text is selected.
* Controlled by invoking a "setSelectAll..." method.
*
* 2) reorderColumns - static convenience method for reodering table columns
*/
@SuppressWarnings("serial")
public class AutoSelectTextTable extends JTable {
private boolean isSelectAllForMouseEvent = true;
private boolean isSelectAllForActionEvent = true;
private boolean isSelectAllForKeyEvent = true;
//
// Constructors
//
/**
* Constructs a default <code>RXTable</code> that is initialized with a default data model, a
* default column model, and a default selection model.
*/
public AutoSelectTextTable() {
this(null, null, null);
}
/**
* Constructs a <code>RXTable</code> that is initialized with <code>dm</code> as the data model,
* a default column model, and a default selection model.
*
* @param dm the data model for the table
*/
public AutoSelectTextTable(TableModel dm) {
this(dm, null, null);
}
/**
* Constructs a <code>RXTable</code> that is initialized with <code>dm</code> as the data model,
* <code>cm</code> as the column model, and a default selection model.
*
* @param dm the data model for the table
* @param cm the column model for the table
*/
public AutoSelectTextTable(TableModel dm, TableColumnModel cm) {
this(dm, cm, null);
}
/**
* Constructs a <code>RXTable</code> that is initialized with <code>dm</code> as the data model,
* <code>cm</code> as the column model, and <code>sm</code> as the selection model. If any of
* the parameters are <code>null</code> this method will initialize the table with the
* corresponding default model. The <code>autoCreateColumnsFromModel</code> flag is set to false
* if <code>cm</code> is non-null, otherwise it is set to true and the column model is populated
* with suitable <code>TableColumns</code> for the columns in <code>dm</code>.
*
* @param dm the data model for the table
* @param cm the column model for the table
* @param sm the row selection model for the table
*/
public AutoSelectTextTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) {
super(dm, cm, sm);
}
/**
* Constructs a <code>RXTable</code> with <code>numRows</code> and <code>numColumns</code> of
* empty cells using <code>DefaultTableModel</code>. The columns will have names of the form
* "A", "B", "C", etc.
*
* @param numRows the number of rows the table holds
* @param numColumns the number of columns the table holds
*/
public AutoSelectTextTable(int numRows, int numColumns) {
this(new DefaultTableModel(numRows, numColumns));
}
/**
* Constructs a <code>RXTable</code> to display the values in the <code>Vector</code> of
* <code>Vectors</code>, <code>rowData</code>, with column names, <code>columnNames</code>. The
* <code>Vectors</code> contained in <code>rowData</code> should contain the values for that
* row. In other words, the value of the cell at row 1, column 5 can be obtained with the
* following code:
* <p>
*
* <pre>
* ((Vector) rowData.elementAt(1)).elementAt(5);
* </pre>
* <p>
*
* @param rowData the data for the new table
* @param columnNames names of each column
*/
public AutoSelectTextTable(Vector rowData, Vector columnNames) {
this(new DefaultTableModel(rowData, columnNames));
}
/**
* Constructs a <code>RXTable</code> to display the values in the two dimensional array,
* <code>rowData</code>, with column names, <code>columnNames</code>. <code>rowData</code> is an
* array of rows, so the value of the cell at row 1, column 5 can be obtained with the following
* code:
* <p>
*
* <pre>
* rowData[1][5];
* </pre>
* <p>
* All rows must be of the same length as <code>columnNames</code>.
* <p>
*
* @param rowData the data for the new table
* @param columnNames names of each column
*/
public AutoSelectTextTable(final Object[][] rowData, final Object[] columnNames) {
super(rowData, columnNames);
}
//
// Overridden methods
//
/*
* Override to provide Select All editing functionality
*/
public boolean editCellAt(int row, int column, EventObject e) {
boolean result = super.editCellAt(row, column, e);
if (isSelectAllForMouseEvent || isSelectAllForActionEvent || isSelectAllForKeyEvent) {
selectAll(e);
}
return result;
}
/*
* Select the text when editing on a text related cell is started
*/
private void selectAll(EventObject e) {
final Component editor = getEditorComponent();
if (editor == null || !(editor instanceof JTextComponent))
return;
if (e == null) {
((JTextComponent) editor).selectAll();
return;
}
// Typing in the cell was used to activate the editor
if (e instanceof KeyEvent && isSelectAllForKeyEvent) {
((JTextComponent) editor).selectAll();
return;
}
// F2 was used to activate the editor
if (e instanceof ActionEvent && isSelectAllForActionEvent) {
((JTextComponent) editor).selectAll();
return;
}
// A mouse click was used to activate the editor.
// Generally this is a double click and the second mouse click is
// passed to the editor which would remove the text selection unless
// we use the invokeLater()
if (e instanceof MouseEvent && isSelectAllForMouseEvent) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
((JTextComponent) editor).selectAll();
}
});
}
}
//
// Newly added methods
//
/*
* Sets the Select All property for for all event types
*/
public void setSelectAllForEdit(boolean isSelectAllForEdit) {
setSelectAllForMouseEvent(isSelectAllForEdit);
setSelectAllForActionEvent(isSelectAllForEdit);
setSelectAllForKeyEvent(isSelectAllForEdit);
}
/*
* Set the Select All property when editing is invoked by the mouse
*/
public void setSelectAllForMouseEvent(boolean isSelectAllForMouseEvent) {
this.isSelectAllForMouseEvent = isSelectAllForMouseEvent;
}
/*
* Set the Select All property when editing is invoked by the "F2" key
*/
public void setSelectAllForActionEvent(boolean isSelectAllForActionEvent) {
this.isSelectAllForActionEvent = isSelectAllForActionEvent;
}
/*
* Set the Select All property when editing is invoked by typing directly into the cell
*/
public void setSelectAllForKeyEvent(boolean isSelectAllForKeyEvent) {
this.isSelectAllForKeyEvent = isSelectAllForKeyEvent;
}
// public void changeSelection(final int row, final int column, boolean toggle, boolean extend)
// {
// super.changeSelection(row, column, toggle, extend);
// editCellAt(row, column);
// transferFocus();
// }
//
// Static, convenience methods
//
/**
* Convenience method to order the table columns of a table. The columns are ordered based on
* the column names specified in the array. If the column name is not found then no column is
* moved. This means you can specify a null value to preserve the current order of a given
* column.
*
* @param table the table containing the columns to be sorted
* @param columnNames an array containing the column names in the order they should be displayed
*/
public static void reorderColumns(JTable table, Object... columnNames) {
TableColumnModel model = table.getColumnModel();
for (int newIndex = 0; newIndex < columnNames.length; newIndex++) {
try {
Object columnName = columnNames[newIndex];
int index = model.getColumnIndex(columnName);
model.moveColumn(index, newIndex);
}
catch (IllegalArgumentException e) {
}
}
}
} // End of Class RXTable