From 67243ed509da16ea283eb8c6fa953389c6a09094 Mon Sep 17 00:00:00 2001 From: psikoi Date: Sat, 2 Jun 2018 09:34:36 +0100 Subject: [PATCH 1/2] Added boolean onSelectedEvent to Material Tabs This new functionality allows a tab to not be selected depending on the value of onTabSelected. For example, for the hiscores, I want to block tab switching when the plugin is already loading someone's hiscores, and in this scenario, I have to return false to make sure the tabs don't switch. --- .../farmingtracker/FarmingTrackerPanel.java | 6 ++++- .../skillcalculator/SkillCalculatorPanel.java | 7 +++++- .../components/materialtabs/MaterialTab.java | 19 ++++++++++----- .../materialtabs/MaterialTabGroup.java | 23 ++++++++++--------- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPanel.java index 6033ade2ee..ab0f4b8d7b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/farmingtracker/FarmingTrackerPanel.java @@ -180,7 +180,11 @@ class FarmingTrackerPanel extends PluginPanel icon.onChanged(resize); resize.run(); - materialTab.setOnSelectEvent(() -> config.setPatch(tab)); + materialTab.setOnSelectEvent(() -> + { + config.setPatch(tab); + return true; + }); tabGroup.addTab(materialTab); if (config.patch() == tab) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPanel.java index bd90a2963d..236e28bac6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/skillcalculator/SkillCalculatorPanel.java @@ -119,7 +119,12 @@ class SkillCalculatorPanel extends PluginPanel { ImageIcon icon = new ImageIcon(iconManager.getSkillImage(calculatorType.getSkill(), true)); MaterialTab tab = new MaterialTab(icon, tabGroup, null); - tab.setOnSelectEvent(() -> uiCalculator.openCalculator(calculatorType)); + tab.setOnSelectEvent(() -> + { + uiCalculator.openCalculator(calculatorType); + return true; + }); + tabGroup.addTab(tab); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/materialtabs/MaterialTab.java b/runelite-client/src/main/java/net/runelite/client/ui/components/materialtabs/MaterialTab.java index ff056785a7..fa21d31edb 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/materialtabs/MaterialTab.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/materialtabs/MaterialTab.java @@ -28,6 +28,7 @@ import com.google.common.base.Strings; import java.awt.Color; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.function.BooleanSupplier; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JComponent; @@ -37,6 +38,7 @@ import javax.swing.border.Border; import javax.swing.border.CompoundBorder; import lombok.Getter; import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import net.runelite.client.ui.ColorScheme; /** @@ -47,6 +49,7 @@ import net.runelite.client.ui.ColorScheme; * * @author Psikoi */ +@Slf4j public class MaterialTab extends JLabel { private static final Border SELECTED_BORDER = new CompoundBorder( @@ -65,7 +68,7 @@ public class MaterialTab extends JLabel /* To be execuded when the tab is selected */ @Setter - private Runnable onSelectEvent; + private BooleanSupplier onSelectEvent; @Getter private boolean selected; @@ -147,15 +150,19 @@ public class MaterialTab extends JLabel } - public void select() + public boolean select() { - setBorder(SELECTED_BORDER); - setForeground(Color.WHITE); - selected = true; if (onSelectEvent != null) { - onSelectEvent.run(); + if (!onSelectEvent.getAsBoolean()) + { + return false; + } } + + setBorder(SELECTED_BORDER); + setForeground(Color.WHITE); + return selected = true; } public void unselect() diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/materialtabs/MaterialTabGroup.java b/runelite-client/src/main/java/net/runelite/client/ui/components/materialtabs/MaterialTabGroup.java index 58fac5474f..e98b520fdc 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/materialtabs/MaterialTabGroup.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/materialtabs/MaterialTabGroup.java @@ -101,24 +101,25 @@ public class MaterialTabGroup extends JPanel return false; } + // If the OnTabSelected returned false, exit the method to prevent tab switching + if (!selectedTab.select()) + { + return false; + } + + // If the display is available, switch from the old to the new display if (display != null) { display.removeAll(); + display.add(selectedTab.getContent()); + display.revalidate(); + display.repaint(); } + // Unselected all other tabs for (MaterialTab tab : tabs) { - if (tab.equals(selectedTab)) - { - tab.select(); - if (display != null) - { - display.add(tab.getContent()); - display.revalidate(); - display.repaint(); - } - } - else + if (!tab.equals(selectedTab)) { tab.unselect(); } From 7ba1324751d66908b6fed1e565c28e39e00617db Mon Sep 17 00:00:00 2001 From: psikoi Date: Sat, 2 Jun 2018 09:40:25 +0100 Subject: [PATCH 2/2] Refactor Hiscore EndPoints to Material Tab In an attempt to clean-up and re-use UI elements, I am applying the material tabs to the hiscores plugin (previously it was jpanels that looked exactly like tabs because at the time this panel was made, there were no icon material tabs yet) Also refactored the GridBagLayout code a little bit, makes it easier to read and expand. --- .../client/plugins/hiscore/HiscorePanel.java | 130 +++++++----------- 1 file changed, 51 insertions(+), 79 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java index 3d4f758713..e8045b7dfe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java @@ -47,7 +47,6 @@ import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; -import javax.swing.border.MatteBorder; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.Experience; @@ -56,6 +55,8 @@ import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.IconTextField; +import net.runelite.client.ui.components.materialtabs.MaterialTab; +import net.runelite.client.ui.components.materialtabs.MaterialTabGroup; import net.runelite.client.util.RunnableExceptionLogger; import net.runelite.client.util.StackFormatter; import net.runelite.http.api.hiscore.HiscoreClient; @@ -130,8 +131,8 @@ public class HiscorePanel extends PluginPanel private final JPanel statsPanel = new JPanel(); - /* A list of all the selectable endpoints (ironman, deadman, etc) */ - private final List endPoints = new ArrayList<>(); + /* Container of all the selectable endpoints (ironman, deadman, etc) */ + private final MaterialTabGroup tabGroup; private final HiscoreClient hiscoreClient = new HiscoreClient(); @@ -166,20 +167,24 @@ public class HiscorePanel extends PluginPanel super(); this.config = config; - setBorder(new EmptyBorder(10, 10, 0, 10)); + // The layout seems to be ignoring the top margin and only gives it + // a 2-3 pixel margin, so I set the value to 18 to compensate + // TODO: Figure out why this layout is ignoring most of the top margin + setBorder(new EmptyBorder(18, 10, 0, 10)); setBackground(ColorScheme.DARK_GRAY_COLOR); - - // Create GBL to arrange sub items - GridBagLayout gridBag = new GridBagLayout(); - setLayout(gridBag); + setLayout(new GridBagLayout()); // Expand sub items to fit width of panel, align to top of panel GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; - c.anchor = GridBagConstraints.NORTH; + c.gridx = 0; + c.gridy = 0; + c.weightx = 1; + c.weighty = 0; + c.insets = new Insets(0, 0, 10, 0); input = new IconTextField(); - input.setPreferredSize(new Dimension(100, 30)); + input.setMinimumSize(new Dimension(0, 30)); input.setBackground(ColorScheme.DARKER_GRAY_COLOR); input.setHoverBackgroundColor(ColorScheme.DARK_GRAY_HOVER_COLOR); input.setIcon(SEARCH_ICON); @@ -207,17 +212,11 @@ public class HiscorePanel extends PluginPanel } }); - c.gridx = 0; - c.gridy = 0; - c.weightx = 1; - c.weighty = 0; - c.insets = new Insets(0, 0, 10, 0); - gridBag.setConstraints(input, c); - add(input); + add(input, c); + c.gridy++; - /* The container for all the endpoint selectors */ - JPanel endpointPanel = new JPanel(); - endpointPanel.setLayout(new GridLayout(1, 5, 7, 1)); + tabGroup = new MaterialTabGroup(); + tabGroup.setLayout(new GridLayout(1, 5, 7, 7)); for (HiscoreEndpoint endpoint : HiscoreEndpoint.values()) { @@ -230,43 +229,37 @@ public class HiscorePanel extends PluginPanel endpoint.name().toLowerCase() + ".png")); } - JPanel panel = new JPanel(); - JLabel label = new JLabel(); + MaterialTab tab = new MaterialTab(new ImageIcon(iconImage), tabGroup, null); + tab.setToolTipText(endpoint.getName() + " Hiscores"); + tab.setOnSelectEvent(() -> + { + if (loading) + { + return false; + } - label.setIcon(new ImageIcon(iconImage)); + selectedEndPoint = endpoint; + return true; + }); - panel.add(label); - panel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - panel.setToolTipText(endpoint.getName() + " Hiscores"); - panel.addMouseListener(new MouseAdapter() + // Adding the lookup method to a mouseListener instead of the above onSelectedEvent + // Because sometimes you might want to switch the tab, without calling for lookup + // Ex: selecting the normal hiscores as default + tab.addMouseListener(new MouseAdapter() { @Override - public void mouseClicked(MouseEvent e) + public void mousePressed(MouseEvent mouseEvent) { if (loading) { return; } + executor.execute(HiscorePanel.this::lookup); - selectedEndPoint = endpoint; - updateButtons(); - } - - @Override - public void mouseEntered(MouseEvent e) - { - panel.setBackground(ColorScheme.DARKER_GRAY_HOVER_COLOR); - } - - @Override - public void mouseExited(MouseEvent e) - { - panel.setBackground(ColorScheme.DARKER_GRAY_COLOR); } }); - endPoints.add(panel); - endpointPanel.add(panel); + tabGroup.addTab(tab); } catch (IOException ex) { @@ -274,14 +267,11 @@ public class HiscorePanel extends PluginPanel } } - /* Default endpoint is the general (normal) endpoint */ - selectedEndPoint = HiscoreEndpoint.NORMAL; - updateButtons(); + // Default selected tab is normal hiscores + resetEndpoints(); - c.gridx = 0; - c.gridy = 1; - gridBag.setConstraints(endpointPanel, c); - add(endpointPanel); + add(tabGroup, c); + c.gridy++; // Panel that holds skill icons GridLayout stats = new GridLayout(8, 3); @@ -296,10 +286,8 @@ public class HiscorePanel extends PluginPanel statsPanel.add(panel); } - c.gridx = 0; - c.gridy = 2; - gridBag.setConstraints(statsPanel, c); - add(statsPanel); + add(statsPanel, c); + c.gridy++; JPanel totalPanel = new JPanel(); totalPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); @@ -308,10 +296,8 @@ public class HiscorePanel extends PluginPanel totalPanel.add(makeSkillPanel(null)); //combat has no hiscore skill, refered to as null totalPanel.add(makeSkillPanel(OVERALL)); - c.gridx = 0; - c.gridy = 3; - gridBag.setConstraints(totalPanel, c); - add(totalPanel); + add(totalPanel, c); + c.gridy++; JPanel minigamePanel = new JPanel(); // These aren't all on one row because when there's a label with four or more digits it causes the details @@ -324,10 +310,8 @@ public class HiscorePanel extends PluginPanel minigamePanel.add(makeSkillPanel(BOUNTY_HUNTER_ROGUE)); minigamePanel.add(makeSkillPanel(BOUNTY_HUNTER_HUNTER)); - c.gridx = 0; - c.gridy = 4; - gridBag.setConstraints(minigamePanel, c); - add(minigamePanel); + add(minigamePanel, c); + c.gridy++; } @Override @@ -376,10 +360,7 @@ public class HiscorePanel extends PluginPanel public void lookup(String username) { input.setText(username); - - selectedEndPoint = HiscoreEndpoint.NORMAL; //reset the endpoint to regular player - updateButtons(); - + resetEndpoints(); lookup(); } @@ -678,18 +659,9 @@ public class HiscorePanel extends PluginPanel return lookup.replace('\u00A0', ' '); } - /* - When an endpoint gets selected, this method will correctly display the selected one - with an orange underline. - */ - private void updateButtons() + private void resetEndpoints() { - for (JPanel panel : endPoints) - { - panel.setBorder(new EmptyBorder(0, 0, 1, 0)); - } - - int selectedIndex = selectedEndPoint.ordinal(); - endPoints.get(selectedIndex).setBorder(new MatteBorder(0, 0, 1, 0, ColorScheme.BRAND_ORANGE)); + // Select the first tab (NORMAL hiscores) + tabGroup.select(tabGroup.getTab(0)); } } \ No newline at end of file