001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer.imagery; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Component; 007import java.awt.GridBagLayout; 008import java.util.List; 009import java.util.Map.Entry; 010import java.util.stream.Collectors; 011 012import javax.swing.JLabel; 013import javax.swing.JPanel; 014import javax.swing.JScrollPane; 015import javax.swing.JTable; 016import javax.swing.ListSelectionModel; 017import javax.swing.RowFilter; 018import javax.swing.event.DocumentEvent; 019import javax.swing.event.DocumentListener; 020import javax.swing.table.AbstractTableModel; 021import javax.swing.table.TableCellRenderer; 022import javax.swing.table.TableColumn; 023import javax.swing.table.TableRowSorter; 024 025import org.openstreetmap.josm.data.imagery.WMTSTileSource.Layer; 026import org.openstreetmap.josm.gui.util.TableHelper; 027import org.openstreetmap.josm.gui.widgets.JosmTextArea; 028import org.openstreetmap.josm.tools.GBC; 029 030/** 031 * Class for displaying WMTS layer selection panel. 032 * @since 13748 033 */ 034public class WMTSLayerSelection extends JPanel { 035 private static final class AbstractTableModelExtension extends AbstractTableModel { 036 private final List<Entry<String, List<Layer>>> layers; 037 038 private AbstractTableModelExtension(List<Entry<String, List<Layer>>> layers) { 039 this.layers = layers; 040 } 041 042 @Override 043 public Object getValueAt(int rowIndex, int columnIndex) { 044 switch (columnIndex) { 045 case 0: 046 return layers.get(rowIndex).getValue() 047 .stream() 048 .map(Layer::getUserTitle) 049 .collect(Collectors.joining(", ")); //this should be only one 050 case 1: 051 return layers.get(rowIndex).getValue() 052 .stream() 053 .map(x -> x.getTileMatrixSet().getCrs()) 054 .collect(Collectors.joining(", ")); 055 case 2: 056 return layers.get(rowIndex).getValue() 057 .stream() 058 .map(x -> x.getTileMatrixSet().getIdentifier()) 059 .collect(Collectors.joining(", ")); //this should be only one 060 default: 061 throw new IllegalArgumentException(); 062 } 063 } 064 065 @Override 066 public int getRowCount() { 067 return layers.size(); 068 } 069 070 @Override 071 public int getColumnCount() { 072 return 3; 073 } 074 075 @Override 076 public String getColumnName(int column) { 077 switch (column) { 078 case 0: return tr("Layer name"); 079 case 1: return tr("Projection"); 080 case 2: return tr("Matrix set identifier"); 081 default: 082 throw new IllegalArgumentException(); 083 } 084 } 085 } 086 087 private final List<Entry<String, List<Layer>>> layers; 088 private final JTable list; 089 090 /** 091 * Constructs a new {@code WMTSLayerSelection}. 092 * @param layers list of grouped layers (by tileMatrixSet and name) 093 */ 094 public WMTSLayerSelection(List<Entry<String, List<Layer>>> layers) { 095 super(new GridBagLayout()); 096 this.layers = layers; 097 list = new JTable( 098 new AbstractTableModelExtension(layers)); 099 TableHelper.setFont(list, getClass()); 100 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 101 list.setAutoCreateRowSorter(true); 102 list.setRowSelectionAllowed(true); 103 list.setColumnSelectionAllowed(false); 104 updateColumnPreferredWidth(list.getColumnModel().getColumn(0)); 105 updateColumnPreferredWidth(list.getColumnModel().getColumn(1)); 106 updateColumnPreferredWidth(list.getColumnModel().getColumn(2)); 107 108 add(new JLabel(tr("Filter layers:")), GBC.eol().fill(GBC.HORIZONTAL)); 109 final JosmTextArea filter = new JosmTextArea(); 110 filter.getDocument().addDocumentListener(new DocumentListener() { 111 @Override 112 public void insertUpdate(DocumentEvent e) { 113 update(); 114 } 115 116 @Override 117 public void removeUpdate(DocumentEvent e) { 118 update(); 119 } 120 121 @Override 122 public void changedUpdate(DocumentEvent e) { 123 update(); 124 } 125 126 @SuppressWarnings({ "unchecked", "rawtypes" }) 127 private void update() { 128 ((TableRowSorter) list.getRowSorter()).setRowFilter(RowFilter.regexFilter("(?i)" + filter.getText())); 129 } 130 131 }); 132 add(filter, GBC.eop().fill(GBC.HORIZONTAL)); 133 add(new JScrollPane(this.list), GBC.eol().fill()); 134 } 135 136 /** 137 * Returns selected layer. 138 * @return selected layer 139 */ 140 public Layer getSelectedLayer() { 141 int index = list.getSelectedRow(); 142 if (index < 0) { 143 return null; //nothing selected 144 } 145 return layers.get(list.convertRowIndexToModel(index)).getValue().get(0); 146 } 147 148 private void updateColumnPreferredWidth(TableColumn column) { 149 TableCellRenderer renderer = column.getHeaderRenderer(); 150 if (renderer == null) { 151 renderer = list.getTableHeader().getDefaultRenderer(); 152 } 153 Component comp = renderer.getTableCellRendererComponent(list, column.getHeaderValue(), false, false, 0, 0); 154 int ret = comp.getPreferredSize().width; 155 156 for (int row = 0; row < list.getRowCount(); row++) { 157 renderer = list.getCellRenderer(row, column.getModelIndex()); 158 comp = list.prepareRenderer(renderer, row, column.getModelIndex()); 159 ret = Math.max(comp.getPreferredSize().width, ret); 160 } 161 column.setPreferredWidth(ret + 10); 162 } 163 164 /** 165 * Returns the list of layers. 166 * @return the list of layers 167 */ 168 public JTable getTable() { 169 return list; 170 } 171}