1
我想繪製一個箭頭在一個圓圈(如時鐘指針),但我無法對齊箭頭的其餘部分。如何用java2d繪製箭頭?
我做了「箭頭」根據this answer,但我不能使它正確定位與線條畫。
的箭頭是越到線的左側,在圖像中如下:
這裏我MCVE:
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);
}
}
}
不想濫用你的善意,但它爲什麼會發生?如果我刪除了'this.contentPane.setBorder(new EmptyBorder(5,5,5,5));'這個箭頭就變成了正常。 – Articuno
邊界正是問題所在。邊框寬5像素。繪製組件時,邊框是組件的一部分,因此座標(0,0)將位於邊框「外部」。在繪製線條時,Graphics2D的默認轉換通過添加(5,5)(=邊框的寬度)的平移來補償此效果。但是當你設置你的轉換時,你首先將它設置爲標識,然後缺少這個額外的轉換,導致錯誤對齊的邊界寬度。 – cello
['Graphics2D']的Javadoc(https://docs.oracle.com/javase/8/docs/api/java/awt/Graphics2D.html):*創建Graphics2D對象時,GraphicsConfiguration指定默認的轉換Graphics2D(組件或圖像)的目標。此默認轉換將用戶空間座標系映射到屏幕和打印機設備座標,以便原點映射到設備目標區域的左上角,同時向右擴展X座標並增加向下延伸的Y座標* – Andreas