001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.history; 003 004import java.util.ArrayList; 005import java.util.List; 006import java.util.concurrent.atomic.AtomicInteger; 007import java.util.stream.IntStream; 008 009import javax.swing.table.AbstractTableModel; 010 011import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item.DiffItemType; 012 013/** 014 * Simple model storing "diff cells" in a list. Could probably have 015 * used a {@link javax.swing.table.DefaultTableModel} instead. 016 */ 017class DiffTableModel extends AbstractTableModel { 018 private transient List<TwoColumnDiff.Item> rows = new ArrayList<>(); 019 private transient int[] rowNumbers; 020 private boolean reversed; 021 022 public void setRows(List<TwoColumnDiff.Item> rows, boolean reversed) { 023 this.rows = rows; 024 this.reversed = reversed; 025 computeRowNumbers(); 026 fireTableDataChanged(); 027 } 028 029 @Override 030 public int getRowCount() { 031 return rows.size(); 032 } 033 034 @Override 035 public int getColumnCount() { 036 return 1; 037 } 038 039 public boolean isReversed() { 040 return reversed; 041 } 042 043 @Override 044 public TwoColumnDiff.Item getValueAt(int rowIndex, int columnIndex) { 045 return rows.get(rowIndex); 046 } 047 048 public int getFirstChange() { 049 return IntStream.range(0, rows.size()) 050 .filter(i -> rows.get(i).state != DiffItemType.SAME) 051 .findFirst().orElse(-1); 052 } 053 054 void computeRowNumbers() { 055 AtomicInteger rowNumber = new AtomicInteger(reversed ? rows.size() : 1); 056 rowNumbers = rows.stream().mapToInt(item -> { 057 if (item.state == DiffItemType.EMPTY) { 058 return -1; 059 } else if (reversed) { 060 return rowNumber.getAndDecrement(); 061 } else { 062 return rowNumber.getAndIncrement(); 063 } 064 }).toArray(); 065 } 066 067 public int getRowNumber(int rowIndex) { 068 return rowNumbers[rowIndex]; 069 } 070}