I am using JTable. One of the cells contains multiple elements (panels, JLabels, JTextAreas and JButtons) and needs to change its height dynamically depending on user's input while editing. My Renderer and editor are in the same class and are using the same method to build the main panel. In the end of this method the preferred height is calculated:
Now this is working fine for rendering and editing of the cells. But I'm facing a problem when adding new rows into this table by adding data to table model. If the table was first rendered with 6 rows, then only max. 6 rows are rendered, no matter how many will be inserted later. So if I add rows in the beginning of the table, these rows are being shown and my old rows "disappear". Updating UI doesn't help. If I remove this code which is setting row height, inserting of rows is working fine!!
The condition will always be true so you keep trying to repaint the table.
It's never a good idea to customize a propery of the table in the render but if you do you need to prevent infinite loops. I would guess the code should be:
If you need more help then post your SSCCE that demonstrates the problem.
Joined: Oct 08, 2009
thanks for the answer! I guess it's not an infinite loop because there is no loop, but the condition is not needed, you are right. Now I created a small executable example of what is happening
This is the main class:
Here goes the table model:
and the renderer:
With this code you can add lines to the table. If you uncomment 2 lines which set the cell height in the last snippet, you don't see added lines. System.out shows, how many lines there should be in the table..
The problem with my real table is that all each cell has a different height which is being changed while editing, so I want to resize it dynamically..
Joined: Jun 13, 2009
I guess it's not an infinite loop because there is no loop
Just because you don't have a loop in your code doesn't mean you didn't create a loop. Add a System.out.println(...) to the renderer code to see the loop.
There are many thrings wrong with your code and I can't explain exactly why you are getting the problem because its a combination of things.
Never, invoke the updateUI() method directly. This is invoked when the LAF is changed. You did not change the LAF.
This is not how you update data in the table. All updates should be done throught the model. The model will then notify the table that a change has been made and the table will repaint itself. So you will need to create a custom addRow(...) method in your TableModel and you will need to fire the appropriate events. Reread the Swing tutorial to see how the custom model there fire events.
Of course the easier solution is to just use the DefaultTableModel you you don't need to do this. Then your code would be something like:
Then when you want to add a row all you do is:
Finally, you will still have the looping problem, so you will need to make a change similiar to the suggestion I made in my first posting. Although you might want to use "!=" intead of "<" to handle situations when the size becomes smaller as well are larger.
Again as I mentioned in my first reply this code doesn't not belong in the renderer. Maybe you should be adding a TableModelListener to the TableModel so you can listen for changes in the data and then reset the row height at that time.
Joined: Oct 08, 2009
thank you so much!!
I took a look at the DefaultTableModel implementation and implemented insertRow() for my model. Basically it is same code I was using outside of the table model, but it also fires an event:
This actually solved the problem!!! Now I can insert rows in my table. I will refactor my code a bit and do same for delete/move rows. And will try to remove the resizing from the renderer, but it might be more complicated..
Thank you for your time!
subject: JTable.setRowHeight() in CellRenderer/Editor: new rows not rendered