⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 liftdemo.java

📁 利用java的线程来模拟电梯的调度。主要来实践操作系统课程的知识。
💻 JAVA
字号:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URL;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;

/**
 * @author  Bai,Hongfei
 * @studyID 022768(University Validity) 02142135(College Validity)
 * @unit    School of Software Egineering , Tongji University
 * @usage   Using multiple threads technology 
 *          to implement process demo of lifts
 */

//控制面板的任务列表的条目内容
class ListCell{
	private String  key;
	private int     value;
	public ListCell(String s,int i){
		key = s;
		value = i;
	}
	public void setValue(int i){
			value=i;
	}
	public String get(){
		return new String("   "+key+"_____"+value);
	}
	public int getValue(){
		return value;
	}
}


//用来控制列表的显示
class CellRenderer extends JLabel implements ListCellRenderer  {
	public Component getListCellRendererComponent(
		   JList list,
		   Object value,            // value to display
		   int index,               // cell index
		   boolean isSelected,      // is the cell selected
		   boolean cellHasFocus)    // the list and the cell have the focus
	{
		setText( ((ListCell)value).get() );
		
		if (isSelected) {
			setBackground(list.getSelectionBackground());
			setForeground(list.getSelectionForeground());
		}
		else {
			setBackground(list.getBackground());
			setForeground(list.getForeground());
		}
		setEnabled(list.isEnabled());
		setFont(list.getFont());
		setOpaque(true);
		return this;
	}
}


//控制面板:主类
public class LiftDemo extends JFrame {
	
	LiftDemo self = null;
	final static int NUM_LIFT = 5;
	final static int NUM_FLOOR=20;
	final static ImageIcon[] image=new ImageIcon[NUM_FLOOR];
	final static ImageIcon[] lfg  =new ImageIcon[NUM_LIFT];
	final static ImageIcon[] lbg  =new ImageIcon[NUM_LIFT];
	
	final Lift[]     lifts      = new Lift[NUM_LIFT];
	final Thread[]   liftThread = new Thread[NUM_LIFT];
	final JLabel[]   state      = new JLabel[NUM_LIFT];
	final JButton[]  signs      = new JButton[NUM_LIFT];
	final ListCell[] cells      = new ListCell[NUM_FLOOR*2];
	final JList      taskList   = new JList(listModel);
	final TextField  floortxt   = new TextField(1);
	static  DefaultListModel listModel = new DefaultListModel();
	
	
	
