我试图用Swing 2d绘制一些可旋转的箭头,网上有一些示例代码,所以我复制并将它们组合成一个应用程序,但是这三种方法中的每一种都存在错误:第一种不旋转从它的中心,另外两个在箭头中看起来不正确,有人能告诉我如何解决它们吗?如何用Java Swing绘制二维箭头?
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.event.*;
public class Arrow_Test extends JPanel implements ChangeListener {
Path2D.Double arrow = createArrow();
double theta = 0;
public void stateChanged(ChangeEvent e) {
int value = ((JSlider) e.getSource()).getValue();
theta = Math.toRadians(value);
repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(6));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int cx = getWidth()/2;
int cy = getHeight()/2;
AffineTransform at = AffineTransform.getTranslateInstance(cx, cy);
at.rotate(theta);
at.scale(2.0, 2.0);
Shape shape = at.createTransformedShape(arrow);
g2.setPaint(Color.blue);
g2.draw(shape);
GeneralPath a = drawArrow(20, 20, 30, 20, 50, 13);
AffineTransform at1 = AffineTransform.getTranslateInstance(cx, cy);
at1.rotate(theta);
at1.scale(2.0, 2.0);
Shape shape1 = at1.createTransformedShape(a);
g2.setPaint(Color.blue);
g2.draw(shape1);
drawArrow(100, 100, 50, 0, g2);
}
private Path2D.Double createArrow() {
int length = 80;
int barb = 15;
double angle = Math.toRadians(20);
Path2D.Double path = new Path2D.Double();
path.moveTo(-length/2, 0);
path.lineTo(length/2, 0);
double x = length/2 - barb * Math.cos(angle);
double y = barb * Math.sin(angle);
path.lineTo(x, y);
x = length/2 - barb * Math.cos(-angle);
y = barb * Math.sin(-angle);
path.moveTo(length/2, 0);
path.lineTo(x, y);
return path;
}
GeneralPath drawArrow(int x1, int y1, int x2, int y2, double length,
double width) {
double x, y;
length = 50;
width = 5;
Point2D start = new Point2D.Double(x1, y1);
Point2D end = new Point2D.Double(x2, y2);
Point2D base = new Point2D.Double();
Point2D back1 = new Point2D.Double();
Point2D back2 = new Point2D.Double();
length = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
// Compute normalized line vector
x = (x2 - x1)/length;
y = (y2 - y1)/length;
// Compute points for arrow head
base.setLocation(x2 - x * length, y2 - y * length);
back1.setLocation(base.getX() - width * y, base.getY() + width * x);
back2.setLocation(base.getX() + length * y, base.getY() - width * x);
Line2D.Double l1 = new Line2D.Double(start, end);
Line2D.Double l2 = new Line2D.Double(end, back2);
Line2D.Double l3 = new Line2D.Double(end, back1);
GeneralPath c = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
c.append(l1, true);
c.append(l2, true);
c.append(l3, true);
return c;
}
private void drawArrow(int x1, int y1, int x2, int y2, Graphics2D g2d) {
int x[] = { 0, 36, 0 };
int y[] = { -10, 0, 10 };
g2d.rotate(theta);
g2d.drawLine(x1 - 20, y1, x1 + 20, y1);
// will move the orgin
g2d.translate(x1, y1);
double angle = findLineAngle(x1 - 20, y1, x1 + 20, y1);
System.out.println("angle is===>" + angle);
g2d.rotate(angle);
g2d.fillPolygon(new Polygon(x, y, 3));
// /will restore orgin
g2d.translate(-x2, -y2);
g2d.rotate(-angle);
}
private double findLineAngle(int x1, int y1, int x2, int y2) {
if ((x2 - x1) == 0)
return Math.PI/2;
return Math.atan((y2 - y1)/(x2 - x1));
}
private JSlider getSlider() {
JSlider slider = new JSlider(-180, 180, 0);
slider.addChangeListener(this);
return slider;
}
public static void main(String[] args) {
Arrow_Test test = new Arrow_Test();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(test);
f.add(test.getSlider(), "Last");
f.setSize(400, 400);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
这个问题可以读取一个可运行的例子太像,“请修复我找到的代码”。为了改善这一点,可以考虑告诉我们关于你发现的**概念**,你已经**如何尝试合并和修复它们,以及它们如何不适合你。换句话说,请考虑向我们展示**你的努力的成果,根据借来的概念编写自己的箭头,而不是借用代码。 –
小心,转换正在复合 – MadProgrammer