Finished Rounded Border
This commit is contained in:
@@ -1,75 +1,52 @@
|
|||||||
package org.openautonomousconnection.oacswing.border;
|
package org.openautonomousconnection.oacswing.border;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
import javax.swing.border.AbstractBorder;
|
import javax.swing.border.AbstractBorder;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
@Getter
|
||||||
* A rounded border that does NOT affect layout (zero insets).
|
public class RoundedBorder extends AbstractBorder {
|
||||||
* Use this for root/content panes where layout must not shift.
|
|
||||||
*/
|
|
||||||
public final class RoundedBorder extends AbstractBorder {
|
|
||||||
|
|
||||||
private final int radius;
|
|
||||||
private final int strokeWidth;
|
|
||||||
private final Color color;
|
private final Color color;
|
||||||
|
private final int radius;
|
||||||
|
private final int thickness;
|
||||||
|
|
||||||
/**
|
public RoundedBorder(Color color, int radius, int thickness) {
|
||||||
* 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;
|
this.color = color;
|
||||||
|
this.radius = radius;
|
||||||
|
this.thickness = thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintBorder(Component c, Graphics g,
|
||||||
|
int x, int y, int w, int h) {
|
||||||
|
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||||
|
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
g2.setColor(color);
|
||||||
|
g2.setStroke(new BasicStroke(thickness));
|
||||||
|
g2.drawRoundRect(
|
||||||
|
x + thickness / 2,
|
||||||
|
y + thickness / 2,
|
||||||
|
w - thickness,
|
||||||
|
h - thickness,
|
||||||
|
radius,
|
||||||
|
radius
|
||||||
|
);
|
||||||
|
|
||||||
|
g2.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Insets getBorderInsets(Component c) {
|
public Insets getBorderInsets(Component c) {
|
||||||
return new Insets(0, 0, 0, 0);
|
return new Insets(thickness, thickness, thickness, thickness);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Insets getBorderInsets(Component c, Insets insets) {
|
|
||||||
insets.top = 0;
|
|
||||||
insets.left = 0;
|
|
||||||
insets.bottom = 0;
|
|
||||||
insets.right = 0;
|
|
||||||
return insets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBorderOpaque() {
|
public boolean isBorderOpaque() {
|
||||||
return false;
|
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));
|
|
||||||
|
|
||||||
int offset = strokeWidth / 2;
|
|
||||||
int w = width - strokeWidth;
|
|
||||||
int h = height - strokeWidth;
|
|
||||||
|
|
||||||
g2.drawRoundRect(
|
|
||||||
x + offset,
|
|
||||||
y + offset,
|
|
||||||
w - 1,
|
|
||||||
h - 1,
|
|
||||||
radius * 2,
|
|
||||||
radius * 2
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
g2.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,9 +3,13 @@ package org.openautonomousconnection.oacswing.component;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.openautonomousconnection.oacswing.border.RoundedBorder;
|
||||||
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
import org.openautonomousconnection.oacswing.component.design.OACColor;
|
import org.openautonomousconnection.oacswing.component.design.OACColor;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.BevelBorder;
|
||||||
|
import javax.swing.border.Border;
|
||||||
import javax.swing.plaf.basic.BasicButtonUI;
|
import javax.swing.plaf.basic.BasicButtonUI;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
@@ -28,8 +32,20 @@ public class OACButton extends JButton implements OACPressable {
|
|||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
private Color disabledColor;
|
private Color disabledColor;
|
||||||
|
|
||||||
@Getter @Setter
|
@Setter
|
||||||
private int cornerRadius = 10;
|
private int cornerRadius = 10;
|
||||||
|
|
||||||
|
private Shape shape;
|
||||||
|
|
||||||
|
private int getCornerRadius() {
|
||||||
|
Border b = getBorder();
|
||||||
|
if (b instanceof RoundedBorder rb) {
|
||||||
|
return rb.getRadius();
|
||||||
|
}
|
||||||
|
return cornerRadius; // Fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public OACButton() {
|
public OACButton() {
|
||||||
super(null, null);
|
super(null, null);
|
||||||
}
|
}
|
||||||
@@ -51,44 +67,71 @@ public class OACButton extends JButton implements OACPressable {
|
|||||||
super(text, icon);
|
super(text, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Color original;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBackground(Color bg) {
|
||||||
|
original = bg;
|
||||||
|
super.setBackground(bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBackground(Color bg) {
|
||||||
|
super.setBackground(bg);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
Color original = getBackground();
|
setContentAreaFilled(false);
|
||||||
|
setOpaque(false);
|
||||||
|
setFocusPainted(false);
|
||||||
|
|
||||||
if (!isEnabled() && getDisabledColor() != null) {
|
if (!isEnabled() && getDisabledColor() != null) {
|
||||||
setBackground(getDisabledColor());
|
super.setBackground(getDisabledColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
addMouseListener(new MouseAdapter() {
|
addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseEntered(MouseEvent e) {
|
public void mouseEntered(MouseEvent e) {
|
||||||
if (!isEnabled() && getDisabledColor() != null) {
|
if (!isEnabled() && getDisabledColor() != null) {
|
||||||
setBackground(getDisabledColor());
|
updateBackground(getDisabledColor());
|
||||||
} else setBackground(getHoveredColor());
|
} else updateBackground(getHoveredColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseExited(MouseEvent e) {
|
public void mouseExited(MouseEvent e) {
|
||||||
if (!isEnabled() && getDisabledColor() != null) {
|
if (!isEnabled() && getDisabledColor() != null) {
|
||||||
setBackground(getDisabledColor());
|
updateBackground(getDisabledColor());
|
||||||
} else setBackground(original);
|
} else updateBackground(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
if (!isEnabled() && getDisabledColor() != null) {
|
if (!isEnabled() && getDisabledColor() != null) {
|
||||||
setBackground(getDisabledColor());
|
updateBackground(getDisabledColor());
|
||||||
} else setBackground(getPressedColor());
|
} else updateBackground(getPressedColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent e) {
|
||||||
if (!isEnabled() && getDisabledColor() != null) {
|
if (!isEnabled() && getDisabledColor() != null) {
|
||||||
setBackground(getDisabledColor());
|
updateBackground(getDisabledColor());
|
||||||
} else setBackground(original);
|
} else updateBackground(original);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public boolean contains(int x, int y) {
|
||||||
|
int r = getCornerRadius();
|
||||||
|
|
||||||
|
if (shape == null || !shape.getBounds().equals(getBounds())) {
|
||||||
|
shape = new RoundRectangle2D.Float(
|
||||||
|
0, 0,
|
||||||
|
getWidth(), getHeight(),
|
||||||
|
r, r
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return shape.contains(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component add(Component comp) {
|
public Component add(Component comp) {
|
||||||
@@ -119,4 +162,26 @@ public class OACButton extends JButton implements OACPressable {
|
|||||||
initOther(comp);
|
initOther(comp);
|
||||||
super.add(comp, constraints, index);
|
super.add(comp, constraints, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||||
|
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
int r = getCornerRadius();
|
||||||
|
|
||||||
|
Color bg = getBackground();
|
||||||
|
if (!isEnabled() && disabledColor != null)
|
||||||
|
bg = disabledColor;
|
||||||
|
else if (getModel().isPressed() && pressedColor != null)
|
||||||
|
bg = pressedColor;
|
||||||
|
|
||||||
|
g2.setColor(bg);
|
||||||
|
g2.fillRoundRect(0, 0, getWidth(), getHeight(), r, r);
|
||||||
|
|
||||||
|
super.paintComponent(g2);
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -53,8 +53,6 @@ public class DesignManager {
|
|||||||
|
|
||||||
boolean hasBorder = designFlags.hasBorder();
|
boolean hasBorder = designFlags.hasBorder();
|
||||||
|
|
||||||
Border border = globalDesign.getBorder();
|
|
||||||
|
|
||||||
if(backgroundColour == null)
|
if(backgroundColour == null)
|
||||||
throw new NullPointerException("Background color cannot be null; please exclude the component from your design instead");
|
throw new NullPointerException("Background color cannot be null; please exclude the component from your design instead");
|
||||||
|
|
||||||
@@ -72,7 +70,8 @@ public class DesignManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasBorder) {
|
if (hasBorder) {
|
||||||
jComponent.setBorder(new RoundedBorder(12, 1, OACColor.DARK_BORDERS.getColor()));
|
jComponent.setBorder(globalDesign.getBorder());
|
||||||
|
jComponent.setOpaque(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
component.init();
|
component.init();
|
||||||
@@ -135,7 +134,7 @@ public class DesignManager {
|
|||||||
Design.DARK.getElements().put(OACRadioButton.class, new DesignFlags(OACColor.DARK_BUTTON));
|
Design.DARK.getElements().put(OACRadioButton.class, new DesignFlags(OACColor.DARK_BUTTON));
|
||||||
Design.DARK.getElements().put(OACTitleBar.class, new DesignFlags(OACColor.DARK_SECTION));
|
Design.DARK.getElements().put(OACTitleBar.class, new DesignFlags(OACColor.DARK_SECTION));
|
||||||
|
|
||||||
Design.DARK.border = new RoundedBorder(10, 1, OACColor.DARK_BORDERS.getColor());
|
Design.DARK.border = new RoundedBorder(OACColor.DARK_BORDERS.getColor(), 20, 2);
|
||||||
|
|
||||||
//Design.DARK.border = new BevelBorder(BevelBorder.LOWERED, OACColor.DARK_BORDERS.getColor(), OACColor.DARK_SHADOW.getColor());
|
//Design.DARK.border = new BevelBorder(BevelBorder.LOWERED, OACColor.DARK_BORDERS.getColor(), OACColor.DARK_SHADOW.getColor());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user