	//构造函数:初始化环境
	public LiftDemo(String s){
		super(s);
		self = this;
		
		JPanel content  = new JPanel();
		JPanel monitor  = new JPanel();
		JPanel simulate = new JPanel();
		
		monitor.setBorder(BorderFactory.createCompoundBorder(
			BorderFactory.createTitledBorder("Lifts' state monitor"), 
			BorderFactory.createEmptyBorder(5,5,5,5)));
		monitor.setLayout(new GridLayout(NUM_LIFT+1,1,5,5));

		simulate.setBorder(BorderFactory.createCompoundBorder(
			BorderFactory.createTitledBorder("Demanding simulation"), 
			BorderFactory.createEmptyBorder(5,10,10,10)));
		simulate.setLayout(new BorderLayout(10,9));
		
		
		for(int i=0;i<NUM_FLOOR;i++)
		{
			String imageName = "LiftImage/s" + (i+1) + ".gif";
			URL iconURL = ClassLoader.getSystemResource(imageName);
			ImageIcon icon = new ImageIcon(iconURL);
			image[i] = icon;
		}
		for(int i=0;i<NUM_LIFT;i++){
			String imageName = "LiftImage/lift" + (i+1) + ".gif";
			URL iconURL = ClassLoader.getSystemResource(imageName);
			ImageIcon icon = new ImageIcon(iconURL);
			lfg[i] = icon;
		}
		for(int i=0;i<NUM_LIFT;i++){
			String imageName = "LiftImage/liftb" + (i+1) + ".gif";
			URL iconURL = ClassLoader.getSystemResource(imageName);
			ImageIcon icon = new ImageIcon(iconURL);
			lbg[i] = icon;
		}
		JPanel[] rows=new JPanel[NUM_LIFT];
		for(int i=0;i<NUM_LIFT;i++){
			rows[i] = new JPanel();
			
			final int index = i;
			state[i] = new JLabel(image[0]);
			signs[i] = new JButton(lfg[i]);
			signs[i].setBorder(BorderFactory.createEmptyBorder());
			signs[i].addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					if(lifts[index].isShowing())
					{
						signs[index].setIcon(lfg[index]);
						lifts[index].hide();
					}
					else
					{
						signs[index].setIcon(lbg[index]);
						lifts[index].show();
					}
				}
			});
			/*signs[i].addMouseListener(new MouseListener(){
				public void mouseEntered(MouseEvent e){}
				public void mouseExited(MouseEvent e){}
				public void mousePressed(MouseEvent e){
					System.out.println("press");
				}
				public void mouseReleased(MouseEvent e){
					System.out.println("release");
				}
				public void mouseClicked(MouseEvent e){
					if(lifts[index].isShowing())
						lifts[index].hide();
					else
						lifts[index].show();
				}
			});*/
			rows[i].add(signs[i]);
			rows[i].add(state[i]);
			
			monitor.add(rows[i]);
		}
		
		for(int i=0;i<NUM_LIFT;i++){//窗体实例
			lifts[i]=new Lift("Lift"+(i+1),state[i],this,(i+1));
			lifts[i].addWindowListener(new WinAdpter(this,i));
			lifts[i].setResizable(false);
			lifts[i].pack();
			lifts[i].hide();
		}
		for(int i=0;i<NUM_LIFT;i++){//线程实例
			liftThread[i]=new Thread(lifts[i],"lift"+i+1);
			liftThread[i].start();
		}
		
		//处理电梯的修复
		JPanel repairPn = new JPanel();
		repairPn.setLayout(new BorderLayout());
		JPanel left = new JPanel();
		JPanel right = new JPanel();
		final TextField repairIDtxt=new TextField(1);
		JButton repairbt=new JButton("Restart");
		repairbt.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					String idstr=repairIDtxt.getText();
					int id=Integer.parseInt(idstr);
					if(id<1 || id>5)throw new NumberFormatException();
					if(lifts[id-1]!=null){
						repairIDtxt.setText("");
						(new JOptionPane()).showMessageDialog(self,"Lift"+id+" is running! No need to restart!","Exception",JOptionPane.ERROR_MESSAGE);
						return;
					}
					repairIDtxt.setText("");
					lifts[id-1]=new Lift("Lift"+(id),state[id-1],self,id);
					lifts[id-1].addWindowListener(new WinAdpter(self,id-1));
					lifts[id-1].setResizable(false);
					lifts[id-1].pack();
					lifts[id-1].hide();
					state[id-1].setIcon(image[0]);
					signs[id-1].setIcon(lfg[id-1]);
					signs[id-1].setEnabled(true);
					
					liftThread[id-1]=new Thread(lifts[id-1],"lift"+id);
					liftThread[id-1].start();
					
				}catch(NumberFormatException ex){
					repairIDtxt.setText("");
					JOptionPane dlg = new JOptionPane();//弹出对话框
					dlg.showMessageDialog(self,"Please Input a correct integer between 1 and "+NUM_LIFT,"Exception",JOptionPane.ERROR_MESSAGE);
				}
				
			}
		});
		left.add(new JLabel("Lift ID:"));
		left.add(repairIDtxt);
		right.add(repairbt);
		repairPn.add(left,BorderLayout.LINE_START);
		repairPn.add(right,BorderLayout.LINE_END);
		monitor.add(repairPn);
		//处理电梯的修复

		
		
		//各楼层的任务列表
		JPanel upPn=new JPanel();
		String imageName = "LiftImage/up.gif";
		URL iconURL = ClassLoader.getSystemResource(imageName);
		JButton upbt = new JButton(new ImageIcon(iconURL));
		imageName = "LiftImage/down.gif";
		iconURL = ClassLoader.getSystemResource(imageName);
		JButton downbt = new JButton(new ImageIcon(iconURL));
		JPanel leftPn=new JPanel();
		leftPn.setLayout(new GridLayout(2,1,5,5));
		leftPn.add(new JLabel("You on:"));
		leftPn.add(floortxt);
		upPn.add(leftPn);
		upPn.add(upbt);
		upPn.add(downbt);
		simulate.add(upPn,BorderLayout.PAGE_START);
		for(int i=0;i<NUM_FLOOR;i++){
			int index=2*i;
			cells[index]  =new ListCell("floor"+(i+1)+" upwd",0);
			cells[index+1]=new ListCell("floor"+(i+1)+" down",0);
			
			listModel.addElement(cells[index]);
			listModel.addElement(cells[index+1]);
		}
		taskList.setCellRenderer(new CellRenderer());
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.getViewport().setView(taskList);
		taskList.setFixedCellWidth(150);
		taskList.setVisibleRowCount(18);
		simulate.add(scrollPane,BorderLayout.PAGE_END);
		
		upbt.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				int dir=2;
				processTask(dir);
			}
		});
		downbt.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				int dir=1;
				processTask(dir);
			}
		});
		//各楼层的任务列表
		
		
		content.add(monitor);
		content.add(simulate);
		this.getContentPane().add(content);
		
		//每隔三秒钟重新评估进行调整
		new Adjust(this).start();
		
	}
	
	public void setList(int id,int r,int dir){
		int index=0;
		if(dir == 2)index=2*(id-1);
		if(dir == 1)index=2*(id-1)+1;
		cells[index].setValue(r+1);
		taskList.repaint();
	}
	
	public void processTask(int dir){
		try{
			String strid=floortxt.getText();
			int id=Integer.parseInt(strid);
			if(id<1 || id>NUM_FLOOR)throw new NumberFormatException();
			
			int minlift = choose(id,dir);
			lifts[minlift].insertTask(id,dir);
			setList(id,minlift,dir);
		}
		catch(NumberFormatException ex){
			floortxt.setText("");
			JOptionPane dlg = new JOptionPane();//弹出对话框
			dlg.showMessageDialog(self,"Please Input a correct integer between 1 and "+NUM_FLOOR,"Exception",JOptionPane.ERROR_MESSAGE);
		}
	}
	
	public int choose(int id,int dir){
		int min= -1;
		int minlift=-1;
		for(int i=0;i<NUM_LIFT;i++){
			if(lifts[i]!=null){
				if(min==-1){
					min=lifts[i].judge(id,dir);
					minlift = i;
					continue;
				}
				int r=lifts[i].judge(id,dir);
					if(r<min){min=r;minlift=i;}
				}
			}
		return minlift;
	}
	
	
	//若电梯内的人按下求救信号控制面板获取相应的消息
	public void help(int lift,int floor){
		JOptionPane dlg = new JOptionPane();//弹出对话框
		dlg.showMessageDialog(self,"Help! Lift "+lift+" on floor "+floor,"Emergency",JOptionPane.WARNING_MESSAGE);
	}
	
	//程序启动的入口函数
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		LiftDemo lift = new LiftDemo("Lift Process Demo");
		lift.setFont(new Font("楷体",Font.BOLD,20));
		lift.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		lift.pack();
		lift.setVisible(true);
	}
}


