mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Refactor error handling code
This commit is contained in:
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -696,7 +696,7 @@ forge-gui-desktop/src/main/java/forge/download/GuiDownloadQuestImages.java -text
|
|||||||
forge-gui-desktop/src/main/java/forge/download/GuiDownloadSetPicturesLQ.java -text
|
forge-gui-desktop/src/main/java/forge/download/GuiDownloadSetPicturesLQ.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/download/GuiDownloader.java -text
|
forge-gui-desktop/src/main/java/forge/download/GuiDownloader.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/download/package-info.java -text
|
forge-gui-desktop/src/main/java/forge/download/package-info.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/error/BugReporter.java -text
|
forge-gui-desktop/src/main/java/forge/error/BugReportDialog.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/error/package-info.java -text
|
forge-gui-desktop/src/main/java/forge/error/package-info.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/gui/CardContainer.java -text
|
forge-gui-desktop/src/main/java/forge/gui/CardContainer.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java -text
|
forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java -text
|
||||||
@@ -1078,7 +1078,6 @@ forge-gui-mobile/src/forge/assets/ImageCache.java -text
|
|||||||
forge-gui-mobile/src/forge/assets/ImageLoader.java -text
|
forge-gui-mobile/src/forge/assets/ImageLoader.java -text
|
||||||
forge-gui-mobile/src/forge/deck/FDeckChooser.java -text
|
forge-gui-mobile/src/forge/deck/FDeckChooser.java -text
|
||||||
forge-gui-mobile/src/forge/deck/FDeckViewer.java -text
|
forge-gui-mobile/src/forge/deck/FDeckViewer.java -text
|
||||||
forge-gui-mobile/src/forge/error/BugReporter.java -text
|
|
||||||
forge-gui-mobile/src/forge/itemmanager/CardManager.java -text
|
forge-gui-mobile/src/forge/itemmanager/CardManager.java -text
|
||||||
forge-gui-mobile/src/forge/itemmanager/DeckManager.java -text
|
forge-gui-mobile/src/forge/itemmanager/DeckManager.java -text
|
||||||
forge-gui-mobile/src/forge/itemmanager/ItemManager.java -text
|
forge-gui-mobile/src/forge/itemmanager/ItemManager.java -text
|
||||||
@@ -16127,6 +16126,7 @@ forge-gui/src/main/java/forge/deck/io/DeckHtmlSerializer.java -text
|
|||||||
forge-gui/src/main/java/forge/deck/io/DeckPreferences.java -text
|
forge-gui/src/main/java/forge/deck/io/DeckPreferences.java -text
|
||||||
forge-gui/src/main/java/forge/deck/io/OldDeckParser.java -text
|
forge-gui/src/main/java/forge/deck/io/OldDeckParser.java -text
|
||||||
forge-gui/src/main/java/forge/deck/io/package-info.java svneol=native#text/plain
|
forge-gui/src/main/java/forge/deck/io/package-info.java svneol=native#text/plain
|
||||||
|
forge-gui/src/main/java/forge/error/BugReporter.java -text
|
||||||
forge-gui/src/main/java/forge/error/ExceptionHandler.java svneol=native#text/plain
|
forge-gui/src/main/java/forge/error/ExceptionHandler.java svneol=native#text/plain
|
||||||
forge-gui/src/main/java/forge/error/package-info.java svneol=native#text/plain
|
forge-gui/src/main/java/forge/error/package-info.java svneol=native#text/plain
|
||||||
forge-gui/src/main/java/forge/events/IUiEventVisitor.java -text
|
forge-gui/src/main/java/forge/events/IUiEventVisitor.java -text
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge;
|
|||||||
|
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.io.File;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -23,7 +24,7 @@ import com.google.common.base.Function;
|
|||||||
import forge.assets.FSkinProp;
|
import forge.assets.FSkinProp;
|
||||||
import forge.assets.ISkinImage;
|
import forge.assets.ISkinImage;
|
||||||
import forge.control.FControl;
|
import forge.control.FControl;
|
||||||
import forge.error.BugReporter;
|
import forge.error.BugReportDialog;
|
||||||
import forge.events.UiEvent;
|
import forge.events.UiEvent;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
@@ -110,21 +111,6 @@ public class GuiDesktop implements IGuiBase {
|
|||||||
return Singletons.getControl().mayShowCard(card);
|
return Singletons.getControl().mayShowCard(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportBug(String details) {
|
|
||||||
BugReporter.reportBug(details);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportException(Throwable ex) {
|
|
||||||
BugReporter.reportException(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportException(Throwable ex, String message) {
|
|
||||||
BugReporter.reportException(ex, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ISkinImage getUnskinnedIcon(String path) {
|
public ISkinImage getUnskinnedIcon(String path) {
|
||||||
return new FSkin.UnskinnedIcon(path);
|
return new FSkin.UnskinnedIcon(path);
|
||||||
@@ -399,4 +385,17 @@ public class GuiDesktop implements IGuiBase {
|
|||||||
}
|
}
|
||||||
return fc.getSelectedFile().getAbsolutePath();
|
return fc.getSelectedFile().getAbsolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showBugReportDialog(String title, String text, boolean showExitAppBtn) {
|
||||||
|
BugReportDialog.show(title, text, showExitAppBtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getSaveFile(File defaultFile) {
|
||||||
|
JFileChooser fc = new JFileChooser();
|
||||||
|
fc.setSelectedFile(defaultFile);
|
||||||
|
fc.showSaveDialog(null);
|
||||||
|
return fc.getSelectedFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ final class ImageLoader extends CacheLoader<String, BufferedImage> {
|
|||||||
//System.out.println(String.format("Found %s at: %s", key, file.getAbsolutePath()));
|
//System.out.println(String.format("Found %s at: %s", key, file.getAbsolutePath()));
|
||||||
try {
|
try {
|
||||||
return ImageIO.read(file);
|
return ImageIO.read(file);
|
||||||
} catch (IOException ex) {
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
BugReporter.reportException(ex, "Could not read image file " + file.getAbsolutePath() + " ");
|
BugReporter.reportException(ex, "Could not read image file " + file.getAbsolutePath() + " ");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
130
forge-gui-desktop/src/main/java/forge/error/BugReportDialog.java
Normal file
130
forge-gui-desktop/src/main/java/forge/error/BugReportDialog.java
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Forge Team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.error;
|
||||||
|
|
||||||
|
import forge.gui.WrapLayout;
|
||||||
|
import forge.toolbox.FHyperlink;
|
||||||
|
import forge.toolbox.FLabel;
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class ErrorViewer. Enables showing and saving error messages that
|
||||||
|
* occurred in forge.
|
||||||
|
*
|
||||||
|
* @author Clemens Koza
|
||||||
|
* @version V1.0 02.08.2009
|
||||||
|
*/
|
||||||
|
public class BugReportDialog {
|
||||||
|
private static boolean dialogShown;
|
||||||
|
|
||||||
|
public static void show(String title, String text, boolean showExitAppBtn) {
|
||||||
|
if (dialogShown) { return; }
|
||||||
|
|
||||||
|
JTextArea area = new JTextArea(text);
|
||||||
|
area.setFont(new Font("Monospaced", Font.PLAIN, 10));
|
||||||
|
area.setEditable(false);
|
||||||
|
area.setLineWrap(true);
|
||||||
|
area.setWrapStyleWord(true);
|
||||||
|
|
||||||
|
JPanel helpPanel = new JPanel(new WrapLayout(FlowLayout.LEFT, 4, 2));
|
||||||
|
for (String word : BugReporter.HELP_URL_LABEL.split(" ")) {
|
||||||
|
helpPanel.add(new FLabel.Builder().text("<html>" + word + "</html>").useSkinColors(false).build());
|
||||||
|
}
|
||||||
|
helpPanel.add(new FHyperlink.Builder().url(BugReporter.HELP_URL).text("<html>this post</html>").useSkinColors(false).build());
|
||||||
|
|
||||||
|
JPanel p = new JPanel(new MigLayout("wrap"));
|
||||||
|
p.add(new FLabel.Builder().text(BugReporter.HELP_TEXT).useSkinColors(false).build(), "gap 5");
|
||||||
|
p.add(helpPanel, "w 600");
|
||||||
|
p.add(new JScrollPane(area), "w 100%, h 100%, gaptop 5");
|
||||||
|
|
||||||
|
// Button is not modified, String gets the automatic listener to hide
|
||||||
|
// the dialog
|
||||||
|
ArrayList<Object> options = new ArrayList<Object>();
|
||||||
|
options.add(new JButton(new _CopyAndGo(area)));
|
||||||
|
options.add(new JButton(new _SaveAction(area)));
|
||||||
|
options.add("Close");
|
||||||
|
if (showExitAppBtn) {
|
||||||
|
options.add(new JButton(new _ExitAction()));
|
||||||
|
}
|
||||||
|
|
||||||
|
JOptionPane pane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE,
|
||||||
|
JOptionPane.DEFAULT_OPTION, null, options.toArray(), options.get(0));
|
||||||
|
JDialog dlg = pane.createDialog(JOptionPane.getRootFrame(), title);
|
||||||
|
dlg.setSize(showExitAppBtn ? 780 : 600, 400);
|
||||||
|
dlg.setResizable(true);
|
||||||
|
dialogShown = true;
|
||||||
|
dlg.setVisible(true);
|
||||||
|
dlg.dispose();
|
||||||
|
dialogShown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
private static class _CopyAndGo extends AbstractAction {
|
||||||
|
private final JTextArea text;
|
||||||
|
|
||||||
|
public _CopyAndGo(JTextArea text) {
|
||||||
|
super("Copy and go to forum");
|
||||||
|
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(final ActionEvent e) {
|
||||||
|
BugReporter.copyAndGoToForums(text.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
private static class _SaveAction extends AbstractAction {
|
||||||
|
private final JTextArea area;
|
||||||
|
|
||||||
|
public _SaveAction(final JTextArea areaParam) {
|
||||||
|
super("Save to file");
|
||||||
|
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||||
|
this.area = areaParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(final ActionEvent e) {
|
||||||
|
BugReporter.saveToFile(area.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
private static class _ExitAction extends AbstractAction {
|
||||||
|
public _ExitAction() {
|
||||||
|
super("Exit application");
|
||||||
|
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(final ActionEvent e) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable instantiation
|
||||||
|
private BugReportDialog() { }
|
||||||
|
}
|
||||||
@@ -1,324 +0,0 @@
|
|||||||
/*
|
|
||||||
* Forge: Play Magic: the Gathering.
|
|
||||||
* Copyright (C) 2011 Forge Team
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package forge.error;
|
|
||||||
|
|
||||||
import forge.FThreads;
|
|
||||||
import forge.gui.WrapLayout;
|
|
||||||
import forge.toolbox.FHyperlink;
|
|
||||||
import forge.toolbox.FLabel;
|
|
||||||
import forge.toolbox.FOptionPane;
|
|
||||||
import forge.util.BuildInfo;
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.datatransfer.StringSelection;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The class ErrorViewer. Enables showing and saving error messages that
|
|
||||||
* occurred in forge.
|
|
||||||
*
|
|
||||||
* @author Clemens Koza
|
|
||||||
* @version V1.0 02.08.2009
|
|
||||||
*/
|
|
||||||
public class BugReporter {
|
|
||||||
private static final int _STACK_OVERFLOW_MAX_MESSAGE_LEN = 16 * 1024;
|
|
||||||
|
|
||||||
private static boolean dialogShown = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows exception information in a format ready to post to the forum as a crash report. Uses the exception's message
|
|
||||||
* as the reason if message is null.
|
|
||||||
*/
|
|
||||||
public static void reportException(final Throwable ex, final String message) {
|
|
||||||
if (ex == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (message != null) {
|
|
||||||
System.err.printf("%s > %s%n", FThreads.debugGetCurrThreadId(), message);
|
|
||||||
}
|
|
||||||
System.err.print( FThreads.debugGetCurrThreadId() + " > " );
|
|
||||||
ex.printStackTrace();
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Description: [describe what you were doing when the crash occurred]\n\n");
|
|
||||||
_buildSpoilerHeader(sb, ex.getClass().getSimpleName());
|
|
||||||
sb.append("\n\n");
|
|
||||||
if (null != message && !message.isEmpty()) {
|
|
||||||
sb.append(FThreads.debugGetCurrThreadId()).append(" > ").append(message).append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
ex.printStackTrace(pw);
|
|
||||||
|
|
||||||
String swStr = sw.toString();
|
|
||||||
if (ex instanceof StackOverflowError &&
|
|
||||||
_STACK_OVERFLOW_MAX_MESSAGE_LEN <= swStr.length()) {
|
|
||||||
// most likely a cycle. only take first portion so the message
|
|
||||||
// doesn't grow too large to post
|
|
||||||
sb.append(swStr, 0, _STACK_OVERFLOW_MAX_MESSAGE_LEN);
|
|
||||||
sb.append("\n... (truncated)");
|
|
||||||
} else {
|
|
||||||
sb.append(swStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
_buildSpoilerFooter(sb);
|
|
||||||
|
|
||||||
_showDialog("Report a crash", sb.toString(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias for reportException(ex, null).
|
|
||||||
*/
|
|
||||||
public static void reportException(final Throwable ex) {
|
|
||||||
reportException(ex, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias for reportException(ex, String.format(format, args)).
|
|
||||||
*/
|
|
||||||
public static void reportException(final Throwable ex, final String format, final Object... args) {
|
|
||||||
reportException(ex, String.format(format, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a forum post template for reporting a bug.
|
|
||||||
*/
|
|
||||||
public static void reportBug(String details) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Description: [describe the problem]\n\n");
|
|
||||||
_buildSpoilerHeader(sb, "General bug report");
|
|
||||||
if (null != details && !details.isEmpty()) {
|
|
||||||
sb.append("\n\n");
|
|
||||||
sb.append(details);
|
|
||||||
}
|
|
||||||
_buildSpoilerFooter(sb);
|
|
||||||
|
|
||||||
_showDialog("Report a bug", sb.toString(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows thread stack information in a format ready to post to the forum.
|
|
||||||
*/
|
|
||||||
public static void reportThreadStacks(final String message) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Description: [describe what you were doing at the time]\n\n");
|
|
||||||
_buildSpoilerHeader(sb, "Thread stack dump");
|
|
||||||
sb.append("\n\n");
|
|
||||||
if (null != message && !message.isEmpty()) {
|
|
||||||
sb.append(message);
|
|
||||||
sb.append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
final Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
|
|
||||||
for (final Entry<Thread, StackTraceElement[]> e : traces.entrySet()) {
|
|
||||||
pw.println();
|
|
||||||
pw.printf("%s (%s):%n", e.getKey().getName(), e.getKey().getId());
|
|
||||||
for (final StackTraceElement el : e.getValue()) {
|
|
||||||
pw.println(el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(sw.toString());
|
|
||||||
_buildSpoilerFooter(sb);
|
|
||||||
_showDialog("Thread stack dump", sb.toString(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias for reportThreadStacks(String.format(format, args))
|
|
||||||
*/
|
|
||||||
public static void reportThreadStacks(final String format, final Object... args) {
|
|
||||||
reportThreadStacks(String.format(format, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static StringBuilder _buildSpoilerHeader(StringBuilder sb, String reportTitle) {
|
|
||||||
sb.append("[spoiler=").append(reportTitle).append("][code]");
|
|
||||||
sb.append("\nForge Version: ").append(BuildInfo.getVersionString());
|
|
||||||
sb.append("\nOperating System: ").append(System.getProperty("os.name"))
|
|
||||||
.append(" ").append(System.getProperty("os.version"))
|
|
||||||
.append(" ").append(System.getProperty("os.arch"));
|
|
||||||
sb.append("\nJava Version: ").append(System.getProperty("java.version"))
|
|
||||||
.append(" ").append(System.getProperty("java.vendor"));
|
|
||||||
return sb;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static StringBuilder _buildSpoilerFooter(StringBuilder sb) {
|
|
||||||
sb.append("[/code][/spoiler]");
|
|
||||||
return sb;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void _showDialog(String title, String text, boolean showExitAppBtn) {
|
|
||||||
if ( dialogShown )
|
|
||||||
return;
|
|
||||||
|
|
||||||
JTextArea area = new JTextArea(text);
|
|
||||||
area.setFont(new Font("Monospaced", Font.PLAIN, 10));
|
|
||||||
area.setEditable(false);
|
|
||||||
area.setLineWrap(true);
|
|
||||||
area.setWrapStyleWord(true);
|
|
||||||
|
|
||||||
String helpText = "<html>A template for a post in the bug reports forum topic is shown below. Just select 'Copy and go to forum' "
|
|
||||||
+ "and the template will be copied to your system clipboard and the forum page will open in your browser. "
|
|
||||||
+ "Then all you have to do is paste the text into a forum post and edit the description line.</html>";
|
|
||||||
String helpUrlLabel = "Reporting bugs in Forge is very important. We sincerely thank you for your time."
|
|
||||||
+ " For help writing a solid bug report, please see:";
|
|
||||||
String helpUrl = "http://www.slightlymagic.net/forum/viewtopic.php?f=26&p=109925#p109925";
|
|
||||||
JPanel helpPanel = new JPanel(new WrapLayout(FlowLayout.LEFT, 4, 2));
|
|
||||||
for (String word : helpUrlLabel.split(" ")) {
|
|
||||||
helpPanel.add(new FLabel.Builder().text("<html>" + word + "</html>").useSkinColors(false).build());
|
|
||||||
}
|
|
||||||
helpPanel.add(new FHyperlink.Builder().url(helpUrl).text("<html>this post</html>").useSkinColors(false).build());
|
|
||||||
|
|
||||||
JPanel p = new JPanel(new MigLayout("wrap"));
|
|
||||||
p.add(new FLabel.Builder().text(helpText).useSkinColors(false).build(), "gap 5");
|
|
||||||
p.add(helpPanel, "w 600");
|
|
||||||
p.add(new JScrollPane(area), "w 100%, h 100%, gaptop 5");
|
|
||||||
|
|
||||||
// determine proper forum URL
|
|
||||||
String forgeVersion = BuildInfo.getVersionString();
|
|
||||||
final String url;
|
|
||||||
if (StringUtils.containsIgnoreCase(forgeVersion, "svn")
|
|
||||||
|| StringUtils.containsIgnoreCase(forgeVersion, "snapshot")) {
|
|
||||||
url = "http://www.slightlymagic.net/forum/viewtopic.php?f=52&t=6333&start=54564487645#bottom";
|
|
||||||
} else {
|
|
||||||
url = "http://www.slightlymagic.net/forum/viewforum.php?f=26";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Button is not modified, String gets the automatic listener to hide
|
|
||||||
// the dialog
|
|
||||||
ArrayList<Object> options = new ArrayList<Object>();
|
|
||||||
options.add(new JButton(new _CopyAndGo(url, area)));
|
|
||||||
options.add(new JButton(new _SaveAction(area)));
|
|
||||||
options.add("Close");
|
|
||||||
if (showExitAppBtn) {
|
|
||||||
options.add(new JButton(new _ExitAction()));
|
|
||||||
}
|
|
||||||
|
|
||||||
JOptionPane pane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE,
|
|
||||||
JOptionPane.DEFAULT_OPTION, null, options.toArray(), options.get(0));
|
|
||||||
JDialog dlg = pane.createDialog(JOptionPane.getRootFrame(), title);
|
|
||||||
dlg.setSize(showExitAppBtn ? 780 : 600, 400);
|
|
||||||
dlg.setResizable(true);
|
|
||||||
dialogShown = true;
|
|
||||||
dlg.setVisible(true);
|
|
||||||
dlg.dispose();
|
|
||||||
dialogShown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static class _CopyAndGo extends AbstractAction {
|
|
||||||
private final String url;
|
|
||||||
private final JTextArea text;
|
|
||||||
|
|
||||||
public _CopyAndGo(String url, JTextArea text) {
|
|
||||||
super("Copy and go to forum");
|
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
|
||||||
|
|
||||||
this.url = url;
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent e) {
|
|
||||||
try {
|
|
||||||
// copy text to clipboard
|
|
||||||
StringSelection ss = new StringSelection(text.getText());
|
|
||||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
|
|
||||||
|
|
||||||
// browse to url
|
|
||||||
Desktop.getDesktop().browse(new URI(url));
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
FOptionPane.showMessageDialog("Sorry, a problem occurred while opening the forum in your default browser.",
|
|
||||||
"A problem occurred", FOptionPane.ERROR_ICON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static class _SaveAction extends AbstractAction {
|
|
||||||
private static JFileChooser c;
|
|
||||||
private final JTextArea area;
|
|
||||||
|
|
||||||
public _SaveAction(final JTextArea areaParam) {
|
|
||||||
super("Save to file");
|
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
|
||||||
this.area = areaParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent e) {
|
|
||||||
if (c == null) {
|
|
||||||
c = new JFileChooser();
|
|
||||||
}
|
|
||||||
|
|
||||||
File f;
|
|
||||||
long curTime = System.currentTimeMillis();
|
|
||||||
for (int i = 0;; i++) {
|
|
||||||
final String name = String.format("%TF-%02d.txt", curTime, i);
|
|
||||||
f = new File(name);
|
|
||||||
if (!f.exists()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.setSelectedFile(f);
|
|
||||||
c.showSaveDialog(null);
|
|
||||||
f = c.getSelectedFile();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final BufferedWriter bw = new BufferedWriter(new FileWriter(f));
|
|
||||||
bw.write(this.area.getText());
|
|
||||||
bw.close();
|
|
||||||
}
|
|
||||||
catch (final IOException ex) {
|
|
||||||
FOptionPane.showMessageDialog("There was an error during saving. Sorry!\n" + ex,
|
|
||||||
"Error saving file", FOptionPane.ERROR_ICON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static class _ExitAction extends AbstractAction {
|
|
||||||
public _ExitAction() {
|
|
||||||
super("Exit application");
|
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent e) {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable instantiation
|
|
||||||
private BugReporter() { }
|
|
||||||
}
|
|
||||||
@@ -186,6 +186,8 @@ public class FNavigationBar extends FTitleBarBase {
|
|||||||
btnForge.addMouseListener(new MouseAdapter() {
|
btnForge.addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
|
int[] x = null;
|
||||||
|
int y = x[2];
|
||||||
if (btnForge.isEnabled() && System.currentTimeMillis() - timeMenuHidden > 250) { //time comparsion needed clicking button a second time to hide menu
|
if (btnForge.isEnabled() && System.currentTimeMillis() - timeMenuHidden > 250) { //time comparsion needed clicking button a second time to hide menu
|
||||||
showForgeMenu(true);
|
showForgeMenu(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package forge;
|
package forge;
|
||||||
|
|
||||||
import forge.error.BugReporter;
|
import forge.error.BugReporter;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +43,8 @@ public class PanelTest extends JFrame {
|
|||||||
public PanelTest() {
|
public PanelTest() {
|
||||||
try {
|
try {
|
||||||
this.jbInit();
|
this.jbInit();
|
||||||
} catch (final Exception ex) {
|
}
|
||||||
|
catch (final Exception ex) {
|
||||||
BugReporter.reportException(ex);
|
BugReporter.reportException(ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge;
|
package forge;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -18,7 +19,6 @@ import forge.assets.FTextureImage;
|
|||||||
import forge.assets.ISkinImage;
|
import forge.assets.ISkinImage;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.FDeckViewer;
|
import forge.deck.FDeckViewer;
|
||||||
import forge.error.BugReporter;
|
|
||||||
import forge.events.UiEvent;
|
import forge.events.UiEvent;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
@@ -103,21 +103,6 @@ public class GuiMobile implements IGuiBase {
|
|||||||
return FControl.mayShowCard(card);
|
return FControl.mayShowCard(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportBug(String details) {
|
|
||||||
BugReporter.reportBug(details);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportException(Throwable ex) {
|
|
||||||
BugReporter.reportException(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportException(Throwable ex, String message) {
|
|
||||||
BugReporter.reportException(ex, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ISkinImage getUnskinnedIcon(String path) {
|
public ISkinImage getUnskinnedIcon(String path) {
|
||||||
return new FTextureImage(new Texture(path));
|
return new FTextureImage(new Texture(path));
|
||||||
@@ -164,6 +149,11 @@ public class GuiMobile implements IGuiBase {
|
|||||||
}.invokeAndWait();
|
}.invokeAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showBugReportDialog(String title, String text, boolean showExitAppBtn) {
|
||||||
|
FOptionPane.showErrorDialog(text, title); //TODO: Create dialog with bells and whistles of desktop bug report dialog
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showCardList(final String title, final String message, final List<PaperCard> list) {
|
public void showCardList(final String title, final String message, final List<PaperCard> list) {
|
||||||
Deck deck = new Deck(title + " - " + message);
|
Deck deck = new Deck(title + " - " + message);
|
||||||
@@ -342,4 +332,9 @@ public class GuiMobile implements IGuiBase {
|
|||||||
public String showFileDialog(String title, String defaultDir) {
|
public String showFileDialog(String title, String defaultDir) {
|
||||||
return ForgeConstants.USER_GAMES_DIR + "Test.fgs"; //TODO: Show dialog
|
return ForgeConstants.USER_GAMES_DIR + "Test.fgs"; //TODO: Show dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getSaveFile(File defaultFile) {
|
||||||
|
return defaultFile; //TODO: Show dialog
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,302 +0,0 @@
|
|||||||
/*
|
|
||||||
* Forge: Play Magic: the Gathering.
|
|
||||||
* Copyright (C) 2011 Forge Team
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package forge.error;
|
|
||||||
|
|
||||||
import forge.util.BuildInfo;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
public class BugReporter {
|
|
||||||
private static final int _STACK_OVERFLOW_MAX_MESSAGE_LEN = 16 * 1024;
|
|
||||||
|
|
||||||
private static boolean dialogShown = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows exception information in a format ready to post to the forum as a crash report. Uses the exception's message
|
|
||||||
* as the reason if message is null.
|
|
||||||
*/
|
|
||||||
public static void reportException(final Throwable ex, final String message) {
|
|
||||||
if (ex == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String threadId = ""; //FThreads.debugGetCurrThreadId()
|
|
||||||
if (message != null) {
|
|
||||||
System.err.printf("%s > %s%n", threadId, message);
|
|
||||||
}
|
|
||||||
System.err.print(threadId + " > " );
|
|
||||||
ex.printStackTrace();
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Description: [describe what you were doing when the crash occurred]\n\n");
|
|
||||||
_buildSpoilerHeader(sb, ex.getClass().getSimpleName());
|
|
||||||
sb.append("\n\n");
|
|
||||||
if (null != message && !message.isEmpty()) {
|
|
||||||
sb.append(threadId).append(" > ").append(message).append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
ex.printStackTrace(pw);
|
|
||||||
|
|
||||||
String swStr = sw.toString();
|
|
||||||
if (ex instanceof StackOverflowError &&
|
|
||||||
_STACK_OVERFLOW_MAX_MESSAGE_LEN <= swStr.length()) {
|
|
||||||
// most likely a cycle. only take first portion so the message
|
|
||||||
// doesn't grow too large to post
|
|
||||||
sb.append(swStr, 0, _STACK_OVERFLOW_MAX_MESSAGE_LEN);
|
|
||||||
sb.append("\n... (truncated)");
|
|
||||||
} else {
|
|
||||||
sb.append(swStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
_buildSpoilerFooter(sb);
|
|
||||||
|
|
||||||
_showDialog("Report a crash", sb.toString(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias for reportException(ex, null).
|
|
||||||
*/
|
|
||||||
public static void reportException(final Throwable ex) {
|
|
||||||
reportException(ex, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias for reportException(ex, String.format(format, args)).
|
|
||||||
*/
|
|
||||||
public static void reportException(final Throwable ex, final String format, final Object... args) {
|
|
||||||
reportException(ex, String.format(format, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a forum post template for reporting a bug.
|
|
||||||
*/
|
|
||||||
public static void reportBug(String details) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Description: [describe the problem]\n\n");
|
|
||||||
_buildSpoilerHeader(sb, "General bug report");
|
|
||||||
if (null != details && !details.isEmpty()) {
|
|
||||||
sb.append("\n\n");
|
|
||||||
sb.append(details);
|
|
||||||
}
|
|
||||||
_buildSpoilerFooter(sb);
|
|
||||||
|
|
||||||
_showDialog("Report a bug", sb.toString(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows thread stack information in a format ready to post to the forum.
|
|
||||||
*/
|
|
||||||
public static void reportThreadStacks(final String message) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Description: [describe what you were doing at the time]\n\n");
|
|
||||||
_buildSpoilerHeader(sb, "Thread stack dump");
|
|
||||||
sb.append("\n\n");
|
|
||||||
if (null != message && !message.isEmpty()) {
|
|
||||||
sb.append(message);
|
|
||||||
sb.append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
final Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
|
|
||||||
for (final Entry<Thread, StackTraceElement[]> e : traces.entrySet()) {
|
|
||||||
pw.println();
|
|
||||||
pw.printf("%s (%s):%n", e.getKey().getName(), e.getKey().getId());
|
|
||||||
for (final StackTraceElement el : e.getValue()) {
|
|
||||||
pw.println(el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(sw.toString());
|
|
||||||
_buildSpoilerFooter(sb);
|
|
||||||
_showDialog("Thread stack dump", sb.toString(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias for reportThreadStacks(String.format(format, args))
|
|
||||||
*/
|
|
||||||
public static void reportThreadStacks(final String format, final Object... args) {
|
|
||||||
reportThreadStacks(String.format(format, args));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static StringBuilder _buildSpoilerHeader(StringBuilder sb, String reportTitle) {
|
|
||||||
sb.append("[spoiler=").append(reportTitle).append("][code]");
|
|
||||||
sb.append("\nForge Version: ").append(BuildInfo.getVersionString());
|
|
||||||
sb.append("\nOperating System: ").append(System.getProperty("os.name"))
|
|
||||||
.append(" ").append(System.getProperty("os.version"))
|
|
||||||
.append(" ").append(System.getProperty("os.arch"));
|
|
||||||
sb.append("\nJava Version: ").append(System.getProperty("java.version"))
|
|
||||||
.append(" ").append(System.getProperty("java.vendor"));
|
|
||||||
return sb;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static StringBuilder _buildSpoilerFooter(StringBuilder sb) {
|
|
||||||
sb.append("[/code][/spoiler]");
|
|
||||||
return sb;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void _showDialog(String title, String text, boolean showExitAppBtn) {
|
|
||||||
if ( dialogShown )
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*JTextArea area = new JTextArea(text);
|
|
||||||
area.setFont(new Font("Monospaced", Font.PLAIN, 10));
|
|
||||||
area.setEditable(false);
|
|
||||||
area.setLineWrap(true);
|
|
||||||
area.setWrapStyleWord(true);
|
|
||||||
|
|
||||||
String helpText = "<html>A template for a post in the bug reports forum topic is shown below. Just select 'Copy and go to forum' "
|
|
||||||
+ "and the template will be copied to your system clipboard and the forum page will open in your browser. "
|
|
||||||
+ "Then all you have to do is paste the text into a forum post and edit the description line.</html>";
|
|
||||||
String helpUrlLabel = "Reporting bugs in Forge is very important. We sincerely thank you for your time."
|
|
||||||
+ " For help writing a solid bug report, please see:";
|
|
||||||
String helpUrl = "http://www.slightlymagic.net/forum/viewtopic.php?f=26&p=109925#p109925";
|
|
||||||
JPanel helpPanel = new JPanel(new WrapLayout(FlowLayout.LEFT, 4, 2));
|
|
||||||
for (String word : helpUrlLabel.split(" ")) {
|
|
||||||
helpPanel.add(new FLabel.Builder().text("<html>" + word + "</html>").useSkinColors(false).build());
|
|
||||||
}
|
|
||||||
helpPanel.add(new FHyperlink.Builder().url(helpUrl).text("<html>this post</html>").useSkinColors(false).build());
|
|
||||||
|
|
||||||
JPanel p = new JPanel(new MigLayout("wrap"));
|
|
||||||
p.add(new FLabel.Builder().text(helpText).useSkinColors(false).build(), "gap 5");
|
|
||||||
p.add(helpPanel, "w 600");
|
|
||||||
p.add(new JScrollPane(area), "w 100%, h 100%, gaptop 5");
|
|
||||||
|
|
||||||
// determine proper forum URL
|
|
||||||
String forgeVersion = BuildInfo.getVersionString();
|
|
||||||
final String url;
|
|
||||||
if (StringUtils.containsIgnoreCase(forgeVersion, "svn")
|
|
||||||
|| StringUtils.containsIgnoreCase(forgeVersion, "snapshot")) {
|
|
||||||
url = "http://www.slightlymagic.net/forum/viewtopic.php?f=52&t=6333&start=54564487645#bottom";
|
|
||||||
} else {
|
|
||||||
url = "http://www.slightlymagic.net/forum/viewforum.php?f=26";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Button is not modified, String gets the automatic listener to hide
|
|
||||||
// the dialog
|
|
||||||
ArrayList<Object> options = new ArrayList<Object>();
|
|
||||||
options.add(new JButton(new _CopyAndGo(url, area)));
|
|
||||||
options.add(new JButton(new _SaveAction(area)));
|
|
||||||
options.add("Close");
|
|
||||||
if (showExitAppBtn) {
|
|
||||||
options.add(new JButton(new _ExitAction()));
|
|
||||||
}
|
|
||||||
|
|
||||||
JOptionPane pane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE,
|
|
||||||
JOptionPane.DEFAULT_OPTION, null, options.toArray(), options.get(0));
|
|
||||||
JDialog dlg = pane.createDialog(JOptionPane.getRootFrame(), title);
|
|
||||||
dlg.setSize(showExitAppBtn ? 780 : 600, 400);
|
|
||||||
dlg.setResizable(true);
|
|
||||||
dialogShown = true;
|
|
||||||
dlg.setVisible(true);
|
|
||||||
dlg.dispose();
|
|
||||||
dialogShown = false;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@SuppressWarnings("serial")
|
|
||||||
private static class _CopyAndGo extends AbstractAction {
|
|
||||||
private final String url;
|
|
||||||
private final JTextArea text;
|
|
||||||
|
|
||||||
public _CopyAndGo(String url, JTextArea text) {
|
|
||||||
super("Copy and go to forum");
|
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
|
||||||
|
|
||||||
this.url = url;
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent e) {
|
|
||||||
try {
|
|
||||||
// copy text to clipboard
|
|
||||||
StringSelection ss = new StringSelection(text.getText());
|
|
||||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
|
|
||||||
|
|
||||||
// browse to url
|
|
||||||
Desktop.getDesktop().browse(new URI(url));
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
FOptionPane.showMessageDialog("Sorry, a problem occurred while opening the forum in your default browser.",
|
|
||||||
"A problem occurred", FOptionPane.ERROR_ICON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static class _SaveAction extends AbstractAction {
|
|
||||||
private static JFileChooser c;
|
|
||||||
private final JTextArea area;
|
|
||||||
|
|
||||||
public _SaveAction(final JTextArea areaParam) {
|
|
||||||
super("Save to file");
|
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
|
||||||
this.area = areaParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent e) {
|
|
||||||
if (c == null) {
|
|
||||||
c = new JFileChooser();
|
|
||||||
}
|
|
||||||
|
|
||||||
File f;
|
|
||||||
long curTime = System.currentTimeMillis();
|
|
||||||
for (int i = 0;; i++) {
|
|
||||||
final String name = String.format("%TF-%02d.txt", curTime, i);
|
|
||||||
f = new File(name);
|
|
||||||
if (!f.exists()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.setSelectedFile(f);
|
|
||||||
c.showSaveDialog(null);
|
|
||||||
f = c.getSelectedFile();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final BufferedWriter bw = new BufferedWriter(new FileWriter(f));
|
|
||||||
bw.write(this.area.getText());
|
|
||||||
bw.close();
|
|
||||||
}
|
|
||||||
catch (final IOException ex) {
|
|
||||||
FOptionPane.showMessageDialog("There was an error during saving. Sorry!\n" + ex,
|
|
||||||
"Error saving file", FOptionPane.ERROR_ICON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static class _ExitAction extends AbstractAction {
|
|
||||||
public _ExitAction() {
|
|
||||||
super("Exit application");
|
|
||||||
this.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent e) {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// disable instantiation
|
|
||||||
private BugReporter() { }
|
|
||||||
}
|
|
||||||
@@ -16,6 +16,8 @@ import forge.util.ThreadUtil;
|
|||||||
public class VDevMenu extends FDropDownMenu {
|
public class VDevMenu extends FDropDownMenu {
|
||||||
@Override
|
@Override
|
||||||
protected void buildMenu() {
|
protected void buildMenu() {
|
||||||
|
int[] x = null;
|
||||||
|
int y = x[1];
|
||||||
addItem(new FMenuItem("Generate Mana", new FEventHandler() {
|
addItem(new FMenuItem("Generate Mana", new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package forge.deck;
|
|||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
import forge.GuiBase;
|
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
@@ -12,6 +11,7 @@ import forge.deck.CardPool;
|
|||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.DeckGroup;
|
import forge.deck.DeckGroup;
|
||||||
import forge.deck.DeckSection;
|
import forge.deck.DeckSection;
|
||||||
|
import forge.error.BugReporter;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
@@ -289,7 +289,7 @@ public class DeckProxy implements InventoryItem {
|
|||||||
StringBuilder errorBuilder = new StringBuilder();
|
StringBuilder errorBuilder = new StringBuilder();
|
||||||
deck.getMain().addAll(gen.getThemeDeck(this.getName(), 60, errorBuilder));
|
deck.getMain().addAll(gen.getThemeDeck(this.getName(), 60, errorBuilder));
|
||||||
if (errorBuilder.length() > 0) {
|
if (errorBuilder.length() > 0) {
|
||||||
GuiBase.getInterface().reportBug(errorBuilder.toString());
|
BugReporter.reportBug(errorBuilder.toString());
|
||||||
}
|
}
|
||||||
return deck;
|
return deck;
|
||||||
}
|
}
|
||||||
|
|||||||
230
forge-gui/src/main/java/forge/error/BugReporter.java
Normal file
230
forge-gui/src/main/java/forge/error/BugReporter.java
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Forge Team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.error;
|
||||||
|
|
||||||
|
import forge.FThreads;
|
||||||
|
import forge.GuiBase;
|
||||||
|
import forge.SOptionPane;
|
||||||
|
import forge.util.BuildInfo;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class ErrorViewer. Enables showing and saving error messages that
|
||||||
|
* occurred in forge.
|
||||||
|
*
|
||||||
|
* @author Clemens Koza
|
||||||
|
* @version V1.0 02.08.2009
|
||||||
|
*/
|
||||||
|
public class BugReporter {
|
||||||
|
private static final int STACK_OVERFLOW_MAX_MESSAGE_LEN = 16 * 1024;
|
||||||
|
|
||||||
|
public static final String HELP_TEXT =
|
||||||
|
"<html>A template for a post in the bug reports forum topic is shown below. Just select 'Copy and go to forum' "
|
||||||
|
+ "and the template will be copied to your system clipboard and the forum page will open in your browser. "
|
||||||
|
+ "Then all you have to do is paste the text into a forum post and edit the description line.</html>";
|
||||||
|
public static final String HELP_URL_LABEL =
|
||||||
|
"Reporting bugs in Forge is very important. We sincerely thank you for your time."
|
||||||
|
+ " For help writing a solid bug report, please see:";
|
||||||
|
public static final String HELP_URL =
|
||||||
|
"http://www.slightlymagic.net/forum/viewtopic.php?f=26&p=109925#p109925";
|
||||||
|
public static final String FORUM_URL;
|
||||||
|
|
||||||
|
static {
|
||||||
|
String forgeVersion = BuildInfo.getVersionString();
|
||||||
|
if (StringUtils.containsIgnoreCase(forgeVersion, "svn") || StringUtils.containsIgnoreCase(forgeVersion, "snapshot")) {
|
||||||
|
FORUM_URL = "http://www.slightlymagic.net/forum/viewtopic.php?f=52&t=6333&start=54564487645#bottom";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FORUM_URL = "http://www.slightlymagic.net/forum/viewforum.php?f=26";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows exception information in a format ready to post to the forum as a crash report. Uses the exception's message
|
||||||
|
* as the reason if message is null.
|
||||||
|
*/
|
||||||
|
public static void reportException(final Throwable ex, final String message) {
|
||||||
|
if (ex == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (message != null) {
|
||||||
|
System.err.printf("%s > %s%n", FThreads.debugGetCurrThreadId(), message);
|
||||||
|
}
|
||||||
|
System.err.print( FThreads.debugGetCurrThreadId() + " > " );
|
||||||
|
ex.printStackTrace();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Description: [describe what you were doing when the crash occurred]\n\n");
|
||||||
|
buildSpoilerHeader(sb, ex.getClass().getSimpleName());
|
||||||
|
sb.append("\n\n");
|
||||||
|
if (null != message && !message.isEmpty()) {
|
||||||
|
sb.append(FThreads.debugGetCurrThreadId()).append(" > ").append(message).append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
ex.printStackTrace(pw);
|
||||||
|
|
||||||
|
String swStr = sw.toString();
|
||||||
|
if (ex instanceof StackOverflowError && swStr.length() >= STACK_OVERFLOW_MAX_MESSAGE_LEN) {
|
||||||
|
// most likely a cycle. only take first portion so the message
|
||||||
|
// doesn't grow too large to post
|
||||||
|
sb.append(swStr, 0, STACK_OVERFLOW_MAX_MESSAGE_LEN);
|
||||||
|
sb.append("\n... (truncated)");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sb.append(swStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
buildSpoilerFooter(sb);
|
||||||
|
|
||||||
|
GuiBase.getInterface().showBugReportDialog("Report a crash", sb.toString(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for reportException(ex, null).
|
||||||
|
*/
|
||||||
|
public static void reportException(final Throwable ex) {
|
||||||
|
reportException(ex, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for reportException(ex, String.format(format, args)).
|
||||||
|
*/
|
||||||
|
public static void reportException(final Throwable ex, final String format, final Object... args) {
|
||||||
|
reportException(ex, String.format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a forum post template for reporting a bug.
|
||||||
|
*/
|
||||||
|
public static void reportBug(String details) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Description: [describe the problem]\n\n");
|
||||||
|
buildSpoilerHeader(sb, "General bug report");
|
||||||
|
if (null != details && !details.isEmpty()) {
|
||||||
|
sb.append("\n\n");
|
||||||
|
sb.append(details);
|
||||||
|
}
|
||||||
|
buildSpoilerFooter(sb);
|
||||||
|
|
||||||
|
GuiBase.getInterface().showBugReportDialog("Report a bug", sb.toString(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows thread stack information in a format ready to post to the forum.
|
||||||
|
*/
|
||||||
|
public static void reportThreadStacks(final String message) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Description: [describe what you were doing at the time]\n\n");
|
||||||
|
buildSpoilerHeader(sb, "Thread stack dump");
|
||||||
|
sb.append("\n\n");
|
||||||
|
if (null != message && !message.isEmpty()) {
|
||||||
|
sb.append(message);
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
final Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
|
||||||
|
for (final Entry<Thread, StackTraceElement[]> e : traces.entrySet()) {
|
||||||
|
pw.println();
|
||||||
|
pw.printf("%s (%s):%n", e.getKey().getName(), e.getKey().getId());
|
||||||
|
for (final StackTraceElement el : e.getValue()) {
|
||||||
|
pw.println(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(sw.toString());
|
||||||
|
buildSpoilerFooter(sb);
|
||||||
|
GuiBase.getInterface().showBugReportDialog("Thread stack dump", sb.toString(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for reportThreadStacks(String.format(format, args))
|
||||||
|
*/
|
||||||
|
public static void reportThreadStacks(final String format, final Object... args) {
|
||||||
|
reportThreadStacks(String.format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StringBuilder buildSpoilerHeader(StringBuilder sb, String reportTitle) {
|
||||||
|
sb.append("[spoiler=").append(reportTitle).append("][code]");
|
||||||
|
sb.append("\nForge Version: ").append(BuildInfo.getVersionString());
|
||||||
|
sb.append("\nOperating System: ").append(System.getProperty("os.name"))
|
||||||
|
.append(" ").append(System.getProperty("os.version"))
|
||||||
|
.append(" ").append(System.getProperty("os.arch"));
|
||||||
|
sb.append("\nJava Version: ").append(System.getProperty("java.version"))
|
||||||
|
.append(" ").append(System.getProperty("java.vendor"));
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StringBuilder buildSpoilerFooter(StringBuilder sb) {
|
||||||
|
sb.append("[/code][/spoiler]");
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copyAndGoToForums(String text) {
|
||||||
|
try {
|
||||||
|
// copy text to clipboard
|
||||||
|
StringSelection ss = new StringSelection(text);
|
||||||
|
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
|
||||||
|
|
||||||
|
// browse to url
|
||||||
|
Desktop.getDesktop().browse(new URI(FORUM_URL));
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
SOptionPane.showMessageDialog("Sorry, a problem occurred while opening the forum in your default browser.",
|
||||||
|
"A problem occurred", SOptionPane.ERROR_ICON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveToFile(String text) {
|
||||||
|
File f;
|
||||||
|
long curTime = System.currentTimeMillis();
|
||||||
|
for (int i = 0;; i++) {
|
||||||
|
final String name = String.format("%TF-%02d.txt", curTime, i);
|
||||||
|
f = new File(name);
|
||||||
|
if (!f.exists()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f = GuiBase.getInterface().getSaveFile(f);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final BufferedWriter bw = new BufferedWriter(new FileWriter(f));
|
||||||
|
bw.write(text);
|
||||||
|
bw.close();
|
||||||
|
}
|
||||||
|
catch (final IOException ex) {
|
||||||
|
SOptionPane.showMessageDialog("There was an error during saving. Sorry!\n" + ex,
|
||||||
|
"Error saving file", SOptionPane.ERROR_ICON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable instantiation
|
||||||
|
private BugReporter() { }
|
||||||
|
}
|
||||||
@@ -20,8 +20,6 @@ package forge.error;
|
|||||||
|
|
||||||
import com.esotericsoftware.minlog.Log;
|
import com.esotericsoftware.minlog.Log;
|
||||||
|
|
||||||
import forge.GuiBase;
|
|
||||||
|
|
||||||
import java.lang.Thread.UncaughtExceptionHandler;
|
import java.lang.Thread.UncaughtExceptionHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +48,7 @@ public class ExceptionHandler implements UncaughtExceptionHandler {
|
|||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void uncaughtException(final Thread t, final Throwable ex) {
|
public final void uncaughtException(final Thread t, final Throwable ex) {
|
||||||
GuiBase.getInterface().reportException(ex);
|
BugReporter.reportException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,6 +59,6 @@ public class ExceptionHandler implements UncaughtExceptionHandler {
|
|||||||
* a {@link java.lang.Throwable} object.
|
* a {@link java.lang.Throwable} object.
|
||||||
*/
|
*/
|
||||||
public final void handle(final Throwable ex) {
|
public final void handle(final Throwable ex) {
|
||||||
GuiBase.getInterface().reportException(ex);
|
BugReporter.reportException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
|||||||
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||||
|
|
||||||
import forge.GuiBase;
|
|
||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
|
import forge.error.BugReporter;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
@@ -95,7 +95,7 @@ public class GauntletIO {
|
|||||||
|
|
||||||
return data;
|
return data;
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
GuiBase.getInterface().reportException(ex, "Error loading Gauntlet Data");
|
BugReporter.reportException(ex, "Error loading Gauntlet Data");
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
} finally {
|
} finally {
|
||||||
if (null != zin) {
|
if (null != zin) {
|
||||||
@@ -110,7 +110,7 @@ public class GauntletIO {
|
|||||||
final XStream xStream = GauntletIO.getSerializer(false);
|
final XStream xStream = GauntletIO.getSerializer(false);
|
||||||
GauntletIO.savePacked(xStream, gd0);
|
GauntletIO.savePacked(xStream, gd0);
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
GuiBase.getInterface().reportException(ex, "Error saving Gauntlet Data.");
|
BugReporter.reportException(ex, "Error saving Gauntlet Data.");
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.interfaces;
|
package forge.interfaces;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -35,16 +36,15 @@ public interface IGuiBase {
|
|||||||
String getInstallRoot();
|
String getInstallRoot();
|
||||||
String getAssetsDir();
|
String getAssetsDir();
|
||||||
boolean mayShowCard(Card card);
|
boolean mayShowCard(Card card);
|
||||||
void reportBug(String details);
|
|
||||||
void reportException(Throwable ex);
|
|
||||||
void reportException(Throwable ex, String message);
|
|
||||||
ISkinImage getUnskinnedIcon(String path);
|
ISkinImage getUnskinnedIcon(String path);
|
||||||
|
void showBugReportDialog(String title, String text, boolean showExitAppBtn);
|
||||||
int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption);
|
int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption);
|
||||||
<T> T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions);
|
<T> T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions);
|
||||||
<T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display);
|
<T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display);
|
||||||
<T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
<T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
||||||
final List<T> sourceChoices, final List<T> destChoices, final Card referenceCard, final boolean sideboardingMode);
|
final List<T> sourceChoices, final List<T> destChoices, final Card referenceCard, final boolean sideboardingMode);
|
||||||
String showFileDialog(String title, String defaultDir);
|
String showFileDialog(String title, String defaultDir);
|
||||||
|
File getSaveFile(File defaultFile);
|
||||||
void showCardList(final String title, final String message, final List<PaperCard> list);
|
void showCardList(final String title, final String message, final List<PaperCard> list);
|
||||||
void fireEvent(UiEvent e);
|
void fireEvent(UiEvent e);
|
||||||
void setCard(Card card);
|
void setCard(Card card);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.match.input;
|
|||||||
|
|
||||||
import forge.FThreads;
|
import forge.FThreads;
|
||||||
import forge.GuiBase;
|
import forge.GuiBase;
|
||||||
|
import forge.error.BugReporter;
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
@@ -17,8 +18,9 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
|
|||||||
FThreads.assertExecutedByEdt(false);
|
FThreads.assertExecutedByEdt(false);
|
||||||
try{
|
try{
|
||||||
cdlDone.await();
|
cdlDone.await();
|
||||||
} catch (InterruptedException e) {
|
}
|
||||||
GuiBase.getInterface().reportException(e);
|
catch (InterruptedException e) {
|
||||||
|
BugReporter.reportException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package forge.net;
|
package forge.net;
|
||||||
|
|
||||||
import forge.GuiBase;
|
import forge.error.BugReporter;
|
||||||
import forge.net.client.NetClient;
|
import forge.net.client.NetClient;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Connector;
|
import org.eclipse.jetty.server.Connector;
|
||||||
@@ -69,8 +69,9 @@ public class NetServer {
|
|||||||
public void send(String data) {
|
public void send(String data) {
|
||||||
try {
|
try {
|
||||||
_connection.sendMessage(data);
|
_connection.sendMessage(data);
|
||||||
} catch (IOException e) {
|
}
|
||||||
GuiBase.getInterface().reportException(e);
|
catch (IOException e) {
|
||||||
|
BugReporter.reportException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +110,7 @@ public class NetServer {
|
|||||||
String host = connector.getHost();
|
String host = connector.getHost();
|
||||||
serverUri = new URI(String.format("ws://%s:%d/", host == null ? "localhost" : host ,port));
|
serverUri = new URI(String.format("ws://%s:%d/", host == null ? "localhost" : host ,port));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
GuiBase.getInterface().reportException(e);
|
BugReporter.reportException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Server started @ " + serverUri);
|
System.out.println("Server started @ " + serverUri);
|
||||||
@@ -124,7 +125,7 @@ public class NetServer {
|
|||||||
srv.stop();
|
srv.stop();
|
||||||
portNumber = -1;
|
portNumber = -1;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
GuiBase.getInterface().reportException(e);
|
BugReporter.reportException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
|||||||
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||||
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
|
||||||
|
|
||||||
import forge.GuiBase;
|
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.DeckSection;
|
import forge.deck.DeckSection;
|
||||||
|
import forge.error.BugReporter;
|
||||||
import forge.item.*;
|
import forge.item.*;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
@@ -120,15 +120,16 @@ public class QuestDataIO {
|
|||||||
if (data.getVersionNumber() != QuestData.CURRENT_VERSION_NUMBER) {
|
if (data.getVersionNumber() != QuestData.CURRENT_VERSION_NUMBER) {
|
||||||
try {
|
try {
|
||||||
QuestDataIO.updateSaveFile(data, bigXML, xmlSaveFile.getName().replace(".dat", ""));
|
QuestDataIO.updateSaveFile(data, bigXML, xmlSaveFile.getName().replace(".dat", ""));
|
||||||
} catch (final Exception e) {
|
}
|
||||||
GuiBase.getInterface().reportException(e);
|
catch (final Exception e) {
|
||||||
|
BugReporter.reportException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
catch (final Exception ex) {
|
catch (final Exception ex) {
|
||||||
GuiBase.getInterface().reportException(ex, "Error loading Quest Data");
|
BugReporter.reportException(ex, "Error loading Quest Data");
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,7 +359,7 @@ public class QuestDataIO {
|
|||||||
|
|
||||||
}
|
}
|
||||||
catch (final Exception ex) {
|
catch (final Exception ex) {
|
||||||
GuiBase.getInterface().reportException(ex, "Error saving Quest Data.");
|
BugReporter.reportException(ex, "Error saving Quest Data.");
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user