Added custom components + moved/rewrote some

To organize the project a bit, decided to add a new folder inside the
ui folder, to hold all custom components. ui/components/

Rewrote IconTextField

I wasn't happy with its functionality, so I rewrote it to
include the following:

- Left aligned centered icons
- Animated gif support (ex: loading wheels)
- Custom hover effects (color change)
- Input blocking

All changes:

- Created new folder ui/components/
- Moved JShadowLabel and JShadowLabelUI to components folder
- Moved IconTextField to components folder
- Rewrote IconTextField
- Created new components: MaterialTab & MaterialTabGroup
- Created new components: CustomScrollBarUI
- Created new components: PluginErrorPanel
- Created new components: ThinProgressBar
- Applied the new scroll bar ui to the UI defaults (UIManager)
This commit is contained in:
Ruben Amendoeira
2018-04-22 03:47:52 +01:00
parent 327c7b9c3b
commit e56e559ecd
21 changed files with 615 additions and 59 deletions

View File

@@ -35,7 +35,6 @@ import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
@@ -46,7 +45,7 @@ import net.runelite.api.Client;
import net.runelite.api.ItemComposition;
import net.runelite.client.game.AsyncBufferedImage;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.hiscore.IconTextField;
import net.runelite.client.ui.components.IconTextField;
import net.runelite.http.api.item.Item;
import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.SearchResult;
@@ -60,7 +59,7 @@ class GrandExchangeSearchPanel extends JPanel
private final ItemManager itemManager;
private final ScheduledExecutorService executor;
private Icon search;
private ImageIcon search;
private IconTextField searchBox = new IconTextField();
private JPanel container = new JPanel();

View File

