@ Робин ответ в основном правильно, просто перевод на яшмы говорят :-)
«Декоратор» - это пользовательская реализация JRDataSource или (здесь) JRRewindableDataSource. Сделайте его только для данных и основывайтесь на RowSorter таблицы, что-то вроде (будьте осторожны: только что скомпилировано, а не протестировано!)
public class JRTableSorterDataSource implements JRRewindableDataSource {
private RowSorter<? extends TableModel> sorter;
private int currentRow = -1;
private HashMap<String, Integer> columnNames = new HashMap<String, Integer>();
public JRTableSorterDataSource(RowSorter<? extends TableModel> sorter) {
if (sorter == null) return; // do nothing, no sorter
this.sorter = sorter;
TableModel tableModel = sorter.getModel();
if (tableModel != null) {
for (int i = 0; i < tableModel.getColumnCount(); i++) {
this.columnNames.put(tableModel.getColumnName(i),
Integer.valueOf(i));
}
}
}
@Override
public Object getFieldValue(JRField field) throws JRException {
String fieldName = field.getName();
Integer columnIndex = this.columnNames.get(fieldName);
return sorter.getModel().getValueAt(sorter.convertRowIndexToModel(currentRow), columnIndex.intValue());
}
@Override
public boolean next() throws JRException {
if (sorter == null || sorter.getModel() == null)
return false;
this.currentRow++;
return (this.currentRow < sorter.getViewRowCount());
}
@Override
public void moveFirst() throws JRException {
this.currentRow = -1;
}
protected int getColumnIndex(JRField field) throws JRException {
String fieldName = field.getName();
Integer columnIndex = this.columnNames.get(fieldName);
if (columnIndex != null) {
return columnIndex;
} else if (fieldName.startsWith("COLUMN_")) {
return Integer.parseInt(fieldName.substring(7));
}
throw new JRException("Unknown column name : " + fieldName);
}
}
Затем используйте его при настройке отчета:
JRDataSource jr = new JRTableSorterDataSource(Dashboard.catalogTbl.getRowSorter());
/// ... same as your example
Редактировать
просто очень быстрый исполняемый фрагмент (слишком ленив, чтобы сделать полный отчет, забыл, как работают эти файлы ;-) - поэтому здесь мы создаем таблицу (со стандартной моделью SwingX), создаем источник данных на его RowSorter и зацикливаемся Значения первого столбца, без проблем:
JTable table = new JXTable(new AncientSwingTeam());
JRDataSource source = new JRTableSorterDataSource(table.getRowSorter());
table.getRowSorter().toggleSortOrder(0);
JRField field = createField("First Name");
String firstNames = "First Name: ";
while (source.next()) {
firstNames += "\n " + source.getFieldValue(field);
}
LOG.info(firstNames);