用JAVASwing实现模拟磁盘调度

来源:互联网 发布:浅谈软件测试技术 编辑:程序博客网 时间:2024/05/24 05:13

通过使用JavaSwing 可以很方便地创建出图形界面,那么在通过java算法解决某些问题的时候可以结合图形界面编程,就可以非常直观地表达你的意图。以下将说明一个实现模拟磁盘调度的的例子。准备好上车了吗?Let’s go!

 首先我们要明确的是磁盘调度主要要用到哪些调度算法,有先来先服务算法,最短寻道优先算法,扫描(电梯调度)算法等。然后设计一个类,提供这些算法对应的方法。

1.Arithmetic.java

import javax.swing.JOptionPane;import javax.swing.JPanel;public class Arithmetic extends JPanel{LogPane log;public Arithmetic(){    log=LogPane.getLog();}   /*判断输入数据是否有效*/public int decide(char str[]){int i=0;while(str[i]!=0){    if(str[i]<'0'||str[i]>'9'){    return 0;    //break;    }i++;}return i;}/*将字符串转换为数字*/int trans(char str[],int a){int i;int sum=0;for(i=0;i<a;i++){    sum=sum+(int)((str[i]-'0')*Math.pow(10,a-i-1));}return sum;}/*冒泡排序算法*/int []bubble(int cidao[],int m){int i,j;int temp;for(i=0;i<m;i++)//使用冒泡法从小到大顺序排列for(j=i+1;j<m;j++){    if(cidao[i]>cidao[j]){    temp=cidao[i];    cidao[i]=cidao[j];    cidao[j]=temp;    }}return cidao;}/*先来先服务算法*/public void FCFS(int cidao[],int now)  //磁道号数组,个数为M{    //int now;//当前磁道号    int sum=0;//总寻道长度    int i,j;    int count=0;    int len=0;    float ave = 0;//平均寻道长度            sum+=Math.abs(cidao[0]-now);            count=count+1;            System.out.println(sum);            //cout<<"磁盘扫描序列为: ";            String buffer="";            for(i=0;i<cidao.length;i++)  {//输出磁盘扫描序列            //  cout<<cidao[i]<<" ";            if(cidao[i]>0){                len++;                buffer+=cidao[i]+" ";            }            }            log.addLog("磁盘扫描序列为: "+buffer.toString());            for(i=0,j=1;j<len;i++,j++){                sum+=Math.abs(cidao[j]-cidao[i]);                count++;            }            ave= sum/len;            System.out.println("sum="+sum+"  count="+count);            //cout<<endl;            //cout<<"平均寻道长度: "<<ave<<endl;            log.addLog("平均寻道长度:"+ave);    }/*最短寻道时间优先调度算法*/  public void SSTF(int cidao[],int now){        int k=1;        int  l,r,len=0;        int i,j,sum=0;        int a,count=0;        float ave;        for(i=0;i<cidao.length;i++)  {             //  cout<<cidao[i]<<" ";            if(cidao[i]>0){                len++;            }            }           cidao=bubble(cidao,len); //调用冒泡排序算法排序           String s="";           for(int z=0;z<len;z++){              // System.out.println(cidao[z]);               s+=cidao[z]+" ";           }           log.addLog("磁道序列从小到大排序为:"+s);            if(cidao[len-1]<=now) //若当前磁道号大于请求序列中最大者,则直接由外向内依次给予各请求服务            {       String buffer="";            //      cout<<"磁盘扫描序列为: ";                    for(i=len-1;i>=0;i--){                        buffer+=cidao[i]+" ";                    }                    log.addLog("磁盘扫描序列为: "+buffer.toString());                    sum=now-cidao[0];                    count=len;            }            if(cidao[0]>=now){ //若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务;                        String buffer="";                        for(i=0;i<len;i++){                            buffer+=cidao[i]+" ";                        }                    log.addLog("磁盘扫描序列为: "+buffer.toString());                    sum=cidao[len-1]-now;                    count=len;            }            if(now>cidao[0]&&now<cidao[len-1]) {//若当前磁道号大于当前请求序列中最小者并且小于最大者            //  cout<<"磁盘扫描序列为: ";                StringBuffer buffer=new StringBuffer("");                while(cidao[k]<now){   //确定当前磁道在已排的序列中的位置                    k++;                    }                l=k-1;                r=k;                while((l>=0)&&(r<len)){ //当前磁道在请求序列范围内                    if(now-cidao[l]<=(cidao[r]-now)) {//选择与当前磁道最近的请求给予服务            //          cout<<cidao[l]<<" ";                        buffer.append(cidao[l]+" ");                        sum+=now-cidao[l];                        now=cidao[l];                        l=l-1;                    }                    else{                //      cout<<cidao[r]<<" ";                        buffer.append(cidao[r]+" ");                        sum+=cidao[r]-now;                        now=cidao[r];                        r=r+1;                    }                }                if(l==-1) {//磁头移动到序列的最小号,返回外侧扫描仍未扫描的磁道                    for(j=r;j<len;j++){            //      cout<<cidao[j]<<" ";                        buffer.append(cidao[j]+" ");                    }                    sum+=cidao[len-1]-cidao[0];                }                 else{ //磁头移动到序列的最大号,返回内侧扫描仍未扫描的磁道                    for(j=l;j>=0;j--){                //  cout<<cidao[j]<<" ";                        buffer.append(cidao[j]+" ");                    }                    sum+=cidao[len-1]-cidao[0];                }                log.addLog("磁盘扫描序列为: "+buffer.toString());            }            ave=sum/len;            log.addLog("平均寻道长度:"+ave);        //  cout<<endl;        //  cout<<"平均寻道长度: "<<ave<<endl;}/*扫描调度算法*/  public void SCAN(int cidao[],int now) { //先要给出当前磁道号和移动臂的移动方向    int k=1;    int l,r,d=0;    int i,j,sum=0;    int a,len=0;    char str[ ]=new char[100];    float ave;    for(i=0;i<cidao.length;i++)  {         //  cout<<cidao[i]<<" ";        if(cidao[i]>0){            len++;        }        }     cidao=bubble(cidao,len);//调用冒泡排序算法排序    //cout<<"请输入当前的磁道号:";       String s="";       for(int z=0;z<len;z++){          // System.out.println(cidao[z]);           s+=cidao[z]+" ";       }       log.addLog("磁道序列从小到大排序为:"+s);    if(cidao[len-1]<=now) //若当前磁道号大于请求序列中最大者,则直接由外向内                        //依次给予各请求服务,此情况同最短寻道优先    {//   cout<<"磁盘扫描序列为:";//输入当前磁道号    StringBuffer buffer=new StringBuffer("");     for(i=len-1;i>=0;i--){    //  cout<<cidao[i]<<" ";         buffer.append(cidao[i]+" ");     }      log.addLog("磁盘扫描序列为: "+buffer.toString());      sum=now-cidao[0];      }    if(cidao[0]>=now)   //若当前磁道号小于请求序列中最小者,则直接由内向外                                                    //依次给予各请求服务,此情况同最短寻道优先    {        StringBuffer buffer=new StringBuffer("");    // cout<<"磁盘扫描序列为: ";     for(i=0;i<len;i++){    // cout<<cidao[i]<<" ";         buffer.append(cidao[i]+" ");     }     log.addLog("磁盘扫描序列为: "+buffer.toString());     sum=cidao[len-1]-now;    }    if(now>cidao[0]&&now<cidao[len-1]) //若当前磁道号大于请求序列中最小者且                                     //小于最大者    {     StringBuffer buffer=new StringBuffer("");      while(cidao[k]<now){        k++;    }    l=k-1;    r=k;    try{    String string=JOptionPane.showInputDialog(this, "请输入当前移动臂的移动的方向(1 表示向外,0表示向内):",             "提示", JOptionPane.INFORMATION_MESSAGE);     d=Integer.parseInt(string);        //cout<<"请输入当前移动臂的移动的方向(1 表示向外,0表示向内):";        //cin>>d;        if(d==0)  //选择移动臂方向向内,则先向内扫描        {        // cout<<"磁盘扫描序列为:";         for(j=1;j>=0;j--){        // cout<<cidao[j]<<" "; //输出向内扫描的序列             buffer.append(cidao[j]+" ");         }         for(j=r;j<len;j++){  //磁头移动到最小号,则改变方向向内扫描为扫描的磁道          //cout<<cidao[j]<<" "; //输出向外扫描的序列             buffer.append(cidao[j]+" ");         }         sum=now-2*cidao[0]+cidao[len-1];        }        else{ //选择移动臂方向向外,则先向外扫描        // cout<<"磁盘扫描序列为:";         for(j=r;j<len;j++){         // cout<<cidao[j]<<" ";//输出向外扫描的序列             buffer.append(cidao[j]+" ");         }         for(j=l;j>=0;j--){        //  cout<<cidao[j]<<" ";             buffer.append(cidao[j]+" ");         }         sum=now-cidao[0]+2*cidao[len-1];        }        log.addLog("磁盘扫描序列为: "+buffer.toString());        //cout<<endl;        //cout<<"平均寻道长度: "<<ave<<endl;    }catch(Exception e){        log.addLog(e.toString());        e.printStackTrace();    }    }    ave= sum/len;    log.addLog("平均寻道长度:"+ave);    }}
 其次,设计界面中要用到的面板类,有两个,一个是选择磁盘调度算法的面板类ArithPane.java,一个是用来打印结果信息的面板类LogPane.java

2.ArithPane.java

 import java.awt.*;import java.awt.event.*;import javax.swing.JButton;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.UIManager;import javax.swing.border.TitledBorder;public class ArithPane extends JPanel implements ActionListener{JButton button1,button2,button3,backButton;Font font=new Font("微软雅黑",Font.PLAIN,16);JLabel label;LogPane log;Arithmetic arith;//int tem[]=new int[1000];int now=0;    public ArithPane() {        // TODO 自动生成的构造函数存根        //tem=DiskOperation.getCidao();        init();          }    public void init(){        try {                UIManager                 .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");              } catch (Exception e) {               e.printStackTrace();              }        this.setLayout(null);        this.setBorder(new TitledBorder("模拟磁盘调度界面"));        log=LogPane.getLog();        arith=new Arithmetic();        label=new JLabel("请选择以下算法来模拟磁盘调度:");        Font font1=new Font("微软雅黑",Font.BOLD,16);        label.setFont(font1);        label.setBounds(20, 20, 350, 30);        backButton=new JButton("返回");        backButton.setFont(font);        backButton.setBounds(530, 15, 80, 30);        backButton.addActionListener(this);        button1=new JButton("先来先服务算法");        button1.setFont(font);        button1.setBounds(170, 80, 250, 30);        button1.addActionListener(this);        button2=new JButton("最短寻道优先算法");        button2.setFont(font);        button2.setBounds(170, 150, 250, 30);        button2.addActionListener(this);        button3=new JButton("扫描(电梯调度)算法");        button3.setFont(font);        button3.setBounds(170, 220, 250, 30);        button3.addActionListener(this);        this.add(backButton);        this.add(label);        this.add(button1);        this.add(button2);        this.add(button3);        this.setVisible(true);        }    @Override    public void actionPerformed(ActionEvent e) {        int[] cidao=DiskOperation.getCidao();        // TODO 自动生成的方法存根        if(e.getSource()==backButton){            DiskOperation.showCard();            log.addLog("返回到主界面!");        }       if(e.getSource()==button1){             int []tem = new int[cidao.length];            for(int i=0;i<tem.length;i++){                tem[i]=cidao[i];            }            int len=JOptionPane.showConfirmDialog(this, "你选择的是先来先服务算法",                     "提示", JOptionPane.YES_NO_OPTION);            if(len==JOptionPane.OK_OPTION){                try{                String str=JOptionPane.showInputDialog(this, "请输入当前磁道号",                         "提示", JOptionPane.INFORMATION_MESSAGE);                now=Integer.parseInt(str);                log.addLog("正在模拟先来先服务算法...");            //  log.addLog("请求磁道序列为:"+cidao);                log.addLog("当前磁道号为:"+now);                arith.FCFS(tem,now);                }catch(Exception e1){                    e1.printStackTrace();                    JOptionPane.showMessageDialog(this, "输入类型错误!", "提示",                             JOptionPane.WARNING_MESSAGE);                    log.addLog(e1.toString());                }            }             }       if(e.getSource()==button2){           int []tem = new int[cidao.length];           for(int i=0;i<tem.length;i++){                tem[i]=cidao[i];            }           int len=JOptionPane.showConfirmDialog(this, "你选择的是最短寻道优先算法",                     "提示", JOptionPane.YES_NO_OPTION);            if(len==JOptionPane.OK_OPTION){                try{                String str=JOptionPane.showInputDialog(this, "请输入当前磁道号",                         "提示", JOptionPane.INFORMATION_MESSAGE);                now=Integer.parseInt(str);                log.addLog("正在模拟最短寻道优先算法...");            //  log.addLog("请求磁道序列为:"+cidao);                log.addLog("当前磁道号为:"+now);                arith.SSTF(tem,now);                }catch(Exception e1){                    e1.printStackTrace();                    JOptionPane.showMessageDialog(this, "输入类型错误!", "提示",                             JOptionPane.WARNING_MESSAGE);                    log.addLog(e1.toString());                }            }        }       if(e.getSource()==button3){           int []tem = new int[cidao.length];           for(int i=0;i<tem.length;i++){                tem[i]=cidao[i];            }           int len=JOptionPane.showConfirmDialog(this, "你选择的是扫描(电梯调度)算法",                     "提示", JOptionPane.YES_NO_OPTION);            if(len==JOptionPane.OK_OPTION){                try{                String str=JOptionPane.showInputDialog(this, "请输入当前磁道号",                         "提示", JOptionPane.INFORMATION_MESSAGE);                now=Integer.parseInt(str);                log.addLog("正在模拟扫描(电梯调度)算法...");            //  log.addLog("请求磁道序列为:"+cidao);                log.addLog("当前磁道号为:"+now);                arith.SCAN(tem, now);                }catch(Exception e1){                    e1.printStackTrace();                    JOptionPane.showMessageDialog(this, "输入类型错误!", "提示",                             JOptionPane.WARNING_MESSAGE);                    log.addLog(e1.toString());                }            }          }    }}

3.LogPane.java(关于这个LogPane,它的好处是可以用来打印一些有用的信息,在本人关于Java的其它文章中也有用到)

import java.awt.*;import javax.swing.*;import java.awt.event.*;import java.util.Date;public class LogPane extends JTabbedPane implements ActionListener{private JScrollPane scroll;private JTextArea textArea;static final LogPane log=new LogPane();    public LogPane() {        // TODO 自动生成的构造函数存根        try {                 UIManager                 .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");              } catch (Exception e) {               e.printStackTrace();              }        textArea=new JTextArea();        textArea.setLineWrap(true);        textArea.setFont(new Font("TimesRoman",Font.PLAIN,18));        scroll=new JScrollPane(textArea);        add(scroll,BorderLayout.CENTER);        this.setTitleAt(0, "Log");        //this.setTitleAt(1, "sddsf");        //this.setFont(new Font("TimesRoman",Font.BOLD,16));        this.setFont(new Font("微软雅黑",Font.BOLD,16));        this.setEnabled(false);        textArea.setEditable(false);    }    @Override    public void actionPerformed(ActionEvent arg0) {        // TODO 自动生成的方法存根    }    public void addLog(String log){        Date current = new  Date(System.currentTimeMillis());        textArea.append(log+"    "+current+"\n");    }    public static LogPane getLog(){        return log;    }    public void addLog(String str,Color color){        Date date=new Date();        textArea.setForeground(color);        textArea.append(str+"\t"+date+"\n");    }}
 最后,编写主类DiskOperation.java,调用上面的两个面板类和一个算法类

4.DiskOperation.java

import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.border.TitledBorder;public class DiskOperation extends JFrame implements ActionListener{ImageIcon img;JSplitPane vsplitPane;JSplitPane hsplitPane;LogPane log;JButton sureButton;JPanel centerPane;JPanel southPane;JPanel pane;static JPanel controlPane;static CardLayout card;Font font=new Font("微软雅黑",Font.PLAIN,16);JLabel label;JTextField textField;ArithPane arithPane;static  int cidao[];public DiskOperation( ){ try {        UIManager         .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");      } catch (Exception e) {       e.printStackTrace();      } try {    init();} catch (Exception e) {    // TODO 自动生成的 catch 块    log.addLog(e.toString());}}private void setBorder(TitledBorder titledBorder) {    // TODO Auto-generated method stub}public void init() throws Exception{arithPane=new ArithPane();  card=new CardLayout();controlPane=new JPanel();controlPane.setLayout(card);controlPane.add("面板二", arithPane);cidao=new int[1000];textField=new JTextField();textField.setFont(font);textField.setBounds(150, 140, 300, 30);label=new JLabel("请输入要请求服务的磁道序列(以空格隔开)");label.setFont(font);label.setBounds(140, 60, 350, 30);log=LogPane.getLog();log.addLog("欢迎来到模拟磁盘调度界面!");pane=new JPanel();pane.setLayout(new BorderLayout());controlPane.add("面板一", pane);card.show(controlPane,"面板一");centerPane=new JPanel();centerPane.setLayout(null);centerPane.add(label);centerPane.add(textField);sureButton=new JButton("确定");sureButton.setFont(font);sureButton.addActionListener(this);southPane=new JPanel();southPane.setLayout(new FlowLayout());southPane.add(sureButton);pane.setBorder(new TitledBorder("欢迎来到中心面板"));pane.add(southPane,BorderLayout.SOUTH);pane.add(centerPane);vsplitPane=new JSplitPane(JSplitPane.VERTICAL_SPLIT);vsplitPane.setTopComponent(new JScrollPane(controlPane));vsplitPane.setBottomComponent( log);vsplitPane.setDividerLocation(320);//button.addActionListener(this);vsplitPane.setEnabled(false);int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;  int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;  add(vsplitPane);setSize(630,530);setLocation((screen_width - this.getWidth()) / 2,          (screen_height - this.getHeight()) / 2);  setBackground(Color.LIGHT_GRAY);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);setBorder(new TitledBorder("模拟磁盘调度"));setResizable(false);setTitle("Author@夜空--模拟磁盘调度");  }public void actionPerformed(ActionEvent e){  if(e.getSource()==sureButton){      String str=textField.getText();      if(str.trim().equals("")){           JOptionPane.showMessageDialog(this, "磁道号序列不能为空!", "提示",                   JOptionPane.WARNING_MESSAGE);      }      else{          try{              String[] buffer=str.split(" ");              if(buffer.length>0){                  for(int i=0;i<buffer.length;i++){                      cidao[i]=Integer.parseInt(buffer[i]);                  }                  log.addLog("你输入的磁道序列为:"+str);                  card.show(controlPane, "面板二");              }              else{                  JOptionPane.showMessageDialog(this, "输入的格式有误", "提示",                           JOptionPane.WARNING_MESSAGE);              }          }          catch(Exception e1){              e1.printStackTrace();              JOptionPane.showMessageDialog(this, "输入的格式有误", "提示",                       JOptionPane.WARNING_MESSAGE);          }      }  } }public static  int[] getCidao(){    return cidao;}public  static void showCard(){    card.show(controlPane,"面板一");}public static void main(String[]args){    new DiskOperation();}}

运行效果



原创粉丝点击