Gridarta Editor
MassChangeDialog.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.mainactions;
21 
22 import java.awt.Component;
23 import java.awt.Dialog.ModalityType;
24 import java.awt.GridBagConstraints;
25 import java.awt.GridBagLayout;
26 import java.awt.Insets;
27 import java.awt.event.WindowEvent;
28 import java.awt.event.WindowListener;
29 import java.util.StringTokenizer;
30 import javax.swing.Box;
31 import javax.swing.JButton;
32 import javax.swing.JDialog;
33 import javax.swing.JOptionPane;
34 import javax.swing.JPanel;
35 import javax.swing.JScrollPane;
36 import javax.swing.JTextArea;
37 import javax.swing.JTextField;
38 import javax.swing.event.DocumentEvent;
39 import javax.swing.event.DocumentListener;
40 import javax.swing.text.JTextComponent;
45 import net.sf.japi.swing.action.ActionBuilder;
46 import net.sf.japi.swing.action.ActionBuilderFactory;
47 import net.sf.japi.swing.action.ActionMethod;
48 import org.jetbrains.annotations.NotNull;
49 import org.jetbrains.annotations.Nullable;
50 
55 public class MassChangeDialog {
56 
60  @NotNull
61  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
62 
66  @NotNull
67  private final JOptionPane optionPane = new JOptionPane();
68 
72  @NotNull
73  private final JButton okButton = new JButton(ACTION_BUILDER.createAction(false, "massChangeOkay", this));
74 
78  @NotNull
79  private final JButton cancelButton = new JButton(ACTION_BUILDER.createAction(false, "massChangeCancel", this));
80 
84  @NotNull
85  private final JTextComponent archNamesTextField = new JTextField(50);
86 
90  @NotNull
91  private final JTextComponent namesTextField = new JTextField(50);
92 
96  @NotNull
97  private final JTextComponent layersTextField = new JTextField(50);
98 
102  @NotNull
103  private final JTextComponent subLayersTextField = new JTextField(50);
104 
108  @Nullable
109  private JDialog dialog;
110 
114  @NotNull
115  private final JTextArea changesTextArea = new JTextArea();
116 
120  public MassChangeDialog() {
121  okButton.setDefaultCapable(true);
122  optionPane.setOptions(new Object[] { okButton, cancelButton });
123  final JPanel panel = new JPanel(new GridBagLayout());
124  final GridBagConstraints labelGbc = new GridBagConstraints();
125  labelGbc.anchor = GridBagConstraints.EAST;
126  labelGbc.insets = new Insets(2, 10, 2, 2);
127  final GridBagConstraints gbc = new GridBagConstraints();
128  gbc.insets = new Insets(2, 2, 2, 2);
129  gbc.fill = GridBagConstraints.HORIZONTAL;
130  gbc.gridwidth = GridBagConstraints.REMAINDER;
131  gbc.weightx = 2.0;
132  panel.setBorder(GUIConstants.DIALOG_BORDER);
133  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeArchNames.text"), labelGbc);
134  panel.add(archNamesTextField, gbc);
135  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeNames.text"), labelGbc);
136  panel.add(namesTextField, gbc);
137  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeLayers.text"), labelGbc);
138  panel.add(layersTextField, gbc);
139  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeSubLayers.text"), labelGbc);
140  panel.add(subLayersTextField, gbc);
141  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeText.text"), labelGbc);
142  changesTextArea.setRows(10);
143  changesTextArea.setColumns(50);
144  final JScrollPane scrollPane = new JScrollPane(changesTextArea);
145  panel.add(scrollPane, gbc);
146  panel.add(Box.createVerticalStrut(5));
147  optionPane.setMessage(panel);
148 
153  final DocumentListener documentListener = new DocumentListener() {
154 
155  @Override
156  public void insertUpdate(@NotNull final DocumentEvent e) {
157  updateOkButton();
158  }
159 
160  @Override
161  public void removeUpdate(@NotNull final DocumentEvent e) {
162  updateOkButton();
163  }
164 
165  @Override
166  public void changedUpdate(@NotNull final DocumentEvent e) {
167  updateOkButton();
168  }
169 
170  };
171 
172  changesTextArea.getDocument().addDocumentListener(documentListener);
173  }
174 
179  @NotNull
180  private final WindowListener windowListener = new WindowListener() {
181 
182  @Override
183  public void windowOpened(@NotNull final WindowEvent e) {
184  // ignore
185  }
186 
187  @Override
188  public void windowClosing(@NotNull final WindowEvent e) {
189  // ignore
190  }
191 
192  @Override
193  public void windowClosed(@NotNull final WindowEvent e) {
194  // ignore
195  }
196 
197  @Override
198  public void windowIconified(@NotNull final WindowEvent e) {
199  // ignore
200  }
201 
202  @Override
203  public void windowDeiconified(@NotNull final WindowEvent e) {
204  // ignore
205  }
206 
207  @Override
208  public void windowActivated(@NotNull final WindowEvent e) {
209  changesTextArea.requestFocusInWindow();
210  assert dialog != null;
211  dialog.removeWindowListener(windowListener);
212  }
213 
214  @Override
215  public void windowDeactivated(@NotNull final WindowEvent e) {
216  // ignore
217  }
218 
219  };
220 
225  private void updateOkButton() {
226  okButton.setEnabled(isOkButtonEnabled());
227  }
228 
234  public boolean showMassChangeDialog(@NotNull final Component parent) {
235  final JDialog tmpDialog;
236  if (dialog == null) {
237  tmpDialog = optionPane.createDialog(parent, ActionBuilderUtils.getString(ACTION_BUILDER, "massChangeTitle"));
238  dialog = tmpDialog;
239  tmpDialog.getRootPane().setDefaultButton(okButton);
240  optionPane.selectInitialValue();
241  tmpDialog.setModalityType(ModalityType.DOCUMENT_MODAL);
242  } else {
243  tmpDialog = dialog;
244  }
245  changesTextArea.setText("");
246  changesTextArea.setCaretPosition(0);
247  okButton.setEnabled(isOkButtonEnabled());
248  tmpDialog.addWindowListener(windowListener);
249  tmpDialog.setVisible(true);
250  tmpDialog.removeWindowListener(windowListener);
251  return optionPane.getValue() == okButton;
252  }
253 
257  @ActionMethod
258  public void massChangeOkay() {
259  if (isOkButtonEnabled()) {
260  optionPane.setValue(okButton);
261  }
262  }
263 
267  @ActionMethod
268  public void massChangeCancel() {
269  optionPane.setValue(cancelButton);
270  }
271 
276  private boolean isOkButtonEnabled() {
277  return !changesTextArea.getText().isEmpty();
278  }
279 
284  @NotNull
285  public String @NotNull [] getArchNames() {
286  final StringTokenizer st = new StringTokenizer(archNamesTextField.getText(), ",");
287  final String[] archNames = new String[st.countTokens()];
288 
289  for (int i = 0; st.hasMoreTokens(); i++) {
290  archNames[i] = st.nextToken();
291  }
292 
293  return archNames;
294  }
295 
300  @NotNull
301  public String @NotNull [] getNames() {
302  final StringTokenizer st = new StringTokenizer(namesTextField.getText(), ",");
303  final String[] names = new String[st.countTokens()];
304 
305  for (int i = 0; st.hasMoreTokens(); i++) {
306  names[i] = st.nextToken();
307  }
308 
309  return names;
310  }
311 
316  @NotNull
317  public Integer @NotNull [] getLayers() {
318  final StringTokenizer st = new StringTokenizer(layersTextField.getText(), ",");
319  final Integer[] layers = new Integer[st.countTokens()];
320 
321  for (int i = 0; st.hasMoreTokens(); i++) {
322  layers[i] = NumberUtils.parseInt(st.nextToken());
323  }
324 
325  return layers;
326  }
327 
332  @NotNull
333  public Integer @NotNull [] getSubLayers() {
334  final StringTokenizer st = new StringTokenizer(subLayersTextField.getText(), ",");
335  final Integer[] subLayers = new Integer[st.countTokens()];
336 
337  for (int i = 0; st.hasMoreTokens(); i++) {
338  subLayers[i] = NumberUtils.parseInt(st.nextToken());
339  }
340 
341  return subLayers;
342  }
343 
348  @NotNull
349  public String getChanges() {
350  return changesTextArea.getText();
351  }
352 
353 }
net.sf.gridarta.mainactions.MassChangeDialog.dialog
JDialog dialog
The JDialog instance or.
Definition: MassChangeDialog.java:109
net.sf.gridarta.utils.NumberUtils.parseInt
static int parseInt(@NotNull final String s)
Parses an integer string.
Definition: NumberUtils.java:41
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.gui.utils.GUIConstants
Defines common UI constants used in different dialogs.
Definition: GUIConstants.java:33
net.sf
net.sf.gridarta.mainactions.MassChangeDialog.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
Action Builder to create Actions.
Definition: MassChangeDialog.java:61
net.sf.gridarta.mainactions.MassChangeDialog.getSubLayers
Integer[] getSubLayers()
Returns the sub-layers to affect.
Definition: MassChangeDialog.java:333
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.gui
Graphical User Interface of Gridarta.
net.sf.gridarta.mainactions.MassChangeDialog.massChangeOkay
void massChangeOkay()
Action method to close the dialog with "OK".
Definition: MassChangeDialog.java:258
net.sf.gridarta.mainactions.MassChangeDialog.okButton
final JButton okButton
The "OK" button.
Definition: MassChangeDialog.java:73
net
net.sf.gridarta.mainactions.MassChangeDialog.changesTextArea
final JTextArea changesTextArea
The text area for specifying the changes to add.
Definition: MassChangeDialog.java:115
net.sf.gridarta.mainactions.MassChangeDialog.layersTextField
final JTextComponent layersTextField
The text field for specifying the layers to match.
Definition: MassChangeDialog.java:97
net.sf.gridarta.mainactions.MassChangeDialog.getLayers
Integer[] getLayers()
Returns the layers to affect.
Definition: MassChangeDialog.java:317
net.sf.gridarta.mainactions.MassChangeDialog
Displays a dialog asking for parameters for the "mass change" function.
Definition: MassChangeDialog.java:55
net.sf.gridarta.mainactions.MassChangeDialog.archNamesTextField
final JTextComponent archNamesTextField
The text field for specifying the arch names to match.
Definition: MassChangeDialog.java:85
net.sf.gridarta.mainactions.MassChangeDialog.getArchNames
String[] getArchNames()
Returns the arch names to affect.
Definition: MassChangeDialog.java:285
net.sf.gridarta.mainactions.MassChangeDialog.optionPane
final JOptionPane optionPane
The JOptionPane instance used to create dialogs.
Definition: MassChangeDialog.java:67
net.sf.gridarta.mainactions.MassChangeDialog.windowListener
final WindowListener windowListener
The WindowListener attached to dialog to call {} after the dialog has been shown.
Definition: MassChangeDialog.java:180
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.mainactions.MassChangeDialog.showMassChangeDialog
boolean showMassChangeDialog(@NotNull final Component parent)
Displays the mass change dialog.
Definition: MassChangeDialog.java:234
net.sf.gridarta.mainactions.MassChangeDialog.getNames
String[] getNames()
Returns the object names to affect.
Definition: MassChangeDialog.java:301
net.sf.gridarta.mainactions.MassChangeDialog.cancelButton
final JButton cancelButton
The "Cancel" button.
Definition: MassChangeDialog.java:79
net.sf.gridarta.mainactions.MassChangeDialog.getChanges
String getChanges()
Returns the actual changes to apply.
Definition: MassChangeDialog.java:349
net.sf.gridarta.mainactions.MassChangeDialog.subLayersTextField
final JTextComponent subLayersTextField
The text field for specifying the sub-layers to match.
Definition: MassChangeDialog.java:103
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.mainactions.MassChangeDialog.namesTextField
final JTextComponent namesTextField
The text field for specifying the object names to match.
Definition: MassChangeDialog.java:91
net.sf.gridarta.mainactions.MassChangeDialog.massChangeCancel
void massChangeCancel()
Action method to close the dialog with "Cancel".
Definition: MassChangeDialog.java:268
net.sf.gridarta.utils.ActionBuilderUtils
Utility class for ActionBuilder related functions.
Definition: ActionBuilderUtils.java:31
net.sf.gridarta.gui.utils
Definition: AnimationComponent.java:20
net.sf.gridarta.gui.utils.TextComponentUtils
Utility class for JTextComponent related functions.
Definition: TextComponentUtils.java:34
net.sf.gridarta.mainactions.MassChangeDialog.isOkButtonEnabled
boolean isOkButtonEnabled()
Returns whether the "OK" button is enabled.
Definition: MassChangeDialog.java:276
net.sf.gridarta.mainactions.MassChangeDialog.MassChangeDialog
MassChangeDialog()
Creates a new instance.
Definition: MassChangeDialog.java:120
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.mainactions.MassChangeDialog.updateOkButton
void updateOkButton()
Updates the enabled state of the "OK" button depending on the dialog's contents.
Definition: MassChangeDialog.java:225
net.sf.gridarta.gui.utils.GUIConstants.DIALOG_BORDER
Border DIALOG_BORDER
The Border object to be used when creating dialogs.
Definition: GUIConstants.java:38
net.sf.gridarta.utils.NumberUtils
Utility class for parsing strings into numbers.
Definition: NumberUtils.java:28