001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.imagery; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.GridBagLayout; 007import java.util.List; 008import java.util.Map; 009import java.util.concurrent.ConcurrentHashMap; 010import java.util.stream.Collectors; 011 012import javax.swing.JPanel; 013import javax.swing.JScrollPane; 014import javax.swing.JTable; 015import javax.swing.ListSelectionModel; 016import javax.swing.table.AbstractTableModel; 017 018import org.openstreetmap.josm.tools.GBC; 019 020/** 021 * Simple table for editing HTTP headers 022 * @author Wiktor Niesiobedzki 023 * 024 */ 025public class HeadersTable extends JPanel { 026 027 private final class HeaderTableModel extends AbstractTableModel { 028 @Override 029 public String getColumnName(int column) { 030 switch (column) { 031 case 0: 032 return tr("Header name"); 033 case 1: 034 return tr("Header value"); 035 default: 036 return ""; 037 } 038 } 039 040 @Override 041 public int getRowCount() { 042 return headers.size() + 1; 043 } 044 045 @Override 046 public int getColumnCount() { 047 return 2; 048 } 049 050 @Override 051 public Object getValueAt(int row, int col) { 052 if (row < headers.size()) { 053 return headers.get(row)[col]; 054 } 055 return ""; 056 } 057 058 @Override 059 public boolean isCellEditable(int row, int column) { 060 return true; 061 } 062 063 @Override 064 public void setValueAt(Object value, int row, int col) { 065 if (row < headers.size()) { 066 String[] headerRow = headers.get(row); 067 headerRow[col] = (String) value; 068 if ("".equals(headerRow[0]) && "".equals(headerRow[1])) { 069 headers.remove(row); 070 fireTableRowsDeleted(row, row); 071 } 072 073 } else if (row == headers.size()) { 074 String[] entry = new String[] {"", ""}; 075 entry[col] = (String) value; 076 headers.add(entry); 077 fireTableRowsInserted(row + 1, row + 1); 078 } 079 fireTableCellUpdated(row, col); 080 } 081 } 082 083 private List<String[]> headers; 084 085 /** 086 * Creates empty table 087 */ 088 public HeadersTable() { 089 this(new ConcurrentHashMap<>()); 090 } 091 092 /** 093 * Create table prefilled with headers 094 * @param headers contents of table 095 */ 096 public HeadersTable(Map<String, String> headers) { 097 super(new GridBagLayout()); 098 this.headers = getHeadersAsVector(headers); 099 JTable table = new JTable(new HeaderTableModel()); 100 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 101 table.setAutoCreateRowSorter(true); 102 table.setRowSelectionAllowed(false); 103 table.setColumnSelectionAllowed(false); 104 add(new JScrollPane(table), GBC.eol().fill()); 105 } 106 107 private static List<String[]> getHeadersAsVector(Map<String, String> headers) { 108 return headers.entrySet().stream().sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey())) 109 .map(e -> new String[] {e.getKey(), e.getValue()}).collect(Collectors.toList()); 110 } 111 112 /** 113 * @return headers provided by user 114 */ 115 public Map<String, String> getHeaders() { 116 return headers.stream().distinct().collect(Collectors.toMap(x -> x[0], x -> x[1])); 117 } 118 119}