gpt4 book ai didi

java - JPanel 中的移动图形

转载 作者:行者123 更新时间:2023-11-30 05:45:41 25 4
gpt4 key购买 nike

我想在单击按钮时将椭圆从 JPanel 中的一个位置移动到另一个位置。这是我想出的代码。然而,当我单击按钮时,这一切都会立即发生,没有明显的运动,从开始到结束都很慢。椭圆形刚刚出现在新位置。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.JPanel;
public class testtest implements ActionListener{
JButton button;
MyDrawPanel panel;
int x = 0;
int y = 0;
public static void main(String[]args){
testtest test = new testtest();
test.go();
}
public void go(){
JFrame frame = new JFrame("Balloon Balls");
panel = new MyDrawPanel();
button = new JButton("Restart");
button.addActionListener(this);
panel.add(button);
frame.setSize(300, 300);
frame.add(panel);
frame.setVisible(true);
}

@Override
public void actionPerformed (ActionEvent e){
for(int i=0;i<130;i++){
x++;
y++;
panel.repaint();
try {
Thread.sleep(100);
} catch(Exception ex) { }
}
}
class MyDrawPanel extends JPanel{
@Override
public void paintComponent(Graphics g){
g.fillOval(x, y, 30, 30);
g.setColor(Color.BLACK);

}
}
}

最佳答案

Swing 是单线程且不是线程安全的。

ActionListener 中使用 Thread.sleep(100) 会阻塞事件调度线程,从而阻止绘制任何内容。在 actionPerformed 方法存在之前,不会发生新的绘制过程。

参见Concurrency in Swing了解更多详情。

Swing 也不是线程安全的,这意味着您永远不应该从 EDT 上下文之外对 UI 进行更改。

最简单的解决方案是使用 Swing Timer ,这将允许建立定期定时回调,这些回调在事件调度线程内执行,但不会阻止 EDT。

您还缺少面向对象的重要概念之一:封装。 x/y 属性实际上应该由 MyDrawPanel 管理,而不是 testtest

例如...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class testtest implements ActionListener {

JButton button;
MyDrawPanel panel;

public static void main(String[] args) {
testtest test = new testtest();
test.go();

}

public void go() {
JFrame frame = new JFrame("Balloon Balls");
panel = new MyDrawPanel();
button = new JButton("Restart");
button.addActionListener(this);
panel.add(button);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

}

private Timer timer;

public void actionPerformed(ActionEvent e) {
if (timer != null) {
return;
}
timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if (panel.update()) {
timer.stop();
timer = null;
}
}
});
timer.start();
}

class MyDrawPanel extends JPanel {

private int xPosy = 0;
private int yPosy = 0;

@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}

public boolean update() {
xPosy++;
yPosy++;
repaint();

return xPosy > getWidth() || yPosy > getHeight();
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillOval(xPosy, yPosy, 30, 30);
g.setColor(Color.BLACK);
}
}
}

关于java - JPanel 中的移动图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54876566/

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