java实训项目-模拟自动挡汽车

Java程序设计课程设计项目名称


项目名称:自动挡汽车操作模拟系统的设计与实现

英文名称:Design and Implementation of Operation Simulation System aboutAutomatic Vehicle

1、功能描述:

1)汽车的操作正常为启动(或熄火)、挂档、制动、油门控制等操作;

2)挂档实现自动挡的4档操作,既驻车档、倒车档、空档、行车档;

3)使用图形界面进行操作,汽车的状态在图形界面上显示出来;

4)操作流程不合理,要有相应的控制;

5)附加功能:

(1)汽车的油也要进行控制,发动机需要消耗汽油,提供汽油报警功能;

(2)汽车的行程数进行控制,用户界面显示当前行程数;

6)正常操作流程为:启动->刹车->挂档->放刹车->汽车运动->加油门->刹车->驻车档->熄火。行驶中严禁换挡,行驶档位不能启动。

参考文档:

【1】系统类的API文档,见CarApp.jar文件内的doc下的index.html文件

【2】系统运行效果,使用控制台,输入命令为:java –jar CarApp.jar

【3】汽车的运行可以选择gif文件,从网上搜索关键词“车运动  gif”或“动漫小车”等关键字搜索你喜欢的gif小车运动图片,然后使用“工具GIF帧提取器 V1.1 绿色版.rar”提出图片中的每帧图片。

【4】系统的运行效果参考图见图1.

图1:系统运行效果图​​

主要有四个类

测试类

public class CarApp {

public static void main(String[] args){

new MyFrame();

}

}

窗口类

import java.awt.BorderLayout;

import java.awt.CardLayout;

import java.awt.Color;

import java.awt.Component;

import java.awt.Dimension;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.GridLayout;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;

//import javafx.beans.value.ChangeListener;

import javax.swing.*; 

import javax.swing.event.*;

public class MyFrame extends JFrame implements ActionListener{

  private JPanel pl1;

  private JPanel pl2;

  private JPanel pl3;

  private JToggleButton start;

  private JToggleButton barke;

  private CardLayout card = null;

  private MytomaticCar car;

  private JRadioButton rb1;

  private JRadioButton rb2;

  private JRadioButton rb3;

  private JRadioButton rb4;

  private JSlider s2;//一个让用户以图形方式在有界区间内通过移动滑块来选择值的组件。

  public  JTextArea area1;

  private JTextArea area;

  private JButton refresh,jiayou;

  private  int s;

  private JTextArea ll3;

