Java 如何正确执行多线程处理,使单个线程上的图标一起在屏幕上移动?

Java 如何正确执行多线程处理,使单个线程上的图标一起在屏幕上移动?,java,multithreading,swing,animation,paintcomponent,Java,Multithreading,Swing,Animation,Paintcomponent,我正在尝试创建一个动画,其中给定数量的图标从帧的左侧开始,然后移动到屏幕的右侧。图标垂直排列,每个图标都应该在自己的线程上运行 我如何让所有图标都这样做?当我创建每个赛车手时,我试着调整posY,但到目前为止,我只能得到创建用于显示的最后一个赛车手 import javax.swing.*; import java.awt.*; public class Races { private JFrame frame; private JPanel gui; private

我正在尝试创建一个动画,其中给定数量的图标从帧的左侧开始,然后移动到屏幕的右侧。图标垂直排列,每个图标都应该在自己的线程上运行

我如何让所有图标都这样做?当我创建每个赛车手时,我试着调整
posY
,但到目前为止,我只能得到创建用于显示的最后一个赛车手

import javax.swing.*;
import java.awt.*;

public class Races {
    private JFrame frame;
    private JPanel gui;
    private Icon img;
    private int imgWidth;
    private int imgHeight;
    private int numOfRacers;  // num of threads / racers

    public static void main(String[] args) {
        new Races(5);
    }

    public Races(int num) {
        numOfRacers = num;
        createGUI();
        frame.add(gui);
        frame.pack();  
        frame.setVisible(true);
    }

    private void createGUI() {
        frame = new JFrame("Off to the Races - by Brienna Herold");
        gui = new JPanel();
        gui.setPreferredSize(new Dimension(imgWidth * 20, imgHeight * numOfRacers));

        img = new ImageIcon("races.png");
        imgWidth = img.getIconWidth();
        imgHeight = img.getIconHeight();

        int posY = 0;
        for (int i = 0; i < numOfRacers; i++) {
            System.out.println("Starting new thread..." + posY);
            racer = new Racer(posY);
            Thread racerThread = new Thread(racer);
            racerThread.start();
            posY += imgHeight;
        }
    }

    protected class Racer extends JPanel implements Runnable {
        private int lastPosX;
        private int posX;
        private int posY;

        public Racer(int _posY) {
            posX = 0;
            posY = _posY;
        }

        @Override
        public void paintComponent(Graphics g) {
            // Call the method on the JPanel
            super.paintComponent(g);
            img.paintIcon(gui, g, posX, posY);
            //posY += imgHeight;
            posX += lastPosX + 3;
        }

        @Override
        public void run() {
            while (true) {
                repaint();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

}
import javax.swing.*;
导入java.awt.*;
公共级别比赛{
私有JFrame;
私有JPanel gui;
私有图标img;
私家侦探;
私人国际照明;
private int numoracers;//线程数/线程数
公共静态void main(字符串[]args){
新种族(5);
}
公共竞赛(整数){
numoracers=num;
createGUI();
frame.add(gui);
frame.pack();
frame.setVisible(true);
}
私有void createGUI(){
frame=新JFrame(“出发参加比赛-由Brienna Herold编写”);
gui=新的JPanel();
setPreferredSize(新维度(imgWidth*20,imghight*numoracers));
img=新图像图标(“races.png”);
imgWidth=img.getIconWidth();
imgHeight=img.getIconHeight();
int-posY=0;
对于(int i=0;i
您只能将一个赛车手零部件添加到车架中

但到目前为止,我只能得到最后一个赛车手,创造了显示

import javax.swing.*;
import java.awt.*;

public class Races {
    private JFrame frame;
    private JPanel gui;
    private Icon img;
    private int imgWidth;
    private int imgHeight;
    private int numOfRacers;  // num of threads / racers

    public static void main(String[] args) {
        new Races(5);
    }

    public Races(int num) {
        numOfRacers = num;
        createGUI();
        frame.add(gui);
        frame.pack();  
        frame.setVisible(true);
    }

    private void createGUI() {
        frame = new JFrame("Off to the Races - by Brienna Herold");
        gui = new JPanel();
        gui.setPreferredSize(new Dimension(imgWidth * 20, imgHeight * numOfRacers));

        img = new ImageIcon("races.png");
        imgWidth = img.getIconWidth();
        imgHeight = img.getIconHeight();

        int posY = 0;
        for (int i = 0; i < numOfRacers; i++) {
            System.out.println("Starting new thread..." + posY);
            racer = new Racer(posY);
            Thread racerThread = new Thread(racer);
            racerThread.start();
            posY += imgHeight;
        }
    }

    protected class Racer extends JPanel implements Runnable {
        private int lastPosX;
        private int posX;
        private int posY;

        public Racer(int _posY) {
            posX = 0;
            posY = _posY;
        }

        @Override
        public void paintComponent(Graphics g) {
            // Call the method on the JPanel
            super.paintComponent(g);
            img.paintIcon(gui, g, posX, posY);
            //posY += imgHeight;
            posX += lastPosX + 3;
        }

        @Override
        public void run() {
            while (true) {
                repaint();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

}
“racer”变量指向创建的最后一个racer组件

如果需要多个组件,则需要使用空布局创建面板。然后需要将每个赛车手组件添加到此面板,然后将面板添加到框架。使用这种方法,您可以使用组件的setLocation(…)方法来移动组件


如果要在其他位置绘制图像,则应使用包含ArrayList或Racer对象的单个面板。然后,当面板的paintComponent()方法被调用时,您将遍历列表,并在每个赛车手的新位置上进行绘制。

Ooh。让我试试这个。你不只是画画。除非在框架中添加组件,否则无法绘制组件。我不知道你在问什么。但是看看你的代码。您有一个不断创建Racer组件新实例的循环。除非将组件添加到框架中,否则框架对组件一无所知,因此无法对其进行绘制。例如,从ArrayList签出绘制对象的示例:是的,我以为我理解了
img.paintIcon(gui、g、posX、posY)
意味着我将在指定的posX、posY位置将图像绘制到
gui
组件上,这将在创建Racer的每个实例时发生。