//每隔三秒进行任务调整的线程
class Adjust extends Thread{
	LiftDemo ctrl;
	public Adjust(LiftDemo control){
		ctrl = control;
	}
	public void run(){
		while(true){
			try{
				this.sleep(3000);
			}catch(Exception e){
				e.printStackTrace();
			}
			for(int i=0;i<ctrl.cells.length;i++){
				ListCell cell = ctrl.cells[i];
				int oldlift = cell.getValue();
				if(oldlift != 0){
					int dir;
					int id;
					if(i%2==0){
						dir = 2;
						id = i/2+1;
					}
					else{
						dir = 1;
						id = (i-1)/2+1;
					}
					int newlift = ctrl.choose(id,dir);
					
					if((newlift+1) != oldlift){
						if( ctrl.lifts[oldlift-1].rmTask(id,dir) ){
							System.out.println("^^^^^task change:floor "+id+" direction "+dir+":old "+oldlift+" new "+(newlift+1));
							ctrl.lifts[newlift].insertTask(id,dir);
							ctrl.setList(id,newlift,dir);
						}
					}
				}
			}
		}
	}
}

class WinAdpter extends WindowAdapter
{
	LiftDemo inst;
	int i;
	WinAdpter(LiftDemo instance,int index)
	{
		inst = instance;
		i = index;
	}
	public void windowClosing(WindowEvent e)
	{
		inst.lifts[i] = null;
		inst.liftThread[i].stop();
		inst.liftThread[i] = null;
		inst.state[i].setIcon(inst.image[i]);
		inst.signs[i].setEnabled(false);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -