diff --git a/.gitattributes b/.gitattributes
index 1d3588c3d3f..7b8695bfee4 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -11431,6 +11431,7 @@ src/main/java/forge/gui/MultiLineLabel.java svneol=native#text/plain
src/main/java/forge/gui/MultiLineLabelUI.java svneol=native#text/plain
src/main/java/forge/gui/MultiPhaseProgressMonitorWithETA.java svneol=native#text/plain
src/main/java/forge/gui/OverlayUtils.java -text
+src/main/java/forge/gui/WrapLayout.java -text
src/main/java/forge/gui/deckeditor/DeckController.java -text
src/main/java/forge/gui/deckeditor/DeckEditorBase.java -text
src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java svneol=native#text/plain
@@ -11519,7 +11520,6 @@ src/main/java/forge/gui/toolbox/FScrollPane.java -text
src/main/java/forge/gui/toolbox/FSkin.java -text
src/main/java/forge/gui/toolbox/FTextArea.java -text
src/main/java/forge/gui/toolbox/FVerticalTabPanel.java -text
-src/main/java/forge/gui/toolbox/SubTab.java -text
src/main/java/forge/gui/toolbox/WrapLayout.java -text
src/main/java/forge/gui/toolbox/package-info.java svneol=native#text/plain
src/main/java/forge/item/BoosterPack.java -text
diff --git a/src/main/java/forge/gui/WrapLayout.java b/src/main/java/forge/gui/WrapLayout.java
new file mode 100644
index 00000000000..f9fb5984125
--- /dev/null
+++ b/src/main/java/forge/gui/WrapLayout.java
@@ -0,0 +1,172 @@
+package forge.gui;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Insets;
+
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
+/**
+ * FlowLayout subclass that fully supports wrapping of components.
+ */
+@SuppressWarnings("serial")
+public class WrapLayout extends FlowLayout {
+ /**
+ * Constructs a new WrapLayout with a left
+ * alignment and a default 5-unit horizontal and vertical gap.
+ */
+ public WrapLayout() {
+ super();
+ }
+
+ /**
+ * Constructs a new FlowLayout with the specified
+ * alignment and a default 5-unit horizontal and vertical gap.
+ * The value of the alignment argument must be one of
+ * WrapLayout, WrapLayout,
+ * or WrapLayout.
+ * @param align the alignment value
+ */
+ public WrapLayout(int align) {
+ super(align);
+ }
+
+ /**
+ * Creates a new flow layout manager with the indicated alignment
+ * and the indicated horizontal and vertical gaps.
+ *
+ * The value of the alignment argument must be one of
+ * WrapLayout, WrapLayout,
+ * or WrapLayout.
+ * @param align the alignment value
+ * @param hgap the horizontal gap between components
+ * @param vgap the vertical gap between components
+ */
+ public WrapLayout(int align, int hgap, int vgap) {
+ super(align, hgap, vgap);
+ }
+
+ /**
+ * Returns the preferred dimensions for this layout given the
+ * visible components in the specified target container.
+ * @param target the component which needs to be laid out
+ * @return the preferred dimensions to lay out the
+ * subcomponents of the specified container
+ */
+ @Override
+ public Dimension preferredLayoutSize(Container target) {
+ return layoutSize(target, true);
+ }
+
+ /**
+ * Returns the minimum dimensions needed to layout the visible
+ * components contained in the specified target container.
+ * @param target the component which needs to be laid out
+ * @return the minimum dimensions to lay out the
+ * subcomponents of the specified container
+ */
+ @Override
+ public Dimension minimumLayoutSize(Container target) {
+ Dimension minimum = layoutSize(target, false);
+ minimum.width -= (getHgap() + 1);
+ return minimum;
+ }
+
+/**
+* Returns the minimum or preferred dimension needed to layout the target
+* container.
+*
+* @param target target to get layout size for
+* @param preferred should preferred size be calculated
+* @return the dimension to layout the target container
+*/
+private Dimension layoutSize(Container target, boolean preferred) {
+synchronized (target.getTreeLock()) {
+ // Each row must fit with the width allocated to the containter.
+ // When the container width = 0, the preferred width of the container
+ // has not yet been calculated so lets ask for the maximum.
+
+ int targetWidth = target.getSize().width;
+
+ if (targetWidth == 0) {
+ targetWidth = Integer.MAX_VALUE;
+ }
+
+ int hgap = getHgap();
+ int vgap = getVgap();
+ Insets insets = target.getInsets();
+ int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
+ int maxWidth = targetWidth - horizontalInsetsAndGap;
+
+ // Fit components into the allowed width
+
+ Dimension dim = new Dimension(0, 0);
+ int rowWidth = 0;
+ int rowHeight = 0;
+
+ int nmembers = target.getComponentCount();
+
+ for (int i = 0; i < nmembers; i++) {
+ Component m = target.getComponent(i);
+
+ if (m.isVisible()) {
+ Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
+
+ // Can't add the component to current row. Start a new row.
+ if (rowWidth + d.width > maxWidth) {
+ addRow(dim, rowWidth, rowHeight);
+ rowWidth = 0;
+ rowHeight = 0;
+ }
+
+ // Add a horizontal gap for all components after the first
+ if (rowWidth != 0) {
+ rowWidth += hgap;
+ }
+
+ rowWidth += d.width;
+ rowHeight = Math.max(rowHeight, d.height);
+ }
+ }
+
+ addRow(dim, rowWidth, rowHeight);
+
+ dim.width += horizontalInsetsAndGap;
+ dim.height += insets.top + insets.bottom + vgap * 2;
+
+ //When using a scroll pane or the DecoratedLookAndFeel we need to
+ // make sure the preferred size is less than the size of the
+ // target containter so shrinking the container size works
+ // correctly. Removing the horizontal gap is an easy way to do this.
+
+ Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
+
+ if (scrollPane != null) {
+ dim.width -= (hgap + 1);
+ }
+
+ return dim;
+ }
+}
+
+/*
+ * A new row has been completed. Use the dimensions of this row
+ * to update the preferred size for the container.
+ *
+ * @param dim update the width and height when appropriate
+ * @param rowWidth the width of the row to add
+ * @param rowHeight the height of the row to add
+ */
+private void addRow(Dimension dim, int rowWidth, int rowHeight) {
+ dim.width = Math.max(dim.width, rowWidth);
+
+ if (dim.height > 0) {
+ dim.height += getVgap();
+ }
+
+ dim.height += rowHeight;
+ }
+}
diff --git a/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java b/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java
index b84f617cc0b..b537f55ce0b 100644
--- a/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java
+++ b/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java
@@ -17,7 +17,6 @@ import forge.game.GameType;
import forge.gui.OverlayUtils;
import forge.gui.deckeditor.QuestCardShop;
import forge.gui.toolbox.FLabel;
-import forge.gui.toolbox.FOverlay;
import forge.gui.toolbox.FPanel;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FTextArea;
@@ -193,8 +192,6 @@ public class SubmenuQuestUtil {
public static void startGame() {
final QuestData qData = AllZone.getQuestData();
final QuestEvent event = selectedOpponent.getEvent();
- final FOverlay overlay = Singletons.getView().getOverlay();
- final FPanel pnl = new FPanel();
OverlayUtils.startGameOverlay();
OverlayUtils.showOverlay();
diff --git a/src/main/java/forge/gui/home/settings/VSubmenuAvatars.java b/src/main/java/forge/gui/home/settings/VSubmenuAvatars.java
index 502cedad612..8bb9f5dce57 100644
--- a/src/main/java/forge/gui/home/settings/VSubmenuAvatars.java
+++ b/src/main/java/forge/gui/home/settings/VSubmenuAvatars.java
@@ -11,6 +11,7 @@ import javax.swing.JScrollPane;
import net.miginfocom.swing.MigLayout;
import forge.Command;
import forge.Singletons;
+import forge.gui.WrapLayout;
import forge.gui.home.EMenuGroup;
import forge.gui.home.EMenuItem;
import forge.gui.home.ICSubmenu;
@@ -18,7 +19,6 @@ import forge.gui.home.IVSubmenu;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FScrollPane;
import forge.gui.toolbox.FSkin;
-import forge.gui.toolbox.WrapLayout;
import forge.properties.ForgePreferences.FPref;
/**
diff --git a/src/main/java/forge/gui/toolbox/SubTab.java b/src/main/java/forge/gui/toolbox/SubTab.java
deleted file mode 100644
index 50660edbe75..00000000000
--- a/src/main/java/forge/gui/toolbox/SubTab.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package forge.gui.toolbox;
-
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-/** Standardized tab for submenus in home screen. */
-public class SubTab extends JPanel {
- private static final long serialVersionUID = -2193833603356739321L;
- private final Color clrBorders, clrHover;
- private final MouseAdapter madHover;
-
- private boolean enabled = false;
- private boolean hovering = false;
- private int w, h;
-
- /** @param s0 {@link java.lang.String} tab text */
- public SubTab(String s0) {
- super();
- this.setOpaque(false);
- this.clrBorders = FSkin.getColor(FSkin.Colors.CLR_BORDERS);
- this.clrHover = FSkin.getColor(FSkin.Colors.CLR_HOVER);
- this.setCursor(new Cursor(Cursor.HAND_CURSOR));
-
- this.madHover = new MouseAdapter() {
- @Override
- public void mouseEntered(MouseEvent e) {
- hovering = true;
- repaintOnlyThisPanel();
- }
- @Override
- public void mouseExited(MouseEvent e) {
- hovering = false;
- repaintOnlyThisPanel();
- }
- };
- this.removeMouseListener(madHover);
- this.addMouseListener(madHover);
-
- final JLabel lbl = new JLabel(s0);
- lbl.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
- lbl.setFont(FSkin.getFont(12));
- this.add(lbl);
- }
-
- /** @param b0 {@link java.lang.Boolean} */
- public void setEnabled(boolean b0) {
- this.enabled = b0;
- this.repaintOnlyThisPanel();
- }
-
- /** @return {@link java.lang.Boolean} */
- public boolean isEnabled() {
- return this.enabled;
- }
-
- /** Prevent panel from repainting the whole screen. */
- public void repaintOnlyThisPanel() {
- final Dimension d = SubTab.this.getSize();
- repaint(0, 0, d.width, d.height);
- }
-
- @Override
- public void paintComponent(Graphics g) {
- super.paintComponent(g);
- w = getWidth();
- h = getHeight();
-
- g.setColor(clrBorders);
-
- if (this.enabled) {
- g.drawLine(0, h - 1, 3, h - 1); // SW
- g.drawLine(3, 10, 3, h); // W
- g.drawArc(3, 0, 20, 20, 90, 90); //NW
- g.drawLine(13, 0, w - 13, 0); //N
- g.drawArc(w - 23, 0, 20, 20, 90, -90); //NE
- g.drawLine(w - 3, 10, w - 3, h); //E
- g.drawLine(w - 3, h - 1, w, h - 1); //SE
- }
- else if (this.hovering) {
- g.drawLine(0, h - 1, w, h - 1);
- g.setColor(clrHover);
- g.fillArc(3, 0, 20, 20, 90, 90); //NW
- g.fillArc(w - 23, 0, 20, 20, 90, -90); //NE
- g.fillRect(3, 10, w - 6, h - 12); // Bottom
- g.fillRect(13, 0, w - 26, 10); // Top
- }
- else {
- g.drawLine(0, h - 1, w, h - 1);
- }
- }
-}