简体   繁体   English

是什么导致此代码重新绘制自身?

[英]What is causing this code to repaint itself?

In the code below, the arrow keys are used to draw a line as in etch-a-sketch (but you have to resize the window first to trigger the panel's focus request at the right time -- that's a question for a different time, perhaps). 在下面的代码中,箭头键用于绘制线条,就像在etch-a-sketch中一样(但是您必须先调整窗口的大小才能在适当的时间触发面板的焦点请求-这是一个不同时间的问题,也许)。 The graphics command g.drawLine() occurs in the keyPressed() function, repaint() is not called explicitly, but the image updates itself as the arrow keys are pressed. 图形命令g.drawLine()发生在keyPressed()函数中,未显式调用repaint(),但是图像在按下箭头键时会自动更新。 Why is that? 这是为什么? All the documentation I have looked at only talks about the JPanel automatically repainting itself when it is resized or uncovered. 我看过的所有文档都只谈到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) { }
}
  • this.requestFocusInWindow(); is a bad idea within the paintComponent method. paintComponent方法中是个坏主意。 Painting should paint the current state and never change the state of the component 绘制应该绘制当前状态,并且永远不要更改组件的状态
  • getGraphics is not how painting is done in Swing. getGraphics不是在Swing中完成绘画的方式。 Custom painting should be done from within the context of the paintComponent method. 自定义绘画应从paintComponent方法的上下文中完成。 See Painting in AWT and Swing and Performing Custom Painting for more details 有关更多详细信息,请参见“ AWT中的绘画”和“摇摆执行自定义绘画
  • Consider using key bindings over KeyListener , as you can control the focus level required to trigger the key events. 考虑在KeyListener使用键绑定,因为您可以控制触发键事件所需的焦点级别。 See How to Use Key Bindings for more details 有关更多详细信息,请参见如何使用键绑定

Remember, you don't control the paint process in Swing, a paint cycle can be triggered by any number of events, most of which you don't actually control. 请记住,您不控制Swing中的绘制过程,绘制周期可以由任意数量的事件触发,其中大多数事件实际上是您无法控制的。 Try working within the process instead of out of it. 尝试在流程中进行工作,而不要超出流程。

Start by creating a List of java.awt.Point . 首先创建一个java.awt.Point List Add each point to the List when a key event occurs. 发生按键事件时,将每个点添加到List Use the paintComponent to iterate over the List and paint the lines between the Point s... 使用paintComponent遍历List并绘制Point s之间的线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM