Gridarta Editor
CFTreasureListTree.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.treasurelist;
21 
22 import java.awt.BorderLayout;
23 import java.awt.Component;
24 import java.awt.Container;
25 import java.awt.Frame;
26 import javax.swing.AbstractButton;
27 import javax.swing.BorderFactory;
28 import javax.swing.JButton;
29 import javax.swing.JDialog;
30 import javax.swing.JPanel;
31 import javax.swing.JScrollPane;
32 import javax.swing.JSplitPane;
33 import javax.swing.JTree;
34 import javax.swing.JViewport;
35 import javax.swing.ScrollPaneConstants;
36 import javax.swing.WindowConstants;
37 import javax.swing.text.JTextComponent;
38 import javax.swing.tree.DefaultMutableTreeNode;
39 import javax.swing.tree.TreeNode;
40 import javax.swing.tree.TreePath;
49 import net.sf.japi.swing.action.ActionBuilder;
50 import net.sf.japi.swing.action.ActionBuilderFactory;
51 import org.jetbrains.annotations.NotNull;
52 import org.jetbrains.annotations.Nullable;
53 
61 public class CFTreasureListTree extends JTree {
62 
66  @NotNull
67  public static final String NONE_SYM = "<none>";
68 
72  @NotNull
73  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
74 
78  private static final long serialVersionUID = 1L;
79 
83  @NotNull
84  private final TreasureTree treasureTree;
85 
90  @NotNull
91  private final Frame parent;
92 
97  @Nullable
98  private JDialog frame;
99 
104  @NotNull
105  private final AbstractButton okButton = new JButton("Select");
106 
111  @NotNull
112  private final AbstractButton noneButton = new JButton("None");
113 
118  @Nullable
119  private JTextComponent input;
120 
130  public CFTreasureListTree(@NotNull final TreasureTree treasureTree, @NotNull final Frame parent, @NotNull final ArchetypeSet<?, ?, ?> archetypeSet, @NotNull final FaceObjectProviders faceObjectProviders, @NotNull final ResourceIcons resourceIcons) {
131  super(treasureTree.getRoot());
132  this.treasureTree = treasureTree;
133  this.parent = parent;
134 
135  final FaceObjectProvidersListener faceObjectProvidersListener = this::repaint;
136  faceObjectProviders.addFaceObjectProvidersListener(faceObjectProvidersListener);
137 
138  putClientProperty("JTree.lineStyle", "Angled");
139  setCellRenderer(new TreasureCellRenderer(archetypeSet, treasureTree.getRoot(), faceObjectProviders, resourceIcons));
140  }
141 
151  public synchronized void showDialog(@Nullable final JTextComponent input, @NotNull final Component parent) {
152  this.input = input;
153 
154  final boolean hasBeenDisplayed = frame != null;
155  if (frame == null) {
156  // open a popup dialog which temporarily disables all other frames
157  frame = new JDialog(this.parent, "Treasurelists", false);
158  frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
159 
160  setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 5));
161  final JScrollPane scrollPane = new JScrollPane(this);
162  scrollPane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
163  scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
164  scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
165 
166  final JPanel buttonPanel = buildButtonPanel();
167  final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, buttonPanel);
168  splitPane.setOneTouchExpandable(false);
169  assert frame != null;
170  splitPane.setDividerLocation(frame.getHeight() - buttonPanel.getMinimumSize().height - 4);
171 
172  splitPane.setDividerSize(4);
173  splitPane.setResizeWeight(1.0);
174 
175  assert frame != null;
176  frame.getContentPane().add(splitPane);
177 
178  expandPath(new TreePath(treasureTree.getRoot()));
179  } else {
180  if (frame.isShowing()) {
181  assert frame != null;
182  frame.setVisible(false);
183  }
184 
185  // collapse everything except root
186  expandPath(new TreePath(treasureTree.getRoot()));
187  for (int i = getRowCount() - 1; i > 0; i--) {
188  collapseRow(i);
189  }
190  }
191 
192  okButton.setVisible(input != null);
193  noneButton.setVisible(input != null);
194 
195  assert frame != null;
196  frame.setSize(470, 550);
197  assert frame != null;
198  frame.setLocationRelativeTo(parent);
199 
200  if (input == null) {
201  scrollRowToVisible(0);
202  setSelectionPath(null);
203  } else {
204  final String listName = input.getText().trim(); // name of pre-selected list
205  final DefaultMutableTreeNode treasureNode = treasureTree.get(listName);
206  if (treasureNode == null) {
207  scrollRowToVisible(0);
208  setSelectionPath(null);
209  } else {
210  final DefaultMutableTreeNode[] node = new DefaultMutableTreeNode[2];
211  node[0] = treasureTree.getRoot();
212  node[1] = treasureNode;
213  final TreePath treePath = new TreePath(node);
214  expandPath(treePath);
215  setSelectionPath(treePath);
216 
217  if (!hasBeenDisplayed) {
218  // If this is the first time, the frame has to be packed,
219  // otherwise no scrolling would be possible (see below).
220  assert frame != null;
221  frame.pack();
222  assert frame != null;
223  frame.setSize(470, 550);
224  setSelectionPath(treePath);
225  }
226 
227  scrollRowToVisible(getRowCount() - 1);
228  scrollPathToVisible(treePath);
229  }
230  }
231  assert frame != null;
232  frame.setVisible(true);
233  }
234 
239  @NotNull
240  private JPanel buildButtonPanel() {
241  final JPanel buttonPanel = new JPanel(new BorderLayout());
242 
243  final Container leftSide = new JPanel();
244  final Container rightSide = new JPanel();
245 
246  okButton.addActionListener(e -> {
247  final String result = getSelectedTreasureList();
248  if (result != null) {
249  selectValue(result);
250  }
251  });
252  rightSide.add(okButton);
253 
254  noneButton.addActionListener(e -> selectValue(NONE_SYM)); // print "none" into the attribute dialog
255  rightSide.add(noneButton);
256 
257  final AbstractButton cancelButton = new JButton("Cancel");
258  cancelButton.addActionListener(e -> {
259  assert frame != null;
260  frame.setVisible(false);
261  });
262  rightSide.add(cancelButton);
263 
264  final AbstractButton helpButton = new JButton("Help");
265  helpButton.addActionListener(e -> new Help(parent, "treasurelists.html").setVisible(true));
266  leftSide.add(helpButton);
267  final Component testButton = new JButton("Test");
268  leftSide.add(testButton);
269  testButton.setEnabled(false); // disable test button until implemented
270 
271  buttonPanel.add(leftSide, BorderLayout.WEST);
272  buttonPanel.add(rightSide, BorderLayout.EAST);
273  return buttonPanel;
274  }
275 
280  private void selectValue(@NotNull final String result) {
281  if (input != null) {
282  input.setText(" " + result);
283  }
284  assert frame != null;
285  frame.setVisible(false);
286  }
287 
294  @Nullable
295  private String getSelectedTreasureList() {
296  if (isSelectionEmpty()) {
297  return null;
298  }
299 
300  TreeNode node = (TreeNode) getSelectionPath().getLastPathComponent();
301 
302  if (node == treasureTree.getRoot()) {
303  return null;
304  }
305 
306  while (true) {
307  final TreeNode parentNode = node.getParent();
308  if (parentNode == treasureTree.getRoot()) {
309  break;
310  }
311  node = parentNode;
312  }
313 
314  // When a treasurelist inside a special sub folder (like
315  // "God Intervention") is selected, also return null because those must
316  // not be used on maps.
317  final TreasureTreeNode treasureTreeNode = (TreasureTreeNode) node;
318  if (treasureTreeNode.getTreasureObj() instanceof FolderTreasureObj) {
319  ACTION_BUILDER.showMessageDialog(frame, "treasurelistForbidden", treasureTreeNode.getTreasureObj().getName());
320  return null;
321  }
322 
323  return treasureTreeNode.getTreasureObj().getName();
324  }
325 
326 }
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.serialVersionUID
static final long serialVersionUID
The serial version UID.
Definition: CFTreasureListTree.java:78
net.sf.gridarta.model.treasurelist.TreasureTreeNode
Subclass: Nodes in the CFTreasureListTree.
Definition: TreasureTreeNode.java:33
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.selectValue
void selectValue(@NotNull final String result)
Selects a value and closes the dialog.
Definition: CFTreasureListTree.java:280
net.sf.gridarta.model.treasurelist.TreasureObj.getName
String getName()
Returns the name of this treasure object.
Definition: TreasureObj.java:225
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
The ActionBuilder.
Definition: CFTreasureListTree.java:73
net.sf.gridarta.model.treasurelist.TreasureTree.get
TreasureTreeNode get(@NotNull final String name)
Returns a treasure list by name.
Definition: TreasureTree.java:60
net.sf
net.sf.gridarta.model.face.FaceObjectProviders
Provider for faces of GameObjects and Archetypes.
Definition: FaceObjectProviders.java:46
net.sf.gridarta.gui.treasurelist.TreasureCellRenderer
This cell renderer is responsible for drawing the treasure-object cells in the JTree.
Definition: TreasureCellRenderer.java:49
net.sf.gridarta.gui.dialog.help.Help
Implements the Help Window is a separate frame with html content.
Definition: Help.java:42
net.sf.gridarta.gui
Graphical User Interface of Gridarta.
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.treasureTree
final TreasureTree treasureTree
All defined treasure lists.
Definition: CFTreasureListTree.java:84
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.noneButton
final AbstractButton noneButton
The button for none.
Definition: CFTreasureListTree.java:112
net
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.okButton
final AbstractButton okButton
The button for ok.
Definition: CFTreasureListTree.java:105
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.parent
final Frame parent
The main view.
Definition: CFTreasureListTree.java:91
net.sf.gridarta.model.treasurelist.TreasureTree
Stores all defined treasure lists.
Definition: TreasureTree.java:32
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.getSelectedTreasureList
String getSelectedTreasureList()
Returns the name of the currently selected treasurelist.
Definition: CFTreasureListTree.java:295
net.sf.gridarta.model.treasurelist.TreasureTree.getRoot
DefaultMutableTreeNode getRoot()
Returns the root node for normal treasure lists.
Definition: TreasureTree.java:87
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.input
JTextComponent input
The text input field.
Definition: CFTreasureListTree.java:119
net.sf.gridarta.gui.dialog.help
The online help system for the Gridarta editor.
Definition: Help.java:20
net.sf.gridarta.model.archetypeset.ArchetypeSet
Interface that captures similarities between different ArchetypeSet implementations.
Definition: ArchetypeSet.java:37
net.sf.gridarta.gui.dialog
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.NONE_SYM
static final String NONE_SYM
The string displayed in attribute dialog for "none".
Definition: CFTreasureListTree.java:67
net.sf.gridarta.model
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.buildButtonPanel
JPanel buildButtonPanel()
Builds the button panel (bottom-line of the dialog window).
Definition: CFTreasureListTree.java:240
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.CFTreasureListTree
CFTreasureListTree(@NotNull final TreasureTree treasureTree, @NotNull final Frame parent, @NotNull final ArchetypeSet<?, ?, ?> archetypeSet, @NotNull final FaceObjectProviders faceObjectProviders, @NotNull final ResourceIcons resourceIcons)
Creates a new instance.
Definition: CFTreasureListTree.java:130
net.sf.gridarta.model.face.FaceObjectProvidersListener
Interface for listeners interested in FaceObjectProviders related events.
Definition: FaceObjectProvidersListener.java:29
net.sf.gridarta.model.face
The face is the appearance of an object.
Definition: AbstractFaceObjects.java:20
net.sf.gridarta.model.treasurelist.TreasureTreeNode.getTreasureObj
TreasureObj getTreasureObj()
Definition: TreasureTreeNode.java:100
net.sf.gridarta.model.treasurelist.FolderTreasureObj
A TreasureObj representing a folder.
Definition: FolderTreasureObj.java:28
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.frame
JDialog frame
JDialog containing the tree.
Definition: CFTreasureListTree.java:98
net.sf.gridarta.utils.ResourceIcons
Creates ImageIcon instances from resources.
Definition: ResourceIcons.java:46
net.sf.gridarta.model.treasurelist
Definition: ArchTreasureObj.java:20
net.sf.gridarta.model.archetypeset
Definition: ArchetypeSet.java:20
net.sf.gridarta.gui.treasurelist.CFTreasureListTree.showDialog
synchronized void showDialog(@Nullable final JTextComponent input, @NotNull final Component parent)
Shows the dialog window containing this tree.
Definition: CFTreasureListTree.java:151
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.gui.treasurelist.CFTreasureListTree
The CFTreasureListTree class fully manages treasurelists.
Definition: CFTreasureListTree.java:61