I'm trying to draw an arrow inside a circle (similar to a clock hand), but I can not align the tip of the arrow with the rest of the line.
The tip of the arrow is to the left of the line, as follows in the image:
Follow my class LineArrow
:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.geom.AffineTransform;
public class LineArrow {
int x;
int y;
int endX;
int endY;
Color color;
int thickness;
public LineArrow(int x, int y, int x2, int y2, Color color, int thickness) {
super();
this.x = x;
this.y = y;
this.endX = x2;
this.endY = y2;
this.color = color;
this.thickness = thickness;
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
g2.setStroke(new BasicStroke(thickness));
g2.drawLine(x, y, endX, endY);;
drawArrowHead(g2);
g2.dispose();
}
private void drawArrowHead(Graphics2D g2) {
Polygon arrowHead = new Polygon();
AffineTransform tx = new AffineTransform();
arrowHead.addPoint(0, 5);
arrowHead.addPoint(-5, -5);
arrowHead.addPoint(5, -5);
tx.setToIdentity();
double angle = Math.atan2(endY - y, endX - x);
tx.translate(endX, endY);
tx.rotate(angle - Math.PI / 2d);
g2.setTransform(tx);
g2.fill(arrowHead);
}
}
Note: I did not add circle drawing code because the above class is self-sufficient to simulate the image problem.
Here's an example:
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class LineArrowTest extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JPanel DrawPanel;
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new LineArrowTest().setVisible(true);
});
}
public LineArrowTest() {
initComponents();
pack();
}
private void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(400, 300));
this.contentPane = new JPanel(new BorderLayout(0, 0));
this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(this.contentPane);
this.DrawPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
LineArrow line = new LineArrow(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight(),
Color.black, 3);
line.draw(g);
}
};
this.contentPane.add(this.DrawPanel, BorderLayout.CENTER);
}
class LineArrow {
int x;
int y;
int endX;
int endY;
Color color;
int thickness;
public LineArrow(int x, int y, int x2, int y2, Color color, int thickness) {
super();
this.x = x;
this.y = y;
this.endX = x2;
this.endY = y2;
this.color = color;
this.thickness = thickness;
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
g2.setStroke(new BasicStroke(thickness));
g2.drawLine(x, y, endX, endY);
;
drawArrowHead(g2);
g2.dispose();
}
private void drawArrowHead(Graphics2D g2) {
Polygon arrowHead = new Polygon();
AffineTransform tx = new AffineTransform();
arrowHead.addPoint(0, 5);
arrowHead.addPoint(-5, -5);
arrowHead.addPoint(5, -5);
tx.setToIdentity();
double angle = Math.atan2(endY - y, endX - x);
tx.translate(endX, endY);
tx.rotate(angle - Math.PI / 2d);
g2.setTransform(tx);
g2.fill(arrowHead);
}
}
}