Gridarta Editor
ExportMapAsImageDialog.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.exportmap;
21 
22 import java.awt.EventQueue;
23 import java.awt.GridBagConstraints;
24 import java.awt.GridBagLayout;
25 import java.awt.Image;
26 import java.awt.image.BufferedImage;
27 import java.io.File;
28 import java.util.prefs.Preferences;
29 import java.util.regex.Pattern;
30 import javax.swing.AbstractButton;
31 import javax.swing.ImageIcon;
32 import javax.swing.JButton;
33 import javax.swing.JCheckBox;
34 import javax.swing.JDialog;
35 import javax.swing.JFileChooser;
36 import javax.swing.JFrame;
37 import javax.swing.JLabel;
38 import javax.swing.JOptionPane;
39 import javax.swing.JPanel;
40 import javax.swing.JProgressBar;
41 import javax.swing.WindowConstants;
42 import net.sf.gridarta.MainControl;
55 import net.sf.japi.swing.action.ActionBuilder;
56 import net.sf.japi.swing.action.ActionBuilderFactory;
57 import net.sf.japi.swing.action.ActionMethod;
58 import org.jetbrains.annotations.NotNull;
59 import org.jetbrains.annotations.Nullable;
60 
65 @SuppressWarnings("ThisEscapedInObjectConstruction")
66 public class ExportMapAsImageDialog<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> extends JOptionPane {
67 
71  private static final int PREVIEW_SIZE = 256;
72 
76  private static final long serialVersionUID = 1L;
77 
81  @NotNull
82  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
83 
87  @NotNull
88  protected static final Preferences PREFERENCES = Preferences.userNodeForPackage(MainControl.class);
89 
93  @NotNull
94  private static final Pattern PATTERN_PATH = Pattern.compile(".*/");
95 
99  @NotNull
101 
105  @NotNull
107 
111  @NotNull
112  private final JButton exportButton = new JButton(ACTION_BUILDER.createAction(false, "exportMapAsImageExport", this));
113 
117  @NotNull
118  private final JButton cancelButton = new JButton(ACTION_BUILDER.createAction(false, "exportMapAsImageCancel", this));
119 
123  @NotNull
124  private final JButton cancelExportButton = new JButton(ACTION_BUILDER.createAction(false, "exportMapAsImageCancelExport", this));
125 
129  @NotNull
130  private final JDialog dialog;
131 
135  @NotNull
136  private final AbstractButton includeTiledMapsCheckbox = new JCheckBox(ACTION_BUILDER.createToggle(false, "exportMapAsImageIncludeTiledMaps", this));
137 
141  @NotNull
143 
147  @NotNull
148  private final JLabel progressLabel = new JLabel();
149 
153  @NotNull
154  private final JProgressBar progressBar = new JProgressBar();
155 
159  @NotNull
160  private final JLabel previewLabel = new JLabel();
161 
165  @NotNull
166  private final JLabel previewImage = new JLabel();
167 
171  private boolean includeTiledMaps = true;
172 
176  private volatile boolean cancelExport;
177 
184  public ExportMapAsImageDialog(@NotNull final JFrame parent, @NotNull final ExportMapAsImageAction<G, A, R> exportMapAsImageAction, @NotNull final MapControl<G, A, R> mapControl) {
185  this.exportMapAsImageAction = exportMapAsImageAction;
186  this.mapControl = mapControl;
187  exportButton.setDefaultCapable(true);
188  final MapFile mapFile = mapControl.getMapModel().getMapFile();
189  final File file;
190  if (mapFile == null) {
191  file = new File(System.getProperty("user.dir")).getAbsoluteFile();
192  } else {
193  final File mapsDir = mapFile.getMapsDir();
194  file = new File(new File(mapsDir, "images"), PATTERN_PATH.matcher(mapFile.getMapPath().getPath()).replaceAll("") + ".png");
195  }
196  outputFileField = new JFileField(this, "exportMapAsImageOutputFile", null, file, JFileChooser.FILES_ONLY | JFileChooser.SAVE_DIALOG);
197  previewImage.setIcon(new ImageIcon(new BufferedImage(PREVIEW_SIZE, PREVIEW_SIZE, BufferedImage.TYPE_INT_ARGB)));
198  cancelExportButton.setEnabled(false);
199  setOptions(new Object[] { exportButton, cancelButton, cancelExportButton });
200  setMessage(createPanel());
201 
202  dialog = createDialog(parent, ACTION_BUILDER.format("exportMapAsImageTitle"));
203  dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
204  dialog.getRootPane().setDefaultButton(exportButton);
205  dialog.setModal(false);
206  dialog.pack();
207  dialog.setVisible(true);
208  }
209 
214  @NotNull
215  public File getOutputFile() {
216  return outputFileField.getFile();
217  }
218 
223  @ActionMethod
224  public boolean isIncludeTiledMaps() {
225  return includeTiledMapsCheckbox.isSelected();
226  }
227 
232  @NotNull
233  private JPanel createPanel() {
234  final JPanel panel = new JPanel();
235  panel.setLayout(new GridBagLayout());
236  panel.setBorder(GUIConstants.DIALOG_BORDER);
237  final GridBagConstraints gbc = new GridBagConstraints();
238  gbc.gridx = 0;
239  gbc.fill = GridBagConstraints.HORIZONTAL;
240  gbc.anchor = GridBagConstraints.LINE_START;
241  final MapModel<G, A, R> mapModel = mapControl.getMapModel();
242  if (mapModel.getMapFile() != null) {
243  final A mapArchObject = mapModel.getMapArchObject();
244  for (final Direction direction : Direction.values()) {
245  if (!mapArchObject.getTilePath(direction).isEmpty()) {
246  includeTiledMapsCheckbox.setSelected(true);
247  panel.add(includeTiledMapsCheckbox, gbc);
248  break;
249  }
250  }
251  }
252  panel.add(ActionBuilderUtils.newLabel(ACTION_BUILDER, "exportMapAsImageOutputLabel"), gbc);
253  panel.add(outputFileField, gbc);
254  panel.add(progressLabel, gbc);
255  panel.add(progressBar, gbc);
256  panel.add(previewLabel, gbc);
257  panel.add(previewImage, gbc);
258  return panel;
259  }
260 
264  @ActionMethod
265  public void exportMapAsImageExport() {
266  final ExportMapProgress progress = new ExportMapProgress() {
267 
268  @Override
269  public void setMax(final int max) {
270  EventQueue.invokeLater(() -> {
271  progressLabel.setText(max + " tiled " + (max == 1 ? "map" : "maps"));
272  progressBar.setMaximum(max);
273  dialog.pack();
274  });
275  }
276 
277  @Override
278  public void setValue(final int value, @NotNull final BufferedImage image) {
279  EventQueue.invokeLater(() -> {
280  progressBar.setIndeterminate(false);
281  progressBar.setStringPainted(true);
282  progressBar.setValue(value);
283  previewLabel.setText(image.getWidth() + "x" + image.getHeight() + " pixels");
284  previewImage.setIcon(new ImageIcon(image.getScaledInstance(PREVIEW_SIZE, PREVIEW_SIZE, Image.SCALE_DEFAULT)));
285  dialog.pack();
286  });
287  }
288 
289  @Override
290  public boolean cancel() {
291  return cancelExport;
292  }
293 
294  };
295  final Runnable runnable = () -> {
296  final boolean ok = exportMapAsImageAction.exportMap(mapControl, includeTiledMaps, outputFileField.getFile(), progress);
297  EventQueue.invokeLater(() -> {
298  setValue(ok ? exportButton : UNINITIALIZED_VALUE);
299  includeTiledMapsCheckbox.setEnabled(true);
300  outputFileField.setEnabled(true);
301  progressBar.setIndeterminate(false);
302  progressBar.setStringPainted(false);
303  progressBar.setMinimum(0);
304  progressBar.setMaximum(1);
305  progressBar.setValue(0);
306  cancelExportButton.setEnabled(false);
307  exportButton.setEnabled(true);
308  dialog.pack();
309  });
310  };
311  includeTiledMapsCheckbox.setEnabled(false);
312  outputFileField.setEnabled(false);
313  progressLabel.setText("");
314  progressBar.setIndeterminate(true);
315  progressBar.setValue(0);
316  progressBar.setMaximum(0);
317  progressBar.setStringPainted(false);
318  previewLabel.setText("");
319  previewImage.setIcon(new ImageIcon(new BufferedImage(PREVIEW_SIZE, PREVIEW_SIZE, BufferedImage.TYPE_INT_ARGB)));
320  cancelExportButton.setEnabled(true);
321  exportButton.setEnabled(false);
322  dialog.pack();
323  cancelExport = false;
324  final Thread thread = new Thread(runnable, "Map Exporter Thread");
325  thread.setDaemon(true);
326  thread.start();
327  }
328 
332  @ActionMethod
333  public void exportMapAsImageCancel() {
334  setValue(cancelButton);
335  }
336 
340  @ActionMethod
342  setValue(UNINITIALIZED_VALUE);
343  }
344 
345  @Override
346  public void setValue(@Nullable final Object newValue) {
347  super.setValue(newValue);
348  cancelExport = true;
349  if (newValue != UNINITIALIZED_VALUE) {
350  dialog.dispose();
351  }
352  }
353 
358  @ActionMethod
360  return includeTiledMaps;
361  }
362 
367  public void setExportMapAsImageIncludeTiledMaps(final boolean includeTiledMaps) {
368  includeTiledMapsCheckbox.setSelected(includeTiledMaps);
369  this.includeTiledMaps = includeTiledMaps;
370  }
371 
372 }
net.sf.gridarta.model.direction.Direction
A direction.
Definition: Direction.java:28
net.sf.gridarta.model.mapmodel.MapModel
A MapModel reflects the data of a map.
Definition: MapModel.java:75
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.setExportMapAsImageIncludeTiledMaps
void setExportMapAsImageIncludeTiledMaps(final boolean includeTiledMaps)
Sets whether to include tiled maps in the image.
Definition: ExportMapAsImageDialog.java:367
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.ExportMapAsImageDialog
ExportMapAsImageDialog(@NotNull final JFrame parent, @NotNull final ExportMapAsImageAction< G, A, R > exportMapAsImageAction, @NotNull final MapControl< G, A, R > mapControl)
Creates a new instance.
Definition: ExportMapAsImageDialog.java:184
net.sf.gridarta.model.mapmodel.MapModel.getMapArchObject
A getMapArchObject()
Returns the Map Arch Object with the meta information about the map.
net.sf.gridarta.model.mapmodel.AbsoluteMapPath.getPath
String getPath()
Returns the map path information.
Definition: AbsoluteMapPath.java:80
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog
Dialog to export a new map file into an image file.
Definition: ExportMapAsImageDialog.java:66
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.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.getOutputFile
File getOutputFile()
Returns the file for saving the image file.
Definition: ExportMapAsImageDialog.java:215
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.isExportMapAsImageIncludeTiledMaps
boolean isExportMapAsImageIncludeTiledMaps()
Returns whether tiled maps are included in the image.
Definition: ExportMapAsImageDialog.java:359
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.cancelExport
volatile boolean cancelExport
Whether the currently running export operation should be cancelled.
Definition: ExportMapAsImageDialog.java:176
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.dialog
final JDialog dialog
The dialog instance.
Definition: ExportMapAsImageDialog.java:130
net.sf
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.createPanel
JPanel createPanel()
Creates the content panel of the dialog.
Definition: ExportMapAsImageDialog.java:233
net.sf.gridarta.model.mapmodel
Definition: AboveFloorInsertionMode.java:20
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.mapControl
final MapControl< G, A, R > mapControl
The map to export.
Definition: ExportMapAsImageDialog.java:106
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.exportMapAsImageCancelExport
void exportMapAsImageCancelExport()
Action method for cancel export.
Definition: ExportMapAsImageDialog.java:341
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.exportmap.ExportMapAsImageDialog.outputFileField
final JFileField outputFileField
The file name of the image file.
Definition: ExportMapAsImageDialog.java:142
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.mapmodel.MapFile.getMapPath
AbsoluteMapPath getMapPath()
Returns the map path within getMapsDir().
Definition: MapFile.java:93
net.sf.gridarta.gui
Graphical User Interface of Gridarta.
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.setValue
void setValue(@Nullable final Object newValue)
Definition: ExportMapAsImageDialog.java:346
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.exportMapAsImageAction
final ExportMapAsImageAction< G, A, R > exportMapAsImageAction
The action to use for exporting the map.
Definition: ExportMapAsImageDialog.java:100
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.exportmap.ExportMapAsImageDialog.exportMapAsImageCancel
void exportMapAsImageCancel()
Action method for cancel.
Definition: ExportMapAsImageDialog.java:333
net.sf.gridarta.action.exportmap.ExportMapProgress
Interface for receiving progress information while the map is exported.
Definition: ExportMapProgress.java:28
net.sf.gridarta.action.exportmap
Classes which implement the {} action.
Definition: ExportMapAsImageAction.java:20
net.sf.gridarta.model.mapmodel.MapFile.getMapsDir
File getMapsDir()
Returns the base directory this map file is part of.
Definition: MapFile.java:84
net.sf.gridarta.gui.utils.JFileField
A component for selecting files.
Definition: JFileField.java:45
net.sf.gridarta.model.maparchobject.MapArchObject
Interface for MapArchObjects.
Definition: MapArchObject.java:40
net.sf.gridarta.model.mapmodel.MapFile
The location of a map file with a map directory.
Definition: MapFile.java:31
net.sf.gridarta.action.exportmap.ExportMapAsImageAction.exportMap
boolean exportMap(@NotNull final MapControl< G, A, R > mapControl, final boolean includeTiledMaps, @NotNull final File file, @NotNull final ExportMapProgress progress)
Exports a map as an image file.
Definition: ExportMapAsImageAction.java:181
net.sf.gridarta.model
net.sf.gridarta.model.archetype.Archetype
Reflects an Archetype.
Definition: Archetype.java:41
net.sf.gridarta.model.mapcontrol.MapControl
Currently nothing more than a marker interface for unification.
Definition: MapControl.java:35
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.action
Definition: AbstractMapCursorAction.java:20
net.sf.gridarta.model.maparchobject
Definition: AbstractMapArchObject.java:20
net.sf.gridarta.gui.utils
Definition: AnimationComponent.java:20
net.sf.gridarta.model.mapmodel.MapModel.getMapFile
MapFile getMapFile()
Returns the map file.
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.exportMapAsImageExport
void exportMapAsImageExport()
Action method for okay.
Definition: ExportMapAsImageDialog.java:265
net.sf.gridarta.gui.dialog.exportmap.ExportMapAsImageDialog.isIncludeTiledMaps
boolean isIncludeTiledMaps()
Returns whether to include tiled maps in the image file.
Definition: ExportMapAsImageDialog.java:224
net.sf.gridarta.gui.utils.JFileField.setEnabled
void setEnabled(final boolean enabled)
Definition: JFileField.java:176
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.action.exportmap.ExportMapAsImageAction
An EditorAction that runs the map export on the current map.
Definition: ExportMapAsImageAction.java:47
net.sf.gridarta.model.direction
Definition: Direction.java:20
net.sf.gridarta.gui.utils.JFileField.getFile
File getFile()
Returns the currently selected file.
Definition: JFileField.java:113
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.MainControl
Interface used as preferences location.
Definition: MainControl.java:27