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-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.mainactions;
21 
22 import java.awt.Component;
23 import java.awt.Dialog;
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 
109  @Nullable
110  private JDialog dialog;
111 
115  @NotNull
116  private final JTextArea changesTextArea = new JTextArea();
117 
121  public MassChangeDialog() {
122  okButton.setDefaultCapable(true);
123  optionPane.setOptions(new Object[] { okButton, cancelButton });
124  final JPanel panel = new JPanel(new GridBagLayout());
125  final GridBagConstraints labelGbc = new GridBagConstraints();
126  labelGbc.anchor = GridBagConstraints.EAST;
127  labelGbc.insets = new Insets(2, 10, 2, 2);
128  final GridBagConstraints gbc = new GridBagConstraints();
129  gbc.insets = new Insets(2, 2, 2, 2);
130  gbc.fill = GridBagConstraints.HORIZONTAL;
131  gbc.gridwidth = GridBagConstraints.REMAINDER;
132  gbc.weightx = 2.0;
133  panel.setBorder(GUIConstants.DIALOG_BORDER);
134  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeArchNames.text"), labelGbc);
135  panel.add(archNamesTextField, gbc);
136  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeNames.text"), labelGbc);
137  panel.add(namesTextField, gbc);
138  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeLayers.text"), labelGbc);
139  panel.add(layersTextField, gbc);
140  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeSubLayers.text"), labelGbc);
141  panel.add(subLayersTextField, gbc);
142  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "massChangeText.text"), labelGbc);
143  changesTextArea.setRows(10);
144  changesTextArea.setColumns(50);
145  final JScrollPane scrollPane = new JScrollPane(changesTextArea);
146  panel.add(scrollPane, gbc);
147  panel.add(Box.createVerticalStrut(5));
148  optionPane.setMessage(panel);
149 
150  TextComponentUtils.setAutoSelectOnFocus(archNamesTextField);
152  TextComponentUtils.setAutoSelectOnFocus(layersTextField);
153  TextComponentUtils.setAutoSelectOnFocus(subLayersTextField);
154  final DocumentListener documentListener = new DocumentListener() {
155 
156  @Override
157  public void insertUpdate(@NotNull final DocumentEvent e) {
158  updateOkButton();
159  }
160 
161  @Override
162  public void removeUpdate(@NotNull final DocumentEvent e) {
163  updateOkButton();
164  }
165 
166  @Override
167  public void changedUpdate(@NotNull final DocumentEvent e) {
168  updateOkButton();
169  }
170 
171  };
172 
173  changesTextArea.getDocument().addDocumentListener(documentListener);
174  }
175 
181  @NotNull
182  private final WindowListener windowListener = new WindowListener() {
183 
184  @Override
185  public void windowOpened(@NotNull final WindowEvent e) {
186  // ignore
187  }
188 
189  @Override
190  public void windowClosing(@NotNull final WindowEvent e) {
191  // ignore
192  }
193 
194  @Override
195  public void windowClosed(@NotNull final WindowEvent e) {
196  // ignore
197  }
198 
199  @Override
200  public void windowIconified(@NotNull final WindowEvent e) {
201  // ignore
202  }
203 
204  @Override
205  public void windowDeiconified(@NotNull final WindowEvent e) {
206  // ignore
207  }
208 
209  @Override
210  public void windowActivated(@NotNull final WindowEvent e) {
211  changesTextArea.requestFocusInWindow();
212  assert dialog != null;
213  dialog.removeWindowListener(windowListener);
214  }
215 
216  @Override
217  public void windowDeactivated(@NotNull final WindowEvent e) {
218  // ignore
219  }
220 
221  };
222 
227  private void updateOkButton() {
228  okButton.setEnabled(isOkButtonEnabled());
229  }
230 
236  public boolean showMassChangeDialog(@NotNull final Component parent) {
237  final JDialog tmpDialog;
238  if (dialog == null) {
239  tmpDialog = optionPane.createDialog(parent, ActionBuilderUtils.getString(ACTION_BUILDER, "massChangeTitle"));
240  dialog = tmpDialog;
241  tmpDialog.getRootPane().setDefaultButton(okButton);
242  optionPane.selectInitialValue();
243  tmpDialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
244  } else {
245  tmpDialog = dialog;
246  }
247  changesTextArea.setText("");
248  changesTextArea.setCaretPosition(0);
249  okButton.setEnabled(isOkButtonEnabled());
250  tmpDialog.addWindowListener(windowListener);
251  tmpDialog.setVisible(true);
252  tmpDialog.removeWindowListener(windowListener);
253  return optionPane.getValue() == okButton;
254  }
255 
259  @ActionMethod
260  public void massChangeOkay() {
261  if (isOkButtonEnabled()) {
262  optionPane.setValue(okButton);
263  }
264  }
265 
269  @ActionMethod
270  public void massChangeCancel() {
271  optionPane.setValue(cancelButton);
272  }
273 
278  private boolean isOkButtonEnabled() {
279  return !changesTextArea.getText().isEmpty();
280  }
281 
286  @NotNull
287  public String[] getArchNames() {
288  final StringTokenizer st = new StringTokenizer(archNamesTextField.getText(), ",");
289  final String[] archNames = new String[st.countTokens()];
290 
291  for (int i = 0; st.hasMoreTokens(); i++) {
292  archNames[i] = st.nextToken();
293  }
294 
295  return archNames;
296  }
297 
302  @NotNull
303  public String[] getNames() {
304  final StringTokenizer st = new StringTokenizer(namesTextField.getText(), ",");
305  final String[] names = new String[st.countTokens()];
306 
307  for (int i = 0; st.hasMoreTokens(); i++) {
308  names[i] = st.nextToken();
309  }
310 
311  return names;
312  }
313 
318  @NotNull
319  public Integer[] getLayers() {
320  final StringTokenizer st = new StringTokenizer(layersTextField.getText(), ",");
321  final Integer[] layers = new Integer[st.countTokens()];
322 
323  for (int i = 0; st.hasMoreTokens(); i++) {
324  layers[i] = NumberUtils.parseInt(st.nextToken());
325  }
326 
327  return layers;
328  }
329 
334  @NotNull
335  public Integer[] getSubLayers() {
336  final StringTokenizer st = new StringTokenizer(subLayersTextField.getText(), ",");
337  final Integer[] subLayers = new Integer[st.countTokens()];
338 
339  for (int i = 0; st.hasMoreTokens(); i++) {
340  subLayers[i] = NumberUtils.parseInt(st.nextToken());
341  }
342 
343  return subLayers;
344  }
345 
350  @NotNull
351  public String getChanges() {
352  return changesTextArea.getText();
353  }
354 
355 }
final JTextArea changesTextArea
The text area for specifying the changes to add.
Displays a dialog asking for parameters for the "mass change" function.
String [] getArchNames()
Returns the arch names to affect.
Graphical User Interface of Gridarta.
boolean showMassChangeDialog(@NotNull final Component parent)
Displays the mass change dialog.
Utility class for parsing strings into numbers.
void massChangeCancel()
Action method to close the dialog with "Cancel".
Integer [] getLayers()
Returns the layers to affect.
final JTextComponent namesTextField
The text field for specifying the object names to match.
boolean isOkButtonEnabled()
Returns whether the "OK" button is enabled.
static String getString(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final String defaultValue)
Returns the value of a key.
static final ActionBuilder ACTION_BUILDER
Action Builder to create Actions.
Base package of all Gridarta classes.
Utility class for JTextComponent related functions.
static int parseInt(@NotNull final String s)
Parses an integer string.
JDialog dialog
The javax.swing.JDialog instance or.
final JTextComponent layersTextField
The text field for specifying the layers to match.
final JTextComponent subLayersTextField
The text field for specifying the sub-layers to match.
String [] getNames()
Returns the object names to affect.
static void setAutoSelectOnFocus(@NotNull final JTextComponent textComponent)
Selects all text of a JTextComponent when the component gains the focus.
final JTextComponent archNamesTextField
The text field for specifying the arch names to match.
Utility class for ActionBuilder related functions.
void massChangeOkay()
Action method to close the dialog with "OK".
String getChanges()
Returns the actual changes to apply.
Border DIALOG_BORDER
The Border object to be used when creating dialogs.
static JLabel newLabel(@NotNull final ActionBuilder actionBuilder, @NotNull final String key)
Creates a new JLabel from a resource key.
void updateOkButton()
Updates the enabled state of the "OK" button depending on the dialog's contents.
final JOptionPane optionPane
The javax.swing.JOptionPane instance used to create dialogs.
final WindowListener windowListener
The java.awt.event.WindowListener attached to dialog to call javax.swing.JOptionPane#selectInitialVal...
final JButton cancelButton
The "Cancel" button.
Integer [] getSubLayers()
Returns the sub-layers to affect.
Defines common UI constants used in different dialogs.