Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

DefaultRowSorter.setSortsOnUpdates(true) Disaster

843807Apr 18 2010 — edited Apr 21 2010
The situation is this: I have a table model in which some of the columns can take their lazy ol' time initializing so they are only loaded as needed. I also wanted to sort on these columns. Of course, the problem is when the sort is started, it only does a partial sort as some of the values aren't actually initialized yet. So setSortsOnUpdates to the rescue!

Well not really. It will sort, but the view isn't repainted properly (or perhaps not at all).

In my context, I am calling repaint on the bounds of a table row after it is loaded and that seems to fix the problem. It was initially broken when I tried to retrofit the cache mechanism to be able to handle the situation - it was calling repaint on the wrong row which is how I stumbled with this problem in the first place.

But it doesn't seem like it should be enough. All the rows that are shifted ought to need repainted too, no?

Anyway, here is a simulation of the situation which depicts the repaint problem. Uncomment the four statements in the actionPerformed method to see that repainting the single row seems to work, at least for this specific circumstance. Sort on the second column, wait about 5 seconds, click around.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.RowSorter.SortKey;
import javax.swing.event.*;
import javax.swing.table.*;

public class SortTest implements Runnable, RowSorterListener, ActionListener {
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new SortTest());
	}
	
	@Override
	public void run() {
		model = new DefaultTableModel(100, 2) {
			public Class<?> getColumnClass(int column) {
				return column == 1 ? Integer.class : Object.class;
			}
		};
		for (int row=model.getRowCount(); --row>=0;) {
			model.setValueAt(createString(), row, 0);
			model.setValueAt(0, row, 1);
		}
		table = new JTable(model);
		table.setAutoCreateRowSorter(true);
		TableRowSorter<?> sorter = (TableRowSorter<?>)table.getRowSorter();
		sorter.setSortsOnUpdates(true);
		sorter.addRowSorterListener(this);
		JFrame frame = new JFrame(getClass().getSimpleName());
		frame.add(new JScrollPane(table));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
	
	private JTable table;
	
	private DefaultTableModel model;
	
	@Override
	public void sorterChanged(RowSorterEvent e) {
		if (load && e.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
			List<SortKey> keys = e.getSource().getSortKeys();
			for (SortKey key : keys) {
				if (key.getColumn() == 1) {
					load = false;
					new Timer(20, this).start();
					break;
				}
			}
		}
	}
	
	private static Random random = new Random();

	private boolean load = true;

	private int row;
	
	@Override
	public void actionPerformed(ActionEvent e) {
		model.setValueAt(new Integer(random.nextInt(900)+100), row, 1);
		
//		Rectangle bounds = table.getCellRect(
//				table.convertRowIndexToView(row), 0, false);
//		bounds.x = 0;
//		bounds.width = table.getWidth();
//		table.repaint(bounds);
		
		if (++row == model.getRowCount())
			((Timer)e.getSource()).stop();
	}
	
	private static String createString() {
		int len = random.nextInt(5)+3;
		char[] c = new char[len];
		for (int j=c.length; --j>=0;)
			c[j] = (char)('A'+random.nextInt(26));
		return new String(c);
	}
}

Comments

Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on May 19 2010
Added on Apr 18 2010
10 comments
727 views