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