Gridarta Editor
AbstractMapTilePane.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.gui.map.maptilepane;
21 
22 import java.awt.Component;
23 import java.awt.GridBagConstraints;
24 import java.awt.GridBagLayout;
25 import java.io.File;
26 import javax.swing.BorderFactory;
27 import javax.swing.JButton;
28 import javax.swing.JComponent;
29 import javax.swing.JPanel;
30 import javax.swing.border.CompoundBorder;
31 import javax.swing.filechooser.FileFilter;
50 import net.sf.japi.swing.action.ActionBuilder;
51 import net.sf.japi.swing.action.ActionBuilderFactory;
52 import net.sf.japi.swing.action.ActionMethod;
53 import org.jetbrains.annotations.NotNull;
54 
65 public abstract class AbstractMapTilePane<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> extends JPanel {
66 
70  private static final long serialVersionUID = 1L;
71 
75  @NotNull
76  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
77 
81  @NotNull
83 
87  @NotNull
88  private final MapModel<G, A, R> mapModel;
89 
93  @NotNull
95 
99  @NotNull
100  private final TileLink[] tileLinks;
101 
105  @NotNull
106  private final int[] nextFocus;
107 
111  @NotNull
112  private final FileFilter mapFileFilter;
113 
117  @NotNull
118  private final MapTilePanel[] tilePaths;
119 
120  @NotNull
122 
126  private final boolean canAttachMaps;
127 
138  protected AbstractMapTilePane(@NotNull final MapManager<G, A, R> mapManager, @NotNull final ProjectSettings projectSettings, @NotNull final MapModel<G, A, R> mapModel, @NotNull final MapLink[][] tileLink, @NotNull final Direction[] directionMapping, @NotNull final int[] nextFocus, @NotNull final FileFilter mapFileFilter) {
139  this.projectSettings = projectSettings;
140  this.mapModel = mapModel;
141  this.nextFocus = nextFocus.clone();
142  this.mapFileFilter = mapFileFilter;
143  assert tileLink.length == 10;
144  tileLinks = new TileLink[] { newTileLink("mapNorth", tileLink[0], Direction.SOUTH), newTileLink("mapEast", tileLink[1], Direction.WEST), newTileLink("mapSouth", tileLink[2], Direction.NORTH), newTileLink("mapWest", tileLink[3], Direction.EAST), newTileLink("mapNorthEast", tileLink[4], Direction.SOUTH_WEST), newTileLink("mapSouthEast", tileLink[5], Direction.NORTH_WEST), newTileLink("mapSouthWest", tileLink[6], Direction.NORTH_EAST), newTileLink("mapNorthWest", tileLink[7], Direction.SOUTH_EAST), newTileLink("mapUp", tileLink[8], Direction.DOWN), newTileLink("mapDown", tileLink[9], Direction.UP) };
145  attachTiledMaps = new AttachTiledMaps<>(mapManager, tileLinks);
146  canAttachMaps = tileLink[0].length + tileLink[1].length + tileLink[2].length + tileLink[3].length + tileLink[4].length + tileLink[5].length + tileLink[6].length + tileLink[7].length + tileLink[8].length + tileLink[9].length > 0;
147  mapArchObject = mapModel.getMapArchObject();
148  tilePaths = buildComponents(directionMapping);
149  }
150 
157  @NotNull
158  private static TileLink newTileLink(@NotNull final String key, @NotNull final MapLink[] mapLinks, @NotNull final Direction revLink) {
159  return new TileLink(ActionBuilderUtils.getString(ACTION_BUILDER, key), mapLinks, revLink);
160  }
161 
167  private MapTilePanel[] buildComponents(@NotNull final Direction[] directionMapping) {
168  setLayout(new GridBagLayout());
169  final GridBagConstraints gbc = new GridBagConstraints();
170  gbc.gridwidth = GridBagConstraints.REMAINDER;
171  gbc.weightx = 1.0;
172  gbc.fill = GridBagConstraints.BOTH;
173  final MapTilePanel[] tilePanels = createTilePanels(directionMapping.length);
174  add(buildTilePanels(tilePanels, directionMapping), gbc);
175  add(buildSubPanel(), gbc);
176  return tilePanels;
177  }
178 
184  @NotNull
185  private MapTilePanel[] createTilePanels(final int directions) {
186  final MapTilePanel[] tilePanels = new MapTilePanel[directions];
187  for (int index = 0; index < tilePanels.length; index++) {
188  final File mapDir = projectSettings.getMapsDirectory();
189  final MapFile mapFile = mapModel.getMapFile();
190  final TilePanel tilePanel = new TilePanel(mapFileFilter, mapArchObject.getTilePath(Direction.values()[index]), mapFile == null ? null : mapFile.getFile(), mapDir);
191  tilePanels[index] = new MapTilePanel(index, nextFocus, tilePanel, tileLinks[index].getName());
192  }
193  return tilePanels;
194  }
195 
202  @NotNull
203  private static Component buildTilePanels(@NotNull final MapTilePanel[] tilePanels, @NotNull final Direction[] directionMapping) {
204  final JComponent panel = new JPanel(new DirectionLayout());
205  panel.setBorder(new CompoundBorder(BorderFactory.createTitledBorder(ActionBuilderUtils.getString(ACTION_BUILDER, "mapTiles")), GUIConstants.DIALOG_BORDER));
206  for (int index = 0; index < tilePanels.length; index++) {
207  panel.add(tilePanels[index].getTilePanel(), directionMapping[index]);
208  }
209  return panel;
210  }
211 
217  @NotNull
218  private Component buildSubPanel() {
219  final JComponent subPanel = new JPanel(new GridBagLayout());
220  subPanel.setBorder(new CompoundBorder(BorderFactory.createTitledBorder(ActionBuilderUtils.getString(ACTION_BUILDER, "mapControl")), GUIConstants.DIALOG_BORDER));
221  final GridBagConstraints gbc = new GridBagConstraints();
222  gbc.fill = GridBagConstraints.NONE;
223  gbc.weightx = 1.0;
224  gbc.weighty = 1.0;
225  if (canAttachMaps) {
226  gbc.anchor = GridBagConstraints.EAST;
227  subPanel.add(new JButton(ACTION_BUILDER.createAction(false, "mapTilesAttach", this)), gbc);
228  }
229  gbc.gridwidth = GridBagConstraints.REMAINDER;
230  gbc.anchor = canAttachMaps ? GridBagConstraints.WEST : GridBagConstraints.CENTER;
231  subPanel.add(new JButton(ACTION_BUILDER.createAction(false, "mapTilesClear", this)), gbc);
232  return subPanel;
233  }
234 
238  @ActionMethod
239  public void mapTilesAttach() {
240  final String[] tmpTilePaths = new String[tilePaths.length];
241  for (int i = 0; i < tmpTilePaths.length; i++) {
242  tmpTilePaths[i] = tilePaths[i].getTilePanel().getText();
243  }
244  final File mapsDirectory = projectSettings.getMapsDirectory();
245  try {
246  attachTiledMaps.attachTiledMaps(mapModel, tmpTilePaths, mapsDirectory, true);
247  } catch (final CannotLoadMapFileException ex) {
248  ACTION_BUILDER.showMessageDialog(this, "mapErrorPath2", ex.getMapPath()); // XXX: ignores ex.getMessage()
249  return;
250  } catch (final CannotSaveMapFileException ex) {
251  ACTION_BUILDER.showMessageDialog(this, "mapErrorFatalWrite", ex.getMessage()); // XXX: ignores ex.getMapFile()
252  return;
253  } catch (final MapSizeMismatchException ex) {
254  ACTION_BUILDER.showMessageDialog(this, "mapErrorDifferentSize", mapModel.getMapArchObject().getMapName(), ex.getMapSize().getWidth(), ex.getMapSize().getHeight(), ex.getMapFile(), ex.getOtherMapSize().getWidth(), ex.getOtherMapSize().getHeight());
255  return;
256  } catch (final UnsavedMapException ignored) {
257  ACTION_BUILDER.showMessageDialog(this, "mapErrorUnsaved");
258  return;
259  }
260  for (int i = 0; i < tmpTilePaths.length; i++) {
261  tilePaths[i].getTilePanel().setText(tmpTilePaths[i], true);
262  }
263  }
264 
268  @ActionMethod
269  public void mapTilesClear() {
270  for (final MapTilePanel tilePath : tilePaths) {
271  tilePath.getTilePanel().setText("", true);
272  }
273  }
274 
279  public void modifyMapProperties() {
280  for (int i = 0; i < tilePaths.length; i++) {
281  mapArchObject.setTilePath(Direction.values()[i], tilePaths[i].getTilePanel().getText());
282  }
283  }
284 
288  public void restoreMapProperties() {
289  for (final MapTilePanel tilePath : tilePaths) {
290  tilePath.getTilePanel().mapTileRevert();
291  }
292  }
293 
299  @NotNull
300  public MapTilePanel getTilePath(final int direction) {
301  return tilePaths[direction];
302  }
303 
304 }
Size2D getMapSize()
Returns the size of the first map.
A MapTilePanel extends a TilePanel with a border and makes focus traversal work within the map tile p...
Component buildSubPanel()
Creates the sub-panel that holds the buttons to attach maps or clear all paths.
A MapModel reflects the data of a map.
Definition: MapModel.java:75
A MapManager manages all opened maps.
Definition: MapManager.java:37
Graphical User Interface of Gridarta.
void restoreMapProperties()
Restores the settings from the map.
final TileLink [] tileLinks
The tile links for the attach map algorithm.
Settings that apply to a project.
AbstractMapTilePane(@NotNull final MapManager< G, A, R > mapManager, @NotNull final ProjectSettings projectSettings, @NotNull final MapModel< G, A, R > mapModel, @NotNull final MapLink[][] tileLink, @NotNull final Direction[] directionMapping, @NotNull final int[] nextFocus, @NotNull final FileFilter mapFileFilter)
Create an AbstractMapTilePane.
Exception thrown if a map file cannot be saved.
static Component buildTilePanels(@NotNull final MapTilePanel[] tilePanels, @NotNull final Direction[] directionMapping)
Builds the tile panel.
A tile panel displays exactly one direction for map tiling.
Definition: TilePanel.java:52
static final long serialVersionUID
Serial Version UID.
final ProjectSettings projectSettings
The project settings instance.
void attachTiledMaps(@NotNull final MapModel< G, A, R > mapModel, @NotNull final String[] tilePaths, @NotNull final File mapsDirectory, final boolean performAction)
Updates tile paths of a map.
static TileLink newTileLink(@NotNull final String key, @NotNull final MapLink[] mapLinks, @NotNull final Direction revLink)
Creates a new TileLink.
MapTilePanel getTilePath(final int direction)
Returns one tile path.
MapTilePanel [] buildComponents(@NotNull final Direction[] directionMapping)
Builds the components of this panel.
static String getString(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final String defaultValue)
Returns the value of a key.
Exception thrown if a map file cannot be loaded.
Base package of all Gridarta classes.
void mapTilesAttach()
Action method for tiles attaching automatically.
Size2D getOtherMapSize()
Returns the size of the second map.
Reflects a game object (object on a map).
Definition: GameObject.java:36
static final ActionBuilder ACTION_BUILDER
Action Builder.
final MapModel< G, A, R > mapModel
The map in context.
void setText(@NotNull final String text, final boolean keepRA)
Sets the text.
Definition: TilePanel.java:219
final MapTilePanel [] tilePaths
The JTextFields with the tile paths.
GameObjects are the objects based on Archetypes found on maps.
int getWidth()
Returns the width of the area.
Definition: Size2D.java:96
void modifyMapProperties()
Invoke this method if the dialog using this pane is confirmed with OK to write the information from t...
Utility class for ActionBuilder related functions.
File getMapFile()
Returns the map File of the first map.
A getMapArchObject()
Returns the Map Arch Object with the meta information about the map.
final FileFilter mapFileFilter
Swing FileFilter for map files.
Exception thrown if an operation is attempted on an unsaved map.
MapTilePanel [] createTilePanels(final int directions)
Builds all MapTilePanels for all directions.
final boolean canAttachMaps
Whether "attach maps" function is available.
void mapTilesClear()
Action method for tiles clearing paths.
MapFile getMapFile()
Returns the map file.
Border DIALOG_BORDER
The Border object to be used when creating dialogs.
File getFile()
Returns a File for this map file.
Definition: MapFile.java:102
File getMapsDirectory()
Returns the default maps directory.
void setTilePath(@NotNull Direction direction, @NotNull String tilePath)
Sets a tile path.
int getHeight()
Returns the height of the area.
Definition: Size2D.java:104
String getTilePath(@NotNull Direction direction)
Returns a tile path.
The location of a map file with a map directory.
Definition: MapFile.java:31
Exception thrown if the size of a map file is unexpected.
Defines common UI constants used in different dialogs.
final MapArchObject< A > mapArchObject
The MapArchObject to show.
Attaches maps to adjacent tiled maps.
This class implements a layout that is similar to java.awt.BorderLayout but implements those directio...
String getMapPath()
Returns the map path that could not be loaded.