source: josm/trunk/src/org/openstreetmap/josm/gui/io/UploadSelectionDialog.java@ 5998

Last change on this file since 5998 was 5998, checked in by Don-vip, 11 years ago

fix #8775 - IllegalComponentStateException when remembering position of dialogs not displayed on screen

  • Property svn:eol-style set to native
File size: 10.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Dimension;
8import java.awt.FlowLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.WindowAdapter;
11import java.awt.event.WindowEvent;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.Comparator;
16import java.util.List;
17
18import javax.swing.AbstractAction;
19import javax.swing.AbstractListModel;
20import javax.swing.Action;
21import javax.swing.BorderFactory;
22import javax.swing.JComponent;
23import javax.swing.JDialog;
24import javax.swing.JLabel;
25import javax.swing.JList;
26import javax.swing.JOptionPane;
27import javax.swing.JPanel;
28import javax.swing.JScrollPane;
29import javax.swing.JSplitPane;
30import javax.swing.KeyStroke;
31import javax.swing.ListSelectionModel;
32import javax.swing.event.ListSelectionEvent;
33import javax.swing.event.ListSelectionListener;
34
35import org.openstreetmap.josm.Main;
36import org.openstreetmap.josm.data.osm.OsmPrimitive;
37import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
38import org.openstreetmap.josm.gui.DefaultNameFormatter;
39import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
40import org.openstreetmap.josm.gui.SideButton;
41import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
42import org.openstreetmap.josm.gui.help.HelpUtil;
43import org.openstreetmap.josm.tools.ImageProvider;
44import org.openstreetmap.josm.tools.WindowGeometry;
45
46/**
47 * This dialog can be used to select individual object for uploading.
48 *
49 *
50 */
51public class UploadSelectionDialog extends JDialog {
52
53 private OsmPrimitiveList lstSelectedPrimitives;
54 private OsmPrimitiveList lstDeletedPrimitives;
55 private JSplitPane spLists;
56 private boolean canceled;
57 private SideButton btnContinue;
58
59 protected JPanel buildSelectedPrimitivesPanel() {
60 JPanel pnl = new JPanel();
61 pnl.setLayout(new BorderLayout());
62 JLabel lbl = new JLabel(tr("<html>Mark modified objects <strong>from the current selection</strong> to be uploaded to the server.</html>"));
63 lbl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
64 pnl.add(lbl, BorderLayout.NORTH);
65 pnl.add(new JScrollPane(lstSelectedPrimitives = new OsmPrimitiveList()), BorderLayout.CENTER);
66 return pnl;
67 }
68
69 protected JPanel buildDeletedPrimitivesPanel() {
70 JPanel pnl = new JPanel();
71 pnl.setLayout(new BorderLayout());
72 JLabel lbl = new JLabel(tr("<html>Mark <strong>locally deleted objects</strong> to be deleted on the server.</html>"));
73 lbl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
74 pnl.add(lbl, BorderLayout.NORTH);
75 pnl.add(new JScrollPane(lstDeletedPrimitives = new OsmPrimitiveList()), BorderLayout.CENTER);
76 return pnl;
77 }
78
79 protected JPanel buildButtonPanel() {
80 JPanel pnl = new JPanel();
81 pnl.setLayout(new FlowLayout());
82 ContinueAction continueAction = new ContinueAction();
83 pnl.add(btnContinue = new SideButton(continueAction));
84 btnContinue.setFocusable(true);
85 lstDeletedPrimitives.getSelectionModel().addListSelectionListener(continueAction);
86 lstSelectedPrimitives.getSelectionModel().addListSelectionListener(continueAction);
87
88 pnl.add(new SideButton(new CancelAction()));
89 pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/UploadSelection"))));
90 return pnl;
91 }
92
93 protected void build() {
94 setLayout(new BorderLayout());
95 spLists = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
96 spLists.setTopComponent(buildSelectedPrimitivesPanel());
97 spLists.setBottomComponent(buildDeletedPrimitivesPanel());
98 add(spLists, BorderLayout.CENTER);
99 add(buildButtonPanel(), BorderLayout.SOUTH);
100 addWindowListener(
101 new WindowAdapter() {
102 @Override
103 public void windowOpened(WindowEvent e) {
104 spLists.setDividerLocation(0.5);
105 btnContinue.requestFocusInWindow();
106 }
107
108 @Override
109 public void windowClosing(WindowEvent e) {
110 setCanceled(true);
111 }
112 }
113 );
114 setTitle(tr("Select objects to upload"));
115 HelpUtil.setHelpContext(getRootPane(), HelpUtil.ht("/Dialog/UploadSelection"));
116 }
117
118 public UploadSelectionDialog() {
119 super(JOptionPane.getFrameForComponent(Main.parent), ModalityType.DOCUMENT_MODAL);
120 build();
121 }
122
123 public void populate(Collection<OsmPrimitive> selected, Collection<OsmPrimitive> deleted) {
124 if (selected != null) {
125 lstSelectedPrimitives.getOsmPrimitiveListModel().setPrimitives(new ArrayList<OsmPrimitive>(selected));
126 if (!selected.isEmpty()) {
127 lstSelectedPrimitives.getSelectionModel().setSelectionInterval(0, selected.size()-1);
128 } else {
129 lstSelectedPrimitives.getSelectionModel().clearSelection();
130 }
131 } else {
132 lstSelectedPrimitives.getOsmPrimitiveListModel().setPrimitives(null);
133 lstSelectedPrimitives.getSelectionModel().clearSelection();
134 }
135
136 if (deleted != null) {
137 lstDeletedPrimitives.getOsmPrimitiveListModel().setPrimitives(new ArrayList<OsmPrimitive>(deleted));
138 } else {
139 lstDeletedPrimitives.getOsmPrimitiveListModel().setPrimitives(null);
140 }
141 }
142
143 public boolean isCanceled() {
144 return canceled;
145 }
146
147 protected void setCanceled(boolean canceled) {
148 this.canceled = canceled;
149 }
150
151 public List<OsmPrimitive> getSelectedPrimitives() {
152 ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>();
153 System.out.println("selected length:" +lstSelectedPrimitives.getSelectedIndices().length);
154 for (int i=0; i< lstSelectedPrimitives.getSelectedIndices().length;i++) {
155 System.out.println("selected:" +lstSelectedPrimitives.getSelectedIndices()[i]);
156 }
157 ret.addAll(lstSelectedPrimitives.getOsmPrimitiveListModel().getPrimitives(lstSelectedPrimitives.getSelectedIndices()));
158 ret.addAll(lstDeletedPrimitives.getOsmPrimitiveListModel().getPrimitives(lstDeletedPrimitives.getSelectedIndices()));
159 return ret;
160 }
161
162 @Override
163 public void setVisible(boolean visible) {
164 if (visible) {
165 new WindowGeometry(
166 getClass().getName() + ".geometry",
167 WindowGeometry.centerInWindow(
168 Main.parent,
169 new Dimension(200,400)
170 )
171 ).applySafe(this);
172 } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775
173 new WindowGeometry(this).remember(getClass().getName() + ".geometry");
174 }
175 super.setVisible(visible);
176 }
177
178 static class OsmPrimitiveList extends JList {
179 protected void init() {
180 setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
181 setCellRenderer(new OsmPrimitivRenderer());
182 }
183
184 public OsmPrimitiveList() {
185 super(new OsmPrimitiveListModel());
186 init();
187 }
188
189 public OsmPrimitiveList(OsmPrimitiveListModel model) {
190 super(model);
191 init();
192 }
193
194 public OsmPrimitiveListModel getOsmPrimitiveListModel() {
195 return (OsmPrimitiveListModel)getModel();
196 }
197 }
198
199 static class OsmPrimitiveListModel extends AbstractListModel {
200 private List<OsmPrimitive> data;
201
202 public OsmPrimitiveListModel() {
203 }
204
205 protected void sort() {
206 if (data == null)
207 return;
208 Collections.sort(
209 data,
210 new Comparator<OsmPrimitive>() {
211 private DefaultNameFormatter formatter = DefaultNameFormatter.getInstance();
212 public int compare(OsmPrimitive o1, OsmPrimitive o2) {
213 int ret = OsmPrimitiveType.from(o1).compareTo(OsmPrimitiveType.from(o2));
214 if (ret != 0) return ret;
215 return o1.getDisplayName(formatter).compareTo(o1.getDisplayName(formatter));
216 }
217 }
218 );
219 }
220
221 public OsmPrimitiveListModel(List<OsmPrimitive> data) {
222 setPrimitives(data);
223 }
224
225 public void setPrimitives(List<OsmPrimitive> data) {
226 this.data = data;
227 sort();
228 if (data != null) {
229 fireContentsChanged(this,0, data.size());
230 } else {
231 fireContentsChanged(this, 0,0);
232 }
233 }
234
235 public Object getElementAt(int index) {
236 if (data == null)
237 return null;
238 return data.get(index);
239 }
240
241 public int getSize() {
242 if (data == null)
243 return 0;
244 return data.size();
245 }
246
247 public List<OsmPrimitive> getPrimitives(int [] indices) {
248 if (indices == null || indices.length == 0)
249 return Collections.emptyList();
250 ArrayList<OsmPrimitive> ret = new ArrayList<OsmPrimitive>(indices.length);
251 for (int i: indices) {
252 if (i < 0) {
253 continue;
254 }
255 ret.add(data.get(i));
256 }
257 return ret;
258 }
259 }
260
261 class CancelAction extends AbstractAction {
262 public CancelAction() {
263 putValue(Action.SHORT_DESCRIPTION, tr("Cancel uploading"));
264 putValue(Action.NAME, tr("Cancel"));
265 putValue(Action.SMALL_ICON, ImageProvider.get("", "cancel"));
266 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
267 .put(KeyStroke.getKeyStroke("ESCAPE"), "ESCAPE");
268 getRootPane().getActionMap().put("ESCAPE", this);
269 setEnabled(true);
270 }
271
272 public void actionPerformed(ActionEvent e) {
273 setCanceled(true);
274 setVisible(false);
275 }
276 }
277
278 class ContinueAction extends AbstractAction implements ListSelectionListener {
279 public ContinueAction() {
280 putValue(Action.SHORT_DESCRIPTION, tr("Continue uploading"));
281 putValue(Action.NAME, tr("Continue"));
282 putValue(Action.SMALL_ICON, ImageProvider.get("", "upload"));
283 updateEnabledState();
284 }
285
286 public void actionPerformed(ActionEvent e) {
287 setCanceled(false);
288 setVisible(false);
289 }
290
291 protected void updateEnabledState() {
292 setEnabled(lstSelectedPrimitives.getSelectedIndex() >=0
293 || lstDeletedPrimitives.getSelectedIndex() >= 0);
294 }
295
296 public void valueChanged(ListSelectionEvent e) {
297 updateEnabledState();
298 }
299 }
300}
Note: See TracBrowser for help on using the repository browser.