Gridarta Editor
FindDialog.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2023 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.find;
21 
22 import java.awt.Component;
23 import java.awt.Container;
24 import java.awt.FlowLayout;
25 import java.awt.Point;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.List;
29 import javax.swing.AbstractButton;
30 import javax.swing.BorderFactory;
31 import javax.swing.Box;
32 import javax.swing.BoxLayout;
33 import javax.swing.JButton;
34 import javax.swing.JCheckBox;
35 import javax.swing.JDialog;
36 import javax.swing.JOptionPane;
37 import javax.swing.JPanel;
38 import javax.swing.JTextField;
39 import javax.swing.WindowConstants;
40 import javax.swing.text.JTextComponent;
58 import net.sf.japi.swing.action.ActionBuilder;
59 import net.sf.japi.swing.action.ActionBuilderFactory;
60 import net.sf.japi.swing.action.ActionMethod;
61 import org.jetbrains.annotations.NotNull;
62 
67 public class FindDialog<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> extends JOptionPane {
68 
72  private static final long serialVersionUID = 1L;
73 
77  @NotNull
78  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
79 
83  @NotNull
84  private final JDialog dialog;
85 
89  @NotNull
90  private final Component parent;
91 
95  private boolean isBuilt;
96 
100  @NotNull
102 
106  @NotNull
107  private final JTextComponent findInput = new JTextField(20);
108 
112  @NotNull
113  private final AbstractButton findNameCheckbox = new JCheckBox(ActionBuilderUtils.getString(ACTION_BUILDER, "findWhereName"));
114 
118  @NotNull
119  private final AbstractButton findArchCheckbox = new JCheckBox(ActionBuilderUtils.getString(ACTION_BUILDER, "findWhereArch"));
120 
124  @NotNull
125  private final AbstractButton findMsgCheckbox = new JCheckBox(ActionBuilderUtils.getString(ACTION_BUILDER, "findWhereMsg"));
126 
130  @NotNull
131  private final AbstractButton findFaceCheckbox = new JCheckBox(ActionBuilderUtils.getString(ACTION_BUILDER, "findWhereFace"));
132 
136  @NotNull
137  private final AbstractButton findSlayingCheckbox = new JCheckBox(ActionBuilderUtils.getString(ACTION_BUILDER, "findWhereSlaying"));
138 
142  @NotNull
143  private final AbstractButton findOtherCheckbox = new JCheckBox(ActionBuilderUtils.getString(ACTION_BUILDER, "findWhereOther"));
144 
149  public FindDialog(@NotNull final Component parent) {
150  dialog = createDialog(parent, "");
151  dialog.setModal(false);
152  dialog.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
153  this.parent = parent;
154 
156  }
157 
162  public void display(@NotNull final MapView<G, A, R> mapView) {
163  if (isBuilt) {
164  this.mapView = mapView;
165 
166  dialog.pack();
167  dialog.toFront();
168  } else {
169  this.mapView = mapView;
170  final JPanel mainPanel = new JPanel();
171  mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
172  mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 2, 5));
173 
174  final Container lineFind = new JPanel(new FlowLayout(FlowLayout.LEFT));
175  lineFind.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "findFind"));
176  lineFind.add(Box.createVerticalStrut(3));
177  lineFind.add(findInput);
178  lineFind.add(Box.createVerticalStrut(3));
179  mainPanel.add(lineFind);
180 
181  final Container lineWhere = new JPanel(new FlowLayout(FlowLayout.LEFT));
182  lineWhere.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "findWhere"));
183  lineWhere.add(Box.createVerticalStrut(5));
184 
185  final JPanel panelWhere = new JPanel();
186  panelWhere.setLayout(new BoxLayout(panelWhere, BoxLayout.Y_AXIS));
187  panelWhere.add(findNameCheckbox);
188  panelWhere.add(findArchCheckbox);
189  panelWhere.add(findMsgCheckbox);
190  panelWhere.add(findFaceCheckbox);
191  panelWhere.add(findSlayingCheckbox);
192  panelWhere.add(findOtherCheckbox);
193  lineWhere.add(panelWhere);
194  mainPanel.add(lineWhere);
195 
196  final JButton okButton = new JButton(ACTION_BUILDER.createAction(false, "findOk", this));
197  final JButton cancelButton = new JButton(ACTION_BUILDER.createAction(false, "findCancel", this));
198 
199  findNameCheckbox.setSelected(true);
200  findMsgCheckbox.setSelected(true);
201  findSlayingCheckbox.setSelected(true);
202 
203  setMessage(mainPanel);
204  setOptions(new Object[] { okButton, cancelButton });
205  dialog.getRootPane().setDefaultButton(okButton);
206  dialog.pack();
207  dialog.setLocationRelativeTo(parent);
208 
209  isBuilt = true;
210  }
212  dialog.setVisible(true);
213  findInput.requestFocusInWindow();
214  }
215 
224  public boolean findAgain(@NotNull final MapView<G, A, R> mapView, final boolean forward, final boolean performAction) {
225  if (this.mapView != mapView) {
226  return false;
227  }
228  if (performAction) {
229  doFind(forward);
230  }
231  return true;
232  }
233 
237  @ActionMethod
238  public void findOk() {
239  if (doFind(true)) {
240  dialog.setVisible(false);
241  }
242  }
243 
247  @ActionMethod
248  public void findCancel() {
249  dialog.setVisible(false);
250  }
251 
258  private boolean doFind(final boolean forward) {
259  final String findString = findInput.getText().trim();
260  final Collection<MatchCriteria<G, A, R>> matchCriterias = new ArrayList<>();
261  if (findNameCheckbox.isSelected()) {
262  matchCriterias.add(new ObjectNameMatchCriteria<>(findString));
263  }
264  if (findArchCheckbox.isSelected()) {
265  matchCriterias.add(new ArchetypeNameMatchCriteria<>(findString));
266  }
267  if (findMsgCheckbox.isSelected()) {
268  matchCriterias.add(new AttributeValueMatchCriteria<>("msg", findString));
269  }
270  if (findFaceCheckbox.isSelected()) {
271  matchCriterias.add(new AttributeValueMatchCriteria<>("face", findString));
272  matchCriterias.add(new AttributeValueMatchCriteria<>("animation", findString));
273  }
274  if (findSlayingCheckbox.isSelected()) {
275  matchCriterias.add(new AttributeValueMatchCriteria<>("slaying", findString));
276  }
277  if (findOtherCheckbox.isSelected()) {
278  matchCriterias.add(new AttributeOtherValueMatchCriteria<>(findString, "msg", "face", "animation", "slaying"));
279  }
280  return !matchCriterias.isEmpty() && doFind(matchCriterias, forward) > 0;
281  }
282 
290  private int doFind(@NotNull final Iterable<MatchCriteria<G, A, R>> matchCriterias, final boolean forward) {
291  final List<G> matchingGameObjects = new ArrayList<>();
292  final Collection<MapSquare<G, A, R>> matchingMapSquares = new ArrayList<>();
293  final MapControl<G, A, R> mapControl = mapView.getMapControl();
294  final MapModel<G, A, R> mapModel = mapControl.getMapModel();
295  for (final MapSquare<G, A, R> mapSquare : mapModel) {
296  boolean matchesMapSquare = false;
297  for (final G gameObject : mapSquare.recursive()) {
298  for (final MatchCriteria<G, A, R> matchCriteria : matchCriterias) {
299  if (matchCriteria.matches(gameObject)) {
300  matchingGameObjects.add(gameObject);
301  matchesMapSquare = true;
302  }
303  }
304  }
305  if (matchesMapSquare) {
306  matchingMapSquares.add(mapSquare);
307  }
308  }
309  selectMapSquares(matchingMapSquares);
310  setMapCursor(forward, matchingGameObjects);
311  return matchingGameObjects.size();
312  }
313 
318  private void selectMapSquares(@NotNull final Iterable<MapSquare<G, A, R>> mapSquares) {
319  final MapGrid mapGrid = mapView.getMapGrid();
320  mapGrid.unSelect();
321  final Point p = new Point();
322  for (final MapSquare<G, A, R> mapSquare : mapSquares) {
323  p.x = mapSquare.getMapX();
324  p.y = mapSquare.getMapY();
325  mapGrid.select(p, SelectionMode.ADD);
326  }
327  }
328 
335  private void setMapCursor(final boolean forward, @NotNull final List<G> gameObjects) {
336  if (gameObjects.isEmpty()) {
337  return;
338  }
339 
340  final MapCursor<G, A, R> mapCursor = mapView.getMapCursor();
341  final int index;
342  final G selectedGameObject = mapCursor.getGameObject();
343  if (selectedGameObject == null) {
344  index = 0;
345  } else {
346  final int selectedIndex = gameObjects.indexOf(selectedGameObject);
347  if (selectedIndex == -1) {
348  index = 0;
349  } else if (forward) {
350  index = selectedIndex + 1 < gameObjects.size() ? selectedIndex + 1 : 0;
351  } else {
352  index = (selectedIndex > 0 ? selectedIndex : gameObjects.size()) - 1;
353  }
354  }
355  mapCursor.setGameObject(gameObjects.get(index));
356  }
357 
362  public void dispose(@NotNull final MapView<G, A, R> mapView) {
363  if (mapView == this.mapView) {
364  dialog.setVisible(false);
365  }
366  }
367 
368 }
net.sf.gridarta.model.mapmodel.MapModel
A MapModel reflects the data of a map.
Definition: MapModel.java:75
net.sf.gridarta.gui.dialog.find.FindDialog.findOk
void findOk()
Action method for Ok button.
Definition: FindDialog.java:238
net.sf.gridarta.gui.map.mapview.MapView.getMapGrid
MapGrid getMapGrid()
Returns the MapGrid of this view.
net.sf.gridarta.gui.dialog.find.FindDialog.findAgain
boolean findAgain(@NotNull final MapView< G, A, R > mapView, final boolean forward, final boolean performAction)
Re-executes the previous find operation.
Definition: FindDialog.java:224
net.sf.gridarta.model.mapmodel.MapModel.getMapArchObject
A getMapArchObject()
Returns the Map Arch Object with the meta information about the map.
net.sf.gridarta.gui.dialog.find.FindDialog.display
void display(@NotNull final MapView< G, A, R > mapView)
Replace objects on the map.
Definition: FindDialog.java:162
net.sf.gridarta.model.select.MatchCriteria
Criteria for game object matchers.
Definition: MatchCriteria.java:31
net.sf.gridarta.gui.map.mapview.MapView.getMapControl
MapControl< G, A, R > getMapControl()
Return the controller of this view.
net.sf.gridarta.gui.dialog.find.FindDialog.findInput
final JTextComponent findInput
The text input field for the string to find.
Definition: FindDialog.java:107
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.gui.dialog.find.FindDialog.findArchCheckbox
final AbstractButton findArchCheckbox
The checkbox for matching archetype names.
Definition: FindDialog.java:119
net.sf.gridarta.model.mapmodel.MapSquare
A single Map Square.
Definition: MapSquare.java:45
net.sf.gridarta.model.select.AttributeOtherValueMatchCriteria
A MatchCriteria that matches attribute values of all but a set of attributes.
Definition: AttributeOtherValueMatchCriteria.java:36
net.sf
net.sf.gridarta.model.mapcursor.MapCursor.getGameObject
G getGameObject()
Returns the selected GameObject.
Definition: MapCursor.java:437
net.sf.gridarta.gui.dialog.find.FindDialog.parent
final Component parent
The parent component for dialogs.
Definition: FindDialog.java:90
net.sf.gridarta.model.select.ArchetypeNameMatchCriteria
A MatchCriteria that matches by archetype name.
Definition: ArchetypeNameMatchCriteria.java:33
net.sf.gridarta.model.mapmodel
Definition: AboveFloorInsertionMode.java:20
net.sf.gridarta.gui.dialog.find.FindDialog.isBuilt
boolean isBuilt
Whether this find dialog has been displayed.
Definition: FindDialog.java:95
net.sf.gridarta.gui.dialog.find.FindDialog.findNameCheckbox
final AbstractButton findNameCheckbox
The checkbox for matching 'name' attributes.
Definition: FindDialog.java:113
net.sf.gridarta.model.archetype
Definition: AbstractArchetype.java:20
net.sf.gridarta.model.gameobject.GameObject
Reflects a game object (object on a map).
Definition: GameObject.java:36
net.sf.gridarta.gui.dialog.find.FindDialog.dispose
void dispose(@NotNull final MapView< G, A, R > mapView)
Disposes the find dialog.
Definition: FindDialog.java:362
net.sf.gridarta.model.select
Definition: ArchetypeNameMatchCriteria.java:20
net.sf.gridarta.model.mapcontrol
Definition: DefaultMapControl.java:20
net.sf.gridarta.utils.ActionBuilderUtils.newLabel
static JLabel newLabel(@NotNull final ActionBuilder actionBuilder, @NotNull final String key)
Creates a new JLabel from a resource key.
Definition: ActionBuilderUtils.java:117
net.sf.gridarta.model.select.AttributeValueMatchCriteria
A MatchCriteria that matches an attribute value.
Definition: AttributeValueMatchCriteria.java:31
net.sf.gridarta.gui.dialog.find.FindDialog.mapView
MapView< G, A, R > mapView
The MapView to operate on.
Definition: FindDialog.java:101
net.sf.gridarta.model.mapcursor.MapCursor.setGameObject
void setGameObject(@Nullable final G gameObject)
Sets the selected GameObject.
Definition: MapCursor.java:446
net.sf.gridarta.gui
Graphical User Interface of Gridarta.
net.sf.gridarta.gui.dialog.find.FindDialog.doFind
int doFind(@NotNull final Iterable< MatchCriteria< G, A, R >> matchCriterias, final boolean forward)
This method performs the actual find action on a map.
Definition: FindDialog.java:290
net.sf.gridarta.gui.map.mapview.MapView.getMapCursor
MapCursor< G, A, R > getMapCursor()
Returns the MapCursor of this view.
net.sf.gridarta.model.gameobject
GameObjects are the objects based on Archetypes found on maps.
Definition: AbstractGameObject.java:20
net
net.sf.gridarta.gui.dialog.find.FindDialog.findOtherCheckbox
final AbstractButton findOtherCheckbox
The checkbox for matching all other attributes.
Definition: FindDialog.java:143
net.sf.gridarta.model.maparchobject.MapArchObject
Interface for MapArchObjects.
Definition: MapArchObject.java:40
net.sf.gridarta.gui.map.mapview
Definition: AbstractMapView.java:20
net.sf.gridarta.gui.dialog.find.FindDialog.findCancel
void findCancel()
Action method for Cancel button.
Definition: FindDialog.java:248
net.sf.gridarta.gui.dialog.find.FindDialog
This dialog manages the find action.
Definition: FindDialog.java:67
net.sf.gridarta.gui.map.mapview.MapView
A map view consists of a map grid and a map cursor, and is attached to a map control.
Definition: MapView.java:43
net.sf.gridarta.model.mapgrid.SelectionMode
Modes that describe how squares get selected.
Definition: SelectionMode.java:26
net.sf.gridarta.utils.ActionBuilderUtils.format
static String format(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final Object... args)
Returns the value of a key.
Definition: ActionBuilderUtils.java:101
net.sf.gridarta.model.mapcursor.MapCursor
MapCursor provides methods to move and drag on map.
Definition: MapCursor.java:58
net.sf.gridarta.model.mapgrid.MapGrid.select
void select(@NotNull final Point pos, @NotNull final SelectionMode selectionMode)
Selects or deselects a single square.
Definition: MapGrid.java:408
net.sf.gridarta.utils.ActionBuilderUtils.getString
static String getString(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final String defaultValue)
Returns the value of a key.
Definition: ActionBuilderUtils.java:71
net.sf.gridarta.gui.dialog.find.FindDialog.serialVersionUID
static final long serialVersionUID
Serial Version UID.
Definition: FindDialog.java:72
net.sf.gridarta.model.mapgrid.MapGrid
2D-Grid containing flags for selection, pre-selection, cursor, warnings and errors.
Definition: MapGrid.java:46
net.sf.gridarta.model.mapgrid.SelectionMode.ADD
ADD
All squares that are preselected get selected.
Definition: SelectionMode.java:31
net.sf.gridarta.gui.dialog.find.FindDialog.dialog
final JDialog dialog
The dialog instance.
Definition: FindDialog.java:84
net.sf.gridarta.gui.dialog.find.FindDialog.findSlayingCheckbox
final AbstractButton findSlayingCheckbox
The checkbox for matching 'slaying' attributes.
Definition: FindDialog.java:137
net.sf.gridarta.model.mapgrid
Definition: MapGrid.java:20
net.sf.gridarta.model
net.sf.gridarta.model.archetype.Archetype
Reflects an Archetype.
Definition: Archetype.java:41
net.sf.gridarta.gui.utils.TextComponentUtils.setAutoSelectOnFocus
static void setAutoSelectOnFocus(@NotNull final JTextComponent textComponent)
Selects all text of a JTextComponent when the component gains the focus.
Definition: TextComponentUtils.java:47
net.sf.gridarta.gui.dialog.find.FindDialog.selectMapSquares
void selectMapSquares(@NotNull final Iterable< MapSquare< G, A, R >> mapSquares)
Selects a set of MapSquares on the map.
Definition: FindDialog.java:318
net.sf.gridarta.gui.map
Base classes for rendering maps.
Definition: AbstractPerMapDialogManager.java:20
net.sf.gridarta.model.select.ObjectNameMatchCriteria
A MatchCriteria that matches by object name.
Definition: ObjectNameMatchCriteria.java:33
net.sf.gridarta.gui.dialog.find.FindDialog.findFaceCheckbox
final AbstractButton findFaceCheckbox
The checkbox for matching 'face' or 'animation' attributes.
Definition: FindDialog.java:131
net.sf.gridarta.gui.dialog.find.FindDialog.setMapCursor
void setMapCursor(final boolean forward, @NotNull final List< G > gameObjects)
Moves the cursor to the next or previous matching game object.
Definition: FindDialog.java:335
net.sf.gridarta.gui.dialog.find.FindDialog.findMsgCheckbox
final AbstractButton findMsgCheckbox
The checkbox for matching 'msg' attributes.
Definition: FindDialog.java:125
net.sf.gridarta.model.mapcontrol.MapControl
Currently nothing more than a marker interface for unification.
Definition: MapControl.java:35
net.sf.gridarta.gui.dialog.find.FindDialog.FindDialog
FindDialog(@NotNull final Component parent)
Creates a new instance.
Definition: FindDialog.java:149
net.sf.gridarta.utils.ActionBuilderUtils
Utility class for ActionBuilder related functions.
Definition: ActionBuilderUtils.java:31
net.sf.gridarta.model.mapcontrol.MapControl.getMapModel
MapModel< G, A, R > getMapModel()
Returns the map model.
net.sf.gridarta.model.maparchobject
Definition: AbstractMapArchObject.java:20
net.sf.gridarta.gui.utils
Definition: AnimationComponent.java:20
net.sf.gridarta.model.mapcursor
Definition: MapCursor.java:20
net.sf.gridarta.gui.dialog.find.FindDialog.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
Action Builder.
Definition: FindDialog.java:78
net.sf.gridarta.gui.utils.TextComponentUtils
Utility class for JTextComponent related functions.
Definition: TextComponentUtils.java:34
net.sf.gridarta.gui.dialog.find.FindDialog.doFind
boolean doFind(final boolean forward)
Executes one find operation.
Definition: FindDialog.java:258
net.sf.gridarta.model.mapgrid.MapGrid.unSelect
void unSelect()
Clears all selection and pre-selection flags from the grid.
Definition: MapGrid.java:263
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20