From 653128cd9701856a4025b794f3652ace0dc1caa6 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 22 Jul 2017 14:08:41 -0400 Subject: [PATCH] runelite-client: fix some incorrect swing usage All swing operations should be on the event dispatch thread --- .../java/net/runelite/client/RuneLite.java | 8 ++- .../net/runelite/client/callback/Hooks.java | 19 ++++++- .../net/runelite/client/plugins/Plugin.java | 3 +- .../client/plugins/account/AccountPlugin.java | 8 ++- .../client/plugins/config/ConfigPlugin.java | 5 +- .../client/plugins/devtools/DevTools.java | 7 ++- .../client/plugins/hiscore/Hiscore.java | 7 ++- .../client/plugins/xptracker/XPTracker.java | 55 ++++++++++--------- .../net/runelite/client/ui/ClientPanel.java | 11 ++-- .../java/net/runelite/client/ui/ClientUI.java | 37 ++++++++----- 10 files changed, 101 insertions(+), 59 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 0f1fb47b6a..3de44e4d5c 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -41,6 +41,7 @@ import java.io.InputStreamReader; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import javax.imageio.ImageIO; +import javax.swing.SwingUtilities; import joptsimple.OptionParser; import joptsimple.OptionSet; import net.runelite.api.Client; @@ -118,9 +119,12 @@ public class RuneLite public void start() throws Exception { - gui = new ClientUI(); + SwingUtilities.invokeAndWait(() -> + { + gui = new ClientUI(); - setupTrayIcon(); + setupTrayIcon(); + }); configManager.load(); diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 41182b6637..4a251764b7 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -26,6 +26,8 @@ package net.runelite.client.callback; import java.awt.Graphics; import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import javax.swing.SwingUtilities; import net.runelite.api.ChatMessageType; import net.runelite.api.MenuAction; import net.runelite.api.Skill; @@ -88,11 +90,24 @@ public class Hooks OverlayRenderer renderer = runelite.getRenderer(); + assert !SwingUtilities.isEventDispatchThread(); + try { - renderer.render(image); + SwingUtilities.invokeAndWait(() -> + { + + try + { + renderer.render(image); + } + catch (Exception ex) + { + logger.warn("Error during overlay rendering", ex); + } + }); } - catch (Exception ex) + catch (InterruptedException | InvocationTargetException ex) { logger.warn("Error during overlay rendering", ex); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java index 2dcfdab658..56d3ac01fa 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/Plugin.java @@ -28,6 +28,7 @@ import com.google.common.util.concurrent.AbstractIdleService; import java.util.Collection; import java.util.Collections; import java.util.concurrent.Executor; +import javax.swing.SwingUtilities; import net.runelite.client.ui.overlay.Overlay; public abstract class Plugin extends AbstractIdleService @@ -54,6 +55,6 @@ public abstract class Plugin extends AbstractIdleService @Override protected Executor executor() { - return r -> r.run(); + return r -> SwingUtilities.invokeLater(r); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java index 66ed9aa850..c1a38e3c71 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java @@ -55,14 +55,18 @@ public class AccountPlugin extends Plugin private final RuneLite runelite = RuneLite.getRunelite(); private final ClientUI ui = runelite.getGui(); - private final NavigationButton loginButton = new NavigationButton("Login"); - private final NavigationButton logoutButton = new NavigationButton("Logout"); + + private NavigationButton loginButton; + private NavigationButton logoutButton; private final AccountClient loginClient = new AccountClient(); @Override protected void startUp() throws Exception { + loginButton = new NavigationButton("Login"); + logoutButton = new NavigationButton("Logout"); + ImageIcon icon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("login_icon.png"))); loginButton.getButton().setIcon(icon); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java index 93265affbc..ef69c19981 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java @@ -38,13 +38,16 @@ public class ConfigPlugin extends Plugin { private static final Logger logger = LoggerFactory.getLogger(ConfigPlugin.class); - private final NavigationButton navButton = new NavigationButton("Configuration"); private final RuneLite runelite = RuneLite.getRunelite(); private final ClientUI ui = runelite.getGui(); + private NavigationButton navButton; + @Override protected void startUp() throws Exception { + navButton = new NavigationButton("Configuration"); + navButton.getButton().addActionListener(this::setPluginPanel); ImageIcon icon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("config_icon.png"))); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevTools.java b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevTools.java index 09b884e8b1..cdbefc1128 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevTools.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/devtools/DevTools.java @@ -39,8 +39,8 @@ import net.runelite.client.ui.overlay.Overlay; public class DevTools extends Plugin { private final DevToolsOverlay overlay = new DevToolsOverlay(this); - private final DevToolsPanel panel = new DevToolsPanel(this); - private final NavigationButton navButton = new NavigationButton("DevTools"); + private DevToolsPanel panel; + private NavigationButton navButton; private final ClientUI ui = RuneLite.getRunelite().getGui(); private boolean togglePlayers; @@ -61,6 +61,9 @@ public class DevTools extends Plugin @Override protected void startUp() throws Exception { + panel = new DevToolsPanel(this); + navButton = new NavigationButton("DevTools"); + navButton.getButton().addActionListener(this::setPluginPanel); ImageIcon icon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("devtools_icon.png"))); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/Hiscore.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/Hiscore.java index 8017054f95..f0748d4783 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/Hiscore.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/Hiscore.java @@ -46,12 +46,15 @@ public class Hiscore extends Plugin private final RuneLite runeLite = RuneLite.getRunelite(); private final ClientUI ui = runeLite.getGui(); - private final NavigationButton navButton = new NavigationButton("Hiscore"); - private final HiscorePanel hiscorePanel = new HiscorePanel(runeLite); + private NavigationButton navButton; + private HiscorePanel hiscorePanel; @Override protected void startUp() throws Exception { + navButton = new NavigationButton("Hiscore"); + hiscorePanel = new HiscorePanel(runeLite); + navButton.getButton().addActionListener(this::setPluginPanel); ImageIcon icon = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("hiscore.gif"))); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XPTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XPTracker.java index 7ca55b7190..468a072ce5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XPTracker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XPTracker.java @@ -48,10 +48,37 @@ public class XPTracker extends Plugin private final ClientUI ui = runeLite.getGui(); private final Client client = RuneLite.getClient(); - private final NavigationButton navButton = new NavigationButton("XP Tracker"); - private final XPPanel xpPanel = new XPPanel(runeLite, this); + private NavigationButton navButton; + private XPPanel xpPanel; private final SkillXPInfo[] xpInfos = new SkillXPInfo[NUMBER_OF_SKILLS]; + @Override + protected void startUp() throws Exception + { + navButton = new NavigationButton("XP Tracker"); + xpPanel = new XPPanel(runeLite, this); + + navButton.getButton().addActionListener(this::setPluginPanel); + + navButton.getButton().setText("XP"); + ui.getNavigationPanel().addNavigation(navButton); + + Font font = Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsStream("/runescape.ttf")); + font = font.deriveFont(Font.BOLD, 16); + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + ge.registerFont(font); + } + + @Override + protected void shutDown() throws Exception + { + } + + private void setPluginPanel(ActionEvent e) + { + ui.expand(xpPanel); + } + @Subscribe public void onGameStateChanged(GameStateChanged event) { @@ -80,30 +107,6 @@ public class XPTracker extends Plugin } } - private void setPluginPanel(ActionEvent e) - { - ui.expand(xpPanel); - } - - @Override - protected void startUp() throws Exception - { - navButton.getButton().addActionListener(this::setPluginPanel); - - navButton.getButton().setText("XP"); - ui.getNavigationPanel().addNavigation(navButton); - - Font font = Font.createFont(Font.TRUETYPE_FONT, getClass().getResourceAsStream("/runescape.ttf")); - font = font.deriveFont(Font.BOLD, 16); - GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); - ge.registerFont(font); - } - - @Override - protected void shutDown() throws Exception - { - } - @Schedule( period = 600, unit = ChronoUnit.MILLIS diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java index cf2dcbe342..5c99632a9d 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java @@ -28,6 +28,7 @@ import java.applet.Applet; import java.awt.Color; import java.awt.Dimension; import java.awt.BorderLayout; +import java.io.IOException; import javax.swing.JPanel; import net.runelite.api.Client; import net.runelite.client.ClientLoader; @@ -44,19 +45,17 @@ final class ClientPanel extends JPanel private Applet rs; - public ClientPanel(boolean loadRs) throws Exception + public ClientPanel() { setSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setLayout(new BorderLayout()); setBackground(Color.black); + } - if (!loadRs) - { - return; - } - + public void loadRs() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException + { ClientLoader loader = new ClientLoader(); UpdateCheckClient updateCheck = new UpdateCheckClient(); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 4d6f03c447..7845b9938b 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -28,19 +28,22 @@ import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.IOException; import java.util.Objects; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.SwingUtilities; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.client.RuneLite; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class ClientUI extends JFrame { + private static final Logger logger = LoggerFactory.getLogger(ClientUI.class); + private static final int PANEL_WIDTH = 805; private static final int PANEL_HEIGHT = 541; private static final int EXPANDED_WIDTH = PANEL_WIDTH + PluginPanel.PANEL_WIDTH; @@ -51,7 +54,7 @@ public final class ClientUI extends JFrame private NavigationPanel navigationPanel; private PluginPanel pluginPanel; - public ClientUI() throws Exception + public ClientUI() { init(); pack(); @@ -62,8 +65,10 @@ public final class ClientUI extends JFrame setVisible(true); } - private void init() throws Exception + private void init() { + assert SwingUtilities.isEventDispatchThread(); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); @@ -76,19 +81,21 @@ public final class ClientUI extends JFrame } }); - JPopupMenu.setDefaultLightWeightPopupEnabled(false); - try - { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } - catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ignored) - { - } - container = new JPanel(); container.setLayout(new BorderLayout(0, 0)); - panel = new ClientPanel(!RuneLite.getOptions().has("no-rs")); + panel = new ClientPanel(); + if (!RuneLite.getOptions().has("no-rs")) + { + try + { + panel.loadRs(); + } + catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException ex) + { + logger.warn("Error loading RS!", ex); + } + } container.add(panel, BorderLayout.CENTER); navContainer = new JPanel();