  public MyFrame(){

//大容器设置

super("自动挡小车模拟驾驶系统");

pack();//调整此窗口的大小,以适合其子组件的首选大小和布局

//setDefaultCloseOperation(3);//默认关闭状态

setSize(500, 680);

Dimension screen = //屏幕居中

      Toolkit.getDefaultToolkit().getScreenSize();

    setLocation((int)((screen.getWidth() - getWidth()) / 2.0D), (int)((screen.getHeight() - getHeight()) / 2.0D));


this.car= new MytomaticCar(new Engine());//创建自动控制对象并以发动机作为参数调用相应的构造函数

this.card = new CardLayout();

//容器上部分

    this.pl1= new JPanel(card);//创建容器对象采用卡片布局

    add(this.pl1, BorderLayout.NORTH);

    this.pl1.setBorder(BorderFactory.createTitledBorder("汽车状态显示"));//BorderFactory创建一个具有指定颜色的线边框。

ImageIcon[] ims = new ImageIcon[25];//创建一个数组未初始化的图像图标。

int i = 0;

String[] imfn = new String[25];//用来存储相对路径制定文件名

JPanel[] pls = new JPanel[25];//面板数组装卡片

for (i = 0; i < 25; i++) imfn[i] = (".\\images\\Frame" + i + ".jpg");

for (i = 0; i < 25; i++) ims[i] = new ImageIcon(imfn[i]);//根据指定的文件创建一个 ImageIcon,指定 String 可以是一个文件名或是一条文件路径

for (i = 0; i < 25; i++) {

  pls[i] = new JPanel();//创建对象并加载图片到面板上

  pls[i].add(new JLabel(ims[i]));//把图片放在标签中再放到面板中显示

  this.pl1.add(pls[i], "p" + i);//加到面板中去 同时命名

    }

//容器中间部分(显示耗油量和里程数)

this.pl3 = new JPanel();

    this.pl3.setBorder(BorderFactory.createTitledBorder("数据显示"));       

        add(this.pl3,BorderLayout.CENTER);


        JLabel jl1 = new JLabel("油量(L):");

        this.area1 = new JTextArea(1,5);

        this.ll3=new JTextArea(1,7);

        this.area1.setFont(new Font("华文行楷",Font.BOLD,20));

        this.ll3.setFont(new Font("华文行楷",Font.BOLD,20));

        this.ll3.setEditable(false);

        this.ll3.setBackground(Color.yellow);

        pl3.add(jl1);

        pl3.add(ll3);

        this.jiayou=new JButton("加油");

        this.jiayou.addActionListener(this);

        pl3.add(this.jiayou);

        pl3.add(area1);


        JLabel jl2 = new JLabel("里程(KM):");     

        pl3.add(jl2);

        this.area= new JTextArea(1,5);

        this.area.setEditable(false);

        this.area.setBackground(Color.blue);

        this.area.setForeground(Color.RED);

        this.area.setFont(new Font("华文行楷",Font.BOLD,20));

        pl3.add(this.area);

        this.refresh=new JButton("重置");

        this.refresh.addActionListener(this);

        pl3.add(this.refresh);



//容器下部分

this.pl2 = new JPanel();

    this.pl2.setBorder(BorderFactory.createTitledBorder("汽车驾驶室"));       

        add(this.pl2,BorderLayout.SOUTH);


    //四个小部件的添加

    JPanel m1=new JPanel();

    m1.setBorder(BorderFactory.createTitledBorder("引擎发动器"));

    m1.setLayout(new GridLayout(7,2));//网格布局管理器

    this.start=new JToggleButton("启动");//JToggleButton按钮按下去会陷下 去,不会弹回来,除非你再按一次

    this.start.addActionListener(this);//添加监听器

    m1.add(new JLabel(""));

    m1.add(this.start);

    this.pl2.add(m1);

    this.pl2.add(new JLabel("    "));


    JPanel m2 = new JPanel();

    m2.setBorder(BorderFactory.createTitledBorder("制动器"));

    m2.setLayout(new GridLayout(7,2));//网格布局管理器

    this.barke=new JToggleButton("制动器");//JToggleButton按钮按下去会陷下 去,不会弹回来,除非你再按一次

    this.barke.addActionListener(this);//添加监听器

    m2.add(new JLabel("  "));

    m2.add(this.barke);

    this.pl2.add(m2);

    this.pl2.add(new JLabel("    "));


    JPanel m3 = new JPanel();

    m3.setBorder(BorderFactory.createTitledBorder("档位控制器"));

    m3.setLayout(new GridLayout(1,3));

    //需要再创一个小面板才能实现排序

    JPanel m33=new JPanel();

    m33.setLayout(new GridLayout(8,2));

    this.rb1 = new JRadioButton("P");

    this.rb1.addActionListener(this);

    this.rb1.setSelected(true);//默认位置

    this.rb2 = new JRadioButton("R");

    this.rb2.addActionListener(this);

    this.rb3 = new JRadioButton("N");

    this.rb3.addActionListener(this);

    this.rb4 = new JRadioButton("D");

    this.rb4.addActionListener(this);

    ButtonGroup grp1 = new ButtonGroup();//单选按钮

    m3.add(new JLabel("  "));

    grp1.add(this.rb1); grp1.add(this.rb2); grp1.add(this.rb3); grp1.add(this.rb4);

    m33.add(this.rb1);m33.add(new JLabel(""));m33.add(this.rb2); m33.add(new JLabel(""));

    m33.add(this.rb3);m33.add(new JLabel("")); m33.add(this.rb4);

    m3.add(m33);

    this.pl2.add(m3);

    this.pl2.add(new JLabel("    "));

    JPanel m4 = new JPanel();

    m4.setBorder(BorderFactory.createTitledBorder("油门控制器"));

    m4.setLayout(new GridLayout(0, 2));

    this.s2 = new JSlider(1, 0, 200, 0);

        this.s2.setForeground(Color.ORANGE);

        this.s2.setMajorTickSpacing(50);

        this.s2.setMinorTickSpacing(10);

        this.s2.setPaintTicks(true);

        this.s2.setPaintLabels(true);

        this.s2.setPaintTrack(true);

        this.s2.setSnapToTicks(true);

        this.s2.addChangeListener(new ChangeListener()//事件监听器

        {

          public void stateChanged(ChangeEvent e)

          {

            int n = MyFrame.this.s2.getValue();

            MyFrame.this.car.addSpeed(n);

          }

        });

    m4.add(s2);

    this.pl2.add(m4);

    this.pl2.add(new JLabel("    "));


    int nn=this.car.getoil();

    this.ll3.setText(""+nn);

    setVisible(true);//可视 一定放在所有组件放好之后  否则有些不会显示

    showautocarspeed();//控制显示车速

}

public void actionPerformed(ActionEvent e){

Object o = e.getSource();//获得按钮的变化

    if ((o instanceof JRadioButton)) {//单选按钮变化

      JRadioButton rbt = (JRadioButton)e.getSource();//获取按钮状态

      String ch = rbt.getText();//获得按钮的字符

      String s = "PRND";

      int n = s.indexOf(ch);//返回该字符在字符串中出现的位置

      int gear = this.car.getGear();//获得档位

      if (!this.car.getParkBrake()){//判断制动器状态

        JOptionPane.showMessageDialog(this, "制动时才能换挡!", "非法操作", 0);

        switch (gear) {//制动时候才能换挡的操作若换挡,则不会改变单选按钮的选中状态

        case 0:

          this.rb1.setSelected(true);//将该按钮设置为选中模式

          break;

        case 1:

          this.rb2.setSelected(true);

          break;

        case 2:

          this.rb3.setSelected(true);

          break;

        case 3:

          this.rb4.setSelected(true);

        default:

          break;

        }

      }else {

        this.car.engageGear(n);//挂档操作

      }

    }else if ((o instanceof JToggleButton)) {//判断按钮是否是JToggleButton

      JToggleButton jtb = (JToggleButton)o;

      String name = jtb.getText();

      if (name.equals("启动")) {

        this.car.startEngine();

        this.s2.setValue(1);

        jtb.setText("熄火");

      }else if(name.equals("制动器")) {

        if (!this.car.ParkBrake) {

          this.car.brake();

          this.s2.setValue(1);

          jtb.setText("制动中");

        }

      } else if (name.equals("熄火")){

    if(this.car.getGear()!=0){

        JOptionPane.showMessageDialog(this, "停车挡才能熄火!", "非法操作", 0);

        this.start.setSelected(true);


    }else{

    jtb.setText("启动");

            this.rb1.setSelected(true);

            this.car.flameout();

        }        

      }else if(name.equals("制动中")){

          this.car.freeBrake();

          jtb.setText("制动器");

      }

  }else if((o instanceof JButton)){

  JButton jtb = (JButton)o;

  String name = jtb.getText();

  if((!this.car.getParkBrake()) && (this.car.getEngineThread() != null) && (this.car.getEngineThread().isAlive())){//判断状态

  JOptionPane.showMessageDialog(this, "运动状态不能进行此操作", "非法操作", 0);

  }else if(name.equals("重置")){

        this.area.setText("0");      

        this.s=0;

  }else if(name.equals("加油")&& (this.car.getEngineThread() == null)){

    String sss=area1.getText();

    int n=Integer.parseInt(sss);  

    int nn=this.car.getoil();

    if(nn<500){

    if(n+nn>=500){

    this.ll3.setText(""+500);

    }else{

    this.car.addOil(n);

    int ppp=this.car.getoil();

    this.ll3.setText(""+ppp);

    }    

    }else if(nn==500){

    JOptionPane.showMessageDialog(this, "油量已满", "非法操作", 0);

    }          

  }  

  }

}

public void showautocarspeed(){

    while (true){

    if(this.car.getEngineThread() != null){

      int n=this.car.getoil();//显示油量

          this.ll3.setText(""+n);   

    }

    if((this.car.getoil()==69)||(this.car.getoil()==70)){

        JOptionPane.showMessageDialog(this, "油量不足", "非法操作", 0);

        }

        if(this.car.getoil()==0){

        this.start.setText("启动");

            this.start.setSelected(false);

            this.car.flameout();

        }          

      try{

        Thread.sleep(1411 - this.car.getSpeed());


        if ((!this.car.getParkBrake()) && (this.car.getEngineThread() != null) && (this.car.getEngineThread().isAlive())) {

        this.area.setText(""+s);    //显示里程 

          if (this.car.getGear() == 1) {//后退挡

            this.card.previous(this.pl1);

            this.s=s+1;


            continue;

          }

          if (this.car.getGear() == 3) {//前进档

            this.card.next(this.pl1);

            this.s=s+1;

            continue;

          }

        }

      }catch (InterruptedException e){

        e.printStackTrace();

      }




    }

}


}

