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