[英]Swing paint method
我在JPanel
中的绘制方法有问题。 首先,我创建一个扩展JFrame
的类。 然后,我创建一个扩展面板的类,并从该类中创建一个对象并添加到框架中。
我想要通过按键盘上的右键( VK_RIGHT
)在2秒内在面板上绘制小矩形。 (这意味着将矩形清除并绘制到新位置。我的问题是:我无法执行定时绘制方法和重新绘制方法。我希望每两秒矩形前进5次(逐步),但矩形仅前进一次。
我的代码是:
Panel
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Panel extends JPanel{
private int x;
private int y;
public Panel()
{
x=100;
y=100;
this.setBackground(Color.RED);
}
//--------------------------------
@Override
public void paint(Graphics g)
{
super.paint(g);
g.setColor(Color.BLACK);
g.fillRect(x, y, 20, 20);
}
//--------------------------------
@Override
public void repaint()
{
super.repaint();
x+=20;
}
//--------------------------------
}
Frame
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class Frame extends JFrame {
private Panel p;
public Frame()
{
super("Test");
this.setBounds(1200, 300, 400, 400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p=new Panel();
this.add(p);
this.addKeyListener(new KeyLis());
}
//----------------------------------
public static void main(String[] args) {
Frame a=new Frame();
a.setVisible(true);
}
//-----------------------------------
private class KeyLis implements KeyListener
{
@Override
public void keyPressed(KeyEvent arg0) {
if(arg0.getKeyCode() == KeyEvent.VK_RIGHT)
{
for(int i=0;i<5;i++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.repaint();
}
}
}
//---------------
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
//---------------
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
//---------------
}
//-----------------------------------------
}
您的问题主要是在KeyListener
的for-loop
,该for-loop
阻塞了Event调度线程,从而阻止绘制更新。
一个简单的解决方案是使用Swing Timer
,它在后台等待,在EDT上触发滴答,从而确保从中更新ui并定期安排更新。
有关更多详细信息,请参见Swing中的并发和如何使用Swing计时器 。
如果由于某种原因而难以理解Swing Timer
,则也可以尝试使用SwingWorker
,它允许您使用后台线程进行循环,但是它提供了在EDT上下文中更新状态的方法。
有关更多详细信息,请参见工作线程和SwingWorker 。
通常,覆盖paintComponent
而不是paint
。 有关更多详细信息,请参见执行自定义绘画 。
不要使用repaint
来更新您的状态,您可能不是唯一一个调用它的人,而是创建一个可以在视图和关键控制器之间共享的模型。
我也建议不要使用KeyListener
而要使用键绑定API
有关更多详细信息,请参见如何使用键绑定 。
如果您设置使用线程:
将您的KeyPressed事件更改为:
@Override
public void keyPressed(KeyEvent arg0) {
if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
PaintThread th = new PaintThread(p);
th.start();
}
}
创建了一个线程:
import java.util.logging.Level;
import java.util.logging.Logger;
public class PaintThread extends Thread{
Panel panel;
PaintThread(Panel panel){
this.panel = panel;
}
@Override
public void run() {
for(int i = 0; i<5; i++){
try {
this.sleep(1000);
panel.repaint();
} catch (InterruptedException ex) {
Logger.getLogger(PaintThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.