引擎类

public class Engine implements Runnable{//多线程,汽车运行是发动机需要启动

public int speed = 0;

private MytomaticCar car;

public void setCar(MytomaticCar car){//在汽车上安装发动机

  this.car = car;

}

public void run(){

    while (true){

      try{

        Thread.sleep(2000-this.car.getSpeed());

      }

      catch (InterruptedException e){

        e.printStackTrace();

      }

      if(this.car.innage > 0) {

        this.car.innage -= 1;

        if(!this.car.getParkBrake()&&this.car.innage > 0)

          if (this.car.getGear() == 1)

          {

            this.car.innage -= 1;

          }

          else if (this.car.getGear() == 3&&this.car.innage > 1)

          {

            this.car.innage -= 2;

          }

      }else{

        try{

          this.car.flameout();

        }catch (Exception localException){


        }

      }


          if (this.car.innage >= 70)

        continue;         

    }

  }

}

控制室类

public class MytomaticCar {

  public static int innage = 500;

  private Engine engine;

  private Thread engineThread;

  public static  int P = 0;

  public static final int R = 1;

  public static final int N = 2;

  public static final int D = 3;

  public boolean ParkBrake = false;

  private int gear = 0;


  public MytomaticCar(){//无参构造方法

    this.engine = null;

  }

