Java中的图形;更新帧而不闪烁屏幕

时间:2015-02-26 00:36:18

标签: java graphics

我写了一些代码,在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(),如果你知道一个,我也很想知道。

1 个答案:

答案 0 :(得分:1)

Graphics g = jPanel1.getGraphics();这不是Swing中的绘画方式。您已经规避了Swing组件提供的双缓冲支持。

相反,请创建自定义JPanel并覆盖它的paintComponent方法(确保在进行任何自定义绘画之前调用super.paintComponent)并在那里执行绘画。

在自定义JPanel中,将MouseListener添加到其中,当触发mouseMoved时,更新所需的状态变量(最后一个点和鼠标点)和致电repaint

有关如何完成绘画的详细信息,请参阅Painting in AWT and SwingPerforming Custom Painting