Gridarta Editor
GoMapDialog.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.gui.dialog.gomap;
21 
22 import java.awt.BorderLayout;
23 import java.awt.Component;
24 import java.awt.Dialog.ModalityType;
25 import java.awt.Window;
26 import java.awt.event.MouseEvent;
27 import java.awt.event.MouseListener;
28 import java.awt.event.WindowEvent;
29 import java.awt.event.WindowListener;
30 import java.io.IOException;
31 import java.util.Collection;
32 import java.util.Comparator;
33 import java.util.List;
34 import java.util.TreeSet;
35 import javax.swing.JComponent;
36 import javax.swing.JDialog;
37 import javax.swing.JList;
38 import javax.swing.JPanel;
39 import javax.swing.JScrollPane;
40 import javax.swing.JTextField;
41 import javax.swing.ListSelectionModel;
42 import javax.swing.ScrollPaneConstants;
43 import javax.swing.SwingUtilities;
44 import javax.swing.border.EmptyBorder;
45 import javax.swing.event.DocumentEvent;
46 import javax.swing.event.DocumentListener;
47 import javax.swing.text.JTextComponent;
60 import net.sf.japi.swing.action.ActionBuilder;
61 import net.sf.japi.swing.action.ActionBuilderFactory;
62 import net.sf.japi.swing.action.ActionMethod;
63 import org.jetbrains.annotations.NotNull;
64 
69 public class GoMapDialog<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> {
70 
74  @NotNull
75  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
76 
80  @NotNull
81  private final JDialog dialog;
82 
86  @NotNull
87  private final JTextComponent input;
88 
92  @NotNull
93  private final MapsIndex mapsIndex;
94 
98  @NotNull
100 
104  @NotNull
105  private final GoMapListModel listModel = new GoMapListModel();
106 
110  @NotNull
111  private final JList<MapFile> list = new JList<>(listModel);
112 
116  private boolean dialogShown;
117 
121  @NotNull
122  private final Comparator<MapFile> mapNameComparator = new Comparator<MapFile>() {
123 
124  @Override
125  public int compare(@NotNull final MapFile o1, @NotNull final MapFile o2) {
126  final String name1 = mapsIndex.getName(o1);
127  final String name2 = mapsIndex.getName(o2);
128 
129  if (name1 == null) {
130  //noinspection VariableNotUsedInsideIf
131  return name2 == null ? 0 : -1;
132  }
133 
134  if (name2 == null) {
135  return +1;
136  }
137 
138  final int cmp = name1.compareToIgnoreCase(name2);
139  return cmp == 0 ? o1.getFile().compareTo(o2.getFile()) : cmp;
140  }
141 
142  };
143 
149  @NotNull
151 
152  @Override
153  public void valueAdded(@NotNull final MapFile value) {
154  // ignore
155  }
156 
157  @Override
158  public void valueRemoved(@NotNull final MapFile value) {
159  // ignore
160  }
161 
162  @Override
163  public void nameChanged() {
165  }
166 
167  @Override
168  public void pendingChanged() {
169  // ignore
170  }
171 
172  @Override
173  public void indexingFinished() {
175  }
176 
177  };
178 
185  @NotNull
186  private final WindowListener windowListener = new WindowListener() {
187 
188  @Override
189  public void windowOpened(final WindowEvent e) {
190  if (!dialogShown) {
191  dialogShown = true;
193  doSearch();
194  }
195  }
196 
197  @Override
198  public void windowClosing(final WindowEvent e) {
199  // ignore
200  }
201 
202  @Override
203  public void windowClosed(final WindowEvent e) {
204  if (dialogShown) {
205  dialogShown = false;
207  }
208  }
209 
210  @Override
211  public void windowIconified(final WindowEvent e) {
212  // ignore
213  }
214 
215  @Override
216  public void windowDeiconified(final WindowEvent e) {
217  // ignore
218  }
219 
220  @Override
221  public void windowActivated(final WindowEvent e) {
222  // ignore
223  }
224 
225  @Override
226  public void windowDeactivated(final WindowEvent e) {
227  // ignore
228  }
229 
230  };
231 
236  @NotNull
238 
239  @Override
240  public void change() {
241  if (!dialogShown) {
242  return;
243  }
244 
245  SwingUtilities.invokeLater(new Runnable() {
246 
247  @Override
248  public void run() {
249  //XXX:suppress incorrect warning
250  if (dialogShown) {
251  doSearch();
252  }
253  }
254 
255  });
256  }
257 
258  });
259 
266  public GoMapDialog(@NotNull final Window parent, @NotNull final MapsIndex mapsIndex, @NotNull final MapViewsManager<G, A, R> mapViewsManager) {
267  this.mapsIndex = mapsIndex;
268  this.mapViewsManager = mapViewsManager;
269  final Component label = ActionBuilderUtils.newLabel(ACTION_BUILDER, "goMapLabel");
270 
271  input = new JTextField();
272  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapScrollUp", this));
273  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapScrollDown", this));
274  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapScrollPageUp", this));
275  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapScrollPageDown", this));
276  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapScrollTop", this));
277  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapScrollBottom", this));
278  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapSelectUp", this));
279  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapSelectDown", this));
280  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapCancel", this));
281  SwingUtils.addAction(input, ACTION_BUILDER.createAction(false, "goMapApply", this));
282  final DocumentListener documentListener = new DocumentListener() {
283 
284  @Override
285  public void changedUpdate(@NotNull final DocumentEvent e) {
286  doSearch();
287  }
288 
289  @Override
290  public void insertUpdate(@NotNull final DocumentEvent e) {
291  doSearch();
292  }
293 
294  @Override
295  public void removeUpdate(@NotNull final DocumentEvent e) {
296  doSearch();
297  }
298 
299  };
300  input.getDocument().addDocumentListener(documentListener);
302 
303  final JComponent inputPanel = new JPanel(new BorderLayout());
304  inputPanel.add(label, BorderLayout.NORTH);
305  inputPanel.add(input, BorderLayout.CENTER);
306  inputPanel.setBorder(new EmptyBorder(3, 3, 3, 3));
307 
308  list.setFocusable(false);
309  final Component scrollPane = new JScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
310  list.setCellRenderer(new MapListCellRenderer(mapsIndex));
311  list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
312  final MouseListener mouseListener = new MouseListener() {
313 
314  @Override
315  public void mouseClicked(final MouseEvent e) {
316  // ignore
317  }
318 
319  @Override
320  public void mousePressed(final MouseEvent e) {
321  if (e.getClickCount() > 1) {
322  goMapApply();
323  }
324  }
325 
326  @Override
327  public void mouseReleased(final MouseEvent e) {
328  // ignore
329  }
330 
331  @Override
332  public void mouseEntered(final MouseEvent e) {
333  // ignore
334  }
335 
336  @Override
337  public void mouseExited(final MouseEvent e) {
338  // ignore
339  }
340 
341  };
342  list.addMouseListener(mouseListener);
343 
344  dialog = new JDialog(parent);
345  dialog.setResizable(false);
346  dialog.setSize(600, 400);
347  dialog.setLocationRelativeTo(parent);
348  dialog.setUndecorated(true);
349  dialog.setLayout(new BorderLayout());
350  dialog.add(inputPanel, BorderLayout.NORTH);
351  dialog.add(scrollPane, BorderLayout.CENTER);
352  dialog.setModalityType(ModalityType.DOCUMENT_MODAL);
353  dialog.addWindowListener(windowListener);
354  }
355 
359  public void showDialog() {
360  dialog.setVisible(true);
361  }
362 
366  private void doSearch() {
367  final String mapName = input.getText();
368  if (mapName.isEmpty()) {
369  listModel.clear();
370  return;
371  }
372 
373  final Collection<MapFile> maps = mapsIndex.findPartialName(mapName);
374  final Collection<MapFile> sortedMaps = new TreeSet<>(mapNameComparator);
375  sortedMaps.addAll(maps);
376  listModel.enable(false);
377  listModel.clear();
378  for (final MapFile map : sortedMaps) {
379  listModel.addElement(map);
380  }
381  listModel.enable(true);
382  list.setSelectedIndex(0);
383  list.ensureIndexIsVisible(0);
384  }
385 
389  @ActionMethod
390  public void goMapApply() {
391  if (goMap()) {
392  dialog.removeWindowListener(windowListener);
393  dialog.dispose();
394  }
395  }
396 
400  @ActionMethod
401  public void goMapCancel() {
402  dialog.removeWindowListener(windowListener);
403  dialog.dispose();
404  }
405 
409  @ActionMethod
410  public void goMapScrollUp() {
411  final int index = list.getMinSelectionIndex();
412  final int newIndex = (index > 0 ? index : listModel.size()) - 1;
413  list.setSelectedIndex(newIndex);
414  list.ensureIndexIsVisible(newIndex);
415  }
416 
420  @ActionMethod
421  public void goMapScrollDown() {
422  final int index = list.getMaxSelectionIndex() + 1;
423  final int newIndex = index < listModel.size() ? index : 0;
424  list.setSelectedIndex(newIndex);
425  list.ensureIndexIsVisible(newIndex);
426  }
427 
431  @ActionMethod
432  public void goMapScrollPageUp() {
433  final int index = list.getMinSelectionIndex();
434  final int firstIndex = list.getFirstVisibleIndex();
435  final int newIndex;
436  if (firstIndex == -1) {
437  newIndex = -1;
438  } else if (index == -1) {
439  newIndex = firstIndex;
440  } else if (index > firstIndex) {
441  newIndex = firstIndex;
442  } else {
443  newIndex = Math.max(firstIndex - (list.getLastVisibleIndex() - firstIndex), 0);
444  }
445  list.setSelectedIndex(newIndex);
446  list.ensureIndexIsVisible(newIndex);
447  }
448 
452  @ActionMethod
453  public void goMapScrollPageDown() {
454  final int index = list.getMaxSelectionIndex();
455  final int lastIndex = list.getLastVisibleIndex();
456  final int newIndex;
457  if (lastIndex == -1) {
458  newIndex = -1;
459  } else if (index == -1) {
460  newIndex = lastIndex;
461  } else if (index < lastIndex) {
462  newIndex = lastIndex;
463  } else {
464  newIndex = Math.min(lastIndex + (lastIndex - list.getFirstVisibleIndex()), listModel.size() - 1);
465  }
466  list.setSelectedIndex(newIndex);
467  list.ensureIndexIsVisible(newIndex);
468  }
469 
473  @ActionMethod
474  public void goMapScrollTop() {
475  final int newIndex = 0;
476  list.setSelectedIndex(newIndex);
477  list.ensureIndexIsVisible(newIndex);
478  }
479 
483  @ActionMethod
484  public void goMapScrollBottom() {
485  final int newIndex = listModel.size() - 1;
486  list.setSelectedIndex(newIndex);
487  list.ensureIndexIsVisible(newIndex);
488  }
489 
493  @ActionMethod
494  public void goMapSelectUp() {
495  final int index = list.getMinSelectionIndex();
496  if (index != 0) {
497  final int newIndex = (index > 0 ? index : listModel.size()) - 1;
498  list.addSelectionInterval(newIndex, newIndex);
499  list.ensureIndexIsVisible(newIndex);
500  }
501  }
502 
506  @ActionMethod
507  public void goMapSelectDown() {
508  final int index = list.getMaxSelectionIndex();
509  if (index + 1 < listModel.size()) {
510  final int newIndex = index + 1;
511  list.addSelectionInterval(newIndex, newIndex);
512  list.ensureIndexIsVisible(newIndex);
513  }
514  }
515 
520  private boolean goMap() {
521  final List<MapFile> selectedValues = list.getSelectedValuesList();
522  boolean result = false;
523  for (final MapFile selectedValue : selectedValues) {
524  try {
525  mapViewsManager.openMapFileWithView(selectedValue, null);
526  result = true;
527  } catch (final IOException ex) {
528  ACTION_BUILDER.showMessageDialog(dialog, "goMapIOException", selectedValue, ex.getMessage());
529  }
530  }
531  return result;
532  }
533 
534 }
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.dialogShown
boolean dialogShown
Definition: GoMapDialog.java:116
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapSelectUp
void goMapSelectUp()
Definition: GoMapDialog.java:494
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.list
final JList< MapFile > list
Definition: GoMapDialog.java:111
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.listModel
final GoMapListModel listModel
Definition: GoMapDialog.java:105
net.sf.gridarta
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapScrollBottom
void goMapScrollBottom()
Definition: GoMapDialog.java:484
net.sf.gridarta.model.index.AbstractIndex.removeIndexListener
void removeIndexListener(@NotNull final IndexListener< V > listener)
Definition: AbstractIndex.java:274
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapApply
void goMapApply()
Definition: GoMapDialog.java:390
net.sf
net.sf.gridarta.model.index.AbstractIndex.addIndexListener
void addIndexListener(@NotNull final IndexListener< V > listener)
Definition: AbstractIndex.java:269
net.sf.gridarta.model.mapmodel
Definition: AboveFloorInsertionMode.java:20
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapSelectDown
void goMapSelectDown()
Definition: GoMapDialog.java:507
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.doSearch
void doSearch()
Definition: GoMapDialog.java:366
net.sf.gridarta.model.archetype
Definition: AbstractArchetype.java:20
net.sf.gridarta.model.gameobject.GameObject
Definition: GameObject.java:36
net.sf.gridarta.utils.ActionBuilderUtils.newLabel
static JLabel newLabel(@NotNull final ActionBuilder actionBuilder, @NotNull final String key)
Definition: ActionBuilderUtils.java:117
net.sf.gridarta.gui.utils.SwingUtils.addAction
static void addAction(@NotNull final JComponent textComponent, @NotNull final Action action)
Definition: SwingUtils.java:71
net.sf.gridarta.gui
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.windowListener
final WindowListener windowListener
Definition: GoMapDialog.java:186
net.sf.gridarta.model.gameobject
Definition: AbstractGameObject.java:20
net
net.sf.gridarta.model.index.AbstractIndex.getName
String getName(@NotNull final V value)
Definition: AbstractIndex.java:233
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.dialog
final JDialog dialog
Definition: GoMapDialog.java:81
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapScrollPageUp
void goMapScrollPageUp()
Definition: GoMapDialog.java:432
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
Definition: GoMapDialog.java:75
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapScrollTop
void goMapScrollTop()
Definition: GoMapDialog.java:474
net.sf.gridarta.gui.utils.SwingUtils
Definition: SwingUtils.java:37
net.sf.gridarta.model.maparchobject.MapArchObject
Definition: MapArchObject.java:40
net.sf.gridarta.gui.map.mapview
Definition: AbstractMapView.java:20
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapScrollUp
void goMapScrollUp()
Definition: GoMapDialog.java:410
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.delayedChangeManager
final DelayedChangeManager delayedChangeManager
Definition: GoMapDialog.java:237
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapCancel
void goMapCancel()
Definition: GoMapDialog.java:401
net.sf.gridarta.model.mapmodel.MapFile
Definition: MapFile.java:31
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMap
boolean goMap()
Definition: GoMapDialog.java:520
net.sf.gridarta.gui.dialog.gomap.GoMapListModel.enable
void enable(final boolean enabled)
Definition: GoMapListModel.java:72
net.sf.gridarta.model.index
Definition: AbstractIndex.java:20
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.showDialog
void showDialog()
Definition: GoMapDialog.java:359
net.sf.gridarta.model
net.sf.gridarta.model.archetype.Archetype
Definition: Archetype.java:41
net.sf.gridarta.utils.DelayedChangeListener
Definition: DelayedChangeListener.java:26
net.sf.gridarta.gui.utils.TextComponentUtils.setAutoSelectOnFocus
static void setAutoSelectOnFocus(@NotNull final JTextComponent textComponent)
Definition: TextComponentUtils.java:48
net.sf.gridarta.model.index.AbstractIndex.findPartialName
Collection< V > findPartialName(@NotNull final String name)
Definition: AbstractIndex.java:104
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.GoMapDialog
GoMapDialog(@NotNull final Window parent, @NotNull final MapsIndex mapsIndex, @NotNull final MapViewsManager< G, A, R > mapViewsManager)
Definition: GoMapDialog.java:266
net.sf.gridarta.gui.map
Definition: AbstractPerMapDialogManager.java:20
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapScrollPageDown
void goMapScrollPageDown()
Definition: GoMapDialog.java:453
net.sf.gridarta.utils.DelayedChangeManager.change
void change()
Definition: DelayedChangeManager.java:208
net.sf.gridarta.model.index.IndexListener
Definition: IndexListener.java:30
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.indexListener
final IndexListener< MapFile > indexListener
Definition: GoMapDialog.java:150
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.input
final JTextComponent input
Definition: GoMapDialog.java:87
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.mapsIndex
final MapsIndex mapsIndex
Definition: GoMapDialog.java:93
net.sf.gridarta.utils.ActionBuilderUtils
Definition: ActionBuilderUtils.java:31
net.sf.gridarta.utils.DelayedChangeManager.finish
void finish()
Definition: DelayedChangeManager.java:218
net.sf.gridarta.model.index.MapsIndex
Definition: MapsIndex.java:28
net.sf.gridarta.model.maparchobject
Definition: AbstractMapArchObject.java:20
net.sf.gridarta.gui.dialog.gomap.GoMapDialog
Definition: GoMapDialog.java:69
net.sf.gridarta.gui.utils
Definition: AnimationComponent.java:20
net.sf.gridarta.gui.dialog.gomap.MapListCellRenderer
Definition: MapListCellRenderer.java:34
net.sf.gridarta.gui.map.mapview.MapViewsManager.openMapFileWithView
MapView< G, A, R > openMapFileWithView(@NotNull final MapFile mapFile, @Nullable final Point viewPosition)
Definition: MapViewsManager.java:333
net.sf.gridarta.utils.DelayedChangeManager
Definition: DelayedChangeManager.java:32
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.mapViewsManager
final MapViewsManager< G, A, R > mapViewsManager
Definition: GoMapDialog.java:99
net.sf.gridarta.gui.utils.TextComponentUtils
Definition: TextComponentUtils.java:35
net.sf.gridarta.gui.map.mapview.MapViewsManager
Definition: MapViewsManager.java:47
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.mapNameComparator
final Comparator< MapFile > mapNameComparator
Definition: GoMapDialog.java:122
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.gui.dialog.gomap.GoMapListModel
Definition: GoMapListModel.java:29
net.sf.gridarta.gui.dialog.gomap.GoMapDialog.goMapScrollDown
void goMapScrollDown()
Definition: GoMapDialog.java:421