  public MytomaticCar(Engine engine) {//有参构造方法

    this.engine = engine;

    engine.setCar(this);

  }




  public Thread getEngineThread(){//获得发动机线程

    return this.engineThread;

  }

  public void setEngine(Engine engine){//安装发动机

    this.engine = engine;

    engine.setCar(this);

}



  public int getoil(){//获取油量

      return this.innage;

  }

  public void addOil(int value){//加油操作

  if(this.innage<500){

  this.innage+= value;

  }

  }


  public boolean startEngine(){//启动发动

    if (this.engineThread == null) {

      this.engineThread = new Thread(this.engine);

    }

    if (!this.engineThread.isAlive()) {

      this.engineThread.start();

      System.out.println("发动机启动正常!");

    }

    return true;

  }

      public void flameout(){//熄火操作

    try{

      if (this.engineThread.isAlive())

        this.engineThread.stop();

    }catch (Exception localException) {

    }finally {//初始化操作

      this.engineThread = null;

      this.gear = 0;

    }

  }




      public boolean getParkBrake(){//制动状态

      return this.ParkBrake;

    }

    public void freeBrake(){//放刹车

      if (((this.gear == 1) || (this.gear == 3)) && (this.engineThread != null) && (this.engineThread.isAlive())) {

        this.engine.speed = 10;

      }

      this.ParkBrake = false;

    }

    public void brake(){//刹车

      this.engine.speed = 0;

      this.ParkBrake = true;

    }




      public int getGear(){//获得档位

    return this.gear;

  }

    public void engageGear(int gear){//挂挡操作

    if (this.ParkBrake)

      this.gear = gear;

  }

  public int getSpeed(){//提出汽车速度

    return this.engine.speed;

  }

  public void addSpeed(int n){//加速

    if ((this.engine.speed >= 0) && (this.engine.speed < 1200))

      this.engine.speed = (10 + n * 100);

  }




}

小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:701136382 这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!

你可能感兴趣的:(java实训项目-模拟自动挡汽车)