简体   繁体   中英

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. 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:

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. Better would be to use a timer which is triggered every 100ms and calls the 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)

For completeness (and because it was fun to do): a version without threads but with :

  • javax.swing.Timer which stops after all cars finished.
  • counts the final position of each car
  • displays a text for those like who don't have a car 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();
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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