From fd1e9129eba9ebaf8b9be2046208e659cd53e2f2 Mon Sep 17 00:00:00 2001 From: UnlegitDqrk Date: Sun, 8 Feb 2026 15:57:43 +0100 Subject: [PATCH] Color bug fixes --- .idea/discord.xml | 7 ++ .../oacswing/border/RoundedBorder.java | 76 +++++++++---- .../oacswing/component/OACButton.java | 103 ++++++++++-------- .../oacswing/component/OACComponent.java | 2 +- .../oacswing/component/OACPressable.java | 9 +- .../component/design/DesignFlags.java | 10 +- .../component/design/DesignManager.java | 32 +++--- .../oacswing/component/design/OACColor.java | 4 +- 8 files changed, 150 insertions(+), 93 deletions(-) create mode 100644 .idea/discord.xml diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 0000000..30bab2a --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/main/java/org/openautonomousconnection/oacswing/border/RoundedBorder.java b/src/main/java/org/openautonomousconnection/oacswing/border/RoundedBorder.java index 04e5578..c6c938a 100644 --- a/src/main/java/org/openautonomousconnection/oacswing/border/RoundedBorder.java +++ b/src/main/java/org/openautonomousconnection/oacswing/border/RoundedBorder.java @@ -1,45 +1,75 @@ -// Source - https://stackoverflow.com/a/3634480 -// Posted by Lalchand, modified by community. See post 'Timeline' for change history -// Retrieved 2026-02-08, License - CC BY-SA 3.0 - package org.openautonomousconnection.oacswing.border; -import lombok.Getter; - import javax.swing.border.AbstractBorder; -import javax.swing.border.Border; import java.awt.*; -@Getter -public class RoundedBorder extends AbstractBorder { +/** + * A rounded border that does NOT affect layout (zero insets). + * Use this for root/content panes where layout must not shift. + */ +public final class RoundedBorder extends AbstractBorder { - private int radius; - private Color color; + private final int radius; + private final int strokeWidth; + private final Color color; - public RoundedBorder(int radius, Color color) { + /** + * Creates an overlay rounded border. + * + * @param radius corner radius in pixels (must be >= 0) + * @param strokeWidth stroke width in pixels (must be >= 1) + * @param color border color (not null) + */ + public RoundedBorder(int radius, int strokeWidth, Color color) { + if (radius < 0) throw new IllegalArgumentException("radius must be >= 0"); + if (strokeWidth < 1) throw new IllegalArgumentException("strokeWidth must be >= 1"); + if (color == null) throw new IllegalArgumentException("color must not be null"); this.radius = radius; + this.strokeWidth = strokeWidth; this.color = color; } + @Override + public Insets getBorderInsets(Component c) { + return new Insets(0, 0, 0, 0); + } - public Insets getBorderInsets( Component c, Insets insets ) { - insets.left = insets.top = insets.right = insets.bottom = 18; + @Override + public Insets getBorderInsets(Component c, Insets insets) { + insets.top = 0; + insets.left = 0; + insets.bottom = 0; + insets.right = 0; return insets; } + @Override public boolean isBorderOpaque() { - return true; + return false; } + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Graphics2D g2 = (Graphics2D) g.create(); + try { + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setColor(color); + g2.setStroke(new BasicStroke(strokeWidth)); - public void paintBorder( Component c, Graphics g, int x, int y, - int width, int height) { - int w = width; - int h = height; + int offset = strokeWidth / 2; + int w = width - strokeWidth; + int h = height - strokeWidth; - g.translate(x, y); - g.setColor( c.getBackground().darker() ); - g.drawRoundRect( 0, 0, w-2, h-2, 8, 8 ); - g.translate(-x, -y); + g2.drawRoundRect( + x + offset, + y + offset, + w - 1, + h - 1, + radius * 2, + radius * 2 + ); + } finally { + g2.dispose(); + } } } \ No newline at end of file diff --git a/src/main/java/org/openautonomousconnection/oacswing/component/OACButton.java b/src/main/java/org/openautonomousconnection/oacswing/component/OACButton.java index c2070df..b0eea6c 100644 --- a/src/main/java/org/openautonomousconnection/oacswing/component/OACButton.java +++ b/src/main/java/org/openautonomousconnection/oacswing/component/OACButton.java @@ -1,121 +1,132 @@ -/* Author: Maple - * Feb. 2 2026 - * */ - package org.openautonomousconnection.oacswing.component; import lombok.Getter; import lombok.NonNull; import lombok.Setter; -import org.openautonomousconnection.oacswing.component.design.Design; import org.openautonomousconnection.oacswing.component.design.OACColor; import javax.swing.*; +import javax.swing.plaf.basic.BasicButtonUI; import java.awt.*; +import java.awt.event.ComponentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.geom.RoundRectangle2D; import java.beans.ConstructorProperties; +/** + * Rounded Swing button with proper hover, pressed and disabled color handling. + */ public class OACButton extends JButton implements OACPressable { - @Getter @Setter - protected Color pressColor = null; - protected Color previousColor = null; + @Getter @Setter + private Color pressedColor; + + @Getter @Setter + private Color hoveredColor; + + @Getter @Setter + private Color disabledColor; + + @Getter @Setter + private int cornerRadius = 10; + + private boolean hovered = false; + private boolean pressed = false; public OACButton() { super(null, null); - - this.init(); } public OACButton(Icon icon) { super(null, icon); - - this.init(); } @ConstructorProperties({"text"}) public OACButton(String text) { super(text, null); - - this.init(); } public OACButton(Action a) { super(a); - - this.init(); } public OACButton(String text, Icon icon) { super(text, icon); - - this.init(); } - protected void init() { - this.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - previousColor = getBackground(); + @Override + public void init() { + Color original = getBackground(); - if(pressColor != null) - setBackground(pressColor); - - super.mousePressed(e); - } - - @Override - public void mouseReleased(MouseEvent e) { - setBackground(previousColor); - - super.mouseReleased(e); - } + if (!isEnabled() && getDisabledColor() != null) { + setBackground(getDisabledColor()); + } + addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { - //TODO: Hover + hovered = true; - super.mouseEntered(e); + if (!isEnabled() && getDisabledColor() != null) { + setBackground(getDisabledColor()); + } else setBackground(getHoveredColor()); } @Override public void mouseExited(MouseEvent e) { - //TODO: Hover - - super.mouseExited(e); + hovered = false; + pressed = false; + if (!isEnabled() && getDisabledColor() != null) { + setBackground(getDisabledColor()); + } else setBackground(original); } + @Override + public void mousePressed(MouseEvent e) { + pressed = true; + if (!isEnabled() && getDisabledColor() != null) { + setBackground(getDisabledColor()); + } else setBackground(getPressedColor()); + } + + @Override + public void mouseReleased(MouseEvent e) { + pressed = false; + if (!isEnabled() && getDisabledColor() != null) { + setBackground(getDisabledColor()); + } else setBackground(original); + } }); } @Override public Component add(Component comp) { - this.initOther(comp); + initOther(comp); return super.add(comp); } @Override public Component add(Component comp, int index) { - this.initOther(comp); + initOther(comp); return super.add(comp, index); } @Override public void add(@NonNull Component comp, Object constraints) { - this.initOther(comp); + initOther(comp); super.add(comp, constraints); } @Override public Component add(String name, Component comp) { - this.initOther(comp); + initOther(comp); return super.add(name, comp); } @Override public void add(Component comp, Object constraints, int index) { - this.initOther(comp); + initOther(comp); super.add(comp, constraints, index); } -} +} \ No newline at end of file diff --git a/src/main/java/org/openautonomousconnection/oacswing/component/OACComponent.java b/src/main/java/org/openautonomousconnection/oacswing/component/OACComponent.java index b0822f0..fe02d08 100644 --- a/src/main/java/org/openautonomousconnection/oacswing/component/OACComponent.java +++ b/src/main/java/org/openautonomousconnection/oacswing/component/OACComponent.java @@ -18,7 +18,7 @@ public interface OACComponent { // this.setBackground(design.getElements().get(this.getClass()).getColor()); } - void setBackground(Color color); + default void init() {} default void initOther(Component comp) { if(comp instanceof OACComponent component) diff --git a/src/main/java/org/openautonomousconnection/oacswing/component/OACPressable.java b/src/main/java/org/openautonomousconnection/oacswing/component/OACPressable.java index 746693c..4724d52 100644 --- a/src/main/java/org/openautonomousconnection/oacswing/component/OACPressable.java +++ b/src/main/java/org/openautonomousconnection/oacswing/component/OACPressable.java @@ -6,7 +6,12 @@ import java.awt.*; public interface OACPressable extends OACComponent { - Color getPressColor(); + Color getPressedColor(); + void setPressedColor(Color color); - void setPressColor(Color color); + Color getHoveredColor(); + void setHoveredColor(Color color); + + Color getDisabledColor(); + void setDisabledColor(Color color); } diff --git a/src/main/java/org/openautonomousconnection/oacswing/component/design/DesignFlags.java b/src/main/java/org/openautonomousconnection/oacswing/component/design/DesignFlags.java index 7d26b58..59086fb 100644 --- a/src/main/java/org/openautonomousconnection/oacswing/component/design/DesignFlags.java +++ b/src/main/java/org/openautonomousconnection/oacswing/component/design/DesignFlags.java @@ -1,19 +1,19 @@ package org.openautonomousconnection.oacswing.component.design; -public record DesignFlags(OACColor background, OACColor foreground, OACColor pressed, OACColor hovered, boolean hasBorder) { +public record DesignFlags(OACColor background, OACColor foreground, OACColor pressed, OACColor hovered, OACColor disabled, boolean hasBorder) { public DesignFlags(OACColor background) { - this(background, null, null, null, false); + this(background, null, null, null, null, false); } public DesignFlags(OACColor background, OACColor foreground) { - this(background, foreground, null, null, false); + this(background, foreground, null, null, null, false); } public DesignFlags(OACColor background, boolean hasBorder) { - this(background, null, null, null, hasBorder); + this(background, null, null, null, null, hasBorder); } public DesignFlags(OACColor background, OACColor foreground, boolean hasBorder) { - this(background, foreground, null, null, hasBorder); + this(background, foreground, null, null, null, hasBorder); } } diff --git a/src/main/java/org/openautonomousconnection/oacswing/component/design/DesignManager.java b/src/main/java/org/openautonomousconnection/oacswing/component/design/DesignManager.java index 4c45c39..cde3c74 100644 --- a/src/main/java/org/openautonomousconnection/oacswing/component/design/DesignManager.java +++ b/src/main/java/org/openautonomousconnection/oacswing/component/design/DesignManager.java @@ -49,6 +49,7 @@ public class DesignManager { OACColor hovered = designFlags.hovered(); OACColor pressed = designFlags.pressed(); + OACColor disabled = designFlags.disabled(); boolean hasBorder = designFlags.hasBorder(); @@ -57,21 +58,24 @@ public class DesignManager { if(backgroundColour == null) throw new NullPointerException("Background color cannot be null; please exclude the component from your design instead"); - component.setBackground(backgroundColour.getColor()); - - if(component instanceof OACPressable pressable) { - // TODO: if(hovered != null) - - if(pressed != null) - pressable.setPressColor(pressed.getColor()); + if (component instanceof OACPressable pressable) { + if (hovered != null) pressable.setHoveredColor(hovered.getColor()); + if (pressed != null) pressable.setPressedColor(pressed.getColor()); + if (disabled != null) pressable.setDisabledColor(disabled.getColor()); } - if(component instanceof JComponent jComponent) { - if(foregroundColour != null) - jComponent.setForeground(foregroundColour.getColor()); + if (component instanceof JComponent jComponent) { + jComponent.setBackground(backgroundColour.getColor()); - if (hasBorder) - jComponent.setBorder(BorderFactory.createCompoundBorder(border, jComponent.getBorder())); + if (foregroundColour != null) { + jComponent.setForeground(foregroundColour.getColor()); + } + + if (hasBorder) { + jComponent.setBorder(new RoundedBorder(12, 1, OACColor.DARK_BORDERS.getColor())); + } + + component.init(); } } @@ -111,7 +115,7 @@ public class DesignManager { } static { - Design.DARK.getElements().put(OACButton.class, new DesignFlags(OACColor.DARK_BUTTON, OACColor.DARK_TEXT, OACColor.DARK_BUTTON_HOVER, OACColor.DARK_BUTTON_HOVER, true)); + Design.DARK.getElements().put(OACButton.class, new DesignFlags(OACColor.DARK_BUTTON, OACColor.DARK_TEXT, OACColor.DARK_BUTTON_HOVER, OACColor.DARK_BUTTON_HOVER, OACColor.DARK_INACTIVE_BUTTON, true)); Design.DARK.getElements().put(OACCheckBox.class, new DesignFlags(OACColor.DARK_INPUT_FIELD)); Design.DARK.getElements().put(OACCheckBoxMenuItem.class, new DesignFlags(OACColor.DARK_ITEM)); Design.DARK.getElements().put(OACColorChooser.class, new DesignFlags(OACColor.DARK_SECTION)); @@ -131,7 +135,7 @@ public class DesignManager { Design.DARK.getElements().put(OACRadioButton.class, new DesignFlags(OACColor.DARK_BUTTON)); Design.DARK.getElements().put(OACTitleBar.class, new DesignFlags(OACColor.DARK_SECTION)); - Design.DARK.border = new RoundedBorder(10, OACColor.DARK_BORDERS.getColor()); + Design.DARK.border = new RoundedBorder(10, 1, OACColor.DARK_BORDERS.getColor()); //Design.DARK.border = new BevelBorder(BevelBorder.LOWERED, OACColor.DARK_BORDERS.getColor(), OACColor.DARK_SHADOW.getColor()); diff --git a/src/main/java/org/openautonomousconnection/oacswing/component/design/OACColor.java b/src/main/java/org/openautonomousconnection/oacswing/component/design/OACColor.java index f5cc4a2..9d72740 100644 --- a/src/main/java/org/openautonomousconnection/oacswing/component/design/OACColor.java +++ b/src/main/java/org/openautonomousconnection/oacswing/component/design/OACColor.java @@ -17,9 +17,9 @@ public enum OACColor { DARK_INPUT_BUTTON_HOVER(Color.decode("#1c2140")), DARK_ITEM(Color.decode("#d7dbe5")), DARK_BORDERS(Color.decode("#2a2f42")), - DARK_BUTTON(Color.decode("#3b5bdb")), + DARK_BUTTON_HOVER(Color.decode("#3b5bdb")), DARK_INACTIVE_BUTTON(Color.decode("#151a2b")), - DARK_BUTTON_HOVER(Color.decode("#151a2b")), + DARK_BUTTON(Color.decode("#151a2b")), DARK_TEXT(Color.decode("#cfd3dc")), DARK_SUBTITLE(Color.decode("#9aa0aa")), DARK_LINK(Color.decode("#b4c6ff")),