是什么导致此代码重绘自己?

时间:2014-11-04 23:10:08

标签: java swing paintcomponent

在下面的代码中,箭头键用于绘制一条线,就像在etch-a-sketch中一样(但是你必须先调整窗口大小以在合适的时间触发面板的焦点请求 - #39;也许是一个不同时间的问题。图形命令g.drawLine()发生在keyPressed()函数中,不会显式调用repaint(),但是当按下箭头键时图像会自动更新。这是为什么?我所看到的所有文档都只谈到了JPanel在调整大小或未被覆盖时自动重新绘制的内容。

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

public class Etch extends JPanel implements KeyListener{
    public int xPrev, yPrev, xNew, yNew, inc;

    public Etch(int start){
        xPrev = start;
        yPrev = start;
        xNew = start;
        yNew = start;
        inc = 10;
        addKeyListener(this);


    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        this.requestFocusInWindow();
    }


    public static void main(String[] args)
    {
        JFrame w = new JFrame("Keyboard");
        w.setBounds(100, 100, 600, 600);
        w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Etch panel = new Etch(200);
        panel.setFocusable(true);
        panel.setBackground(Color.RED);

        Container c = w.getContentPane();
        c.add(panel);

        w.setResizable(true);
        w.setVisible(true);

    }

    public void keyPressed(KeyEvent e){
        int code = e.getKeyCode();


        if (code == KeyEvent.VK_UP){
            xPrev = xNew;
            yPrev = yNew;
            yNew -= inc;

        }
        if (code == KeyEvent.VK_DOWN){
            xPrev = xNew;
            yPrev = yNew;
            yNew += inc;

        }
        if (code == KeyEvent.VK_LEFT){
            xPrev = xNew;
            yPrev = yNew;
            xNew -= inc;
        }
        if (code == KeyEvent.VK_RIGHT){
            xPrev = xNew;
            yPrev = yNew;
            xNew += inc;
        }

        Graphics g = this.getGraphics();
        g.setColor(Color.BLUE);
        g.drawLine(xPrev, yPrev, xNew, yNew);
    }

    // Not used but required by the KeyListener interface
    public void keyReleased (KeyEvent e) { }

    public void keyTyped (KeyEvent e) { }
}

1 个答案:

答案 0 :(得分:2)

  • this.requestFocusInWindow();paintComponent方法中是一个坏主意。绘画应该绘制当前状态,永远不会改变组件的状态
  • getGraphics不是在Swing中完成绘画的方式。自定义绘画应该在paintComponent方法的上下文中完成。有关详细信息,请参阅Painting in AWT and SwingPerforming Custom Painting
  • 考虑使用KeyListener上的键绑定,因为您可以控制触发键事件所需的焦点级别。有关详细信息,请参阅How to Use Key Bindings

请记住,你不能控制Swing中的绘画过程,任何数量的事件都可以触发绘画周期,其中大部分都是你实际上无法控制的。尝试在流程中工作,而不是在流程中工作。

首先创建List java.awt.Point。发生键事件时,将每个点添加到List。使用paintComponent迭代List并绘制Point s之间的线...