gpt4 book ai didi

java - 球不动;线?

转载 作者:行者123 更新时间:2023-12-01 17:43:36 30 4
gpt4 key购买 nike

这是一个让球以对角线方式下降的 UI,但球保持静止;线程似乎无法正常工作。你能告诉我如何让球移动吗?

请下载一个球并更改目录,以便程序可以找到您的球的分配位置。没有必要下载足球场,但如果您愿意,也可以。最后,我要感谢您花时间寻找这个故障。

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import java.io.File;

class Animation extends JFrame implements ActionListener { //Frame and listener

Rectangle2D dimensions = new Rectangle2D.Double(0,0,850,595); //Not implemented limits
JButton animate, stop;
Runnable runnable;
Thread move;

public Animation() {
setLayout(new BorderLayout()); //BorderLayout disposition
setTitle("Pelota en acción");

animate = new JButton("Animate it!"); //Button to create balls
animate.setBounds(0,0,120,30);
animate.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
Image ball = null;
new Layout().createEllipse(ball);
runnable = new Layout();
move = new Thread(runnable);
move.start();
}
});

stop = new JButton("Freeze"); //Button to interrupt thread (not implemented)
stop.setBounds(0,0,120,30);
stop.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
move.interrupt();
Layout.running = false;
}
});

JPanel subPanel = new JPanel(); //Layout with its buttons situated to the south
subPanel.add(animate);
subPanel.add(stop);
add(subPanel,BorderLayout.SOUTH);

add(new Layout());
}

public static void main(String[] args) {
Animation ventana = new Animation();
ventana.setSize(850,625);
ventana.setLocationRelativeTo(null);
ventana.setVisible(true);
ventana.setDefaultCloseOperation(EXIT_ON_CLOSE);
}

@Override
public void actionPerformed(ActionEvent e) {} //Tag
} //Class close


class Layout extends JPanel implements Runnable { //Layout and thread

int X,Y; //Coordenadas
static boolean running = true; //"To interrupt the thread" momentaneously.
static ArrayList<Image> balls = new ArrayList<>(); //Balls collection

@Override
public void run () { //Just moves ball towards Narnia xd
while(running) {
X++; Y++;
System.out.println(X+" "+Y);
repaint();
updateUI();
try {
Thread.sleep(4);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
repaint();
updateUI();

try {
URL url = new URL("https://www.freejpg.com.ar/image-900/9c/9ca2/F100004898-textura_pasto_verde_linea_de_cal.jpg");
Image picture = ImageIO.read(url);
g.drawImage(picture,0,0,null);
} catch(IOException e){
System.out.println("URL image was not found");
}
finally {
try {
//----------------------------------------------------------------------------
Image picture = ImageIO.read(new File("C:\\Users\\Home\\Desktop\\Cancha.jpg")); //Pitch
//----------------------------------------------------------------------------
g.drawImage(picture, 0, 0, null);
} catch (IOException ex) {
System.out.println("Pitch image was not found");
}
}

for (Image ball : balls) { //I add balls to the Layout
g2.drawImage(ball,X,Y,100,100,null);
}
}

public void createEllipse (Image ball) { //Method that adds balls to the collection
try {
//-------------------------------------------------------------------- Ball
ball = ImageIO.read(new File("C:\\Users\\Home\\Desktop\\Pelota.png")); //Change this
//-------------------------------------------------------------------- Ball
} catch(IOException ex) {
System.out.println("Any balls were found");
}
balls.add(ball);
}
}

最佳答案

所以要分解你的代码:

当按下按钮时,您将执行以下代码:

Image ball = null;
new Layout().createEllipse(ball);
runnable = new Layout();
move = new Thread(runnable);
move.start();

这将创建一个新的布局。其中的 run() 方法将增加 XY 变量。它们在这里声明:

int X,Y;  //Coordenadas 

这些是实例变量,这意味着它们属于您新创建的布局

然后你在新的 Layout 上调用 repaint(),这不会执行任何操作,因为这个新的 Layout 尚未添加到某个窗口。

那么,如何解决这个问题呢?

首先,您必须保留原始的布局:

class Animation extends JFrame { // no need to implement ActionListener
Rectangle2D dimensions = new Rectangle2D.Double(0,0,850,595); //Not implemented limits
JButton animate, stop;
Thread move;
Layout layout;

然后在创建布局时记住布局:

// before: add(new Layout());
layout = new Layout();
add(layout);

然后使用 ActionListener 中的布局:

layout.createEllipse(ball);
move = new Thread(layout);
move.start();

这可能会出现一些并发问题(Swing 不是线程安全的),因此为了更好地衡量,您应该在 AWTEventThread 中调用 repaint():

// in run(), was repaint():
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
repaint();
}
});

现在,还剩下一些清理任务:
删除此代码:

  @Override
public void actionPerformed(ActionEvent e) {} //Tag

不再需要它,因为您没有实现 ActionListener

删除某些字段中的static修饰符,并添加 volatile :

volatile int X,Y;  //Coordenadas
volatile boolean running = true; //"To interrupt the thread" momentaneously.
ArrayList<Image> balls = new ArrayList<>(); //Balls collection
从多个线程访问的变量需要

volatile

同时从 paint 方法中删除 repaint()resetUI() 。你不需要它们。

对于paint中的图片:你应该缓存它们。将它们存储在一个字段中,这样您就不必每次都加载图片。

完成所有这些后,您的代码会更加干净,但仍然有一些问题需要解决。但至少你有一些工作。

关于java - 球不动;线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58045427/

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