【发布时间】:2018-01-28 22:24:26
【问题描述】:
我有以下最少的代码来画一条带箭头的线:
package gui;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import javax.swing.JPanel;
public class StateBtn extends JPanel {
private static final long serialVersionUID = -431114028667352251L;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// enable antialiasing
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// draw the arrow
Line2D.Double line = new Line2D.Double(0, getHeight()/2, 20, getHeight()/2);
drawArrowHead(g2, line);
g2.draw(line);
// If I call repaint() here (like in my answer below), it works
}
private void drawArrowHead(Graphics2D g2d, Line2D.Double line) {
AffineTransform tx = new AffineTransform();
tx.setToIdentity();
double angle = Math.atan2(line.y2-line.y1, line.x2-line.x1);
tx.translate(line.x2, line.y2);
tx.rotate((angle-Math.PI/2d));
Polygon arrowHead = new Polygon();
arrowHead.addPoint(0,5);
arrowHead.addPoint(-5,-5);
arrowHead.addPoint(5,-5);
Graphics2D g = (Graphics2D) g2d.create();
g.setTransform(tx);
g.fill(arrowHead);
g.dispose();
}
}
它是这样创建的:
package gui;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main extends JFrame {
private static final long serialVersionUID = 4085389089535850911L;
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setLocation(0, 0);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
StateBtn stateBtn = new StateBtn();
stateBtn.setBounds(200,200,35,35);
contentPane.add(stateBtn);
}
}
线条绘制正确,但箭头在我调用 repaint() 之前是不可见的。问题是该元素是可拖动的,因此每次更改位置时我都必须调用 repaint() 两次。这会使代码更复杂,GUI 会滞后。
为什么箭头不能和线一起画?真的没有人可以帮助我吗?
【问题讨论】:
-
更多上下文可能会有所帮助。让我们看看您在哪里使用此代码的minimal reproducible example 代码。侧不(与手头的问题无关):永远不要从绘画方法中调用
setBackground(...)。这属于其他地方,可能在构造函数或事件侦听器中,但从不在绘画方法中。 -
好的,我把代码扩展了一下。
-
我想,是的。方法 drawArrowHead 来自 Stack Overflow 上的另一个线程。
标签: java swing graphics awt graphics2d