Gridarta Editor
DefaultObjectChooser.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.panel.objectchooser;
21 
22 import java.awt.BorderLayout;
23 import java.awt.Point;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.List;
28 import javax.swing.JPanel;
29 import javax.swing.JTabbedPane;
30 import javax.swing.SwingConstants;
31 import javax.swing.event.ChangeEvent;
32 import javax.swing.event.ChangeListener;
53 import org.jetbrains.annotations.NotNull;
54 import org.jetbrains.annotations.Nullable;
55 
60 public class DefaultObjectChooser<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> extends JPanel implements ObjectChooser<G, A, R> {
61 
65  private static final long serialVersionUID = 1L;
66 
70  @NotNull
72 
76  @NotNull
78 
83  @NotNull
85 
89  @NotNull
90  private final JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP);
91 
95  @NotNull
96  private final List<ObjectChooserTab<G, A, R>> tabs = new ArrayList<>();
97 
101  @NotNull
102  private final Collection<ObjectChooserListener<G, A, R>> listeners = new ArrayList<>();
103 
107  @Nullable
109 
113  @Nullable
115 
119  @Nullable
121 
125  @Nullable
127 
131  private int selectedIndex = -2;
132 
136  @NotNull
138 
139  @Override
140  public void mapCursorChangedPos(@NotNull final Point location) {
141  updatePickmapInfo(activePickmapView == null ? null : activePickmapView.getMapCursor());
142  }
143 
144  @Override
145  public void mapCursorChangedMode() {
146  // ignore
147  }
148 
149  @Override
150  public void mapCursorChangedGameObject(@Nullable final MapSquare<G, A, R> mapSquare, @Nullable final G gameObject) {
151  // ignore
152  }
153 
154  @Override
155  public void mapCursorChangedSize() {
156  // ignore
157  }
158 
159  };
160 
169  public DefaultObjectChooser(@NotNull final ObjectChooserTab<G, A, R> archetypeChooserControl, @NotNull final ObjectChooserTab<G, A, R> pickmapChooserControl, @NotNull final ArchetypeChooserModel<G, A, R> archetypeChooserModel, @NotNull final PickmapChooserModel<G, A, R> pickmapChooserModel, @NotNull final ArchetypeTypeSet archetypeTypeSet) {
170  super(new BorderLayout());
171  this.pickmapChooserControl = pickmapChooserControl;
172  this.archetypeChooserModel = archetypeChooserModel;
173  objectChoiceDisplay = new ObjectChoiceDisplay(archetypeTypeSet);
174 
175  cursorSelection = getSelection();
176 
177  addTab(archetypeChooserControl);
178  addTab(pickmapChooserControl);
179 
180  final ChangeListener changeListener = new ChangeListener() {
181 
182  @Override
183  public void stateChanged(final ChangeEvent e) {
185  }
186 
187  };
188  tabbedPane.addChangeListener(changeListener);
189 
191  add(tabbedPane, BorderLayout.CENTER);
192  add(objectChoiceDisplay, BorderLayout.SOUTH);
193 
194  final ArchetypeChooserModelListener<G, A, R> archetypeChooserModelListener = new ArchetypeChooserModelListener<G, A, R>() {
195 
196  @Override
197  public void selectedPanelChanged(@NotNull final ArchetypeChooserPanel<G, A, R> selectedPanel) {
198  // ignore
199  }
200 
201  @Override
202  public void selectedFolderChanged(@NotNull final ArchetypeChooserFolder<G, A, R> selectedFolder) {
203  // ignore
204  }
205 
206  @Override
207  public void selectedArchetypeChanged(@Nullable final R selectedArchetype) {
208  if (!isPickmapActive()) {
209  fireSelectionChanged(selectedArchetype);
210  }
211  }
212 
213  @Override
214  public void directionChanged(@Nullable final Integer direction) {
215  // ignore
216  }
217 
218  @Override
219  public void displayModeChanged(@NotNull final DisplayMode<G, A, R> displayMode) {
220  // ignore
221  }
222 
223  };
224  archetypeChooserModel.addArchetypeChooserModelListener(archetypeChooserModelListener);
225 
226  final PickmapChooserModelListener<G, A, R> pickmapChooserModelListener = new PickmapChooserModelListener<G, A, R>() {
227 
228  @Override
229  public void activePickmapChanged(@Nullable final PickmapState<G, A, R> pickmapState) {
230  if (activePickmapState != pickmapState) { // ignore non-changes
231  updateActivePickmap(pickmapState);
232  }
233  }
234 
235  @Override
236  public void pickmapReverted(@NotNull final PickmapState<G, A, R> pickmapState) {
237  if (activePickmapState == pickmapState) { // ignore unless active pickmap was reverted
238  updateActivePickmap(pickmapState);
239  }
240  }
241 
242  @Override
243  public void pickmapModifiedChanged(final int index, @NotNull final PickmapState<G, A, R> pickmapState) {
244  // ignore
245  }
246 
247  };
248  pickmapChooserModel.addPickmapChooserListener(pickmapChooserModelListener);
249 
250  objectChoiceDisplay.showObjectChooserQuickObject(cursorSelection, isPickmapActive());
251  }
252 
257  private void addTab(@NotNull final ObjectChooserTab<G, A, R> tab) {
258  tabs.add(tab);
259  tabbedPane.addTab(tab.getTitle(), tab.getComponent());
260  }
261 
266  private void setActiveTab(final int index) {
267  @Nullable ObjectChooserTab<G, A, R> tab;
268  try {
269  tab = tabs.get(index);
270  } catch (final IndexOutOfBoundsException ignored) {
271  tab = null;
272  }
273  if (activeTab == tab) {
274  return;
275  }
276 
277  if (activeTab != null) {
278  activeTab.setActive(false);
279  }
280  activeTab = tab;
281  if (activeTab != null) {
282  activeTab.setActive(true);
283  }
284  for (final ObjectChooserListener<G, A, R> listener : listeners) {
285  listener.pickmapActiveChanged(isPickmapActive());
286  }
287  if (isPickmapActive()) {
288  updatePickmapInfo(activePickmapView == null ? null : activePickmapView.getMapCursor());
289  } else {
290  final ArchetypeChooserPanel<G, A, R> selectedPanel = archetypeChooserModel.getSelectedPanel();
291  fireSelectionChanged(selectedPanel == null ? null : selectedPanel.getSelectedFolder().getSelectedArchetype());
292  }
293  }
294 
295  @Override
296  public final boolean isPickmapActive() {
297  return activeTab == pickmapChooserControl;
298  }
299 
305  @Override
306  public boolean isMatching(@NotNull final G gameObject) {
307  return activeTab != null && activeTab.isMatching(gameObject);
308  }
309 
310  @Override
311  public void addObjectChooserListener(@NotNull final ObjectChooserListener<G, A, R> listener) {
312  listeners.add(listener);
313  }
314 
315  @Override
316  public void removeObjectChooserListener(@NotNull final ObjectChooserListener<G, A, R> listener) {
317  listeners.remove(listener);
318  }
319 
320  @Override
322  tabbedPane.setSelectedIndex(0);
323  }
324 
325  @Override
327  tabbedPane.setSelectedIndex(1);
328  }
329 
330  @Nullable
331  @Override
333  return cursorSelection;
334  }
335 
336  @Nullable
337  @Override
339  return activeTab == null ? null : activeTab.getSelection();
340  }
341 
342  @NotNull
343  @Override
344  public List<? extends BaseObject<G, A, R, ?>> getSelections() {
345  return activeTab == null ? Collections.<G>emptyList() : activeTab.getSelections();
346  }
347 
351  private void updateSelectedIndex() {
352  final int index = tabbedPane.getSelectedIndex();
353  if (index != selectedIndex) {
354  selectedIndex = index;
355  setActiveTab(index);
356  }
357  }
358 
363  private void updateActivePickmap(@Nullable final PickmapState<G, A, R> pickmapState) {
364  if (activePickmapView != null) {
365  activePickmapView.getMapCursor().removeMapCursorListener(mapCursorListener);
366  }
367  activePickmapState = pickmapState;
369  if (activePickmapView != null) {
370  activePickmapView.getMapCursor().addMapCursorListener(mapCursorListener);
371  }
372  }
373 
377  private void updateActivePickmap() {
378  activePickmapView = activePickmapState != null ? activePickmapState.getMapView() : null;
379  updatePickmapInfo(activePickmapView == null ? null : activePickmapView.getMapCursor());
380  }
381 
386  private void updatePickmapInfo(@Nullable final MapCursor<G, A, R> mapCursor) {
387  if (isPickmapActive()) {
388  @Nullable final BaseObject<G, A, R, ?> gameObject;
389  if (mapCursor == null) {
390  gameObject = null;
391  } else {
392  final Point location = mapCursor.getLocation();
393  if (activePickmapState == null) {
394  gameObject = null;
395  } else {
396  final MapControl<G, A, R> pickmap = activePickmapState.getPickmap();
397  if (pickmap == null) {
398  gameObject = null;
399  } else {
400  final MapModel<G, A, R> mapModel = pickmap.getMapModel();
401  gameObject = mapModel.getMapSquare(location).getFirst();
402  }
403  }
404  }
405  fireSelectionChanged(gameObject);
406  }
407  }
408 
413  private void fireSelectionChanged(@Nullable final BaseObject<G, A, R, ?> gameObject) {
414  if (cursorSelection == gameObject) {
415  return;
416  }
417  cursorSelection = gameObject;
418 
419  for (final ObjectChooserListener<G, A, R> listener : listeners) {
420  listener.selectionChanged(gameObject);
421  }
422 
423  objectChoiceDisplay.showObjectChooserQuickObject(gameObject, isPickmapActive());
424  }
425 
426 }
final ObjectChoiceDisplay objectChoiceDisplay
The ObjectChoiceDisplay that display information about the currently selected object.
final MapCursorListener< G, A, R > mapCursorListener
The map cursor listener attached to activePickmapView.
A MapModel reflects the data of a map.
Definition: MapModel.java:75
Graphical User Interface of Gridarta.
A named panel within the ArchetypeChooserModel.
Manages ArchetypeType instances, list, and bitmask definitions.
Maintains the state of a pickmap file.
A named folder within the ArchetypeChooserModel.
void removeObjectChooserListener(@NotNull final ObjectChooserListener< G, A, R > listener)
MapCursor provides methods to move and drag on map.
Definition: MapCursor.java:57
BaseObject< G, A, R, ?> cursorSelection
The last reported selection.
final JTabbedPane tabbedPane
Panel holding both archetype chooser and pickmap chooser.
MapModel< G, A, R > getMapModel()
Returns the map model.
void updatePickmapInfo(@Nullable final MapCursor< G, A, R > mapCursor)
Updates the display information for the active pickmap.
Base package of all Gridarta classes.
void addMapCursorListener(@NotNull final MapCursorListener< G, A, R > listener)
Register a MapCursorListener.
Definition: MapCursor.java:419
ArchetypeChooserPanel< G, A, R > getSelectedPanel()
Returns the selected ArchetypeChooserPanel.
Reflects a game object (object on a map).
Definition: GameObject.java:36
void addTab(@NotNull final ObjectChooserTab< G, A, R > tab)
Adds a tab.
final List< ObjectChooserTab< G, A, R > > tabs
The tabs in the same order as tabbedPane.
MapControl< G, A, R > getPickmap()
Returns the MapControl representing this pickmap.
PickmapState< G, A, R > activePickmapState
The last known active PickmapState.
MapSquare< G, A, R > getMapSquare(@NotNull Point pos)
Get the square at a specified location.
GameObjects are the objects based on Archetypes found on maps.
final Collection< ObjectChooserListener< G, A, R > > listeners
The registered listeners.
void fireSelectionChanged(@Nullable final BaseObject< G, A, R, ?> gameObject)
Notifies all listeners that the selection may have changed.
G getFirst(@NotNull final GameObjectMatcher gameObjectMatcher)
Returns the first occurrence of a matching game object.
Definition: MapSquare.java:226
void setActiveTab(final int index)
Records whether the archetype chooser or the pickmap chooser is active.
final ObjectChooserTab< G, A, R > pickmapChooserControl
The pickmap chooser control.
Base classes for rendering maps.
MapView< G, A, R > getMapView()
Returns the MapView instance for this pickmap.
BaseObject< G, A, R, ?> getSelection()
Returns the selected game object.
Classes implementing the pickmap chooser.
DefaultObjectChooser(@NotNull final ObjectChooserTab< G, A, R > archetypeChooserControl, @NotNull final ObjectChooserTab< G, A, R > pickmapChooserControl, @NotNull final ArchetypeChooserModel< G, A, R > archetypeChooserModel, @NotNull final PickmapChooserModel< G, A, R > pickmapChooserModel, @NotNull final ArchetypeTypeSet archetypeTypeSet)
Creates a new instance.
Interface for listeners interested in ArchetypeChooserModel related events.
Abstract base class for classes implementing display modes of the archetype chooser.
MapView< G, A, R > activePickmapView
The MapView of activePickmapState.
void updateActivePickmap(@Nullable final PickmapState< G, A, R > pickmapState)
Records an active pickmap.
final ArchetypeChooserModel< G, A, R > archetypeChooserModel
The ArchetypeChooserModel.
void showObjectChooserQuickObject(@Nullable final BaseObject<?, ?, ?, ?> gameObject, final boolean isPickmapActive)
Displays information about the selected game object.
MapCursor< G, A, R > getMapCursor()
Returns the MapCursor of this view.
Currently nothing more than a marker interface for unification.
Definition: MapControl.java:35
A map view consists of a map grid and a map cursor, and is attached to a map control.
Definition: MapView.java:43
void setActive(boolean active)
Called whenever this tab becomes active or inactive.
ArchetypeChooserFolder< G, A, R > getSelectedFolder()
Returns the selected ArchetypeChooserFolder.
boolean isMatching(@NotNull G gameObject)
Returns whether the current selection matches the given game object.
void addObjectChooserListener(@NotNull final ObjectChooserListener< G, A, R > listener)
Common base interface for ObjectChoosers.
static final long serialVersionUID
The serial version UID.
Interface for listeners listening to MapCursor related events.
The object choice display shows information about the selected object in the object chooser...
Defines types of GameObjects with corresponding attributes.
boolean isMatching(@NotNull final G gameObject)
Returns whether a given game object matches the selection.
void updateActivePickmap()
Updates the display state after activePickmapState has changed.
List<? extends BaseObject< G, A, R, ?> > getSelections()
Returns the selected game objects.
void removeMapCursorListener(@NotNull final MapCursorListener< G, A, R > listener)
Remove a MapCursorListener.
Definition: MapCursor.java:427
ObjectChooserTab< G, A, R > activeTab
The active tab or.