posted 2 years ago
I don't know where the code on codejava.net comes from, but IMHO their CountryCellEditor is not quality code.
Here's their implementation:Lines 38-42 create a new instance of JComboBox and populate its entries, which is slow. The idea is that this method should be fast. Speed is crucial in a Cell Renderer, and definitely not as crucial in a Cell Editor, but this method is called when the user clicks a cell for editing. The ComboBox should be already set up (as much as possible) before this method is called, so that the user does not perceive a delay. This code could be changed to instantiate the ComboBox, and populate its entries, in the constructor.
Line 44 is appropriate. If the code were changed to instantiate the ComboBox in the constructor, this line would still appear here in the getTableCellEditorComponent() method.
Line 45 is setting an ActionListener on the ComboBox. This is appropriate, so that when the user hits the enter key the Cell Editor will finish editing, rather than remaining in the cell and requiring the user to hit the escape key or click somewhere to actually complete the edit. But there are problems:
Presuming that we have improved the code by only instantiating the ComboBox only once, then the action listener needs to be added only once, outside of this method.Having the CountryCellEditor actually implement the ActionListener interface, and adding this as the listener, is an old coding style. Modern code would probably structure this differently. But it could work with this structure, except...But what it's actually doing in the actionPerformed() method (lines 58-59) isn't quite right. It is taking the selected value and storing it in the country instance variable, so it can later be returned by the getCellEditorValue() method, which I guess is fine. [If the ComboBox were an instance variable, then wouldn't need to keep country as a separate variable but could simply have getCellEditorValue() return cb.getSelectedItem()—no ActionListener needed to get getCellEditorValue() to work correctly.] But the ActionListener is not doing anything else. It's not notifying the table that the edit has completed, and it should.
Lines 47-51 are misguided, I think. This would be appropriate for a Cell Renderer, not so much for a Cell Editor. It's possible that something like this could work in a Cell Editor, but it would take some experimentation. As the very least, I think line 50 is setting the wrong color. It would be more appropriate to setBackground(table.getBackground()). That is, to match the ComboBox's background with the table's (regular non-selected) background, rather than to the table's (selected) foreground. But I think it would probably be best to skip these lines entirely and let the ComboBox have its default background.
They declare the CountryCellEditor class itself (lines 16-17) is like this:I can understand why they want to extend AbstractCellEditor because that way they inherit a bunch of event-handling methods and don't have to mess with them. But I think I would prefer to do it like this instead:This way, the Cell Editor is a JComboBox, which I kind of like better, but the trade-off is that we then need to implement those event-handling methods (which isn't too bad). But the other way could work too. This is simply my preference.
Anyway, my code might look something like this: