这是我为带有图形用户界面的十字路并发应用程序所做的实现,但是在运行应用程序一段时间后出现了某种冲突,无法真正解决实际问题 请原谅我的减价幅度很差,谢谢您的支持
我的窗口类:
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);
}
}
我的View类:
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();
}
}
}
}
}
我的应用主班:
package com.example.trafic;
public class App {
public static void main(String[] args) throws InterruptedException {
Window frame = new Window();
new Thread(new Task(frame)).start();
new Thread(new Run(frame.view)).start();
}
}
答案 0 :(得分:1)
以下代码实现了Model-View-Controller模式,以演示一个简单的结点控制,该问题已尝试进行。
该代码是一个文件的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();
}
}
}
}