gpt4 book ai didi

java - Swing 油漆法

转载 作者:行者123 更新时间:2023-12-02 02:54:55 24 4
gpt4 key购买 nike

我在 JPanel 中的绘制方法中遇到问题。首先,我创建一个扩展 JFrame 的类。然后我创建一个扩展面板的类,并从该类创建一个对象并添加到框架中。

我希望通过按键盘上的右键(VK_RIGHT),在 2 秒内在面板上绘制小矩形。 (这意味着矩形清除并绘制在新位置。我的问题是:我无法执行定时绘制方法和重绘方法。我希望每两秒矩形前进 5 次(一步一步),但矩形只前进一次.

我的代码是:

面板

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;
}

//--------------------------------
}

框架

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,它阻塞了事件调度线程,从而阻止了更新的绘制。

简单的解决方案是使用 Swing 计时器,它在后台等待,触发 EDT 上的滴答声,使其安全地更新 ui 并定期安排更新。

参见Concurrency in SwingHow to use Swing Timers了解更多详情

如果由于某种原因,您发现 Swing Timer 难以理解,您也可以尝试使用 SwingWorker,它允许您使用后台线程来循环,但它提供了在 EDT 上下文中更新状态的方法。

参见Worker Threads and SwingWorker了解更多详情

建议

作为一般规则,重写 paintComponent 而不是 paint。请参阅Performing Custom Painting了解更多详情

不要使用repaint来更新你的状态,你可能不是唯一调用它的人,相反,创建一个可以在 View 和你的关键 Controller 之间共享的模型。

参见Model-View-ControllerObserver Pattern一些想法

我也不鼓励使用 KeyListener 并改用键绑定(bind) API

参见How to Use Key Bindings了解更多详情

关于java - Swing 油漆法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43264847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com