001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.dialogs.relation; 003import java.util.ArrayList; 004import java.util.Collection; 005import java.util.List; 006 007import javax.swing.table.AbstractTableModel; 008 009import org.openstreetmap.josm.Main; 010import org.openstreetmap.josm.data.SelectionChangedListener; 011import org.openstreetmap.josm.data.osm.DataSet; 012import org.openstreetmap.josm.data.osm.OsmPrimitive; 013import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent; 014import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener; 015import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent; 016import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; 017import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent; 018import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener; 019import org.openstreetmap.josm.gui.layer.OsmDataLayer; 020import org.openstreetmap.josm.tools.CheckParameterUtil; 021 022public class SelectionTableModel extends AbstractTableModel implements SelectionChangedListener, ActiveLayerChangeListener, LayerChangeListener { 023 024 /** this selection table model only displays selected primitives in this layer */ 025 private final transient OsmDataLayer layer; 026 private final transient List<OsmPrimitive> cache; 027 028 /** 029 * constructor 030 * 031 * @param layer the data layer. Must not be null. 032 * @throws IllegalArgumentException if layer is null 033 */ 034 public SelectionTableModel(OsmDataLayer layer) { 035 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 036 this.layer = layer; 037 cache = new ArrayList<>(); 038 populateSelectedPrimitives(layer); 039 } 040 041 /** 042 * Registers listeners (selection change and layer change). 043 */ 044 public void register() { 045 DataSet.addSelectionListener(this); 046 Main.getLayerManager().addActiveLayerChangeListener(this); 047 } 048 049 /** 050 * Unregisters listeners (selection change and layer change). 051 */ 052 public void unregister() { 053 DataSet.removeSelectionListener(this); 054 Main.getLayerManager().removeActiveLayerChangeListener(this); 055 } 056 057 @Override 058 public int getColumnCount() { 059 return 1; 060 } 061 062 @Override 063 public int getRowCount() { 064 if (Main.getLayerManager().getEditLayer() != layer) 065 return 0; 066 return cache.size(); 067 } 068 069 @Override 070 public Object getValueAt(int rowIndex, int columnIndex) { 071 return cache.get(rowIndex); 072 } 073 074 @Override 075 public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) { 076 if (e.getPreviousActiveLayer() == layer) { 077 cache.clear(); 078 } 079 if (e.getSource().getActiveLayer() == layer) { 080 cache.addAll(layer.data.getAllSelected()); 081 } 082 fireTableDataChanged(); 083 } 084 085 @Override 086 public void layerAdded(LayerAddEvent e) { 087 // do nothing 088 } 089 090 @Override 091 public void layerRemoving(LayerRemoveEvent e) { 092 if (e.getRemovedLayer() == layer) { 093 unregister(); 094 } 095 this.cache.clear(); 096 fireTableDataChanged(); 097 } 098 099 @Override 100 public void layerOrderChanged(LayerOrderChangeEvent e) { 101 // do nothing 102 } 103 104 @Override 105 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 106 if (layer == Main.getLayerManager().getEditLayer()) { 107 cache.clear(); 108 cache.addAll(newSelection); 109 } else { 110 cache.clear(); 111 } 112 fireTableDataChanged(); 113 } 114 115 public List<OsmPrimitive> getSelection() { 116 return cache; 117 } 118 119 /** 120 * populates the model with the primitives currently selected in 121 * <code>layer</code> 122 * 123 * @param layer the data layer 124 */ 125 protected void populateSelectedPrimitives(OsmDataLayer layer) { 126 selectionChanged(layer.data.getAllSelected()); 127 } 128 129 /** 130 * Replies the primitive at row <code>row</code> in this model 131 * 132 * @param row the row 133 * @return the primitive at row <code>row</code> in this model 134 * @throws ArrayIndexOutOfBoundsException if index is invalid 135 */ 136 public OsmPrimitive getPrimitive(int row) { 137 return cache.get(row); 138 } 139 140}