From 768b004d3eeaf49bdc86b522e8b546de8dc2cd76 Mon Sep 17 00:00:00 2001 From: rkfg Date: Sun, 6 Mar 2016 02:41:23 +0300 Subject: [PATCH] Fix race condition on tooltip resize in EDT. CardInfoPane.setCard() performs the tooltip resize, initially it's of zero width and height. The resize happens in the EDT but location is calculated in the thread pool's thread, i.e. before the first resize. Because of that the first time the tooltip appears it may be partially off-screen, nothing fatal but looks ugly. Now all calculations are moved to EDT as well and they're guaranteed to happen after the resize. --- .../mage/client/components/ColorPane.java | 27 +++++++------------ .../plugins/adapters/MageActionCallback.java | 21 +++++++-------- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/components/ColorPane.java b/Mage.Client/src/main/java/mage/client/components/ColorPane.java index a5a0dc107f8..deb15736e7d 100644 --- a/Mage.Client/src/main/java/mage/client/components/ColorPane.java +++ b/Mage.Client/src/main/java/mage/client/components/ColorPane.java @@ -4,6 +4,7 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; +import java.awt.MouseInfo; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -59,23 +60,12 @@ public class ColorPane extends JEditorPane { try { final Component container = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER); if (e.getEventType() == EventType.EXITED) { - setPopupVisibility(null, container, false); + setPopupVisibility(container, false); } if (e.getEventType() == EventType.ENTERED) { CardInfoPane cardInfoPane = (CardInfoPane) MageFrame.getUI().getComponent(MageComponents.CARD_INFO_PANE); cardInfoPane.setCard(new CardView(card.getMockCard()), container); - Point mousePosition = MageFrame.getDesktop().getMousePosition(); - int popupY = 0; - if (mousePosition == null) { // switched to another window - popupY = getLocationOnScreen().y; - } else { - popupY = mousePosition.y; - } - Point location = new Point(getLocationOnScreen().x - container.getWidth(), popupY); - Component parentComponent = MageFrame.getInstance(); - location = GuiDisplayUtil.keepComponentInsideParent(location, parentComponent.getLocationOnScreen(), - container, parentComponent); - setPopupVisibility(location, container, true); + setPopupVisibility(container, true); } } catch (InterruptedException e1) { e1.printStackTrace(); @@ -92,7 +82,7 @@ public class ColorPane extends JEditorPane { public void mouseExited(MouseEvent e) { tooltipCounter = 1; // will decrement and become effectively zero on leaving the pane try { - setPopupVisibility(null, MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER), false); + setPopupVisibility(MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER), false); } catch (InterruptedException e1) { e1.printStackTrace(); } @@ -100,15 +90,16 @@ public class ColorPane extends JEditorPane { }); } - private void setPopupVisibility(final Point location, final Component container, final boolean show) + private void setPopupVisibility(final Component container, final boolean show) throws InterruptedException { final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - if (location != null) { - container.setLocation(location); - } + Point location = new Point(getLocationOnScreen().x - container.getWidth(), MouseInfo.getPointerInfo().getLocation().y); + Component parentComponent = MageFrame.getInstance(); + location = GuiDisplayUtil.keepComponentInsideParent(location, parentComponent.getLocationOnScreen(), container, parentComponent); + container.setLocation(location); tooltipCounter += show ? 1 : -1; if (tooltipCounter < 0) { tooltipCounter = 0; diff --git a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java index 015280b3d3b..356b5090bce 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java +++ b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java @@ -182,24 +182,14 @@ public class MageActionCallback implements ActionCallback { ((CardInfoPane) popup2).setCard(data.card, popupContainer); - if (data.locationOnScreen == null) { - data.locationOnScreen = data.component.getLocationOnScreen(); - } - - Point location = new Point((int) data.locationOnScreen.getX() + data.popupOffsetX - 40, (int) data.locationOnScreen.getY() + data.popupOffsetY - 40); - location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, popup2, parentComponent); - location.translate(-parentPoint.x, -parentPoint.y); - - ThreadUtils.sleep(200); - - showPopup(popupContainer, location); + showPopup(popupContainer, popup2); } catch (InterruptedException e) { LOGGER.warn(e.getMessage()); } } - public void showPopup(final Component popupContainer, final Point location) throws InterruptedException { + public void showPopup(final Component popupContainer, final Component infoPane) throws InterruptedException { final Component c = MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE); SwingUtilities.invokeLater(new Runnable() { @Override @@ -207,6 +197,13 @@ public class MageActionCallback implements ActionCallback { if (!popupTextWindowOpen || !enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { return; } + if (data.locationOnScreen == null) { + data.locationOnScreen = data.component.getLocationOnScreen(); + } + + Point location = new Point((int) data.locationOnScreen.getX() + data.popupOffsetX - 40, (int) data.locationOnScreen.getY() + data.popupOffsetY - 40); + location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, infoPane, parentComponent); + location.translate(-parentPoint.x, -parentPoint.y); popupContainer.setLocation(location); popupContainer.setVisible(true); c.repaint();