diff --git a/src/main/java/forge/FThreads.java b/src/main/java/forge/FThreads.java index a6caef25fbb..a2dec8a4838 100644 --- a/src/main/java/forge/FThreads.java +++ b/src/main/java/forge/FThreads.java @@ -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 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(); diff --git a/src/main/java/forge/control/input/InputLockUI.java b/src/main/java/forge/control/input/InputLockUI.java index 5beace5ed26..0a959b0f5a3 100644 --- a/src/main/java/forge/control/input/InputLockUI.java +++ b/src/main/java/forge/control/input/InputLockUI.java @@ -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); } }; diff --git a/src/main/java/forge/game/MatchController.java b/src/main/java/forge/game/MatchController.java index eae422cd7fa..68814e0373c 100644 --- a/src/main/java/forge/game/MatchController.java +++ b/src/main/java/forge/game/MatchController.java @@ -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); } diff --git a/src/main/java/forge/game/zone/MagicStack.java b/src/main/java/forge/game/zone/MagicStack.java index 9bc6e3ea990..702c8bc260a 100644 --- a/src/main/java/forge/game/zone/MagicStack.java +++ b/src/main/java/forge/game/zone/MagicStack.java @@ -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()) { diff --git a/src/main/java/forge/gui/GuiChoose.java b/src/main/java/forge/gui/GuiChoose.java index 607c810f090..8b699aa0b14 100644 --- a/src/main/java/forge/gui/GuiChoose.java +++ b/src/main/java/forge/gui/GuiChoose.java @@ -131,7 +131,7 @@ public class GuiChoose { }; FutureTask> future = new FutureTask>(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> ft = new FutureTask>(callable); - FThreads.invokeInEDTAndWait(ft); + FThreads.invokeInEdtAndWait(ft); try { return ft.get(); } catch (Exception e) { // we have waited enough diff --git a/src/main/java/forge/gui/GuiDialog.java b/src/main/java/forge/gui/GuiDialog.java index cbf60ce3deb..62e951fa0c8 100644 --- a/src/main/java/forge/gui/GuiDialog.java +++ b/src/main/java/forge/gui/GuiDialog.java @@ -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 confirmTask = new Callable() { + @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 future = new FutureTask(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; } /** diff --git a/src/main/java/forge/gui/InputProxy.java b/src/main/java/forge/gui/InputProxy.java index 590e31f3c1c..2ab6a653751 100644 --- a/src/main/java/forge/gui/InputProxy.java +++ b/src/main/java/forge/gui/InputProxy.java @@ -79,7 +79,7 @@ public class InputProxy implements Observer { // if( nextInput instanceof AiInput ) // FThreads.invokeInNewThread(showMessage, true); // else - FThreads.invokeInEDT(showMessage); + FThreads.invokeInEdtLater(showMessage); } /** *

diff --git a/src/main/java/forge/gui/framework/SDisplayUtil.java b/src/main/java/forge/gui/framework/SDisplayUtil.java index 05fb0b26a63..93f3d84663a 100644 --- a/src/main/java/forge/gui/framework/SDisplayUtil.java +++ b/src/main/java/forge/gui/framework/SDisplayUtil.java @@ -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   {@link java.gui.framework.IVDoc} */ public static void showTab(final IVDoc 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); } } diff --git a/src/main/java/forge/gui/match/CMatchUI.java b/src/main/java/forge/gui/match/CMatchUI.java index 618f34c5897..0a81bce5d13 100644 --- a/src/main/java/forge/gui/match/CMatchUI.java +++ b/src/main/java/forge/gui/match/CMatchUI.java @@ -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); } diff --git a/src/main/java/forge/gui/match/controllers/CStack.java b/src/main/java/forge/gui/match/controllers/CStack.java index 80696a8a2d0..980c06bd708 100644 --- a/src/main/java/forge/gui/match/controllers/CStack.java +++ b/src/main/java/forge/gui/match/controllers/CStack.java @@ -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(); } }; } diff --git a/src/main/java/forge/gui/match/views/VStack.java b/src/main/java/forge/gui/match/views/VStack.java index 45364e7f5b9..5ffad5ae1d8 100644 --- a/src/main/java/forge/gui/match/views/VStack.java +++ b/src/main/java/forge/gui/match/views/VStack.java @@ -175,7 +175,7 @@ public enum VStack implements IVDoc { /* * 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. */ diff --git a/src/main/java/forge/view/arcane/PlayArea.java b/src/main/java/forge/view/arcane/PlayArea.java index 3c2648e55eb..b81737924bc 100644 --- a/src/main/java/forge/view/arcane/PlayArea.java +++ b/src/main/java/forge/view/arcane/PlayArea.java @@ -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