FThreads - renamed methods that plan tasks for EDT.

all calls to CMatchUI.setCard have to be performed from EDT, otherwise an exception will raise. - this fixes problems with Goblin Guides and Inquisition of Kozilek (and all others whose effects displayed a card in UI to confirm or choose from list)
This commit is contained in:
Maxmtg
2013-04-05 06:22:25 +00:00
parent 81f692162c
commit 4e85736756
12 changed files with 67 additions and 37 deletions

View File

@@ -56,10 +56,20 @@ public class FThreads {
* TODO: Write javadoc for this method.
* @param runnable
*/
public static void invokeInEDT(Runnable runnable) {
public static void invokeInEdtLater(Runnable runnable) {
SwingUtilities.invokeLater(runnable);
}
/**
* TODO: Write javadoc for this method.
*/
public static void invokeInEdtNowOrLater(Runnable proc) {
if( isEDT() )
proc.run();
else
invokeInEdtLater(proc);
}
/**
* Invoke the given Runnable in an Event Dispatch Thread and wait for it to
* finish; but <B>try to use SwingUtilities.invokeLater instead whenever
@@ -72,7 +82,7 @@ public class FThreads {
* the Runnable to run
* @see javax.swing.SwingUtilities#invokeLater(Runnable)
*/
public static void invokeInEDTAndWait(final Runnable proc) {
public static void invokeInEdtAndWait(final Runnable proc) {
if (SwingUtilities.isEventDispatchThread()) {
// Just run in the current thread.
proc.run();

View File

@@ -37,7 +37,7 @@ public class InputLockUI implements Input {
public void run() {
if ( ixCall != iCall.get() || !isActive()) // cancel the message if it's not from latest call or input is gone already
return;
FThreads.invokeInEDT(showMessageFromEdt);
FThreads.invokeInEdtLater(showMessageFromEdt);
}
};

View File

@@ -202,8 +202,6 @@ public class MatchController {
CMessage.SINGLETON_INSTANCE.updateGameInfo(this);
// Update observers
currentGame.getGameLog().updateObservers();
CMatchUI.SINGLETON_INSTANCE.setCard(Singletons.getControl().getPlayer().getCardsIn(ZoneType.Hand).get(0));
} catch (Exception e) {
BugReporter.reportException(e);
}

View File

@@ -58,8 +58,6 @@ import forge.game.player.AIPlayer;
import forge.game.player.HumanPlayer;
import forge.game.player.Player;
import forge.gui.GuiChoose;
import forge.gui.framework.EDocID;
import forge.gui.framework.SDisplayUtil;
import forge.util.MyObservable;
/**
@@ -607,7 +605,6 @@ public class MagicStack extends MyObservable {
game.getPhaseHandler().setPriority(sp.getActivatingPlayer());
}
SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
this.updateObservers();
if (sp.isSpell() && !sp.getSourceCard().isCopiedSpell()) {

View File

@@ -131,7 +131,7 @@ public class GuiChoose {
};
FutureTask<List<T>> future = new FutureTask<List<T>>(showChoice);
FThreads.invokeInEDTAndWait(future);
FThreads.invokeInEdtAndWait(future);
try {
return future.get();
} catch (Exception e) { // should be no exception here
@@ -200,7 +200,7 @@ public class GuiChoose {
};
FutureTask<List<T>> ft = new FutureTask<List<T>>(callable);
FThreads.invokeInEDTAndWait(ft);
FThreads.invokeInEdtAndWait(ft);
try {
return ft.get();
} catch (Exception e) { // we have waited enough

View File

@@ -1,8 +1,14 @@
package forge.gui;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import javax.swing.JOptionPane;
import org.apache.commons.lang3.StringUtils;
import forge.Card;
import forge.FThreads;
import forge.Singletons;
import forge.game.event.FlipCoinEvent;
import forge.game.player.Player;
@@ -26,23 +32,28 @@ public class GuiDialog {
return GuiDialog.confirm(c, question, true, options);
}
public static boolean confirm(final Card c, String question, final boolean defaultIsYes, final String[] options) {
CMatchUI.SINGLETON_INSTANCE.setCard(c);
final StringBuilder title = new StringBuilder();
if ( c != null)
title.append(c.getName()).append(" - Ability");
if (!(question.length() > 0)) {
question = "Activate card's ability?";
public static boolean confirm(final Card c, final String question, final boolean defaultIsYes, final String[] options) {
Callable<Boolean> confirmTask = new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
CMatchUI.SINGLETON_INSTANCE.setCard(c);
final String title = c == null ? "Question" : c.getName() + " - Ability";
String questionToUse = StringUtils.isBlank(question) ? "Activate card's ability?" : question;
String[] opts = options == null ? defaultConfirmOptions : options;
int answer = JOptionPane.showOptionDialog(null, questionToUse, title,
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
opts, opts[defaultIsYes ? 0 : 1]);
return answer == JOptionPane.YES_OPTION;
}};
FutureTask<Boolean> future = new FutureTask<Boolean>(confirmTask);
FThreads.invokeInEdtAndWait(future);
try {
return future.get().booleanValue();
} catch (Exception e) { // should be no exception here
e.printStackTrace();
}
int answer;
String[] opts = options == null ? defaultConfirmOptions : options;
answer = JOptionPane.showOptionDialog(null, question, title.toString(), JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, opts, opts[defaultIsYes ? 0 : 1]);
return answer == JOptionPane.YES_OPTION;
return false;
}
/**

View File

@@ -79,7 +79,7 @@ public class InputProxy implements Observer {
// if( nextInput instanceof AiInput )
// FThreads.invokeInNewThread(showMessage, true);
// else
FThreads.invokeInEDT(showMessage);
FThreads.invokeInEdtLater(showMessage);
}
/**
* <p>

View File

@@ -9,6 +9,8 @@ import java.util.TimerTask;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import forge.FThreads;
/**
* Experimental static factory for generic operations carried out
* onto specific members of the framework. Doublestrike 11-04-12
@@ -86,11 +88,19 @@ public class SDisplayUtil {
/** @param tab0 &emsp; {@link java.gui.framework.IVDoc} */
public static void showTab(final IVDoc<? extends ICDoc> tab0) {
Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
tab0.getParentCell().setSelected(tab0);
// set focus back to previous owner, if any
if (null != c) {
c.requestFocusInWindow();
}
Runnable showTabRoutine = new Runnable() {
@Override
public void run() {
FThreads.assertExecutedByEdt(true);
Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
tab0.getParentCell().setSelected(tab0);
// set focus back to previous owner, if any
if (null != c) {
c.requestFocusInWindow();
}
}
};
FThreads.invokeInEdtNowOrLater(showTabRoutine);
}
}

View File

@@ -197,7 +197,7 @@ public enum CMatchUI {
}
final Object[] result = { null }; // how else can I extract a value from EDT thread?
FThreads.invokeInEDTAndWait(new Runnable() {
FThreads.invokeInEdtAndWait(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
@@ -237,6 +237,7 @@ public enum CMatchUI {
}
public void setCard(final Card c) {
FThreads.assertExecutedByEdt(true);
setCard(c, false);
}

View File

@@ -4,6 +4,7 @@ import java.util.Observable;
import java.util.Observer;
import forge.Command;
import forge.FThreads;
import forge.gui.framework.EDocID;
import forge.gui.framework.ICDoc;
import forge.gui.framework.SDisplayUtil;
@@ -48,6 +49,8 @@ public enum CStack implements ICDoc, Observer {
@Override
public void update(Observable arg0, Object arg1) {
SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
update();
FThreads.invokeInEdtNowOrLater(doUpdate);
}
private final Runnable doUpdate = new Runnable() { @Override public void run() {update(); } };
}

View File

@@ -175,7 +175,7 @@ public enum VStack implements IVDoc<CStack> {
/*
* This updates the Card Picture/Detail when the spell is added to
* the stack. This funcaitonality was not present in v 1.1.8.
* the stack. This functionality was not present in v 1.1.8.
*
* Problem is described in TODO right above this.
*/

View File

@@ -503,7 +503,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
public void setupPlayZone() {
boolean wasSet = wantRedraw.getAndSet(true);
if(wasSet) return;
FThreads.invokeInEDT(new Runnable() {
FThreads.invokeInEdtLater(new Runnable() {
@Override
public void run() {
try { // user won't notice, but the requests coming in that interval won't trigger re-draw