Gridarta Editor
DefaultErrorView.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.dialog.errorview;
21 
22 import java.awt.Component;
23 import java.awt.Dialog;
24 import java.awt.Dimension;
25 import java.lang.reflect.InvocationTargetException;
26 import java.util.EnumMap;
27 import java.util.Map;
28 import java.util.concurrent.Semaphore;
29 import javax.swing.JButton;
30 import javax.swing.JOptionPane;
31 import javax.swing.JScrollPane;
32 import javax.swing.JTree;
33 import javax.swing.SwingUtilities;
34 import javax.swing.tree.DefaultMutableTreeNode;
35 import javax.swing.tree.DefaultTreeModel;
36 import javax.swing.tree.TreePath;
40 import net.sf.japi.swing.action.ActionBuilder;
41 import net.sf.japi.swing.action.ActionBuilderFactory;
42 import net.sf.japi.swing.action.ActionMethod;
43 import org.jetbrains.annotations.NotNull;
44 import org.jetbrains.annotations.Nullable;
45 
50 public class DefaultErrorView implements ErrorView {
51 
55  @NotNull
56  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
57 
61  @NotNull
62  private final DefaultTreeModel treeModel = new DefaultTreeModel(null);
63 
67  @NotNull
68  private final DefaultMutableTreeNode treeRoot = new ErrorEntry(treeModel, "/", true);
69 
73  @NotNull
74  private final Map<ErrorViewCategory, ErrorEntry> categories = new EnumMap<>(ErrorViewCategory.class);
75 
79  @Nullable
80  private final Component parent;
81 
85  private boolean errors;
86 
90  @Nullable
91  private Dialog dialog;
92 
96  @NotNull
97  private final Object dialogSync = new Object();
98 
102  @Nullable
103  private JButton okButton;
104 
109  @NotNull
110  private final Semaphore semaphore = new Semaphore(0);
111 
117  public DefaultErrorView(@Nullable final Component parent) {
118  treeModel.setRoot(treeRoot);
119  this.parent = parent;
120  }
121 
122  @Override
123  public void addError(@NotNull final ErrorViewCategory categoryName, @NotNull final String message) {
124  addEntry(categoryName, message);
125  errors = true;
126  }
127 
128  @Override
129  public void addError(@NotNull final ErrorViewCategory categoryName, final int lineNo, @NotNull final String message) {
130  addEntry(categoryName, lineNo + ": " + message);
131  errors = true;
132  }
133 
134  @Override
135  public void addWarning(@NotNull final ErrorViewCategory categoryName, @NotNull final String message) {
136  addEntry(categoryName, "Warning: " + message);
137  }
138 
139  @Override
140  public void addWarning(@NotNull final ErrorViewCategory categoryName, final int lineNo, @NotNull final String message) {
141  addEntry(categoryName, "Warning: line " + lineNo + ": " + message);
142  }
143 
149  private void addEntry(final ErrorViewCategory categoryName, final String message) {
150  final Runnable runnable = new Runnable() {
151 
152  @Override
153  public void run() {
154  final ErrorEntry category = getCategory(categoryName);
155  final ErrorEntry errorEntry = new ErrorEntry(treeModel, message, false);
156  category.add(errorEntry);
157  showDialog(category, errorEntry);
158  }
159 
160  };
161  if (SwingUtilities.isEventDispatchThread()) {
162  runnable.run();
163  } else {
164  try {
165  SwingUtilities.invokeAndWait(runnable);
166  } catch (final InterruptedException ignored) {
167  Thread.currentThread().interrupt();
168  } catch (final InvocationTargetException ex) {
169  throw new RuntimeException(ex);
170  }
171  }
172  }
173 
179  @NotNull
180  private ErrorEntry getCategory(@NotNull final ErrorViewCategory categoryName) {
181  final ErrorEntry existingErrorEntry = categories.get(categoryName);
182  if (existingErrorEntry != null) {
183  return existingErrorEntry;
184  }
185 
186  final ErrorEntry category = new ErrorEntry(treeModel, categoryName.toString(), true);
187  categories.put(categoryName, category);
188  treeRoot.add(category);
189  return category;
190  }
191 
192  @Override
193  public boolean hasErrors() {
194  return errors;
195  }
196 
203  private void showDialog(@NotNull final ErrorEntry category, @NotNull final ErrorEntry errorEntry) {
204  synchronized (dialogSync) {
205  if (dialog == null) {
206  showDialogInt(category, errorEntry);
207  }
208  }
209  }
210 
217  private void showDialogInt(@NotNull final ErrorEntry category, @NotNull final ErrorEntry errorEntry) {
218  final JTree tree = new JTree(treeModel);
219  final JScrollPane scrollPane = new JScrollPane(tree);
220  tree.setExpandsSelectedPaths(true);
221  final TreePath path = new TreePath(new Object[] { treeRoot, category, errorEntry, });
222  tree.setSelectionPath(path);
223  tree.scrollPathToVisible(path);
224  okButton = new JButton(ACTION_BUILDER.createAction(false, "errorViewOk", this));
225  final JOptionPane pane = new JOptionPane(scrollPane, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[] { okButton, }, okButton) {
226 
228  private static final long serialVersionUID = 1L;
229 
230  @Override
231  public void setValue(@Nullable final Object newValue) {
232  super.setValue(newValue);
233  if (newValue != UNINITIALIZED_VALUE) {
234  errorViewOk();
235  }
236  }
237 
238  };
239  pane.setPreferredSize(new Dimension(800, 600));
240  assert okButton != null;
241  okButton.setEnabled(false);
242  dialog = pane.createDialog(parent, ActionBuilderUtils.getString(ACTION_BUILDER, "errorViewTitle"));
243  pane.selectInitialValue();
244  assert dialog != null;
245  dialog.pack();
246  assert dialog != null;
247  dialog.setModal(false);
248  assert dialog != null;
249  dialog.setVisible(true);
250  }
251 
252  @Override
253  public void waitDialog() throws InterruptedException {
254  if (hasDialog()) {
255  final Runnable runnable = new Runnable() {
256 
257  @Override
258  public void run() {
259  assert okButton != null;
260  okButton.setEnabled(true);
261  }
262 
263  };
264  if (SwingUtilities.isEventDispatchThread()) {
265  runnable.run();
266  } else {
267  try {
268  SwingUtilities.invokeAndWait(runnable);
269  } catch (final InvocationTargetException ex) {
270  throw new RuntimeException(ex);
271  }
272  }
273 
274  semaphore.acquire();
275  }
276 
277  if (Thread.interrupted()) {
278  throw new InterruptedException("current thread was interrupted");
279  }
280  }
281 
285  @ActionMethod
286  public void errorViewOk() {
287  synchronized (dialogSync) {
288  if (dialog != null) {
289  try {
290  dialog.dispose();
291  dialog = null;
292  } finally {
293  semaphore.release();
294  }
295  }
296  }
297  }
298 
303  private boolean hasDialog() {
304  synchronized (dialogSync) {
305  return dialog != null;
306  }
307  }
308 
309 }
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.hasErrors
boolean hasErrors()
Definition: DefaultErrorView.java:193
net.sf.gridarta
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.DefaultErrorView
DefaultErrorView(@Nullable final Component parent)
Definition: DefaultErrorView.java:117
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.getCategory
ErrorEntry getCategory(@NotNull final ErrorViewCategory categoryName)
Definition: DefaultErrorView.java:180
net.sf
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.categories
final Map< ErrorViewCategory, ErrorEntry > categories
Definition: DefaultErrorView.java:74
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView
Definition: DefaultErrorView.java:50
net.sf.gridarta.gui.dialog.errorview.ErrorEntry.add
void add(@NotNull final MutableTreeNode newChild)
Definition: ErrorEntry.java:56
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.treeRoot
final DefaultMutableTreeNode treeRoot
Definition: DefaultErrorView.java:68
net.sf.gridarta.model.errorview.ErrorView
Definition: ErrorView.java:28
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.showDialogInt
void showDialogInt(@NotNull final ErrorEntry category, @NotNull final ErrorEntry errorEntry)
Definition: DefaultErrorView.java:217
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.addEntry
void addEntry(final ErrorViewCategory categoryName, final String message)
Definition: DefaultErrorView.java:149
net
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.waitDialog
void waitDialog()
Definition: DefaultErrorView.java:253
net.sf.gridarta.model.errorview
Definition: ErrorView.java:20
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.semaphore
final Semaphore semaphore
Definition: DefaultErrorView.java:110
net.sf.gridarta.model.errorview.ErrorViewCategory
Definition: ErrorViewCategory.java:28
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.addWarning
void addWarning(@NotNull final ErrorViewCategory categoryName, final int lineNo, @NotNull final String message)
Definition: DefaultErrorView.java:140
net.sf.gridarta.utils.ActionBuilderUtils.getString
static String getString(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final String defaultValue)
Definition: ActionBuilderUtils.java:71
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.errors
boolean errors
Definition: DefaultErrorView.java:85
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.hasDialog
boolean hasDialog()
Definition: DefaultErrorView.java:303
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.addWarning
void addWarning(@NotNull final ErrorViewCategory categoryName, @NotNull final String message)
Definition: DefaultErrorView.java:135
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.addError
void addError(@NotNull final ErrorViewCategory categoryName, @NotNull final String message)
Definition: DefaultErrorView.java:123
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.errorViewOk
void errorViewOk()
Definition: DefaultErrorView.java:286
net.sf.gridarta.model
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.parent
final Component parent
Definition: DefaultErrorView.java:80
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.showDialog
void showDialog(@NotNull final ErrorEntry category, @NotNull final ErrorEntry errorEntry)
Definition: DefaultErrorView.java:203
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.addError
void addError(@NotNull final ErrorViewCategory categoryName, final int lineNo, @NotNull final String message)
Definition: DefaultErrorView.java:129
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.dialog
Dialog dialog
Definition: DefaultErrorView.java:91
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.okButton
JButton okButton
Definition: DefaultErrorView.java:103
net.sf.gridarta.utils.ActionBuilderUtils
Definition: ActionBuilderUtils.java:31
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.dialogSync
final Object dialogSync
Definition: DefaultErrorView.java:97
net.sf.gridarta.gui.dialog.errorview.ErrorEntry
Definition: ErrorEntry.java:31
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.treeModel
final DefaultTreeModel treeModel
Definition: DefaultErrorView.java:62
net.sf.gridarta.gui.dialog.errorview.DefaultErrorView.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
Definition: DefaultErrorView.java:56
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20