Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 摇摆和多线程:为什么汽车相撞?_Java_Multithreading_Swing_Custom Painting - Fatal编程技术网

Java 摇摆和多线程:为什么汽车相撞?

Java 摇摆和多线程:为什么汽车相撞?,java,multithreading,swing,custom-painting,Java,Multithreading,Swing,Custom Painting,这是我为具有图形用户界面的cross road并发应用程序所做的实现,但在运行应用程序一段时间后,不知何故发生了冲突,无法真正了解实际问题 请原谅我是新来的,所以我很感激你的支持 我的窗口类: package com.example.trafic; import javax.swing.*; public class Window extends JFrame { View view = new View(); public Window(){ this.s

这是我为具有图形用户界面的cross road并发应用程序所做的实现,但在运行应用程序一段时间后,不知何故发生了冲突,无法真正了解实际问题 请原谅我是新来的,所以我很感激你的支持

我的窗口类:

package com.example.trafic;

import javax.swing.*;

public class Window extends JFrame {
    View view = new View();

    public Window(){
        this.setTitle("Trafic App");
        this.setSize(720, 450);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setContentPane(view);
        this.setResizable(false);
        this.setVisible(true);
    }
}
我的观点类:

package com.example.trafic;

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

public class View extends JPanel {
    //private Thread t;

    // DIMENSION
    public int width = 720;
    public int height = 420;
    public int route_width = 100;
    public int lamp_width = 30;
    public int car_width = 60;
    public int car_height = 70;

    public int positionV = 0;
    public int positionH = 0;
    public int feu = 1;

    @Override
    public void paintComponent(Graphics g2) {
        // TEXTTURE
        g2.setColor(Color.DARK_GRAY);
        g2.fillRect(0, 0, width, height);

        // ROUTE
        g2.setColor(Color.LIGHT_GRAY);
        g2.fillRect( width / 2 - route_width / 2, 0, route_width, 420);
        g2.fillRect(0, height / 2 - route_width / 2, 720, route_width);

        // LAMPE
        g2.setColor((feu == 1 ) ? Color.RED : Color.GREEN );
        g2.fillOval(width / 2 - route_width, height / 2 - route_width, lamp_width, lamp_width);
        g2.setColor((feu == 2 ) ? Color.RED : Color.GREEN);
        g2.fillOval(width / 2 + route_width - 30, height / 2 - route_width , lamp_width, lamp_width);
        ImageIcon ia = new ImageIcon(View.class.getResource("/images/carh.png"));
        Image carH = ia.getImage();
        ImageIcon ib = new ImageIcon(View.class.getResource("/images/carv.png"));
        Image carV = ib.getImage();
        g2.drawImage(carH, 10 + width / 2 - car_width / 2, 10 + positionH, this);
        g2.drawImage(carV, 720 - positionV, 10 + height / 2 - car_height / 2, this);
    }

    public void setLight(int feu){
        this.feu = feu;
        this.repaint();
    }

    public void setCarV(int i){
        this.positionV = i;
        this.repaint();
    }

    public void setCarH(int i) {
        this.positionH = i;
        this.repaint();
    }
}
我的任务类:

package com.example.trafic;

public class Task implements Runnable {
    Window frame;
    static int Feu = 1;

    public Task(Window frame) {
        this.frame = frame;
    }

    public void run() {
        while (true) {
            try {
                Thread.sleep(4000);
                if (Feu == 1) {
                    Feu = 2;
                    System.out.println("Feu 2 ON");
                } else {
                    Feu = 1;
                    System.out.println("Feu 1 ON");
                }
                frame.view.setLight(Feu);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
我的跑步课:

package com.example.trafic;

public class Run implements Runnable {
    View view;

    public Run(View view) {
        this.view = view;
    }

    public void run() {
        while (Task.Feu == 2) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        while(true){
            int i = 0 ;

            int l = (Task.Feu == 1) ? 720 : 450;
            for (int j = 0; j < l; j++) {
                try {
                    Thread.sleep(2);
                    if ((Task.Feu == 1)) {
                        view.setCarV(++i);
                    } else {
                        view.setCarH(++i);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

以下代码实现了模型-视图-控制器模式,以演示在问题中尝试的一个简单连接控件。
代码是一个文件MCVE:它可以复制粘贴到
Junction.java
并运行
请注意以下评论:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

//serves as controller. "wires" up model, view and updating thread
public class Junction {

    private static final int TRAFFIC_LIGHT_CYCLE = 4000;
    private boolean isVerticalRed = false;

    Junction() {
        Model model = new Model();
        Window frame = new Window(model);
        model.setObserver(frame);
        //use time to change lights
        Timer timer = new Timer(TRAFFIC_LIGHT_CYCLE, e->{
            isVerticalRed = ! isVerticalRed;
            model.setVerticalRed(isVerticalRed);
        });

        timer.start();
        new Thread(new CarsUpdater(model)).start();
    }

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

//view of the mvc model. listens to changes in model using Observer interface
class Window extends JFrame implements Observer{

    private final View view;

    public Window(Model model){

        this.setTitle("Trafic App");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        view = new View(model);
        this.setContentPane(view);
        pack();
        this.setResizable(false);
        this.setVisible(true);
    }

    //respond to model changes
    @Override
    public void changed() {
        repaint();
    }
}

class View extends JPanel {

    // DIMENSION
    private final static int ROUTE_WIDTH = 100, LAMP_WIDTH = 30;
    private final int CAR_WIDTH = 60, CAR_HEIGHT = 70;

    //Construct resources once
    private Image carH, carV;

    private final Model model;

    View(Model model) {

        this.model = model;

        //Construct resources once
        try {
            //use publically available resources to make code mcve 
            ImageIcon ia = new ImageIcon(new URL("https://i.imgur.com/wIO1liB.png"));
            carH = ia.getImage();
            ImageIcon ib = new ImageIcon(new URL("https://i.imgur.com/gEbZMHe.png"));
            carV = ib.getImage();
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }

        setPreferredSize(new Dimension(model.getWidth(), model.getHeight()));
    }

    @Override
    public void paintComponent(Graphics g2) {

        super.paintComponent(g2);
        // TEXTTURE
        g2.setColor(Color.DARK_GRAY);
        g2.fillRect(0, 0, model.getWidth(), model.getHeight());

        // ROUTE
        g2.setColor(Color.LIGHT_GRAY);
        g2.fillRect( model.getWidth() / 2 - ROUTE_WIDTH / 2, 0, ROUTE_WIDTH, 420);
        g2.fillRect(0, model.getHeight() / 2 - ROUTE_WIDTH / 2,  model.getWidth(), ROUTE_WIDTH);

        // LAMPE
        g2.setColor(model.isVerticalRed() ?  Color.RED : Color.GREEN  );
        g2.fillOval(model.getWidth() / 2 - ROUTE_WIDTH,  model.getHeight() / 2 - ROUTE_WIDTH, LAMP_WIDTH, LAMP_WIDTH);

        g2.setColor(model.isVerticalRed() ? Color.GREEN : Color.RED);
        g2.fillOval( model.getWidth() / 2 + ROUTE_WIDTH - 30,  model.getHeight()/ 2 - ROUTE_WIDTH , LAMP_WIDTH, LAMP_WIDTH);

        g2.drawImage(carH, 10 + model.getWidth() / 2 - CAR_WIDTH / 2, 10 + model.getVerticalCarPosition(), this);
        g2.drawImage(carV,  model.getWidth() - model.getHorizontalCarPosition(), 10 +  model.getHeight() / 2 - CAR_HEIGHT / 2, this);
    }
}

interface Observer {
    void changed();
}

//model encapsulates information that view needs
class Model {

    private final static int W = 720, H = 420;
    private static final long SPEED = 2;
    private Observer observer;

    //is read / write by more than one thread getters and setters
    //need to be synchronized
    private boolean isVerticalRed = false;     //boolean to flag which light is red
    private int hPosition = 0,  vPosition = 0;

    boolean isVerticalRed() {
        return isVerticalRed;
    }

    void setVerticalRed(boolean isVerticalRed) {
        this.isVerticalRed = isVerticalRed;
        notifyObserver();
    }

    int getHorizontalCarPosition(){
        return hPosition;
    }

    //move horizontal car continuously, until meets stop condition
    void clearHorizontalCarFromJunction() throws InterruptedException{
        while(hPosition != W / 3){
            Thread.sleep(SPEED);
            stepHorizontal();
        }
    }

    //move horizontal one step
    void stepHorizontal(){
        int newH= hPosition  +1 > W ?  0 : hPosition +1;
        setHorizontalCarPosition(newH);
    }

    void setHorizontalCarPosition(int i){
        hPosition = i;
        notifyObserver();
    }

    //move vertical car continuously, until meets stop condition
    void clearVerticalCarFromJunction() throws InterruptedException{
        while(vPosition != H / 4){
            Thread.sleep(SPEED);
            stepVertical();
        }
    }
    //move vertical car one step
    void stepVertical(){
        int newV = vPosition +1 > H ?  0 : vPosition +1;
        setVerticalCarPosition(newV);
    }

    int getVerticalCarPosition(){
        return vPosition;
    }

    void setVerticalCarPosition(int i) {
        vPosition = i;
        notifyObserver();
    }

    int getWidth(){ return W;   }

    int getHeight(){ return H;  }

    void setObserver(Observer observer) {
        this.observer = observer;
    }

    void notifyObserver(){
        if(observer != null) {
            observer.changed();
        }
    }

    long getSpeed(){
        return SPEED;
    }
}

class CarsUpdater implements Runnable {

    private final Model model;

    public CarsUpdater(Model model) {
        this.model = model;
    }

    @Override
    public void run() {

        while(true){;

            try {

                Thread.sleep(model.getSpeed());
                if (model.isVerticalRed()) {
                    model.clearVerticalCarFromJunction();
                    model.stepHorizontal();
                } else {
                    model.clearHorizontalCarFromJunction();
                    model.stepVertical();
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

您必须更具体地说明代码中哪里出了问题,以及具体出了什么问题。1)为了更快地获得更好的帮助,请添加or。2) 请对代码和代码片段、结构化文档(如HTML/XML或输入/输出)使用代码格式。要执行此操作,请选择文本并单击消息发布/编辑表单顶部的
{}
按钮。问题似乎在于,当您更换车灯时,您没有检查另一辆车是否不在交叉路口。例如,当car的指示灯变为绿色时,car不应在car驶出交叉口之前移动。只有在交通灯之前,才以红色停车。如需更多帮助,请参阅上面的评论:非常感谢,先生,您将在我的小项目中拯救我,我永远不会忘记您的帮助,因为它帮助解决了问题。通过接受答案,它可以帮助其他人找到有效的解决方案。还要注意,当代码以MCVE的形式出现时,查看答案的值是多么容易。在问题中张贴MCVE有助于我们(无偿志愿者)了解问题。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

//serves as controller. "wires" up model, view and updating thread
public class Junction {

    private static final int TRAFFIC_LIGHT_CYCLE = 4000;
    private boolean isVerticalRed = false;

    Junction() {
        Model model = new Model();
        Window frame = new Window(model);
        model.setObserver(frame);
        //use time to change lights
        Timer timer = new Timer(TRAFFIC_LIGHT_CYCLE, e->{
            isVerticalRed = ! isVerticalRed;
            model.setVerticalRed(isVerticalRed);
        });

        timer.start();
        new Thread(new CarsUpdater(model)).start();
    }

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

//view of the mvc model. listens to changes in model using Observer interface
class Window extends JFrame implements Observer{

    private final View view;

    public Window(Model model){

        this.setTitle("Trafic App");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        view = new View(model);
        this.setContentPane(view);
        pack();
        this.setResizable(false);
        this.setVisible(true);
    }

    //respond to model changes
    @Override
    public void changed() {
        repaint();
    }
}

class View extends JPanel {

    // DIMENSION
    private final static int ROUTE_WIDTH = 100, LAMP_WIDTH = 30;
    private final int CAR_WIDTH = 60, CAR_HEIGHT = 70;

    //Construct resources once
    private Image carH, carV;

    private final Model model;

    View(Model model) {

        this.model = model;

        //Construct resources once
        try {
            //use publically available resources to make code mcve 
            ImageIcon ia = new ImageIcon(new URL("https://i.imgur.com/wIO1liB.png"));
            carH = ia.getImage();
            ImageIcon ib = new ImageIcon(new URL("https://i.imgur.com/gEbZMHe.png"));
            carV = ib.getImage();
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }

        setPreferredSize(new Dimension(model.getWidth(), model.getHeight()));
    }

    @Override
    public void paintComponent(Graphics g2) {

        super.paintComponent(g2);
        // TEXTTURE
        g2.setColor(Color.DARK_GRAY);
        g2.fillRect(0, 0, model.getWidth(), model.getHeight());

        // ROUTE
        g2.setColor(Color.LIGHT_GRAY);
        g2.fillRect( model.getWidth() / 2 - ROUTE_WIDTH / 2, 0, ROUTE_WIDTH, 420);
        g2.fillRect(0, model.getHeight() / 2 - ROUTE_WIDTH / 2,  model.getWidth(), ROUTE_WIDTH);

        // LAMPE
        g2.setColor(model.isVerticalRed() ?  Color.RED : Color.GREEN  );
        g2.fillOval(model.getWidth() / 2 - ROUTE_WIDTH,  model.getHeight() / 2 - ROUTE_WIDTH, LAMP_WIDTH, LAMP_WIDTH);

        g2.setColor(model.isVerticalRed() ? Color.GREEN : Color.RED);
        g2.fillOval( model.getWidth() / 2 + ROUTE_WIDTH - 30,  model.getHeight()/ 2 - ROUTE_WIDTH , LAMP_WIDTH, LAMP_WIDTH);

        g2.drawImage(carH, 10 + model.getWidth() / 2 - CAR_WIDTH / 2, 10 + model.getVerticalCarPosition(), this);
        g2.drawImage(carV,  model.getWidth() - model.getHorizontalCarPosition(), 10 +  model.getHeight() / 2 - CAR_HEIGHT / 2, this);
    }
}

interface Observer {
    void changed();
}

//model encapsulates information that view needs
class Model {

    private final static int W = 720, H = 420;
    private static final long SPEED = 2;
    private Observer observer;

    //is read / write by more than one thread getters and setters
    //need to be synchronized
    private boolean isVerticalRed = false;     //boolean to flag which light is red
    private int hPosition = 0,  vPosition = 0;

    boolean isVerticalRed() {
        return isVerticalRed;
    }

    void setVerticalRed(boolean isVerticalRed) {
        this.isVerticalRed = isVerticalRed;
        notifyObserver();
    }

    int getHorizontalCarPosition(){
        return hPosition;
    }

    //move horizontal car continuously, until meets stop condition
    void clearHorizontalCarFromJunction() throws InterruptedException{
        while(hPosition != W / 3){
            Thread.sleep(SPEED);
            stepHorizontal();
        }
    }

    //move horizontal one step
    void stepHorizontal(){
        int newH= hPosition  +1 > W ?  0 : hPosition +1;
        setHorizontalCarPosition(newH);
    }

    void setHorizontalCarPosition(int i){
        hPosition = i;
        notifyObserver();
    }

    //move vertical car continuously, until meets stop condition
    void clearVerticalCarFromJunction() throws InterruptedException{
        while(vPosition != H / 4){
            Thread.sleep(SPEED);
            stepVertical();
        }
    }
    //move vertical car one step
    void stepVertical(){
        int newV = vPosition +1 > H ?  0 : vPosition +1;
        setVerticalCarPosition(newV);
    }

    int getVerticalCarPosition(){
        return vPosition;
    }

    void setVerticalCarPosition(int i) {
        vPosition = i;
        notifyObserver();
    }

    int getWidth(){ return W;   }

    int getHeight(){ return H;  }

    void setObserver(Observer observer) {
        this.observer = observer;
    }

    void notifyObserver(){
        if(observer != null) {
            observer.changed();
        }
    }

    long getSpeed(){
        return SPEED;
    }
}

class CarsUpdater implements Runnable {

    private final Model model;

    public CarsUpdater(Model model) {
        this.model = model;
    }

    @Override
    public void run() {

        while(true){;

            try {

                Thread.sleep(model.getSpeed());
                if (model.isVerticalRed()) {
                    model.clearVerticalCarFromJunction();
                    model.stepHorizontal();
                } else {
                    model.clearHorizontalCarFromJunction();
                    model.stepVertical();
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}