20 package net.sf.gridarta.gui.dialog.replace;
22 import java.awt.Component;
23 import java.awt.Container;
24 import java.awt.FlowLayout;
25 import java.awt.event.ItemEvent;
26 import java.awt.event.ItemListener;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Iterator;
30 import java.util.List;
31 import javax.swing.BorderFactory;
32 import javax.swing.Box;
33 import javax.swing.BoxLayout;
34 import javax.swing.Icon;
35 import javax.swing.JButton;
36 import javax.swing.JComboBox;
37 import javax.swing.JDialog;
38 import javax.swing.JLabel;
39 import javax.swing.JOptionPane;
40 import javax.swing.JPanel;
41 import javax.swing.JTextField;
42 import javax.swing.WindowConstants;
43 import javax.swing.text.JTextComponent;
63 import net.
sf.japi.swing.action.ActionBuilder;
64 import net.
sf.japi.swing.action.ActionBuilderFactory;
65 import net.
sf.japi.swing.action.ActionMethod;
66 import org.jetbrains.annotations.NotNull;
67 import org.jetbrains.annotations.Nullable;
85 private static final ActionBuilder
ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder(
"net.sf.gridarta");
207 @SuppressWarnings(
"RedundantFieldInitialization")
217 public void pickmapActiveChanged(
final boolean pickmapActive) {
235 public void facesReloaded() {
250 public ReplaceDialog(@NotNull
final Component parent, @NotNull
final CopyBuffer<G, A, R> copyBuffer, @NotNull
final ObjectChooser<G, A, R> objectChooser, @NotNull
final FaceObjectProviders faceObjectProviders, @NotNull
final InsertionModeSet<G, A, R> insertionModeSet) {
253 dialog.setModal(
false);
254 dialog.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
274 rfHeading.setText(
"\"" + mapView.getMapControl().getMapModel().getMapArchObject().getMapName() +
"\":");
275 replaceInput1.setText(
"");
278 if (replaceArch == null) {
279 replaceWithBox.setSelectedIndex(REPLACE_WITH_COPY_BUFFER);
280 iconLabel.setIcon(null);
281 rfArchName.setText(
"");
282 colonLabel.setText(
"");
284 replaceWithBox.setSelectedIndex(REPLACE_WITH_OBJECT_CHOOSER);
285 iconLabel.setIcon(faceObjectProviders.getFace(replaceArch));
286 rfArchName.setText(
" " + replaceArch.
getBestName());
287 colonLabel.setText(
":");
290 if (mapView.getSelectedSquares().size() > 1) {
291 replaceEntireBox.setSelectedIndex(REPLACE_ON_SELECTION);
293 replaceEntireBox.setSelectedIndex(REPLACE_ON_MAP);
296 replaceDensityInput.setText(
"100");
302 final JPanel mainPanel =
new JPanel();
303 mainPanel.setLayout(
new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
304 mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 2, 5));
307 final Container line1 =
new JPanel(
new FlowLayout(FlowLayout.LEFT));
309 line1.add(Box.createVerticalStrut(3));
312 if (mapView.getSelectedSquares().size() > 1) {
313 replaceEntireBox.setSelectedIndex(REPLACE_ON_SELECTION);
315 replaceEntireBox.setSelectedIndex(REPLACE_ON_MAP);
317 line1.add(replaceEntireBox);
318 line1.add(Box.createVerticalStrut(3));
319 rfHeading =
new JLabel(
"\"" + mapView.getMapControl().getMapModel().getMapArchObject().getMapName() +
"\":");
320 line1.add(rfHeading);
321 mainPanel.add(line1);
324 final Container line2 =
new JPanel(
new FlowLayout(FlowLayout.LEFT));
326 line2.add(Box.createVerticalStrut(5));
329 replaceCriteria.setSelectedIndex(0);
331 line2.add(replaceCriteria);
332 line2.add(Box.createVerticalStrut(5));
334 replaceInput1 =
new JTextField(20);
336 line2.add(replaceInput1);
337 mainPanel.add(line2);
340 final Container line3 =
new JPanel(
new FlowLayout(FlowLayout.LEFT));
342 line3.add(Box.createVerticalStrut(5));
346 if (replaceArch == null) {
347 replaceWithBox.setSelectedIndex(REPLACE_WITH_NOTHING);
349 replaceWithBox.setSelectedIndex(REPLACE_WITH_OBJECT_CHOOSER);
351 replaceWithBox.addItemListener(
new ReplaceWithBoxItemListener());
353 line3.add(replaceWithBox);
355 iconLabel =
new JLabel();
356 if (replaceArch != null) {
357 colonLabel =
new JLabel(
":");
358 iconLabel.setIcon(faceObjectProviders.getFace(replaceArch));
359 rfArchName =
new JLabel(
" " + replaceArch.
getBestName());
361 colonLabel =
new JLabel(
"");
362 rfArchName =
new JLabel(
"");
364 line3.add(colonLabel);
365 line3.add(Box.createVerticalStrut(5));
366 line3.add(iconLabel);
367 line3.add(rfArchName);
368 mainPanel.add(line3);
371 final Container line4 =
new JPanel(
new FlowLayout(FlowLayout.LEFT));
373 line4.add(Box.createVerticalStrut(5));
374 replaceDensityInput =
new JTextField(5);
376 line4.add(replaceDensityInput);
377 replaceDensityInput.setText(
"100");
378 mainPanel.add(line4);
380 final JButton okButton =
new JButton(ACTION_BUILDER.createAction(
false,
"replaceOk",
this));
381 final JButton applyButton =
new JButton(ACTION_BUILDER.createAction(
false,
"replaceApply",
this));
382 final JButton cancelButton =
new JButton(ACTION_BUILDER.createAction(
false,
"replaceCancel",
this));
384 setMessage(mainPanel);
385 setOptions(
new Object[] { okButton, applyButton, cancelButton });
386 dialog.getRootPane().setDefaultButton(okButton);
388 dialog.setLocationRelativeTo(parent);
391 dialog.setVisible(
true);
403 replaceArch = newArch;
404 if (newArch != null) {
405 final Icon oldIcon = iconLabel.getIcon();
407 iconLabel.setIcon(faceObjectProviders.getFace(newArch));
408 rfArchName.setText(
" " + newArch.getBestName());
409 colonLabel.setText(
":");
412 if (alwaysPack || (oldIcon == null && iconLabel.getIcon() != null) || (oldIcon != null && iconLabel.getIcon() == null) || (oldIcon != iconLabel.getIcon() && oldIcon != null && oldIcon.getIconHeight() != iconLabel.getIcon().getIconHeight())) {
416 iconLabel.setIcon(null);
417 rfArchName.setText(
"");
418 colonLabel.setText(
"");
434 @Nullable
final List<? extends BaseObject<G, A, R, ?>> replaceList;
437 if (replaceArch == null) {
440 replaceList =
newList(replaceArch);
456 final Collection<G> objectsToReplace =
new ArrayList<>();
457 final int replaceListSize = replaceList == null ? 0 : replaceList.size();
462 int replaceCount = 0;
467 objectsToReplace.clear();
468 for (
final G node : square) {
469 if (node.isHead() && matchCriteria.matches(node)) {
471 objectsToReplace.add(node);
477 for (
final G objectToReplace : objectsToReplace) {
478 final Iterator<G> it = square.iterator();
481 while (it.hasNext()) {
484 if (node == objectToReplace) {
495 if (replaceListSize > 0 && !deleteOnly) {
497 if (replaceListSize == 1) {
498 randomArch = replaceList.get(0);
500 randomArch = replaceList.get(
RandomUtils.
RND.nextInt(replaceList.size()));
524 private static <T> List<T>
newList(@NotNull
final T element) {
525 final List<T> list =
new ArrayList<>(1);
537 final int selectedIndex = replaceWithBox.getSelectedIndex();
538 if (e.getStateChange() == ItemEvent.SELECTED &&
lastSelectedIndex != selectedIndex) {
540 switch (selectedIndex) {
548 iconLabel.setIcon(null);
549 size = replaceCopyBuffer.size();
550 rfArchName.setText(String.valueOf(size));
551 colonLabel.setText(
":");
557 iconLabel.setIcon(null);
558 size = replacePickmap.size();
559 rfArchName.setText(String.valueOf(size));
560 colonLabel.setText(
":");
565 iconLabel.setIcon(null);
566 rfArchName.setText(
"");
567 colonLabel.setText(
"");
583 dialog.setVisible(
false);
600 final String matchString = replaceInput1.getText().trim();
602 final boolean entireMap = replaceEntireBox.getSelectedIndex() ==
REPLACE_ON_MAP;
604 if (!entireMap && mapView.
getMapGrid().getSelectedRec() == null) {
611 if (replaceCriteria.getSelectedIndex() == 0) {
613 }
else if (replaceCriteria.getSelectedIndex() == 1) {
619 final int replaceDensity;
621 replaceDensity = Integer.parseInt(replaceDensityInput.getText());
622 }
catch (
final NumberFormatException ignored) {
623 ACTION_BUILDER.showMessageDialog(
this,
"replaceInvalidDensity");
626 if (replaceDensity < 1 || replaceDensity > 100) {
627 ACTION_BUILDER.showMessageDialog(
this,
"replaceInvalidDensity");
631 final int replaceCount =
doReplace(matchCriteria, entireMap, deleteOnly, replaceDensity);
632 if (replaceCount <= 0) {
633 ACTION_BUILDER.showMessageDialog(
this,
"replacedZero");
637 if (replaceCount == 1) {
638 ACTION_BUILDER.showMessageDialog(
this,
"replacedOne");
640 ACTION_BUILDER.showMessageDialog(
this,
"replacedMany", replaceCount);
650 dialog.setVisible(
false);
658 if (mapView == this.mapView) {
659 dialog.setVisible(
false);
final InsertionModeSet< G, A, R > insertionModeSet
The InsertionModeSet to use.
final JDialog dialog
The dialog instance.
List< MapSquare< G, A, R > > getSelectedSquares()
Returns the selected squares.
A MapModel reflects the data of a map.
Graphical User Interface of Gridarta.
static final int REPLACE_WITH_COPY_BUFFER
Index for replaceWithBox: replace with copy buffer contents.
final ObjectChooserListener< G, A, R > objectChooserListener
The ObjectChooserListener for tracking the selection.
static final ActionBuilder ACTION_BUILDER
Action Builder.
boolean isBuilt
Whether this replace dialog has been displayed.
void endTransaction()
End a transaction.
MapGrid getMapGrid()
Returns the MapGrid of this view.
void display(@NotNull final MapView< G, A, R > mapView)
Replace objects on the map.
static final long serialVersionUID
Serial Version UID.
void replaceOk()
Action method for Ok button.
void replaceApply()
Action method for Apply button.
static final int REPLACE_ON_MAP
Index for replaceEntireBox: replace map.
BaseObject< G, A, R, ?> getSelection()
Returns the active arch in the left-side panel.
void dispose(@NotNull final MapView< G, A, R > mapView)
Disposes the replace dialog.
JComboBox< String > replaceCriteria
Item-listener for the "replace with"-selection box.
BaseObject< G, A, R, ?> replaceArch
Objects will be replaced with this game object.
MapControl< G, A, R > getMapControl()
Return the controller of this view.
JTextComponent replaceInput1
static< T > List< T > newList(@NotNull final T element)
Creates a new list containing one element.
void replaceCancel()
Action method for Cancel button.
MapModel< G, A, R > getMapModel()
Returns the map model.
void addFaceObjectProvidersListener(@NotNull final FaceObjectProvidersListener listener)
Adds a FaceObjectProvidersListener to be notified about changes.
static String getString(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final String defaultValue)
Returns the value of a key.
G insertBaseObject(@NotNull BaseObject< G, A, R, ?> baseObject, @NotNull Point pos, boolean allowMany, boolean join, @NotNull InsertionMode< G, A, R > insertionMode)
Inserts a BaseObject to a map.
Base package of all Gridarta classes.
Reflects a game object (object on a map).
boolean doReplace()
Executes one replace operation.
static final int REPLACE_ON_SELECTION
Index for replaceEntireBox: replace selection.
static final int REPLACE_WITH_PICKMAP
Index for replaceWithBox: replace with pickmap contents.
static final int REPLACE_WITH_NOTHING
Index for replaceWithBox: delete matching game objects.
InsertionMode< G, A, R > getTopmostInsertionMode()
Returns the "topmost" insertion mode.
GameObjects are the objects based on Archetypes found on maps.
int doReplace(@NotNull final MatchCriteria< G, A, R > matchCriteria, final boolean entireMap, final boolean deleteOnly, final int replaceDensity)
This method performs the actual replace action on a map.
G insertArchToMap(@NotNull BaseObject< G, A, R, ?> templateBaseObject, @Nullable G nextGameObject, @NotNull Point pos, boolean join)
Insert a game object to the map at a specified position.
final CopyBuffer< G, A, R > copyBuffer
The CopyBuffer.
static final Random RND
Global random number generator.
List< G > getAllGameObjects()
Return all game objects.
List<? extends BaseObject< G, A, R, ?> > getSelections()
Returns the selected arches in the left-side panel.
Base classes for rendering maps.
Point getMapLocation()
Returns the coordinate of this GameObject on its map.
final ObjectChooser< G, A, R > objectChooser
The object chooser to use.
void updateArchSelection(@Nullable final BaseObject< G, A, R, ?> newArch, final boolean alwaysPack)
Update which arch is displayed as replace object.
MapView< G, A, R > mapView
The MapView to operate on.
JTextComponent replaceDensityInput
Input field for replace density value.
String getBestName()
Returns the name which is best appropriate to describe this GameObject.
List<? extends BaseObject< G, A, R, ?> > replacePickmap
final Component parent
The parent component for dialogs.
Utility class for ActionBuilder related functions.
final FaceObjectProviders faceObjectProviders
The FaceObjectProviders for looking up faces.
A MatchCriteria that matches by object name.
ReplaceDialog(@NotNull final Component parent, @NotNull final CopyBuffer< G, A, R > copyBuffer, @NotNull final ObjectChooser< G, A, R > objectChooser, @NotNull final FaceObjectProviders faceObjectProviders, @NotNull final InsertionModeSet< G, A, R > insertionModeSet)
Creates a new instance.
Interface for listeners interested in FaceObjectProviders related events.
static final int REPLACE_WITH_OBJECT_CHOOSER
Index for replaceWithBox: replace with object chooser selection.
A getMapArchObject()
Returns the Map Arch Object with the meta information about the map.
Provider for faces of GameObjects and Archetypes.
The face is the appearance of an object.
void itemStateChanged(@NotNull final ItemEvent e)
Currently nothing more than a marker interface for unification.
BaseObject< G, A, R, ?> getCursorSelection()
Returns the selected archetype (if the archetype chooser is active) or the game object selected by th...
A map view consists of a map grid and a map cursor, and is attached to a map control.
JComboBox< String > replaceWithBox
boolean isMulti()
Returns whether this Archetype is a multi-part object.
static JLabel newLabel(@NotNull final ActionBuilder actionBuilder, @NotNull final String key)
Creates a new JLabel from a resource key.
Common base interface for ObjectChoosers.
void beginTransaction(@NotNull String name)
Starts a new transaction.
A MatchCriteria that matches by archetype name.
Criteria for game object matchers.
Interface for listener interested in ObjectChooser events.
JComboBox< String > replaceEntireBox
Common base implementation of CopyBuffer.
final FaceObjectProvidersListener faceObjectProvidersListener
The FaceObjectProvidersListener for detecting reloaded faces.
List< G > replaceCopyBuffer
Interface for MapArchObjects.
This dialog manages the replace action.