diff --git a/src/main/java/forge/CardReader.java b/src/main/java/forge/CardReader.java index 28da5df7e20..1e57ce6d86d 100644 --- a/src/main/java/forge/CardReader.java +++ b/src/main/java/forge/CardReader.java @@ -37,31 +37,39 @@ import forge.view.FView; * @author Forge * @version $Id$ */ -public class CardReader implements Runnable, NewConstants { +public class CardReader + implements Runnable, // NOPMD by Braids on 8/18/11 10:55 PM + NewConstants +{ + private static final String CARD_FILE_DOT_EXTENSION = ".txt"; // NOPMD by Braids on 8/18/11 11:04 PM + /** Default charset when loading from files. */ - public static final String DEFAULT_CHARSET_NAME = "US-ASCII"; + public static final String DEFAULT_CHARSET_NAME = "US-ASCII"; // NOPMD by Braids on 8/18/11 10:54 PM /** Regex that matches a single hyphen (-) or space. */ public static final Pattern HYPHEN_OR_SPACE = Pattern.compile("[ -]"); /** Regex for punctuation that we omit from card file names. */ - public static final Pattern PUNCTUATION_TO_ZAP = Pattern.compile("[,'\"]"); + public static final Pattern PUNCTUATION_TO_ZAP = Pattern.compile("[,'\"]"); // NOPMD by Braids on 8/18/11 10:54 PM /** Regex that matches two or more underscores (_). */ - public static final Pattern MULTIPLE_UNDERSCORES = Pattern.compile("__+"); + public static final Pattern MULTIPLE_UNDERSCORES = Pattern.compile("__+"); // NOPMD by Braids on 8/18/11 10:54 PM /** Special value for estimatedFilesRemaining. */ - protected static final int UNKNOWN_NUMBER_OF_FILES_REMAINING = -1; + protected static final int UNKNOWN_NUMBER_OF_FILES_REMAINING = -1; // NOPMD by Braids on 8/18/11 10:54 PM - private Map mapToFill; - private File cardsfolder; + private transient Map mapToFill; + private transient File cardsfolder; - private ZipFile zip; - private Charset charset; + private transient ZipFile zip; + private transient Charset charset; - private Enumeration zipEnum; - private long estimatedFilesRemaining = UNKNOWN_NUMBER_OF_FILES_REMAINING; - private Iterable findNonDirsIterable; + private transient Enumeration zipEnum; + + private transient long estimatedFilesRemaining = // NOPMD by Braids on 8/18/11 10:56 PM + UNKNOWN_NUMBER_OF_FILES_REMAINING; + + private transient Iterable findNonDirsIterable; // NOPMD by Braids on 8/18/11 10:56 PM @@ -90,17 +98,19 @@ public class CardReader implements Runnable, NewConstants { */ public CardReader(final File theCardsFolder, final Map theMapToFill, final boolean useZip) { if (theMapToFill == null) { - throw new NullPointerException("theMapToFill must not be null."); + throw new NullPointerException("theMapToFill must not be null."); // NOPMD by Braids on 8/18/11 10:53 PM } this.mapToFill = theMapToFill; if (!theCardsFolder.exists()) { - throw new RuntimeException("CardReader : constructor error -- file not found -- filename is " + throw new RuntimeException(// NOPMD by Braids on 8/18/11 10:53 PM + "CardReader : constructor error -- file not found -- filename is " + theCardsFolder.getAbsolutePath()); } if (!theCardsFolder.isDirectory()) { - throw new RuntimeException("CardReader : constructor error -- not a directory -- " + throw new RuntimeException(// NOPMD by Braids on 8/18/11 10:53 PM + "CardReader : constructor error -- not a directory -- " + theCardsFolder.getAbsolutePath()); } @@ -114,7 +124,7 @@ public class CardReader implements Runnable, NewConstants { try { this.zip = new ZipFile(zipFile); } catch (Exception exn) { - System.err.println("Error reading zip file \"" + System.err.println("Error reading zip file \"" // NOPMD by Braids on 8/18/11 10:53 PM + zipFile.getAbsolutePath() + "\": " + exn + ". " + "Defaulting to txt files in \"" + theCardsFolder.getAbsolutePath() @@ -186,28 +196,7 @@ public class CardReader implements Runnable, NewConstants { } - if (zip != null) { - monitor.setTotalUnitsThisPhase(estimatedFilesRemaining); - ZipEntry entry; - - // zipEnum was initialized in the constructor. - while (zipEnum.hasMoreElements()) { - entry = (ZipEntry) zipEnum.nextElement(); - - if (entry.isDirectory() || !entry.getName().endsWith(".txt")) { - monitor.incrementUnitsCompletedThisPhase(1L); - continue; - } - - result = loadCard(entry); - monitor.incrementUnitsCompletedThisPhase(1L); - - if (cardName != null && cardName.equals(result.getName())) { - break; - } - } - - } else { + if (zip == null) { if (estimatedFilesRemaining == UNKNOWN_NUMBER_OF_FILES_REMAINING) { final Generator findNonDirsGen = new FindNonDirectoriesSkipDotDirectoriesGenerator(cardsfolder); estimatedFilesRemaining = GeneratorFunctions.estimateSize(findNonDirsGen); @@ -217,7 +206,7 @@ public class CardReader implements Runnable, NewConstants { monitor.setTotalUnitsThisPhase(estimatedFilesRemaining); for (File cardTxtFile : findNonDirsIterable) { - if (!cardTxtFile.getName().endsWith(".txt")) { + if (!cardTxtFile.getName().endsWith(CARD_FILE_DOT_EXTENSION)) { monitor.incrementUnitsCompletedThisPhase(1L); continue; } @@ -231,6 +220,27 @@ public class CardReader implements Runnable, NewConstants { } //endfor + } else { + monitor.setTotalUnitsThisPhase(estimatedFilesRemaining); + ZipEntry entry; + + // zipEnum was initialized in the constructor. + while (zipEnum.hasMoreElements()) { + entry = (ZipEntry) zipEnum.nextElement(); + + if (entry.isDirectory() || !entry.getName().endsWith(CARD_FILE_DOT_EXTENSION)) { + monitor.incrementUnitsCompletedThisPhase(1L); + continue; + } + + result = loadCard(entry); + monitor.incrementUnitsCompletedThisPhase(1L); + + if (cardName != null && cardName.equals(result.getName())) { + break; + } + } + } //endif if (monitor != null) { @@ -270,7 +280,7 @@ public class CardReader implements Runnable, NewConstants { return line; } catch (Exception ex) { ErrorViewer.showError(ex); - throw new RuntimeException("CardReader : readLine(Card) error", ex); + throw new RuntimeException("CardReader : readLine(Card) error", ex); // NOPMD by Braids on 8/18/11 10:53 PM } } //readLine(BufferedReader) @@ -290,76 +300,88 @@ public class CardReader implements Runnable, NewConstants { inputStreamReader = new InputStreamReader(inputStream, charset); reader = new BufferedReader(inputStreamReader); - String s = readLine(reader); - while (!"End".equals(s)) { - if (s.startsWith("#")) { + String line = readLine(reader); + while (!"End".equals(line)) { + if (line.charAt(0) == '#') { // NOPMD by Braids on 8/18/11 10:59 PM //no need to do anything, this indicates a comment line - } else if (s.startsWith("Name:")) { - String t = s.substring(5); + } else if (line.startsWith("Name:")) { + final String value = line.substring(5); //System.out.println(s); - if (!mapToFill.containsKey(t)) { - card.setName(t); - } else { + if (mapToFill.containsKey(value)) { break; // this card has already been loaded. + } else { + card.setName(value); } - } else if (s.startsWith("ManaCost:")) { - String t = s.substring(9); + } else if (line.startsWith("ManaCost:")) { + final String value = line.substring(9); //System.out.println(s); - if (!"no cost".equals(t)) { - card.setManaCost(t); + if (!"no cost".equals(value)) { + card.setManaCost(value); } - } else if (s.startsWith("Types:")) { - addTypes(card, s.substring(6)); - } else if (s.startsWith("Text:")) { - String t = s.substring(5); + } else if (line.startsWith("Types:")) { + addTypes(card, line.substring("Types:".length())); + } else if (line.startsWith("Text:")) { + String value = line.substring("Text:".length()); // if (!t.equals("no text")); - if ("no text".equals(t)) { - t = ""; + if ("no text".equals(value)) { + value = ""; } - card.setText(t); - } else if (s.startsWith("PT:")) { - String t = s.substring(3); - String[] pt = t.split("/"); - int att = pt[0].contains("*") ? 0 : Integer.parseInt(pt[0]); - int def = pt[1].contains("*") ? 0 : Integer.parseInt(pt[1]); - card.setBaseAttackString(pt[0]); - card.setBaseDefenseString(pt[1]); + card.setText(value); + } else if (line.startsWith("PT:")) { + final String value = line.substring("PT:".length()); + final String[] powTough = value.split("/"); + int att; + if (powTough[0].contains("*")) { + att = 0; + } else { + att = Integer.parseInt(powTough[0]); + } + + int def; + if (powTough[1].contains("*")) { + def = 0; + } else { + def = Integer.parseInt(powTough[1]); + } + + card.setBaseAttackString(powTough[0]); + card.setBaseDefenseString(powTough[1]); card.setBaseAttack(att); card.setBaseDefense(def); - } else if (s.startsWith("Loyalty:")) { - String[] splitStr = s.split(":"); - int loyal = Integer.parseInt(splitStr[1]); + } else if (line.startsWith("Loyalty:")) { + final String[] splitStr = line.split(":"); + final int loyal = Integer.parseInt(splitStr[1]); card.setBaseLoyalty(loyal); - } else if (s.startsWith("K:")) { - String t = s.substring(2); - card.addIntrinsicKeyword(t); - } else if (s.startsWith("SVar:")) { - String[] t = s.split(":", 3); - card.setSVar(t[1], t[2]); - } else if (s.startsWith("A:")) { - String t = s.substring(2); - card.addIntrinsicAbility(t); - } else if (s.startsWith("T:")) { - String t = s.substring(2); - card.addTrigger(TriggerHandler.parseTrigger(t, card, true)); - } else if (s.startsWith("S:")) { - String t = s.substring(2); - card.addStaticAbilityString(t); - } else if (s.startsWith("SetInfo:")) { - String t = s.substring(8); - card.addSet(new SetInfo(t)); + } else if (line.startsWith("K:")) { + final String value = line.substring(2); + card.addIntrinsicKeyword(value); + } else if (line.startsWith("SVar:")) { + final String[] value = line.split(":", 3); + card.setSVar(value[1], value[2]); + } else if (line.startsWith("A:")) { + final String value = line.substring(2); + card.addIntrinsicAbility(value); + } else if (line.startsWith("T:")) { + final String value = line.substring(2); + card.addTrigger(TriggerHandler.parseTrigger(value, card, true)); + } else if (line.startsWith("S:")) { + final String value = line.substring(2); + card.addStaticAbilityString(value); + } else if (line.startsWith("SetInfo:")) { + final String value = line.substring("SetInfo:".length()); + card.addSet(new SetInfo(value)); // NOPMD by Braids on 8/18/11 11:08 PM } - s = readLine(reader); + line = readLine(reader); } // while !End } finally { try { reader.close(); - } catch (IOException ignored) { + } catch (IOException ignored) { // NOPMD by Braids on 8/18/11 11:08 PM } try { inputStreamReader.close(); - } catch (IOException ignored) { + } catch (IOException ignored) { // NOPMD by Braids on 8/18/11 11:08 PM } } @@ -392,12 +414,13 @@ public class CardReader implements Runnable, NewConstants { return loadCard(fileInputStream); } catch (FileNotFoundException ex) { ErrorViewer.showError(ex, "File \"%s\" exception", pathToTxtFile.getAbsolutePath()); - throw new RuntimeException("CardReader : run error -- file exception -- filename is " + throw new RuntimeException(// NOPMD by Braids on 8/18/11 10:53 PM + "CardReader : run error -- file exception -- filename is " + pathToTxtFile.getPath(), ex); } finally { try { fileInputStream.close(); - } catch (IOException ignored) { + } catch (IOException ignored) { // NOPMD by Braids on 8/18/11 11:08 PM } } } @@ -416,13 +439,13 @@ public class CardReader implements Runnable, NewConstants { return loadCard(zipInputStream); } catch (IOException exn) { - throw new RuntimeException(exn); + throw new RuntimeException(exn); // NOPMD by Braids on 8/18/11 10:53 PM } finally { try { if (zipInputStream != null) { zipInputStream.close(); } - } catch (IOException ignored) { + } catch (IOException ignored) { // NOPMD by Braids on 8/18/11 11:08 PM } } } @@ -455,14 +478,14 @@ public class CardReader implements Runnable, NewConstants { baseFileName = PUNCTUATION_TO_ZAP.matcher(baseFileName).replaceAll(""); // Place the file within a single-letter subdirectory. - StringBuffer buf = new StringBuffer(1 + 1 + baseFileName.length() + ".txt".length()); + final StringBuffer buf = new StringBuffer(1 + 1 + baseFileName.length() + CARD_FILE_DOT_EXTENSION.length()); buf.append(Character.toLowerCase(baseFileName.charAt(0))); // Zip file is always created with unix-style path names. buf.append('/'); buf.append(baseFileName.toLowerCase(Locale.ENGLISH)); - buf.append(".txt"); + buf.append(CARD_FILE_DOT_EXTENSION); return buf.toString(); } @@ -474,20 +497,18 @@ public class CardReader implements Runnable, NewConstants { * * @return a new Card instance having that name, or null if not found */ - public final Card findCard(final String canonicalASCIIName) { + public final Card findCard(final String canonicalASCIIName) { // NOPMD by Braids on 8/18/11 11:08 PM UtilFunctions.checkNotNull("canonicalASCIIName", canonicalASCIIName); - String cardFilePath = toMostLikelyPath(canonicalASCIIName); + final String cardFilePath = toMostLikelyPath(canonicalASCIIName); Card result = null; if (zip != null) { - ZipEntry entry = zip.getEntry(cardFilePath); + final ZipEntry entry = zip.getEntry(cardFilePath); if (entry != null) { result = loadCard(entry); - } else { - //System.err.println(":Could not find \"" + cardFilePath + "\" in zip file."); } } diff --git a/src/main/java/forge/gui/MultiPhaseProgressMonitorWithETA.java b/src/main/java/forge/gui/MultiPhaseProgressMonitorWithETA.java index ba9d0d3b4ed..2935ef641ea 100644 --- a/src/main/java/forge/gui/MultiPhaseProgressMonitorWithETA.java +++ b/src/main/java/forge/gui/MultiPhaseProgressMonitorWithETA.java @@ -1,107 +1,115 @@ package forge.gui; -import java.lang.reflect.InvocationTargetException; - import javax.swing.JDialog; import javax.swing.JProgressBar; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; -import forge.Gui_ProgressBarWindow; import net.slightlymagic.braids.util.UtilFunctions; import net.slightlymagic.braids.util.progress_monitor.BaseProgressMonitor; +import forge.Gui_ProgressBarWindow; /** * GUI Progress Monitor that displays the ETA (Estimated Time of Arrival or - * completion) on some platforms and supports one or multiple phases of + * completion) on some platforms and supports one or multiple phases of * progress. - * + * * In this implementation, each phase opens a new dialog. */ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { - private Gui_ProgressBarWindow dialog; - private String title; + private transient Gui_ProgressBarWindow dialog; + private transient String title; - /** - * Convenience for - * MultiPhaseProgressMonitorWithETA(title, numPhases, totalUnitsFirstPhase, - * minUIUpdateIntervalSec, null); - * - * @see #MultiPhaseProgressMonitorWithETA(String,int,long,float,float[]) - */ - public MultiPhaseProgressMonitorWithETA(String title, int numPhases, - long totalUnitsFirstPhase, float minUIUpdateIntervalSec) - { - this(title, numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec, null); - } - /** - * Create a GUI progress monitor and open its first dialog. - * - * Like all swing components, this constructor must be invoked from the - * swing Event Dispatching Thread. The rest of the methods of this class - * are exempt from this requirement. - * - * @param title the title to give the dialog box(es) - * - * @param numPhases the total number of phases to expect - * - * @param totalUnitsFirstPhase the total number of units that will be - * processed in the first phase - * - * @param minUIUpdateIntervalSec the approximate interval at which to - * update the dialog box in seconds - * - * @param phaseWeights see BaseProgressMonitor - * - * @see BaseProgressMonitor#BaseProgressMonitor(int,long,float,float[]) - */ - public MultiPhaseProgressMonitorWithETA(String title, int numPhases, - long totalUnitsFirstPhase, float minUIUpdateIntervalSec, - float[] phaseWeights) - { - super(numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec, - phaseWeights); + /** + * Convenience for + * MultiPhaseProgressMonitorWithETA(title, numPhases, totalUnitsFirstPhase, + * minUIUpdateIntervalSec, null). + * + * @see #MultiPhaseProgressMonitorWithETA(String,int,long,float,float[]) + * + * @param neoTitle the title to give the dialog box(es) + * + * @param numPhases the total number of phases to expect + * + * @param totalUnitsFirstPhase the total number of units that will be + * processed in the first phase + * + * @param minUIUpdateIntervalSec the approximate interval at which to + * update the dialog box in seconds + */ + public MultiPhaseProgressMonitorWithETA(final String neoTitle, final int numPhases, + final long totalUnitsFirstPhase, final float minUIUpdateIntervalSec) // NOPMD by Braids on 8/18/11 11:16 PM + { + this(neoTitle, numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec, null); + } + /** + * Create a GUI progress monitor and open its first dialog. + * + * Like all swing components, this constructor must be invoked from the + * swing Event Dispatching Thread. The rest of the methods of this class + * are exempt from this requirement. + * + * @param neoTitle the title to give the dialog box(es) + * + * @param numPhases the total number of phases to expect + * + * @param totalUnitsFirstPhase the total number of units that will be + * processed in the first phase + * + * @param minUIUpdateIntervalSec the approximate interval at which to + * update the dialog box in seconds + * + * @param phaseWeights see BaseProgressMonitor + * + * @see BaseProgressMonitor#BaseProgressMonitor(int,long,float,float[]) + */ + public MultiPhaseProgressMonitorWithETA(final String neoTitle, final int numPhases, + final long totalUnitsFirstPhase, final float minUIUpdateIntervalSec, // NOPMD by Braids on 8/18/11 11:16 PM + final float[] phaseWeights) + { + super(numPhases, totalUnitsFirstPhase, minUIUpdateIntervalSec, + phaseWeights); if (!SwingUtilities.isEventDispatchThread()) { throw new IllegalStateException("must be called from within an event dispatch thread"); } - this.title = title; + this.title = neoTitle; - if (totalUnitsFirstPhase > 0 && dialog == null) { - throw new IllegalStateException("dialog is null"); - } - } + if (totalUnitsFirstPhase > 0 && dialog == null) { + throw new IllegalStateException("dialog is null"); + } + } - /** - * For developer testing. - * - * @param args ignored - */ + /** + * For developer testing. + * + * @param args ignored + */ public static void main(final String[] args) { - System.out.println("Initializing..."); + System.out.println("Initializing..."); // NOPMD by Braids on 8/18/11 11:13 PM - SwingUtilities.invokeLater(new Runnable() { + SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:16 PM public void run() { - final int totalUnitsFirstPhase = 5000; + final int totalUnitsFirstPhase = 5000; // NOPMD by Braids on 8/18/11 11:16 PM final MultiPhaseProgressMonitorWithETA monitor = - new MultiPhaseProgressMonitorWithETA("Testing 2 phases", 2, totalUnitsFirstPhase, 1.0f, - new float[] {2, 1}); + new MultiPhaseProgressMonitorWithETA("Testing 2 phases", 2, totalUnitsFirstPhase, 1.0f, + new float[] {2, 1}); - SwingWorker worker = new SwingWorker() { + final SwingWorker worker = new SwingWorker() { @Override public Object doInBackground() { - System.out.println("Running..."); + System.out.println("Running..."); // NOPMD by Braids on 8/18/11 11:14 PM for (int i = 0; i <= totalUnitsFirstPhase; i++) { monitor.incrementUnitsCompletedThisPhase(1); - System.out.print("\ri = " + i); + System.out.print("\ri = " + i); // NOPMD by Braids on 8/18/11 11:14 PM try { Thread.sleep(1); @@ -109,15 +117,15 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { // blank } } - System.out.println(); + System.out.println(); // NOPMD by Braids on 8/18/11 11:14 PM - final int totalUnitsSecondPhase = 2000; + final int totalUnitsSecondPhase = 2000; // NOPMD by Braids on 8/18/11 11:17 PM monitor.markCurrentPhaseAsComplete(totalUnitsSecondPhase); for (int i = 0; i <= totalUnitsSecondPhase; i++) { monitor.incrementUnitsCompletedThisPhase(1); - System.out.print("\ri = " + i); + System.out.print("\ri = " + i); // NOPMD by Braids on 8/18/11 11:14 PM try { Thread.sleep(1); @@ -128,8 +136,8 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { monitor.markCurrentPhaseAsComplete(0); - System.out.println(); - System.out.println("Done!"); + System.out.println(); // NOPMD by Braids on 8/18/11 11:14 PM + System.out.println("Done!"); // NOPMD by Braids on 8/18/11 11:14 PM return null; } @@ -143,22 +151,22 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { - @Override - /** - * @param numUnits cannot be higher than Integer.MAX_VALUE - * - * @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#setTotalUnitsThisPhase(long) - */ - public void setTotalUnitsThisPhase(final long numUnits) { - super.setTotalUnitsThisPhase(numUnits); - - if (numUnits > Integer.MAX_VALUE) { - throw new IllegalArgumentException("numUnits must be <= " + Integer.MAX_VALUE); - } + @Override + /** + * @param numUnits cannot be higher than Integer.MAX_VALUE + * + * @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#setTotalUnitsThisPhase(long) + */ + public final void setTotalUnitsThisPhase(final long numUnits) { + super.setTotalUnitsThisPhase(numUnits); + + if (numUnits > Integer.MAX_VALUE) { + throw new IllegalArgumentException("numUnits must be <= " + Integer.MAX_VALUE); + } if (numUnits > 0) { // dialog must exist before we exit this method. - UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() { + UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() { // NOPMD by Braids on 8/18/11 11:17 PM public void run() { // (Re)create the progress bar. if (dialog != null) { @@ -171,7 +179,7 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { }); } - SwingUtilities.invokeLater(new Runnable() { + SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:18 PM public void run() { dialog.setTitle(title); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); @@ -181,25 +189,25 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { dialog.setProgressRange(0, (int) numUnits); dialog.reset(); - JProgressBar bar = dialog.getProgressBar(); + final JProgressBar bar = dialog.getProgressBar(); bar.setString(""); bar.setStringPainted(true); bar.setValue(0); - } - }); + } + }); - } + } @Override - /** - * @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#incrementUnitsCompletedThisPhase(long) - */ - public void incrementUnitsCompletedThisPhase(final long numUnits) { - super.incrementUnitsCompletedThisPhase(numUnits); + /** + * @see net.slightlymagic.braids.util.progress_monitor.ProgressMonitor#incrementUnitsCompletedThisPhase(long) + */ + public final void incrementUnitsCompletedThisPhase(final long numUnits) { + super.incrementUnitsCompletedThisPhase(numUnits); - SwingUtilities.invokeLater(new Runnable() { + SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:18 PM public void run() { - for (int i = 0 ; i < numUnits ; i++) { + for (int i = 0; i < numUnits; i++) { dialog.increment(); } } @@ -207,46 +215,46 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { if (shouldUpdateUI()) { - if ((getNumPhases() > 1)) { + if ((getNumPhases() > 1)) { displayUpdate( - "Phase " + getCurrentPhase() + ". " + - //getUnitsCompletedSoFarThisPhase() + " units processed. " + - //"Overall: " + getTotalPercentCompleteAsString() + "% complete, " + - "Overall ETA in " + getRelativeETAAsString() + "." + "Phase " + getCurrentPhase() + ". " + //+ getUnitsCompletedSoFarThisPhase() + " units processed. " + //+ "Overall: " + getTotalPercentCompleteAsString() + "% complete, " + + "Overall ETA in " + getRelativeETAAsString() + "." ); } else { displayUpdate( - //"Overall: " + - getUnitsCompletedSoFarThisPhase() + " units processed; " + - //"(" + getTotalPercentCompleteAsString() + "%); " + - "ETA in " + getRelativeETAAsString() + "." + //"Overall: " + + getUnitsCompletedSoFarThisPhase() + " units processed; " + //+ "(" + getTotalPercentCompleteAsString() + "%); " + + "ETA in " + getRelativeETAAsString() + "." ); } } - - if (getCurrentPhase() == getNumPhases() && - getUnitsCompletedSoFarThisPhase() >= getTotalUnitsThisPhase()) + + if (getCurrentPhase() == getNumPhases() + && getUnitsCompletedSoFarThisPhase() >= getTotalUnitsThisPhase()) { - displayUpdate("Done!"); + displayUpdate("Done!"); } } /** * Shows the message inside the progress dialog; does not always work on * all platforms. - * + * * @param message the message to display */ - public void displayUpdate(final String message) { + public final void displayUpdate(final String message) { - final Runnable proc = new Runnable() { + final Runnable proc = new Runnable() { // NOPMD by Braids on 8/18/11 11:18 PM public void run() { - // i've been having trouble getting the dialog to display its title. - dialog.setTitle(title); + // i've been having trouble getting the dialog to display its title. + dialog.setTitle(title); - JProgressBar bar = dialog.getProgressBar(); - bar.setString(message); + JProgressBar bar = dialog.getProgressBar(); + bar.setString(message); justUpdatedUI(); } @@ -263,7 +271,7 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { @Override public final void dispose() { - SwingUtilities.invokeLater(new Runnable() { + SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:18 PM public void run() { getDialog().dispose(); } @@ -275,8 +283,8 @@ public class MultiPhaseProgressMonitorWithETA extends BaseProgressMonitor { * @return the JDialog for the current phase; use this judiciously to * manipulate the dialog directly. */ - public JDialog getDialog() { - return dialog; + public final JDialog getDialog() { + return dialog; } - + } diff --git a/src/main/java/forge/view/swing/ApplicationView.java b/src/main/java/forge/view/swing/ApplicationView.java index be97992e315..b4f80385b16 100644 --- a/src/main/java/forge/view/swing/ApplicationView.java +++ b/src/main/java/forge/view/swing/ApplicationView.java @@ -1,7 +1,5 @@ package forge.view.swing; -import java.lang.reflect.InvocationTargetException; - import javax.swing.SwingUtilities; import javax.swing.UIManager; @@ -28,24 +26,24 @@ import forge.view.swing.OldGuiNewGame.CardStackOffsetAction; */ public class ApplicationView implements FView { - private SplashFrame splashFrame; + private transient SplashFrame splashFrame; /** * The splashFrame field is guaranteed to exist when this constructor - * exits. + * exits. */ public ApplicationView() { - - // We must use invokeAndWait here to fulfill the constructor's + + // We must use invokeAndWait here to fulfill the constructor's // contract. - UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() { + UtilFunctions.invokeInEventDispatchThreadAndWait(new Runnable() { // NOPMD by Braids on 8/18/11 11:37 PM public void run() { splashFrame = new SplashFrame(); } }); - - SwingUtilities.invokeLater(new Runnable() { + + SwingUtilities.invokeLater(new Runnable() { // NOPMD by Braids on 8/18/11 11:37 PM public void run() { splashFrame.setVisible(true); } @@ -83,7 +81,10 @@ public class ApplicationView implements FView { OldGuiNewGame.smoothLandCheckBox.setSelected(preferences.stackAiLand); OldGuiNewGame.devModeCheckBox.setSelected(preferences.developerMode); OldGuiNewGame.cardOverlay.setSelected(preferences.cardOverlay); + + // FindBugs doesn't like the next line. ImageCache.scaleLargerThanOriginal = preferences.scaleLargerThanOriginal; + OldGuiNewGame.cardScale.setSelected(preferences.scaleLargerThanOriginal); CardStackOffsetAction.set(preferences.stackOffset); CardStackAction.setVal(preferences.maxStackSize); diff --git a/src/main/java/net/slightlymagic/braids/util/UtilFunctions.java b/src/main/java/net/slightlymagic/braids/util/UtilFunctions.java index 889893a5d81..6784db0ea22 100644 --- a/src/main/java/net/slightlymagic/braids/util/UtilFunctions.java +++ b/src/main/java/net/slightlymagic/braids/util/UtilFunctions.java @@ -11,51 +11,55 @@ import javax.swing.SwingUtilities; * Some general-purpose functions. */ public final class UtilFunctions { - /** - * Do not instantiate. - */ - private UtilFunctions() {;} - - /** - * Throws a NullPointerException if param is null. - * - * @param paramName the name of the parameter; may be null - * @param param the parameter to test - */ - public static void checkNotNull(String paramName, Object param) { - if (param != null) return; - - NullPointerException exn = null; + /** + * Do not instantiate. + */ + private UtilFunctions() { + // empty + } - if (paramName != null) { - exn = new NullPointerException(paramName + " must not be null"); - } - else { - // - exn = new NullPointerException(); - } - - // Doctor the exception to appear to come from the caller. - StackTraceElement[] trace = exn.getStackTrace(); - int len = getSliceLength(trace, 1); - exn.setStackTrace(slice(new StackTraceElement[len], trace, 1)); - throw exn; - } - /** - * Invoke the given Runnable in an Event Dispatch Thread and wait for it - * to finish; but try to use SwingUtilities.invokeLater instead whenever - * feasible. - * - * Exceptions generated by SwingUtilities.invokeAndWait (if used), are - * rethrown as RuntimeExceptions. - * - * @see javax.swing.SwingUtilities#invokeLater(Runnable) - * - * @param proc the Runnable to run - */ - public static void invokeInEventDispatchThreadAndWait(final Runnable proc) { + /** + * Throws a NullPointerException if param is null. + * + * @param paramName the name of the parameter; may be null + * @param param the parameter to test + */ + public static void checkNotNull(final String paramName, final Object param) { + if (param != null) { + return; + } + + NullPointerException exn = null; + + if (paramName == null) { + exn = new NullPointerException(); // NOPMD by Braids on 8/18/11 11:19 PM + } + else { + exn = new NullPointerException(paramName + " must not be null"); // NOPMD by Braids on 8/18/11 11:19 PM + } + + // Doctor the exception to appear to come from the caller. + final StackTraceElement[] trace = exn.getStackTrace(); + final int len = getSliceLength(trace, 1); + exn.setStackTrace(slice(new StackTraceElement[len], trace, 1)); + throw exn; + } + + /** + * Invoke the given Runnable in an Event Dispatch Thread and wait for it + * to finish; but try to use SwingUtilities.invokeLater instead whenever + * feasible. + * + * Exceptions generated by SwingUtilities.invokeAndWait (if used), are + * rethrown as RuntimeExceptions. + * + * @see javax.swing.SwingUtilities#invokeLater(Runnable) + * + * @param proc the Runnable to run + */ + public static void invokeInEventDispatchThreadAndWait(final Runnable proc) { // NOPMD by Braids on 8/18/11 11:19 PM if (SwingUtilities.isEventDispatchThread()) { // Just run in the current thread. proc.run(); @@ -64,234 +68,271 @@ public final class UtilFunctions { try { SwingUtilities.invokeAndWait(proc); } catch (InterruptedException exn) { - throw new RuntimeException(exn); + throw new RuntimeException(exn); // NOPMD by Braids on 8/18/11 11:19 PM } catch (InvocationTargetException exn) { - throw new RuntimeException(exn); + throw new RuntimeException(exn); // NOPMD by Braids on 8/18/11 11:19 PM } } } /** - * Create an array from the (rest of) an iterator's output; - * this function is horribly inefficient. - * - * Please, only use it on small iterators. - * - * @param iter the iterator to traverse - * - * @return an array of (the rest of) the iterator's values - */ - public static T[] iteratorToArray(Iterator iter) { - ArrayList list = new ArrayList(); - - T item; - while (iter.hasNext()) { - item = iter.next(); - list.add(item); - } - - @SuppressWarnings("unchecked") - T[] result = (T[]) list.toArray(); - return result; - } - - - /** - * Returns the rightmost portion of an array, Python-style. - * - * @param (inferred automatically) - * - * @param srcArray the array to copy (shallowly) - * - * @param startIndex if positive, the index (from the left) at which to - * start copying; if negative, we treat this as the index from the right. - * For example, calling this with startIndex = -2 returns the last two - * items in the array, if it has that many. - * - * @return a shallow copy of array starting at startIndex; this may return - * an empty array if the startIndex is out of bounds. - */ - public static T[] slice(T[] dstArray, T[] srcArray, - int startIndex) - { - if (startIndex < 0) { - startIndex = srcArray.length + startIndex; - if (startIndex < 0) startIndex = 0; - } + * Create an array from the (rest of) an iterator's output; + * this function is horribly inefficient. + * + * Please, only use it on small iterators. + * + * @param (inferred automatically) + * + * @param iter the iterator to traverse + * + * @return an array of (the rest of) the iterator's values + */ + public static T[] iteratorToArray(final Iterator iter) { + final ArrayList list = new ArrayList(); - if (dstArray == null) { - throw new NullPointerException(); - } - - if (srcArray == null) { - throw new NullPointerException(); - } - - int resultLength = getSliceLength(srcArray, startIndex); - - if (dstArray.length != resultLength) { - throw new ArrayIndexOutOfBoundsException( - "First parameter must have length " + resultLength + ", but length is " + dstArray.length + "."); - } - - int srcIx = startIndex; - - for (int dstIx = 0; - dstIx < resultLength && srcIx < srcArray.length; - dstIx++, srcIx++) - { - dstArray[dstIx] = srcArray[srcIx]; - } - - return dstArray; - } + T item; + while (iter.hasNext()) { + item = iter.next(); + list.add(item); + } - - /** - * Get a slice's length in preparation for taking a slice. - * - * I do not like the fact that I have to use this function, but - * Java left me with little choice. - * - * @see #slice(Object[], Object[], int) - * - * @return the length of the array that would result from calling - * slice(Object[], Object[], int) with the given srcArray and - * startIndex. - */ - public static int getSliceLength(T[] srcArray, int startIndex) { - if (startIndex < 0) { - startIndex = srcArray.length + startIndex; - if (startIndex < 0) startIndex = 0; - } + @SuppressWarnings("unchecked") + final T[] result = (T[]) list.toArray(); + return result; + } - int resultLength = srcArray.length - startIndex; - return resultLength; - } - - /** - * Handles the boilerplate null and isinstance check for an equals method. - * - * Example: - *
-	 * public boolean equals(Object obj) {
-	 *     MyClassName that = checkNullOrNotInstance(this, obj);
-	 *     if (that == null) {
-	 *         return false;
-	 *     }
-	 *     //...
-	 * }
-	 * 
- * - * @param goodInstance a non-null instance of type T; looks neater than - * passing in goodInstance.getClass() - * - * @param obj the object to test - * - * @return null if obj is null or not an instance of goodInstance's class; - * otherwise, we return obj cast to goodInstance's type - */ - public static T checkNullOrNotInstance(T goodInstance, Object obj) { - if (goodInstance == null) { - throw new NullPointerException("first parameter must not be null"); - } - - @SuppressWarnings("unchecked") - Class classT = (Class) goodInstance.getClass(); - - boolean viable = true; + /** + * Returns the rightmost portion of an array, Python-style. + * + * @param (inferred automatically) + * + * @param dstArray the array in which to place new items + * + * @param srcArray the array to copy (shallowly) + * + * @param startIndexIn if positive, the index (from the left) at which to + * start copying; if negative, we treat this as the index from the right. + * For example, calling this with startIndex = -2 returns the last two + * items in the array, if it has that many. + * + * @return a shallow copy of array starting at startIndex; this may return + * an empty array if the startIndex is out of bounds. + */ + public static T[] slice(final T[] dstArray, final T[] srcArray, + final int startIndexIn) + { + int startIndex = startIndexIn; + if (startIndex < 0) { + startIndex = srcArray.length + startIndex; + if (startIndex < 0) { + startIndex = 0; + } + } - if (obj == null) viable = false; - else if (!(classT.isInstance(obj))) viable = false; + if (dstArray == null) { + throw new NullPointerException(); // NOPMD by Braids on 8/18/11 11:19 PM + } - if (viable) { - return classT.cast(obj); - } - return null; - } + if (srcArray == null) { + throw new NullPointerException(); // NOPMD by Braids on 8/18/11 11:19 PM + } - - - /** - * Safely converts an object to a String. - * - * @param obj to convert; may be null - * - * @return "null" if obj is null, obj.toString() otherwise - */ - public static String safeToString(Object obj) { - if (obj == null) { - return "null"; - } - else { - return obj.toString(); - } - } + final int resultLength = getSliceLength(srcArray, startIndex); - /** - * Remove nulls and duplicate items from the list. - * - * This may change the list's ordering. It uses the items' equals methods to - * determine equality. - * - * Advantages over HashSet: This consumes no unnecessary heap-memory, nor - * does it require objects to implement hashCode. It is OK if - * (o1.equals(o2) does not imply o1.hashCode() == o2.hashCode()). - * - * Advantages over TreeSet: This does not require a comparator. - * - * Disadvantages over HashSet and TreeSet: This runs in O(n*n) time. - * - * @param list the list to modify; this is fastest with ArrayList. - */ - public static void smartRemoveDuplicatesAndNulls(List list) - { - // Get rid of pesky leading nulls. - smartRemoveDuplicatesAndNullsHelper(list, 0, null); + if (dstArray.length != resultLength) { + throw new ArrayIndexOutOfBoundsException( + "First parameter must have length " + resultLength + + ", but length is " + dstArray.length + "."); + } - for (int earlierIx = 0; earlierIx < list.size(); earlierIx++) - { - for (int laterIx = earlierIx + 1; laterIx < list.size(); laterIx++) - { - T itemAtEarlierIx = list.get(earlierIx); - - smartRemoveDuplicatesAndNullsHelper(list, laterIx, - itemAtEarlierIx); - } - - } - } + int srcIx = startIndex; - /** - * Helper method for smartRemoveDuplicatesAndNulls that is subject to - * change; if you call this directly, you do so at your own risk! - * - * @param list the list to modify; if all items from startIx to the end - * are either null or equal to objSeenPreviously, then we truncate the - * list just before startIx. - * - * @param startIx the index to examine; we only move items within the range - * of [startIx, list.size()-1]. - * - * @param objSeenPreviously the object with which to compare list[startIx]; - * may be null. - */ - public static void smartRemoveDuplicatesAndNullsHelper( - List list, int startIx, T objSeenPreviously) - { - while (startIx < list.size() && - (list.get(startIx) == null || - list.get(startIx) == objSeenPreviously || - list.get(startIx).equals(objSeenPreviously))) - { - int lastItemIx = list.size()-1; - - // Overwrite the item at laterIx with the one at the end, - // then delete the one at the end. - list.set(startIx, list.get(lastItemIx)); - list.remove(lastItemIx); - } - } + for (int dstIx = 0; + dstIx < resultLength && srcIx < srcArray.length; + dstIx++, srcIx++) + { + dstArray[dstIx] = srcArray[srcIx]; + } + + return dstArray; + } + + + /** + * Get a slice's length in preparation for taking a slice. + * + * I do not like the fact that I have to use this function, but + * Java left me with little choice. + * + * @see #slice(Object[], Object[], int) + * + * @param (inferred automatically) + * + * @param srcArray the array that would be copied (shallowly) + * + * @param startIndexIn if positive, the index (from the left) at which + * copying would start; if negative, we treat this as the index from the + * right. For example, calling this with startIndex = -2 computes the + * length if slice would return the last two items in the array, if it has + * that many. + * + * @return the length of the array that would result from calling + * slice(Object[], Object[], int) with the given srcArray and + * startIndex. + */ + public static int getSliceLength(final T[] srcArray, final int startIndexIn) { + int startIndex = startIndexIn; + + if (startIndex < 0) { + startIndex = srcArray.length + startIndex; + if (startIndex < 0) { + startIndex = 0; + } + } + + final int resultLength = srcArray.length - startIndex; + return resultLength; + } + + + /** + * Handles the boilerplate null and isinstance check for an equals method. + * + * Example: + *
+     * public boolean equals(Object obj) {
+     *     MyClassName that = checkNullOrNotInstance(this, obj);
+     *     if (that == null) {
+     *         return false;
+     *     }
+     *     //...
+     * }
+     * 
+ * + * @param (inferred automatically) + * + * @param goodInstance a non-null instance of type T; looks neater than + * passing in goodInstance.getClass() + * + * @param obj the object to test + * + * @return null if obj is null or not an instance of goodInstance's class; + * otherwise, we return obj cast to goodInstance's type + */ + public static T checkNullOrNotInstance(final T goodInstance, final Object obj) { + if (goodInstance == null) { + throw new NullPointerException("first parameter must not be null"); // NOPMD by Braids on 8/18/11 11:19 PM + } + + @SuppressWarnings("unchecked") + final Class classT = (Class) goodInstance.getClass(); + + boolean viable = true; + + if (obj == null) { + viable = false; + } else if (!(classT.isInstance(obj))) { + viable = false; + } + + T result; + if (viable) { + result = classT.cast(obj); + } else { + result = null; + } + + return result; + } + + + + /** + * Safely converts an object to a String. + * + * @param obj to convert; may be null + * + * @return "null" if obj is null, obj.toString() otherwise + */ + public static String safeToString(final Object obj) { + String result; + + if (obj == null) { + result = "null"; + } + else { + result = obj.toString(); + } + + return result; + } + + /** + * Remove nulls and duplicate items from the list. + * + * This may change the list's ordering. It uses the items' equals methods to + * determine equality. + * + * Advantages over HashSet: This consumes no unnecessary heap-memory, nor + * does it require objects to implement hashCode. It is OK if + * (o1.equals(o2) does not imply o1.hashCode() == o2.hashCode()). + * + * Advantages over TreeSet: This does not require a comparator. + * + * Disadvantages over HashSet and TreeSet: This runs in O(n*n) time. + * + * @param (inferred automatically) + * + * @param list the list to modify; this is fastest with ArrayList. + */ + public static void smartRemoveDuplicatesAndNulls(final List list) { + // Get rid of pesky leading nulls. + smartRemoveDuplicatesAndNullsHelper(list, 0, null); + + for (int earlierIx = 0; earlierIx < list.size(); earlierIx++) { + for (int laterIx = earlierIx + 1; laterIx < list.size(); laterIx++) + { + final T itemAtEarlierIx = list.get(earlierIx); + + smartRemoveDuplicatesAndNullsHelper(list, laterIx, + itemAtEarlierIx); + } + + } + } + + /** + * Helper method for smartRemoveDuplicatesAndNulls that is subject to + * change; if you call this directly, you do so at your own risk! + * + * @param (inferred automatically) + * + * @param list the list to modify; if all items from startIx to the end + * are either null or equal to objSeenPreviously, then we truncate the + * list just before startIx. + * + * @param startIx the index to examine; we only move items within the range + * of [startIx, list.size()-1]. + * + * @param objSeenPreviously the object with which to compare list[startIx]; + * may be null. + */ + public static void smartRemoveDuplicatesAndNullsHelper( + final List list, final int startIx, final T objSeenPreviously) + { + while (startIx < list.size() + && (list.get(startIx) == null + || list.get(startIx) == objSeenPreviously + || list.get(startIx).equals(objSeenPreviously))) + { + final int lastItemIx = list.size() - 1; + + // Overwrite the item at laterIx with the one at the end, + // then delete the one at the end. + list.set(startIx, list.get(lastItemIx)); + list.remove(lastItemIx); + } + } } diff --git a/src/test/java/forge/card/cardFactory/CardFactoryTest.java b/src/test/java/forge/card/cardFactory/CardFactoryTest.java index ebb938711ca..b125c88ddac 100644 --- a/src/test/java/forge/card/cardFactory/CardFactoryTest.java +++ b/src/test/java/forge/card/cardFactory/CardFactoryTest.java @@ -22,11 +22,17 @@ import java.util.TreeSet; * @author Forge * @version $Id$ */ -@Test(groups = {"UnitTest"}, timeOut = 5000) +@Test(groups = {"UnitTest" }, timeOut = CardFactoryTest.DEFAULT_TEST_TIMEOUT_MS) public class CardFactoryTest implements NewConstants { - private CardFactoryInterface factory; + /** The default time to allow a test to run before TestNG ignores it. */ + public static final int DEFAULT_TEST_TIMEOUT_MS = 5000; // NOPMD by Braids on 8/18/11 11:43 PM + private transient CardFactoryInterface factory; + + /** + * Executed before each test method, as in JUnit. + */ @BeforeMethod public final void setUp() { OldGuiNewGame.loadDynamicGamedata(); @@ -37,8 +43,8 @@ public class CardFactoryTest implements NewConstants { * Just a quick test to see if Arc-Slogger is in the database, and if it * has the correct owner. */ - @Test(enabled = true, timeOut = 5000) - public final void test_getCard_1() { + @Test(enabled = true, timeOut = DEFAULT_TEST_TIMEOUT_MS) + public final void test_getCard_1() { // NOPMD by Braids on 8/18/11 11:39 PM final Card card = factory.getCard("Arc-Slogger", null); Assert.assertNotNull(card, "card is not null"); Assert.assertNull(card.getOwner(), "card has correct owner"); @@ -47,19 +53,19 @@ public class CardFactoryTest implements NewConstants { /** * Make sure the method throws an exception when it's supposed to. */ - @Test(enabled = true, timeOut = 5000) - public final void test_getRandomCombinationWithoutRepetition_tooLarge() { + @Test(enabled = true, timeOut = DEFAULT_TEST_TIMEOUT_MS) + public final void test_getRandomCombinationWithoutRepetition_tooLarge() { // NOPMD by Braids on 8/18/11 11:39 PM BraidsAssertFunctions.assertThrowsException(IllegalArgumentException.class, new ClumsyRunnable() { - public void run() throws Exception { + public void run() throws Exception { // NOPMD by Braids on 8/18/11 11:40 PM factory.getRandomCombinationWithoutRepetition(factory.size()); } }); BraidsAssertFunctions.assertThrowsException(IllegalArgumentException.class, new ClumsyRunnable() { - public void run() throws Exception { - int largeDivisorForRandomCombo = 4; + public void run() throws Exception { // NOPMD by Braids on 8/18/11 11:40 PM + final int largeDivisorForRandomCombo = 4; // NOPMD by Braids on 8/18/11 11:41 PM factory.getRandomCombinationWithoutRepetition(factory.size() / largeDivisorForRandomCombo); } }); @@ -70,10 +76,10 @@ public class CardFactoryTest implements NewConstants { * * This doesn't work with LazyCardFactory, so it is too slow to enable by default. */ - @Test(enabled = false, timeOut = 5000) - public final void test_getRandomCombinationWithoutRepetition_oneTenth() { + @Test(enabled = false, timeOut = DEFAULT_TEST_TIMEOUT_MS) + public final void test_getRandomCombinationWithoutRepetition_oneTenth() { // NOPMD by Braids on 8/18/11 11:39 PM factory = new PreloadingCardFactory(ForgeProps.getFile(CARDSFOLDER)); - int divisor = 10; + final int divisor = 10; // NOPMD by Braids on 8/18/11 11:41 PM final CardList actual = factory.getRandomCombinationWithoutRepetition(factory.size() / divisor); final Set cardNames = new TreeSet();