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 9052a9635a..efc647fa3e 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,13 +28,14 @@ import java.applet.Applet; import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Canvas; +import java.awt.Component; +import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Frame; +import java.awt.LayoutManager; import java.awt.SystemTray; import java.awt.TrayIcon; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; @@ -161,16 +162,41 @@ public class ClientUI extends JFrame titleToolbar.putClientProperty(SubstanceTitlePaneUtilities.EXTRA_COMPONENT_KIND, SubstanceTitlePaneUtilities.ExtraComponentKind.TRAILING); titleBar.add(titleToolbar); - // The title bar doesn't have a real layout manager, so we have to do it manually - titleBar.addComponentListener(new ComponentAdapter() + // Substance's default layout manager for the title bar only lays out substance's components + // This wraps the default manager and lays out the TitleToolbar as well. + LayoutManager delegate = titleBar.getLayout(); + titleBar.setLayout(new LayoutManager() { @Override - public void componentResized(ComponentEvent e) + public void addLayoutComponent(String name, Component comp) { - super.componentResized(e); + delegate.addLayoutComponent(name, comp); + } + + @Override + public void removeLayoutComponent(Component comp) + { + delegate.removeLayoutComponent(comp); + } + + @Override + public Dimension preferredLayoutSize(Container parent) + { + return delegate.preferredLayoutSize(parent); + } + + @Override + public Dimension minimumLayoutSize(Container parent) + { + return delegate.minimumLayoutSize(parent); + } + + @Override + public void layoutContainer(Container parent) + { + delegate.layoutContainer(parent); final int width = titleToolbar.getPreferredSize().width; titleToolbar.setBounds(titleBar.getWidth() - 75 - width, 0, width, titleBar.getHeight()); - titleToolbar.revalidate(); } }); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/TitleToolbar.java b/runelite-client/src/main/java/net/runelite/client/ui/TitleToolbar.java index c9c74e05d6..68715ac07f 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/TitleToolbar.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/TitleToolbar.java @@ -24,8 +24,12 @@ */ package net.runelite.client.ui; +import java.awt.Component; +import java.awt.Container; import java.awt.Desktop; +import java.awt.Dimension; import java.awt.Image; +import java.awt.LayoutManager2; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; @@ -33,12 +37,9 @@ import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import javax.imageio.ImageIO; -import javax.swing.BorderFactory; -import javax.swing.GroupLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JPanel; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.client.RuneLiteProperties; import org.pushingpixels.substance.internal.SubstanceSynapse; @@ -47,25 +48,83 @@ import org.pushingpixels.substance.internal.SubstanceSynapse; public class TitleToolbar extends JPanel { private static final int TITLEBAR_SIZE = 23; - - @Getter - private final GroupLayout.SequentialGroup horizontal; - - @Getter - private final GroupLayout.ParallelGroup vertical; + private static final int ITEM_PADDING = 4; public TitleToolbar(RuneLiteProperties properties) { - GroupLayout layout = new GroupLayout(this); - setLayout(layout); + // The only other layout manager that would manage it's preferred size without padding + // was the GroupLayout manager, which doesn't work with dynamic layouts like this one. + // Primarily, it would not remove components unless it was immediately repainted. + setLayout(new LayoutManager2() + { + @Override + public void addLayoutComponent(String name, Component comp) + { + } - setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + @Override + public void addLayoutComponent(Component comp, Object constraints) + { + } - horizontal = layout.createSequentialGroup(); - layout.setHorizontalGroup(horizontal); + @Override + public void removeLayoutComponent(Component comp) + { + } - vertical = layout.createParallelGroup(); - layout.setVerticalGroup(vertical); + @Override + public Dimension preferredLayoutSize(Container parent) + { + int width = parent.getComponentCount() * (TITLEBAR_SIZE + ITEM_PADDING); + return new Dimension(width, TITLEBAR_SIZE); + } + + @Override + public Dimension minimumLayoutSize(Container parent) + { + return preferredLayoutSize(parent); + } + + @Override + public Dimension maximumLayoutSize(Container parent) + { + return preferredLayoutSize(parent); + } + + @Override + public float getLayoutAlignmentX(Container target) + { + return 0; + } + + @Override + public float getLayoutAlignmentY(Container target) + { + return 0; + } + + @Override + public void invalidateLayout(Container target) + { + } + + @Override + public void layoutContainer(Container parent) + { + int x = 0; + for (Component c : parent.getComponents()) + { + x += ITEM_PADDING; + int height = c.getPreferredSize().height; + if (height > TITLEBAR_SIZE) + { + height = TITLEBAR_SIZE; + } + c.setBounds(x, (TITLEBAR_SIZE - height) / 2, TITLEBAR_SIZE, height); + x += TITLEBAR_SIZE; + } + } + }); try { @@ -110,9 +169,14 @@ public class TitleToolbar extends JPanel button.putClientProperty(SubstanceSynapse.FLAT_LOOK, Boolean.TRUE); button.setFocusable(false); - horizontal.addGap(6); - horizontal.addComponent(button, 0, TITLEBAR_SIZE, TITLEBAR_SIZE); - vertical.addComponent(button, 0, TITLEBAR_SIZE, TITLEBAR_SIZE); + add(button); + revalidate(); + } + + @Override + public void remove(Component c) + { + super.remove(c); revalidate(); } }