Closures now please

I’m trying to fix the event handling in some table code someone else wrote a few months back (where “fix” here means “support an ugly legacy global event model without just calling fireTableDataChanged() for every little thing”). I pretty much know what I need it to do, but setting up the test expectations is seriously painful. Among other things, I’m having to crawl the table model to build up “expected” sets of rows and columns for each event, over and over again, with a slightly different crawl condition for each test.

Closures would make this clean, or at least easy. But we don’t have them, so instead it’s:

	private static interface ColMatcher {
		boolean matches(TableColumn col, int index);

	private Set findColumns(ColMatcher matcher) {
		Set expectedCols = new HashSet();
		for (int col = 0, numCols = tableModel.getColumnCount(); col < numCols; col++) {
			TableColumn column = tableModel.getColumn(col);
			if (matcher.matches(column, col)) {
		return Collections.unmodifiableSet(expectedCols);

and then, over and over again:

	public void testSomeLegacyEvent() {
		final Set expectedRows = ...;
		final Set expectedCols = findColumns(new ColMatcher() {
			@Override public boolean matches(TableColumn column, int index) {
				return /* some condition */;

		final NastyLegacyEvent e = ...;

		SwingUtilities.invokeAndWait(new Runnable() {
			@Override public void run() {

				Set affectedColumns = tmListener.getAffectedColumns();
				assertEquals(expectedCols, affectedColumns);
				for (int col : expectedCols) {
					assertEquals(expectedRows, tmListener.getAffectedRows(col));

There’s really got to be a better way