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