I have created a UI using Swing with a JTable. I have implemented a ListSelectionListener through which I am able to fetch records based on the selected row in the table. I am unable to deselect the row after selection.
So basically I should be able to select a row with one click and then I should be able to deselect the row with another click.
I tried using tableName.getSelectionModel.clearSelection, but I don't know how to see if a row is selected or not. What would tell me this?
Another solution I tried is using a Mouse Click Listener. Again, I am not able to write the condition to check if the mouse click happens on the previously selected row. Is there a way by which I can get the previous row selected?
I am using the DefaultTableModel.
This functionality is supported by default by holding down the "Control" key when you use the mouse click. This is the standard that is used by most applications.
If you really want to use a non standard approach then you should probably be customizing the ListSelectionModel. I would guess you would override the setSelectionInterval(...) method. That is you would first check if the row is currently selected. If so, then invoke the clearSelection() method and return. Otherwise invoke super.setSelectionInterval(...).
It may be old but this works.
table = new JTable() {
public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend)
{
//Always toggle on single selection
super.changeSelection(rowIndex, columnIndex, !extend, extend);
}
};
Related
Whenever there is a lostFocus inside a JTable, i need to capture the existing cell's row and column.
However, the condition below is always false because the source is always either a JTextField or a JComboBox.
public void focusLost(FocusEvent e) {
int row, col;
Object source = e.getSource();
if(((Component) source).getParent() instanceof JTable_Ext){ //<-- always false
table = (JTable_Ext) ((Component) source).getParent();
row = table.getSelectedRow();
col = table.getSelectedColumn();
}
To mitigate the above, i remember the row and col during FocusGained (as class level variable). The problem is, if the user click very fast all over the place within the JTable, somehow the row and column information will be out of sync.
Is there a way to get the Row and Col during FocusLost? if not, is there a better way of doing this?
Well, there is the oppositeComponent. The weird thing is, if this listener is attached to the table, the documentation tells that the table should be the "source" component (because it is a FocusLost event and the component that lost the focus is the table itself).
http://download.oracle.com/javase/1.4.2/docs/api/java/awt/event/FocusEvent.html#getOppositeComponent%28%29
Could you just keep a record of row & column using
table.getSelectionModel().addListSelectionListener(...);
table.getColumnModel().getSelectionModel().addListSelectionListener(...);
So every time the use clicks update it, not just on focus events?
If you just want to save the data that was entered in the cell (without hitting return), then you don't need to do anything. The updated information is contained within TableModel of the JTable.
Otherwise you can take a look at .tableChanged() and the associated TableModelEvent, which gives you the last row/column modified. You could keep a variable that is always updated to the latest event row/column. I guess that if you change a cell number without hitting return, it nonetheless registers as an event.
However, the condition below is always false because the source is always either a JTextField or a JComboBox.
This implies that the focusLost event is being generated when you begin editing a cell. So the question is why are you doing this? I think you need to state your actual requirement, because you attempted solution does not seem appropriate.
I have a jTable which currently displays and allows editing of a database table, I am now trying to sort adding tuples.
I am trying to get it to automatically add a row on downarrow at the bottom. So if I am at the bottom on the table and click my down arrow a new row will appear below. I just can't figure out how to do it.
Thanks
James
Action handling of JTable happens in javax.swing.plaf.basic.BasicTableUI. In your case, you probably need to register a new action for SCROLL_DOWN_CHANGE_SELECTION. In the action, check whether the current selection == last row of the table.
If that doesn't work, set a breakpoint in javax.swing.plaf.basic.BasicTableUI.Actions.actionPerformed(ActionEvent) to see which action is really executed.
JTable has a default Action for the down arrow key. If you want to change this behaviour then you need to create a custom Action. You can do this easily by using the Wrapping Actions concept to leverage the default code.
You can also look at Table Tabbing for a working example of wrapping an Action. You code for the Action would be much simpler and would be something like:
if (last row is selected)
add a new row to the table
invoke the default down arrow action
You'll need to create a KeyListener and add this to your table:
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_DOWN)
// check if selected table row = last row and if so: add new row to table model
}
greetz,
Stijn
I've searched for this for quite a while and haven't found a clear example anywhere. I'm a Java newbee using NetBeans. I have a boolean value in the first column of a JTable (called "Enabled") and I have some plugin code that I need to call to see if it has the settings it needs in order to be enabled, and if not, display a message box and prevent Enabled from being checked.
All I really need is for a function to be called when the checkbox is checked and I can take it from there. Does anyone have an example of how to do this?
Thanks for your help!
Harry
You probably want a TableModelListener, as discussed in Listening for Data Changes. Alternatively, you can use a custom editor, as discussed in Concepts: Editors and Renderers and the following section.
All I really need is for a function to
be called when the checkbox is checked
When the checkbox is checked then the value will be changed in the model, which is probably not what your want. I would think you want to prevent the checking of the checkbox in the first place.
The way to prevent a cell from being editable is to override the isCellEditable(...) method of JTable. By overriding this method you can dynamically determine if the cell should be editable or not.
JTable table = new JTable( ... )
{
public boolean isCellEditable(int row, int column)
{
int modelColumn = convertColumnIndexToModel( column );
if (modelColumn == yourBooleanColumn)
return isTheBooleanForThisRowEditable(row);
else
return super.isCellEditable(row, column);
}
};
And a fancier approach would be to create a custom renderer so that the check box looks "disabled" even before the user attempts to click on the cell. See the link provided by trashgod on renderers.
I am trying to make a special kind of jtable. I want the entire table to by default be NOT editable. But when the user clicks a row, then clicks the "Edit" jbutton, that specific row is editable. and once they deslect the row its no longer editable.
How would I go about doing this?
to control which cells are editable, you will need to extend either JTable or JTableModel (see the call to the model in the example below) to ensure that this method from JTable returns true for all the cells in the row(s) you want editable based on your spec.
public boolean isCellEditable(int row, int column) {
return getModel().isCellEditable(row, convertColumnIndexToModel(column));
}
also take a look at this tutorial to learn about TableCellEditors
I was looking for an answer for a previous question and had an ingenious idea to overcome a limit on JTable. I need the editor to be different on a row by row basis, whereas JTable can only handle a single editor for each column.
So my idea is to use a MouseListener to check the row and column on the JTable and set new editor each time.
But, calling setCellEditor() a second time do not have any effect. The editor remains to be the first one that was set. So how can I make "setCellEditor" work a second time for the same column?
Here's the code in MouseListener.
public void mouseClicked(MouseEvent e) {
int cols = resultTable.columnAtPoint(new Point(e.getX(), e.getY()));
int rows = resultTable.rowAtPoint(new Point(e.getX(), e.getY()));
StorageObject item = (StorageObject) resultTable.getModel().getValueAt(rows, cols);
TableColumn col = resultTable.getColumnModel().getColumn(cols);
col.setCellEditor(new MyComboBoxEditor(item.list));
}
I'm not sure why your code isn't working (it's been a while since I've done Swing), but why don't you just override
public TableCellEditor getCellEditor(int row, int column)
On your JTable? Maintain a map of the combo boxes you want to use for each row and in your overriden method return the correct one.
My theory is that when all the mouse listeners registered to the Table/TableCell are invoked, the ones installed to the API classes by default will be invoked first, before your mouse listener. This means the event causing the editor to be fetched will occur before you set it to a different one. Kind of like a race condition, only it's actually defined somewhere in the API source code... That's my naive theory and I can already see some holes in it, so on to my solution:
Override JTable.getCellEditor(int row, int col). This allows you to return whatever editor you want for any cell.