Adding a row to a jTable on downarrow at bottom - java

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

Related

Deselecting the selected row in a JTable

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);
}
};

Disable Selection of Particular rows on a JTable

I am currently using setRowSelectionAllowed(boolean) method. In my implementation, it disables all the rows. However what I want is to to disable some rows and not all the rows. Can someone please help me that to accomplish this?
Here is my code
if (encounterId == currentencounterId)
{
getNstTemplates().getTable().setRowSelectionAllowed(true);
}
else
{
getNstTemplates().getTable().setRowSelectionAllowed(false);
}
You can insert a custom ListSelectionModel into your table that ignores or modifies selection events involving the non-selectable rows.

JTable prevent all sorting

Is it possible to prevent sorting all together on the JTable? Basically I don't want anything to happen when the user clicks the table header, and for the content to be in a static order.
See the Javadoc:
public void setRowSorter(RowSorter sorter)
Parameters: sorter - the RowSorter; null turns sorting off
Basically I don't want anything to happen when the user clicks the table header, and for the content to be in a static order.
basically JTable haven't any Sorter, you have to remove codelines
- JTable#setAutoCreateRowSorter(true);
- table.setRowSorter(sorter);
- custom Comparator added as MouseEvent to the JTableHeader
have look at and read JTable tutorial about Sorting and Filtering
The best and simple way to disable sorting when user clicks on any table header columns:
first you need to create a mouse click listener on the table header
inside of it make only mouse click left avaible (with SwingUtilities)
insert this line of code
yourTableVariable.setRowSorter(null);
Practical example:
yourTableVariable.getTableHeader().addMouseListener(new MouseAdapter() //here you make the click avaible ONLY on Table Header
{
#Override
public void mouseClicked(MouseEvent arg0)
{
if (SwingUtilities.isLeftMouseButton(arg0)) //here you select the mouse left click action
{
yourTableVariable.setRowSorter(null); //here is disableing the sorting
}
}
});

How to get JTable selectedRow and selectedColumn during FocusLost event

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.

refresh setCellEditor for JTable

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.

Categories