我写了一些代码,在JPanel
的中心画一条线。该行不断重绘,以指向mouseMoved
动作侦听器中用户的光标。
一切似乎工作正常,期待在将光标移动一段时间后,重绘的线开始闪烁并变得完全不一致。
由于我的电脑性能不佳或clearRect()
方法是错误的,导致这种闪烁吗?要用的东西?
上述两个原因并不能解释为什么闪光仅在一定量的光标移动后开始。
请随意运行下面的代码,让我知道该行是否开始闪烁:
import java.awt.Graphics;
public class Frame1 extends javax.swing.JFrame {
private javax.swing.JPanel jPanel1;
int x;
int y;
public Frame1() {
initComponents();
x = jPanel1.getWidth()/2;
y = jPanel1.getHeight()/2;
}
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jPanel1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
jPanel1MouseDragged(evt);
}
public void mouseMoved(java.awt.event.MouseEvent evt) {
jPanel1MouseMoved(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 1000, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 680, Short.MAX_VALUE)
);
getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
pack();
}
private void jPanel1MouseDragged(java.awt.event.MouseEvent evt) {
}
private void jPanel1MouseMoved(java.awt.event.MouseEvent evt) {
Graphics g = jPanel1.getGraphics();
g.clearRect(0, 0,jPanel1.getWidth(), jPanel1.getHeight());
g.translate(x, y);
g.drawLine(
0,
0,
(int)(120*Math.cos(Math.atan2(evt.getY() - y, evt.getX() - x))),
(int)(120*Math.sin(Math.atan2(evt.getY() - y, evt.getX() - x)))
);
}
public static void main(String args[])throws Exception {
Frame1 frame = new Frame1();
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
frame.setVisible(true);
}
});
}
}
我怀疑有更好的方法来更新线的位置并重新绘制而不调用clearRect()
,如果你知道一个,我也很想知道。
答案 0 :(得分:1)
Graphics g = jPanel1.getGraphics();
这不是Swing中的绘画方式。您已经规避了Swing组件提供的双缓冲支持。
相反,请创建自定义JPanel
并覆盖它的paintComponent
方法(确保在进行任何自定义绘画之前调用super.paintComponent
)并在那里执行绘画。
在自定义JPanel
中,将MouseListener
添加到其中,当触发mouseMoved
时,更新所需的状态变量(最后一个点和鼠标点)和致电repaint
有关如何完成绘画的详细信息,请参阅Painting in AWT and Swing和Performing Custom Painting