@@ -49,7 +49,6 @@ import javax.imageio.ImageIO;
import javax.inject.Inject;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
@@ -64,6 +63,7 @@ import net.runelite.api.Client;
import net.runelite.api.Experience;
import net.runelite.api.Player;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.IconTextField;
import net.runelite.client.util.StackFormatter;
import net.runelite.http.api.hiscore.HiscoreClient;
import net.runelite.http.api.hiscore.HiscoreEndpoint;
@@ -165,7 +165,7 @@ public class HiscorePanel extends PluginPanel
inputPanel.setLayout(new BorderLayout(7, 7));
inputPanel.setBorder(subPanelBorder);
Icon search;
ImageIcon search;
try
{
BufferedImage icon;
@@ -417,14 +417,14 @@ public class HiscorePanel extends PluginPanel
{
String rank = (result.getBountyHunterHunter().getRank() == -1) ? "Unranked" : StackFormatter.formatNumber(result.getBountyHunterHunter().getRank());
text = "Bounty Hunter - Hunter Kills" + System.lineSeparator()
+ "Rank: " + rank;
+ "Rank: " + rank;
break;
}
case "Last Man Standing":
{
String rank = (result.getLastManStanding().getRank() == -1) ? "Unranked" : StackFormatter.formatNumber(result.getLastManStanding().getRank());
text = "Last Man Standing" + System.lineSeparator()
+ "Rank: " + rank;
+ "Rank: " + rank;
break;
}
case "Overall":
@@ -586,13 +586,13 @@ public class HiscorePanel extends PluginPanel
if (result.getPlayer() != null)
{
int combatLevel = Experience.getCombatLevel(
result.getAttack().getLevel(),
result.getStrength().getLevel(),
result.getDefence().getLevel(),
result.getHitpoints().getLevel(),
result.getMagic().getLevel(),
result.getRanged().getLevel(),
result.getPrayer().getLevel()
result.getAttack().getLevel(),
result.getStrength().getLevel(),
result.getDefence().getLevel(),
result.getHitpoints().getLevel(),
result.getMagic().getLevel(),
result.getRanged().getLevel(),
result.getPrayer().getLevel()
);
label.setText(Integer.toString(combatLevel));
}

View File

@@ -34,7 +34,7 @@ import javax.swing.JLabel;
import javax.swing.JPanel;
import net.runelite.client.plugins.skillcalculator.beans.SkillDataEntry;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.JShadowedLabel;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
class UIActionSlot extends JPanel
{

View File

@@ -33,7 +33,7 @@ import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.JShadowedLabel;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
class UICombinedActionSlot extends JPanel
{

View File

@@ -53,7 +53,7 @@ import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Skill;
import net.runelite.client.game.SkillIconManager;
import net.runelite.client.ui.JShadowedLabel;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
import net.runelite.client.util.LinkBrowser;
import org.pushingpixels.substance.internal.SubstanceSynapse;

View File

@@ -34,6 +34,9 @@ public class ColorScheme
/* The orange color used for the branding's accents */
public static final Color BRAND_ORANGE = new Color(220, 138, 0);
/* The orange color used for the branding's accents, with lowered opacity */
public static final Color BRAND_ORANGE_TRANSPARENT = new Color(220, 138, 0, 120);
public static final Color DARKER_GRAY_COLOR = new Color(30, 30, 30);
public static final Color DARK_GRAY_COLOR = new Color(40, 40, 40);
public static final Color MEDIUM_GRAY_COLOR = new Color(77, 77, 77);

View File

@@ -68,7 +68,6 @@ public abstract class PluginPanel extends JPanel
northPanel.setBackground(ColorScheme.DARK_GRAY_COLOR);
scrollPane = new JScrollPane(northPanel);
scrollPane.getVerticalScrollBar().setUnitIncrement(16); //Otherwise scrollspeed is really slow
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
wrappedPanel = new JPanel();

View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui.components;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicScrollBarUI;
import net.runelite.client.ui.ColorScheme;
/**
* This scroll bar UI is to be used for the "RuneLite Obsidian" client theme.
* It is a part of the client's redesign as detailed on issue #1342
*/
public class CustomScrollBarUI extends BasicScrollBarUI
{
/**
* Overrides the painting of the bar's track (the darker part underneath that extends
* the full page length).
*/
@Override
protected void paintTrack(Graphics graphics, JComponent jComponent, Rectangle rectangle)
{
graphics.setColor(ColorScheme.SCROLL_TRACK_COLOR);
graphics.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
/**
* Overrides the painting of the bar's thumb (the lighter part on top that users
* use to slide up and down the page).
*/
@Override
protected void paintThumb(Graphics graphics, JComponent jComponent, Rectangle rectangle)
{
graphics.setColor(ColorScheme.MEDIUM_GRAY_COLOR);
graphics.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
/**
* Creates an empty JButton to be used as the scroll bar's arrows (to disable the arrows).
*/
protected JButton createEmptyButton()
{
JButton button = new JButton();
Dimension zeroDim = new Dimension(0, 0);
button.setPreferredSize(zeroDim);
button.setMinimumSize(zeroDim);
button.setMaximumSize(zeroDim);
return button;
}
public static ComponentUI createUI(JComponent c)
{
JScrollBar bar = (JScrollBar) c;
bar.setUnitIncrement(16);
bar.setPreferredSize(new Dimension(7, 0));
return new CustomScrollBarUI();
}
/**
* Applies an empty button to the decrease (down arrow) button.
*/
@Override
protected JButton createDecreaseButton(int orientation)
{
return createEmptyButton();
}
/**
* Applies an empty button to the increase (up arrow) button.
*/
@Override
protected JButton createIncreaseButton(int orientation)
{
return createEmptyButton();
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Psikoi <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui.components;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.runelite.client.ui.ColorScheme;
/**
* This component is a JTextField with an icon on its left side.
*/
public class IconTextField extends JPanel
{
private final JTextField textField;
//to support gifs, the icon needs to be wrapped in a JLabel
private final JLabel iconWrapperLabel;
//the default background color, this needs to be stored for hover effects
private Color backgroundColor = ColorScheme.DARKER_GRAY_COLOR;
//the default hover background color, this needs to be stored for hover effects
private Color hoverBackgroundColor;
// the input can be blocked (no clicking, no editing, no hover effects)
private boolean blocked;
public IconTextField()
{
setLayout(new BorderLayout());
this.iconWrapperLabel = new JLabel();
this.iconWrapperLabel.setPreferredSize(new Dimension(30, 0));
this.iconWrapperLabel.setVerticalAlignment(JLabel.CENTER);
this.iconWrapperLabel.setHorizontalAlignment(JLabel.CENTER);
this.textField = new JTextField();
this.textField.setBorder(null);
this.textField.setOpaque(false);
this.textField.setSelectedTextColor(Color.WHITE);
this.textField.setSelectionColor(ColorScheme.BRAND_ORANGE_TRANSPARENT);
add(iconWrapperLabel, BorderLayout.WEST);
add(textField, BorderLayout.CENTER);
textField.addMouseListener(new MouseAdapter()
{
@Override
public void mouseEntered(MouseEvent mouseEvent)
{
if (blocked)
{
return;
}
if (hoverBackgroundColor != null)
{
IconTextField.super.setBackground(hoverBackgroundColor);
}
}
@Override
public void mouseExited(MouseEvent mouseEvent)
{
IconTextField.super.setBackground(backgroundColor);
}
});
}
public void addActionListener(ActionListener actionListener)
{
textField.addActionListener(actionListener);
}
public void setIcon(ImageIcon icon)
{
iconWrapperLabel.setIcon(icon);
}
public String getText()
{
return textField.getText();
}
public void setText(String text)
{
textField.setText(text);
}
@Override
public void setBackground(Color color)
{
if (color == null)
{
return;
}
super.setBackground(color);
this.backgroundColor = color;
}
public void setHoverBackgroundColor(Color hoverBackgroundColor)
{
if (hoverBackgroundColor == null)
{
return;
}
this.hoverBackgroundColor = hoverBackgroundColor;
}
public void setEditable(boolean editable)
{
this.blocked = !editable;
textField.setEditable(editable);
textField.setFocusable(editable);
if (!editable)
{
super.setBackground(backgroundColor);
}
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui.components;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
/**
* A component to display an error/info message (to be used on a plugin panel)
* Example uses are: no ge search results found, no ge offers found.
*/
public class PluginErrorPanel extends JPanel
{
private final JLabel noResultsTitle = new JShadowedLabel();
private final JLabel noResultsDescription = new JShadowedLabel();
public PluginErrorPanel()
{
setOpaque(false);
setBorder(new EmptyBorder(50, 0, 0, 0));
setLayout(new BorderLayout());
noResultsTitle.setForeground(Color.WHITE);
noResultsTitle.setHorizontalAlignment(SwingConstants.CENTER);
noResultsDescription.setFont(FontManager.getRunescapeSmallFont());
noResultsDescription.setForeground(Color.GRAY);
noResultsDescription.setHorizontalAlignment(SwingConstants.CENTER);
add(noResultsTitle, BorderLayout.NORTH);
add(noResultsDescription, BorderLayout.CENTER);
setVisible(false);
}
/**
* Changes the content of the panel to the given parameters.
* The description has to be wrapped in html so that its text can be wrapped.
*/
public void setContent(String title, String description)
{
noResultsTitle.setText(title);
noResultsDescription.setText("<html><body style = 'text-align:center'>" + description + "</body></html>");
setVisible(true);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,54 +23,71 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.hiscore;
package net.runelite.client.ui.components;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JTextField;
import javax.swing.border.Border;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;
import lombok.Setter;
import net.runelite.client.ui.ColorScheme;
public class IconTextField extends JTextField
/**
* A progress bar to be displayed underneath the GE offer item panels
*/
public class ThinProgressBar extends JPanel
{
private Border border;
private Icon icon;
@Setter
private int maximumValue;
@Override
public void setBorder(Border border)
@Setter
private int value;
private final JPanel topBar = new JPanel();
public ThinProgressBar()
{
this.border = border;
setLayout(new BorderLayout());
setBackground(Color.GREEN.darker());
if (icon == null)
topBar.setPreferredSize(new Dimension(100, 4));
topBar.setBackground(ColorScheme.PROGRESS_COMPLETE_COLOR);
add(topBar, BorderLayout.WEST);
}
/**
* Updates the UI based on the percentage progress
*/
public void update()
{
double percentage = getPercentage();
int topWidth = (int) (getSize().width * (percentage / 100));
topBar.setPreferredSize(new Dimension(topWidth, 4));
topBar.repaint();
revalidate();
repaint();
}
public double getPercentage()
{
if (value == 0)
{
super.setBorder(border);
}
else
{
Border margin = BorderFactory.createEmptyBorder(0, icon.getIconWidth() + 4, 0, 0);
Border compound = BorderFactory.createCompoundBorder(border, margin);
super.setBorder(compound);
return 0;
}
return (value * 100) / maximumValue;
}
@Override
public void paintComponent(Graphics graphics)
public void setForeground(Color color)
{
super.paintComponent(graphics);
Insets iconInsets = border.getBorderInsets(this);
icon.paintIcon(this, graphics, iconInsets.left, iconInsets.top);
if (topBar != null)
{
topBar.setBackground(color);
}
setBackground(color.darker());
}
public void setIcon(Icon icon)
{
this.icon = icon;
resetBorder();
}
private void resetBorder()
{
setBorder(border);
}
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui.components.materialtabs;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import lombok.Getter;
import net.runelite.client.ui.ColorScheme;
/**
* This class represents a Material Design inspired tab.
* <p>
* Each tab will communicate with it's containing group when it's clicked
* and that group will display the tab's content on it's own display.
*
* @author Psikoi
*/
public class MaterialTab extends JLabel
{
private static final Border SELECTED_BORDER = new CompoundBorder(
BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.BRAND_ORANGE),
BorderFactory.createEmptyBorder(5, 10, 5, 10));
private static final Border UNSELECTED_BORDER = BorderFactory
.createEmptyBorder(5, 10, 5, 10);
/* The tab's containing group */
private final MaterialTabGroup group;
/* The tab's associated content display */
@Getter
private final JComponent content;
@Getter
private boolean selected;
public MaterialTab(String string, MaterialTabGroup group, JComponent content)
{
super(string);
this.group = group;
this.content = content;
if (selected)
{
select();
}
else
{
unselect();
}
addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent mouseEvent)
{
group.select(MaterialTab.this);
}
});
}
public void select()
{
setBorder(SELECTED_BORDER);
setForeground(Color.WHITE);
selected = true;
}
public void unselect()
{
setBorder(UNSELECTED_BORDER);
setForeground(Color.GRAY);
selected = false;
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui.components.materialtabs;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
/**
* This class will be a container (group) for the new Material Tabs. It will
* contain a list of tabs and a display (JPanel). When a tab is selected, the
* JPanel "display" will display the content associated with that tab.
* <p>
* How to use these tabs:
* <ol>
* <li>1 - Create displays (JPanels) for each tab</li>
* <li>2 - Create an empty JPanel to serve as the group's display</li>
* <li>3 - Create a new MaterialGroup, passing the panel in step 2 as a param</li>
* <li>4 - Create new tabs, passing the group in step 3 and one of the panels in
* step 1 as params</li>
* <li>5 - Add the tabs to the group using the MaterialTabGroup#addTab method</li>
* <li>6 - Select one of the tabs using the MaterialTab#select method</li>
* </ol>
*
* @author Psikoi
*/
public class MaterialTabGroup extends JPanel
{
/* The panel on which the content tab's content will be displayed on. */
private final JPanel display;
/* A list of all the tabs contained in this group. */
private final List<MaterialTab> tabs = new ArrayList<>();
public MaterialTabGroup(JPanel display)
{
this.display = display;
this.display.setLayout(new BorderLayout());
setLayout(new FlowLayout());
setOpaque(false);
}
public void addTab(MaterialTab tab)
{
tabs.add(tab);
add(tab, BorderLayout.NORTH);
}
/***
* Selects a tab from the group, and sets the display's content to the
* tab's associated content.
* @param selectedTab - The tab to select
*/
public boolean select(MaterialTab selectedTab)
{
if (!tabs.contains(selectedTab))
{
return false;
}
display.removeAll();
for (MaterialTab tab : tabs)
{
if (tab.equals(selectedTab))
{
tab.select();
display.add(tab.getContent());
display.repaint();
}
else
{
tab.unselect();
}
}
return true;
}
}

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui;
package net.runelite.client.ui.components.shadowlabel;
import java.awt.Color;
import java.awt.Point;

View File

@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.ui;
package net.runelite.client.ui.components.shadowlabel;
import java.awt.Graphics;
import javax.swing.JLabel;

View File

@@ -60,6 +60,7 @@ import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
import javax.swing.plaf.FontUIResource;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.components.CustomScrollBarUI;
import org.pushingpixels.substance.internal.SubstanceSynapse;
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
@@ -82,6 +83,7 @@ public class SwingUtil
UIManager.put("Button.foreground", Color.WHITE);
UIManager.put("MenuItem.foreground", Color.WHITE);
UIManager.put("ScrollBarUI", CustomScrollBarUI.class.getName());
// Do not render shadows under popups/tooltips.
// Fixes black boxes under popups that are above the game applet.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB