简体   繁体   English

JAVA:如何在不使用线程的情况下完成这项工作?

[英]JAVA: How can I make this work without using thread?

public class CarGame extends JFrame {
    class MyThread extends Thread{
        private JLabel label;
        private int x, y;
        public MyThread(String fname, int x, int y) {
            this.x = x;
            this.y = y;
            label = new JLabel();
            label.setIcon(new ImageIcon(fname));
            label.setBounds(x, y, 100, 100);
            add(label);
        }
        public void run() {
            for (int i=0; i<200; i++) {
                x += 10 * Math.random();
                label.setBounds(x, y, 100, 100);
                repaint();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public CarGame() {
        setTitle("Car Race");
        setSize(600, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(null);
        (new MyThread("car1.gif", 100, 0)).start();
        (new MyThread("car2.gif", 100, 50)).start();
        (new MyThread("car3.gif", 100, 100)).start();
        setVisible(true);
    }
    public static void main(String[] args) {
        CarGame t = new CarGame();
    }
}

Hi, I'm a university student and I got a question while studying JAVA.你好,我是一名大学生,我在学习 JAVA 时遇到了一个问题。 I want to make this Car Game works without using any thread.我想让这个汽车游戏在不使用任何线程的情况下工作。 Please help me!请帮我! Thank you :)谢谢 :)

Create an object for every car which holds its state.为每辆保持其状态的汽车创建一个对象。 Put all cars in a list and iterate over it 200 times:将所有汽车放在一个列表中并迭代 200 次:

import java.util.Arrays;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class CarGame extends JFrame {
    
    class Car {
        private JLabel label;
        private int x, y;
        public Car(String fname, int x, int y) {
            this.x = x;
            this.y = y;
            label = new JLabel();
            label.setIcon(new ImageIcon(fname));
            label.setBounds(x, y, 100, 100);
            add(label);
        }
        
        public void move()
        {
            x += 10 * Math.random();
            label.setBounds(x, y, 100, 100);
            repaint();          
        }
    }
    
    public CarGame() {
        setTitle("Car Race");
        setSize(600, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(null);
        List<Car> cars=Arrays.asList(new Car("car1.gif", 100, 0),new Car("car2.gif", 100, 50),new Car("car3.gif", 100, 100));
        setVisible(true);
        for(int i=0;i<200;i++)
        {
            cars.forEach(car->car.move());
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) {
        CarGame t = new CarGame();
    }
}

You will always have one thread.你将永远只有一个线程。

Remark: using Thread.sleep() for this purpose is not such a good idea as it will block the thread from doing other work.备注:为此目的使用 Thread.sleep() 不是一个好主意,因为它会阻止线程执行其他工作。 Better would be to use a timer which is triggered every 100ms and calls the cars.foreach(…) .最好使用一个每 100 毫秒触发一次并调用cars.foreach(…)cars.foreach(…) Off course this would result in a second thread.当然,这会导致第二个线程。 The timer can be canceled once the first (or last) car reaches the finish.一旦第一辆(或最后一辆)汽车到达终点,就可以取消计时器。 (thanks to @JoopEggen for the valid comment) (感谢@JoopEggen 的有效评论)

For completeness (and because it was fun to do): a version without threads but with :为了完整性(并且因为这样做很有趣):一个没有线程但有:

  • javax.swing.Timer which stops after all cars finished. javax.swing.Timer 在所有汽车完成后停止。
  • counts the final position of each car计算每辆车的最终位置
  • displays a text for those like who don't have a car gif.为那些没有汽车 gif 的人显示文本。
    import java.util.Arrays;
    import java.util.List;
    import javax.swing.Timer;
    
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    
    public class CarGame extends JFrame {
        int width = 600;
    
        int position=1;
        
        class Car {
            private JLabel label;
            private int x, y;
    
            public Car(String fname, int x, int y) {
                this.x = x;
                this.y = y;
                label = new JLabel(fname+">");
                label.setIcon(new ImageIcon(fname+".gif"));
                label.setBounds(x, y, 100, 100);
                add(label);
            }
    
            public boolean move() {
                if (!finished()) {
                    x += 10 * Math.random();
                    label.setBounds(x, y, 100, 100);
                    if(finished())
                        label.setText(label.getText()+"["+(position++)+"]");
                }
                return finished();
            }
    
            public boolean finished() {
                return x > width;
            }
        }
    
        public CarGame() {
            setTitle("Car Race");
            setSize(width+100, 200);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setLayout(null);
            List<Car> cars = Arrays.asList(new Car("car1", 100, 0), new Car("car2", 100, 50),
                    new Car("car3", 100, 100));
            setVisible(true);
            Timer timer=new Timer(100,null);
            timer.addActionListener(e-> {
                    // count the number of non-finished cars
                    if(cars.stream().map(car -> car.move()).filter(b->!b).count()==0)
                        timer.stop();
            });
            timer.start();
        }
    
        public static void main(String[] args) {
            new CarGame();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM