JAVA:如何在不使用线程的情况下使此代码生效?

huangapple go评论62阅读模式
英文:

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();
    }
}

(Note: The provided code is the same as the original code you provided. If you want assistance in modifying the code to work without using threads, please let me know.)

英文:
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&lt;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(&quot;Car Race&quot;);
setSize(600, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
(new MyThread(&quot;car1.gif&quot;, 100, 0)).start();
(new MyThread(&quot;car2.gif&quot;, 100, 50)).start();
(new MyThread(&quot;car3.gif&quot;, 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 JAVA:如何在不使用线程的情况下使此代码生效?

答案1

得分: 1

创建一个对象来保存每辆汽车的状态。将所有汽车放入一个列表中,并迭代它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) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        CarGame t = new CarGame();
    }
}

您将始终有一个线程。

注:出于这个目的,使用Thread.sleep()并不是一个很好的方法,因为它会阻塞线程的其他工作。更好的做法是使用一个定时器,每隔100毫秒触发一次,并调用cars.foreach(…)。当第一(或最后)辆汽车到达终点时,可以取消定时器。(感谢@JoopEggen提供的有效评论)

为了完整性(并且因为这很有趣):一个没有线程但有以下特点的版本:

  • 使用javax.swing.Timer,在所有汽车完成后停止。
  • 计算每辆车的最终位置。
  • 为那些没有汽车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 -> {
            // 计算未完成的汽车数量
            if (cars.stream().map(car -> car.move()).filter(b -> !b).count() == 0)
                timer.stop();
        });
        timer.start();
    }

    public static void main(String[] args) {
        new CarGame();
    }
}
英文:

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(&quot;Car Race&quot;);
setSize(600, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
List&lt;Car&gt; cars=Arrays.asList(new Car(&quot;car1.gif&quot;, 100, 0),new Car(&quot;car2.gif&quot;, 100, 50),new Car(&quot;car3.gif&quot;, 100, 100));
setVisible(true);
for(int i=0;i&lt;200;i++)
{
cars.forEach(car-&gt;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+&quot;&gt;&quot;);
label.setIcon(new ImageIcon(fname+&quot;.gif&quot;));
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()+&quot;[&quot;+(position++)+&quot;]&quot;);
}
return finished();
}
public boolean finished() {
return x &gt; width;
}
}
public CarGame() {
setTitle(&quot;Car Race&quot;);
setSize(width+100, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
List&lt;Car&gt; cars = Arrays.asList(new Car(&quot;car1&quot;, 100, 0), new Car(&quot;car2&quot;, 100, 50),
new Car(&quot;car3&quot;, 100, 100));
setVisible(true);
Timer timer=new Timer(100,null);
timer.addActionListener(e-&gt; {
// count the number of non-finished cars
if(cars.stream().map(car -&gt; car.move()).filter(b-&gt;!b).count()==0)
timer.stop();
});
timer.start();
}
public static void main(String[] args) {
new CarGame();
}
}

huangapple
  • 本文由 发表于 2020年9月17日 17:31:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/63935180.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定