I have a JTable in my code.
And whenever there is an update to any specific column in the row (cell basically), I will update the corresponding icon in that cell.
so I'm basically following these steps.
Step 1: I update the model.
Step2 2: I'm calling
tableModel.fireTableCellUpdated(tableRowIndex, tableColumnIndex);
This works fine.
But problem comes when I drag and drop the columns from one position to another in Table header. And whenever there is an update to any specific cell, I follow the same steps as I mentioned before.
Problem: I'm not seeing the Icon painted. But if I bring the focus on top of that row in table it is painting the icon.
Observation: I see the tableRowIndex and tableColumnIndex are correct after dragging the columns.
Just for testing I added this piece of code in the problem scenario.
examTable.repaint(examTable.getCellRect(examTableRowIndex, examTableColumnIndex, true));
This is repainting the cell properly.
But this is not the right solution I guess. I tried to debug the code I didn't find much about the problem
I'm calling tableModel.fireTableCellUpdated(tableRowIndex, tableColumnIndex);
That is wrong. You should never invoke the firXXX methods directly. That is the job of the TableModel to invoke the appropriate event when the data is changed.
I will update the corresponding icon in that cell.
All you need to do is invoke model.setValueAt(...) method to change the Icon and the model will notify the table that data has changed so the table can repaint itself.
examTable.repaint(...)
Again you should not need to manually invoke repaint on the table
But problem comes when I drag and drop the columns from one position to another in Table header.
Not sure why you need special code for this if you follow the advice from above. But if for some reason it is still necessary then you need to look at the convertColumnIndex...(...) methods to make sure you are using the proper index for your column.
Related
I have a NatTable component with the following layers:
ViewportLayer
SelectionLayer
RowHideShowLayer
ColumnGroupExpandCollapseLayer
ColumnHideShowLayer
DataLayer
I need to show/hide a specific column, when a checkbox selection changes. In order to that, I use the #doCommand() method provided by the NatTable component:
if(selection) {
nattable.doCommand(new ColumnShowCommand(nattable, COLUMN_INDEX));
} else {
nattable.doCommand(new ColumnHideCommand(nattable, COLUMN_INDEX+1));
}
Everything works just fine, excepting the case when ALL the items in the table are selected, and the ColumnHideCommand is executed. On this specific scenario, the whole table content disappears (Screenshot). If there is no selection in the table, or not all the elements are selected, then everything works just fine.
Please let me know if you have any idea what's going on there or if you experienced this kind of issues before. My experience with NatTables is quite limited, so please let me know if you need any additional information. Thank you!
This is a feature of the SelectionLayer to support multi column hide operations based on the column selection. A ColumnHideCommand get consumed and instead a MultiColumnHideCommand is created and executed based on the fully selected columns. The code in charge is located in SelectionLayer#handleColumnHideCommand(ColumnHideCommand). The method is protected, so if you don't need that feature because you only support column hide/show programmatically and not via UI performed by a user, you can override the method to simply perform a super.doCommand(command); without the check for selections.
I want to refresh the JTable data by clicking a button.
The problem is that the old data in the JTable can't be removed and the new data are just added into the table. I tried below ways to remove the old data but none of them works.
1. table.setModel(new DefaultTableModel());
2. ((DefaultTableModel)table.getModel()).setRowCount(0);
3. ((DefaultTableModel)table.getModel()).fireTableDataChanged();
4. ((DefaultTableModel)table.getModel()).getDataVector().removeAllElements();
5. table.repaint();
6. model = (DefaultTableModel)table.getModel();
while(model.getRowCount() > 0) {
model.removeRow(0);
}
Having a refresh button for a JTable is very suspect. It makes me think you aren't correctly adding data as JTables should refresh everytime data is added or removed.
I would verify a couple of things when using a DefaultTableModel:
Make sure to only add data using addRow
Data should only be inserted using insertRow
Remove data using removeRow
Never modify the internal vectors directly. It won't cause events to fire and you're stuck with a refresh button. I don't know why they even expose it. The JavaDocs should at least specifically warn against this.
If all else fails, fire up a debugger and see what happens.
More of your code might be appropriate here. Hard to tell exactly where you're calling these methods and the order. If you change the model and then call fireTableDataChanged() it should work....assuming you've updated the right TableModel. There is a good Java tutorial for using tables: http://docs.oracle.com/javase/tutorial/uiswing/components/table.html
Had the same issue myself, but my solution was different. After checking just about everything, I checked the contents of the table via the console, and found that the contents were indeed being updated. However, the update was not being reflected on the table which was visible on the screen.
In fact, this code:
model = (DefaultTableModel)table.getModel();
while(model.getRowCount() > 0) {
model.removeRow(0);
}
Did not only remove the rows, but also removed the table.
My solution was to remove the table from the form and then re-add it, whenever the table data was changed.
Seemed in my case there was nothing wrong with my coding to generate the table but that the layout manager didn't like overwriting or updating a component the area where I wanted to put it already had something in there.
Something weird going on methinks but at the end of the day this worked for me.
I have a JXTable where the users need to introduce data, then save it. Only the thing is, the user has to deselect the last edited cell before saving it. If they don't, the data of that cell isn't saved.
The only thing I thought of is to change the current selection automatically just before saving. This is what i tried :
table.getSelectionModel().setSelectionInterval(0, 0);
table.getColumnModel().getSelectionModel().setSelectionInterval(0, 0);
OR
table.getSelectionModel().setLeadSelectionIndex(0);
table.getColumnModel().getSelectionModel().setLeadSelectionIndex(0);
None of both seem to work yet these are the only two methods I found to do this.
Can anyone please tell me how to do this properly or propose an alternative to also let it save the data from that last cell?
I am assuming the user clicks on another component (JButton) when he wishes to save data. If you have a reference to the JXTable when that event happens you could add the following piece of code there:
if (table.isEditing()) {
table.getCellEditor().stopCellEditing();
}
The stopCellEditing() should save the state of the model and allow you to save all the contents, including the currently selected / edited cell.
EDIT: As kleopatra pointed out, the default (and better!) way to handle this is through the client property of JTable component:
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
For JXTable this should already be set though, which indicates that the way your UI handling of the save functionality works does not include moving the focus away from the table. So in essence you'd be better off changing the focus when your 'save' event is being fired.
I have some old Java application that uses JTable to show some data and allow input as well.
JTable has 2 columns. Next to JTable, there is button that adds new row into JTable.
My problem is behavior of Tab and Enter keyboard keys and mouse clicks when you navigate JTable.
I will try to explain:
Let say there are 5 rows in JTable:
if I click with mouse on one row, sometime whole row gets highlighted, and sometime cell gets into edit mode (in addition to whole row being higlighted)
Sometime, selected row gets highlighted, but cell above or below highlighted row gets into edit mode
If I use Tab to skip from one field to another, editable field is always above highlighted row.
There are other issues as well.
Any ideas what might be wrong with it?
That sounds a bit odd. Are you fully invalidating your table and notifying listeners etc that the number of rows have changed?
In your table model, loop over all of your TableModelListeners and fire a TableModelEvent 'insert' event:
TableModelEvent event = new TableModelEvent(
modelInstance,
positionOfNewRow,
positionOfNewRow,
TableModelEvent.ALL_COLUMNS,
TableModelEvent.INSERT);
for (TableModelListener l: listeners) {
l.tableChanged(event);
}
If you can't work out the problem, it is possible to write your own behaviour for the table.
These are some useful methods:
editCellAt(int row, int column);
rowAtPoint(Point point);
columnAtPoint(Point point);
You can add your own listeners to the table to intercept events and edit cells in any way you like.
Turn off the Table cell editing. And see how it behaves. Typically this can be handled by changing the TableModel.isCellEditable() method to simply return false.
Turn it back on. Is your instance of JTable subclassed? Is it overriding editCell()? If so that's the method that will trigger an edit based on the event occurring or not. That method is turning on editing inappropriately. The implementation of that method is bad if it's overridden.
If your table isn't subclassed look for calls to editCell(). Those are probably calling it inappropriately so you can look for those calls and start setting breakpoints or log statements.
one question with the java jTable class. Actually I am not a Java programmer and just now using Java to design a GUI in Matlab. What I've done is:
A jTable is built into a Matlab GUI.
I used/called a RowFilter in jTable, which can make the jTable to show the filtering results.
Then from the results in this filtered view I used the removeRow method from table model to remove one or several selected rows.
The problem is that everytime if I remove a row, the table content refreshs itself as wanted, but the scroll bar jumps back to the beginning.
Does anyone know how to inhibit this jumping and keep the original view of jTable? Because this helps me not to have to scroll back to find the original position where I started the deleting.
Thank u for ur advice and help.
Invoke the table's scrollRectToVisible() method; pass it the Rectangle returned by getCellRect() for the desired row.