/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2011, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.swing.dialog; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.swing.AbstractListModel; import org.geotools.referencing.ReferencingFactoryFinder; import org.opengis.referencing.crs.CRSAuthorityFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * List model class for {@code JCRSChooser}. Supports filtering * by case-insensitive sub-string matching. * * @author Michael Bedward * @since 8.0 * @source $URL: $ * @version $Id: $ */ public class CRSListModel extends AbstractListModel { private static class Item { String code; String desc; boolean visible; Item(String code, String desc) { this.code = code; this.desc = desc; visible = true; } @Override public String toString() { return code + ": " + desc; } } private List<Item> allItems = new ArrayList<Item>(); private List<Item> filterItems = new ArrayList<Item>(); /** * Constructor. Populates the model with available reference systems * for the specified authority. If {@code authority} is {@code null} * or empty, it defaults to {@link JCRSChooser#DEFAULT_AUTHORITY}. * * @param authority the authority name * @param showDefaults show GeoTools default reference systems */ public CRSListModel(String authority) { try { CRSAuthorityFactory fac = ReferencingFactoryFinder.getCRSAuthorityFactory(authority, null); Set<String> codes = fac.getAuthorityCodes(CoordinateReferenceSystem.class); if (authority == null || authority.trim().length() == 0) { authority = JCRSChooser.DEFAULT_AUTHORITY; } for (String code : codes) { code = code.trim(); String desc = fac.getDescriptionText(authority + ":" + code).toString(); allItems.add(new Item(code, desc)); } filterItems.addAll(allItems); } catch (Exception ex) { throw new RuntimeException(ex); } } /** * {@inheritDoc} * * @return the length of the list with the current filter applied */ @Override public int getSize() { return filterItems.size(); } /** * {@inheritDoc} * * @return a {@code String} of the form {@code reference code: description} */ @Override public String getElementAt(int i) { return filterItems.get(i).toString(); } /** * Filters the model items by searching for the given sub-string. * Case is ignored for matching. * * @param subStr sub-string to filter on; or {@code null} or * empty string for no filtering */ public void setFilter(String subStr) { filterItems.clear(); if (subStr == null || subStr.trim().length() == 0) { filterItems.addAll(allItems); } else { String lo = subStr.toLowerCase(); for (Item item : allItems) { if (item.code.toLowerCase().contains(lo) || item.desc.toLowerCase().contains(lo)) { filterItems.add(item); } } } fireContentsChanged(this, 0, getSize()); } /** * Gets the code for the given element index. * * @param i the index * @return the code */ public String getCodeAt(int i) { return filterItems.get(i).code; } /** * Searches for the element with the given code. The search * is undertaken on the filtered items. * * @param code the code to match; may be {@code null} or empty in which * case -1 is returned * * @return index of the matching element or -1 if not found. */ public int findCode(String code) { String searchCode = code == null ? null : code.trim(); if (searchCode != null && searchCode.length() > 0) { for (int i = 0; i < filterItems.size(); i++) { if (filterItems.get(i).code.equalsIgnoreCase(code)) { return i; } } } return -1; } }