Reputation: 1572
Maybe my case it's a simple confusion of ideas. How do draw a button like this using Shape?
I don't mind the rounded corners, heres my aproach for a round corner button.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JComponent;
import javax.swing.plaf.basic.BasicButtonUI;
public class PlayButtonUI extends BasicButtonUI{
protected Shape shape;
@Override
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
b.setOpaque(false);//removes that annoying default background
}
@Override public void paint(Graphics g, JComponent c) {
Graphics2D g2 = (Graphics2D)g;
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
drawButtonShape(b);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);//smoth borders
if(model.isArmed()) {
g2.setColor(Color.RED);//color when button is pressed
}else{
g2.setColor(Color.GREEN);//default button color
}
g2.fill(shape);//aplying color
super.paint(g2, c);
}
private void drawButtonShape(JComponent c) {
//button shape is drawn here, 16 are the border radius
shape = new RoundRectangle2D.Float(0, 0, c.getWidth()-1, c.getHeight()-1,16, 16);
}
}
I don't really know how to draw anything at all, this class was a result from a chaotic example that i found somewhere, and then simplified by myself until it just worked, i left some comments for the important lines.
I've been looking for a while, and found this example in oracle docs. https://docs.oracle.com/javase/tutorial/2d/geometry/arbitrary.html
I don't really know how to convert Graphics2D to Shape, please tell me if i'm taking the wrong way.
Upvotes: 0
Views: 366
Reputation: 347244
So, I've spent the better of the day banging my head against this problem, trying to do a whole bunch of trig magic ... I can't even do simple card tricks :P
Then I realised, there are other tricks I could do...
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicButtonUI;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
JButton btn = new JButton();
btn.setUI(new PlayButtonUI());
frame.add(btn);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PlayButtonUI extends BasicButtonUI {
@Override
public Dimension getPreferredSize(JComponent c) {
return new Dimension(200, 200);
}
@Override
public void paint(Graphics g, JComponent c) {
Graphics2D g2 = (Graphics2D) g;
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);//smoth borders
if (model.isArmed()) {
g2.setColor(Color.BLACK);//color when button is pressed
} else {
g2.setColor(Color.GRAY);//default button color
}
float thinkness = Math.min(c.getWidth(), c.getHeight()) * 0.1f;
Shape shape = shapeFor(c, thinkness);
g2.setStroke(new BasicStroke(thinkness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2.fill(shape);//aplying color
g2.draw(shape);
super.paint(g2, c);
}
private Shape shapeFor(JComponent c, float thickness) {
GeneralPath gp = new GeneralPath();
double width = c.getWidth();
double height = c.getHeight();
double vPos = height / 2.0;
double hPos = width - thickness;
gp.moveTo(0.0 + thickness, 0.0 + thickness);
gp.lineTo(hPos, vPos);
gp.lineTo(0.0 + thickness, height - thickness);
gp.closePath();
return gp;
}
}
}
So, this is a slight "cheat". What this actually does is uses the properties of the Stroke
to generate rounded edges, rather than trying to use curveTo
or compound shapes
Have a look at Stroking and Filling Graphics Primitives for more details
Upvotes: 3