在下面的代码中,箭头键用于绘制一条线,就像在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) { }
}
答案 0 :(得分:2)
this.requestFocusInWindow();
在paintComponent
方法中是一个坏主意。绘画应该绘制当前状态,永远不会改变组件的状态getGraphics
不是在Swing中完成绘画的方式。自定义绘画应该在paintComponent
方法的上下文中完成。有关详细信息,请参阅Painting in AWT and Swing和Performing Custom Painting KeyListener
上的键绑定,因为您可以控制触发键事件所需的焦点级别。有关详细信息,请参阅How to Use Key Bindings 请记住,你不能控制Swing中的绘画过程,任何数量的事件都可以触发绘画周期,其中大部分都是你实际上无法控制的。尝试在流程中工作,而不是在流程中工作。
首先创建List
java.awt.Point
。发生键事件时,将每个点添加到List
。使用paintComponent
迭代List
并绘制Point
s之间的线...