001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.download; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Component; 007import java.util.ArrayList; 008import java.util.Arrays; 009import java.util.Collection; 010import java.util.Collections; 011import java.util.LinkedList; 012import java.util.List; 013 014import javax.swing.DefaultListModel; 015import javax.swing.ImageIcon; 016import javax.swing.JLabel; 017import javax.swing.JList; 018import javax.swing.ListCellRenderer; 019import javax.swing.UIManager; 020 021import org.openstreetmap.josm.Main; 022import org.openstreetmap.josm.data.Bounds; 023import org.openstreetmap.josm.tools.ImageProvider; 024 025/** 026 * List class that read and save its content from the bookmark file. 027 * @since 6340 028 */ 029public class BookmarkList extends JList<BookmarkList.Bookmark> { 030 031 /** 032 * Class holding one bookmarkentry. 033 */ 034 public static class Bookmark implements Comparable<Bookmark> { 035 private String name; 036 private Bounds area; 037 038 /** 039 * Constructs a new {@code Bookmark} with the given contents. 040 * @param list Bookmark contents as a list of 5 elements. First item is the name, then come bounds arguments (minlat, minlon, maxlat, maxlon) 041 * @throws NumberFormatException If the bounds arguments are not numbers 042 * @throws IllegalArgumentException If list contain less than 5 elements 043 */ 044 public Bookmark(Collection<String> list) throws NumberFormatException, IllegalArgumentException { 045 List<String> array = new ArrayList<>(list); 046 if(array.size() < 5) 047 throw new IllegalArgumentException(tr("Wrong number of arguments for bookmark")); 048 name = array.get(0); 049 area = new Bounds(Double.parseDouble(array.get(1)), Double.parseDouble(array.get(2)), 050 Double.parseDouble(array.get(3)), Double.parseDouble(array.get(4))); 051 } 052 053 /** 054 * Constructs a new empty {@code Bookmark}. 055 */ 056 public Bookmark() { 057 area = null; 058 name = null; 059 } 060 061 /** 062 * Constructs a new unamed {@code Bookmark} for the given area. 063 * @param area The bookmark area 064 */ 065 public Bookmark(Bounds area) { 066 this.area = area; 067 } 068 069 @Override public String toString() { 070 return name; 071 } 072 073 @Override 074 public int compareTo(Bookmark b) { 075 return name.toLowerCase().compareTo(b.name.toLowerCase()); 076 } 077 078 @Override 079 public int hashCode() { 080 final int prime = 31; 081 int result = 1; 082 result = prime * result + ((area == null) ? 0 : area.hashCode()); 083 result = prime * result + ((name == null) ? 0 : name.hashCode()); 084 return result; 085 } 086 087 @Override 088 public boolean equals(Object obj) { 089 if (this == obj) 090 return true; 091 if (obj == null) 092 return false; 093 if (getClass() != obj.getClass()) 094 return false; 095 Bookmark other = (Bookmark) obj; 096 if (area == null) { 097 if (other.area != null) 098 return false; 099 } else if (!area.equals(other.area)) 100 return false; 101 if (name == null) { 102 if (other.name != null) 103 return false; 104 } else if (!name.equals(other.name)) 105 return false; 106 return true; 107 } 108 109 /** 110 * Returns the bookmark area 111 * @return The bookmark area 112 */ 113 public Bounds getArea() { 114 return area; 115 } 116 117 /** 118 * Returns the bookmark name 119 * @return The bookmark name 120 */ 121 public String getName() { 122 return name; 123 } 124 125 /** 126 * Sets the bookmark name 127 * @param name The bookmark name 128 */ 129 public void setName(String name) { 130 this.name = name; 131 } 132 133 /** 134 * Sets the bookmark area 135 * @param area The bookmark area 136 */ 137 public void setArea(Bounds area) { 138 this.area = area; 139 } 140 } 141 142 /** 143 * Creates a bookmark list as well as the Buttons add and remove. 144 */ 145 public BookmarkList() { 146 setModel(new DefaultListModel<Bookmark>()); 147 load(); 148 setVisibleRowCount(7); 149 setCellRenderer(new BookmarkCellRenderer()); 150 } 151 152 /** 153 * Loads the bookmarks from file. 154 */ 155 public final void load() { 156 DefaultListModel<Bookmark> model = (DefaultListModel<Bookmark>)getModel(); 157 model.removeAllElements(); 158 Collection<Collection<String>> args = Main.pref.getArray("bookmarks", null); 159 if(args != null) { 160 LinkedList<Bookmark> bookmarks = new LinkedList<>(); 161 for(Collection<String> entry : args) { 162 try { 163 bookmarks.add(new Bookmark(entry)); 164 } 165 catch (Exception e) { 166 Main.error(tr("Error reading bookmark entry: %s", e.getMessage())); 167 } 168 } 169 Collections.sort(bookmarks); 170 for (Bookmark b : bookmarks) { 171 model.addElement(b); 172 } 173 } 174 } 175 176 /** 177 * Saves all bookmarks to the preferences file 178 */ 179 public final void save() { 180 LinkedList<Collection<String>> coll = new LinkedList<>(); 181 for (Object o : ((DefaultListModel<Bookmark>)getModel()).toArray()) { 182 String[] array = new String[5]; 183 Bookmark b = (Bookmark) o; 184 array[0] = b.getName(); 185 Bounds area = b.getArea(); 186 array[1] = String.valueOf(area.getMinLat()); 187 array[2] = String.valueOf(area.getMinLon()); 188 array[3] = String.valueOf(area.getMaxLat()); 189 array[4] = String.valueOf(area.getMaxLon()); 190 coll.add(Arrays.asList(array)); 191 } 192 Main.pref.putArray("bookmarks", coll); 193 } 194 195 static class BookmarkCellRenderer extends JLabel implements ListCellRenderer<BookmarkList.Bookmark> { 196 197 private ImageIcon icon; 198 199 public BookmarkCellRenderer() { 200 setOpaque(true); 201 icon = ImageProvider.get("dialogs", "bookmark"); 202 setIcon(icon); 203 } 204 205 protected void renderColor(boolean selected) { 206 if (selected) { 207 setBackground(UIManager.getColor("List.selectionBackground")); 208 setForeground(UIManager.getColor("List.selectionForeground")); 209 } else { 210 setBackground(UIManager.getColor("List.background")); 211 setForeground(UIManager.getColor("List.foreground")); 212 } 213 } 214 215 protected String buildToolTipText(Bookmark b) { 216 Bounds area = b.getArea(); 217 StringBuilder sb = new StringBuilder(); 218 sb.append("<html>min[latitude,longitude]=<strong>[") 219 .append(area.getMinLat()).append(",").append(area.getMinLon()).append("]</strong>") 220 .append("<br>") 221 .append("max[latitude,longitude]=<strong>[") 222 .append(area.getMaxLat()).append(",").append(area.getMaxLon()).append("]</strong>") 223 .append("</html>"); 224 return sb.toString(); 225 226 } 227 228 @Override 229 public Component getListCellRendererComponent(JList<? extends Bookmark> list, Bookmark value, int index, boolean isSelected, boolean cellHasFocus) { 230 renderColor(isSelected); 231 setText(value.getName()); 232 setToolTipText(buildToolTipText(value)); 233 return this; 234 } 235 } 236}