南邮-软件设计实验(Java GUI版)

说在前面:利用此次课程设计的机会,慢慢地加强对编程语言实际应用的能力,不断地丰富知识点!
此篇文章是基于java语言开发GUI的应用程序,希望可以帮助一些想在Java学习中深入的同学(当然,这里应用的都是Java基础),希望可以激发同学们的学习兴趣!
C语言版移步软件设计-C语言版
C++版移步软件设计-C++版
C语言版本均在VC++6.0环境下编译成功!

  本篇程序设计文章所用Java语言版本为:jdk1.8.0_171,IDE环境为Eclipse IDE for Java Developers,如其他环境下未调试成功,请以本文章的软件版本为准!

使用说明:为功能展示方便,本人将各个模块功能单独写一个类,所有的子功能都由主类统一激发,所以有个主类Main.java,其余的类文件均与此主类在同一个包下即可实现主类的子功能调用。
南邮-软件设计实验(Java GUI版)_第1张图片
上图即是本人的目录结构,所有文件都在同一包下。

软件环境:南邮-软件设计实验(Java GUI版)_第2张图片

软件总览

下面两张图片为本程序系统的预览图,本程序将几个子模块程序都分块放在屏幕显示,同时可以根据自己的喜好自行调整位置。

南邮-软件设计实验(Java GUI版)_第3张图片
南邮-软件设计实验(Java GUI版)_第4张图片

代码展示
Main.java
import javax.swing.JFrame;
import java.awt.GridLayout;
import java.awt.Toolkit;

import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Main extends JFrame implements ActionListener{
	JButton A1, A2, A3, A4, A5, B1, B2;
	int x_location, y_location;
	public static void main(String[] args) {
		new Main();
	}
	
	public Main() {
		setTitle("B16031114");
		setSize(600,400);
		x_location = getCenterLocation(1);
		y_location = getCenterLocation(2);
		setLocation(x_location, y_location);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(new GridLayout(2,4));
		
		A1 = new JButton("A1");
		A1.addActionListener(this);
		add(A1);
		
		A2 = new JButton("A2");
		A2.addActionListener(this);
		add(A2);
		
		A3 = new JButton("A3");
		A3.addActionListener(this);
		add(A3);
		
		A4 = new JButton("A4");
		A4.addActionListener(this);
		add(A4);
		
		A5 = new JButton("A5");
		A5.addActionListener(this);
		add(A5);
		
		B1 = new JButton("B1");
		B1.addActionListener(this);
		add(B1);
		
		B2 = new JButton("B2");
		B2.addActionListener(this);
		add(B2);
		
		setVisible(true);
	}

	public int getCenterLocation(int type) {
		double width = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
		double height = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
		if(type == 1) {
			return (int) (width - this.getWidth()) / 2;
		}else {
			return (int) (height - this.getHeight()) / 2;
		}
	} 
	@Override
	public void actionPerformed(ActionEvent event) {
		if(event.getSource() == A1) {
			A1_Frame a1 = new A1_Frame();
			a1.setVisible(true);
		}else if(event.getSource() == A2) {
			A2_Frame a2 = new A2_Frame();
			a2.setVisible(true);
		}else if(event.getSource() == A3) {
			A3_Frame a3 = new A3_Frame();
			a3.setVisible(true);
		}else if(event.getSource() == A4) {
			A4_Frame a4 = new A4_Frame();
			a4.setVisible(true);
		}else if(event.getSource() == A5) {
			A5_Frame a5 = new A5_Frame();
			a5.setVisible(true);
		}else if(event.getSource() == B1) {
			B1_Frame b1 = new B1_Frame();
			b1.setVisible(true);
		}else if(event.getSource() == B2) {
			B2_Frame b2 = new B2_Frame();
			b2.setVisible(true);
		}
	}
}

A档

一、分数统计

课题内容:

  设计一个分数统计程序。包括学生信息的输入输出以及排序。通过该课题全面熟悉数组、字符串、文件的使用,掌握程序设计的基本方法及友好界面的设计。

课题要求:

(1)输入某班级学生的姓名、分数;
(2)对(1)的分数进行降幂排列并输出;
(3)具有输入输出界面。

点击添加数据按钮,列表会自增1,并提示用户填写内容

南邮-软件设计实验(Java GUI版)_第5张图片

若成绩一栏输入有字母等其他字符,当点击排序按钮时会提示上述错误,用户可以根据错误进行修改,若用户不想修改数据,可以直接选择这一栏,点击删除按钮删除本栏内容。

南邮-软件设计实验(Java GUI版)_第6张图片

下面图片展示的是选择一栏点击删除按钮,被选一栏删除掉排序。

南邮-软件设计实验(Java GUI版)_第7张图片 南邮-软件设计实验(Java GUI版)_第8张图片

南邮-软件设计实验(Java GUI版)_第9张图片

代码展示

A1_Frame.java
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.MessageFormat;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class A1_Frame extends JFrame{
	// 默认表格模型
    private DefaultTableModel model = null;
    private JTable table = null;

    private JButton addBtn = null, decBtn = null, solveBtn = null;

    String number = "0";

    public A1_Frame()
    {
        super("学生成绩排名");
        String[][] datas = {};
        String[] titles = { "序号", "姓名","成绩" };
        model = new DefaultTableModel(datas, titles);
        table = new JTable(model);

        addBtn = new JButton("添加数据");
        addBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e)
            {
                number = String.valueOf(Integer.valueOf(number)+1);
                model.addRow(new String[] { number, "", "" });
            }
        });

        JPanel btnPanel = new JPanel();
        btnPanel.setLayout(new GridLayout(2, 1));
        decBtn = new JButton("删除数据");
        decBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            	try {
            		if(table.getRowCount() == 0) {
            			JOptionPane.showMessageDialog(null, "请添加数据", "警告", JOptionPane.INFORMATION_MESSAGE);
            		}else {
                		model.removeRow(table.getSelectedRow());
            		}
            	}catch(ArrayIndexOutOfBoundsException e1) {
            		JOptionPane.showMessageDialog(null, "未选择所要删除的栏目", "警告", JOptionPane.INFORMATION_MESSAGE);
            	}
            }
        });
        
        solveBtn = new JButton("排序");
        
        btnPanel.add(decBtn);
        btnPanel.add(solveBtn);
        
        add(addBtn, BorderLayout.NORTH);
        add(btnPanel,BorderLayout.SOUTH);
        add(new JScrollPane(table));

        setBounds(300, 0, 400, 300);
        setVisible(true);
        	
        //table居中显示
        DefaultTableCellRenderer tcr = new DefaultTableCellRenderer();
        tcr.setHorizontalAlignment(JLabel.CENTER);
        table.setDefaultRenderer(Object.class, tcr);
        table.setFont(new Font("Serif",0,18));
        table.setRowHeight(30);
        main_solve();
        
        table.addMouseListener(new MouseAdapter(){
        	 public void mouseClicked(MouseEvent e) {
        	   table.clearSelection();
        	 }
        });
    }

    private void main_solve() {
    	
    	solveBtn.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				boolean infoCom = false;
				String[] name = new String[table.getRowCount()];
				float[] score = new float[table.getRowCount()];
				if(table.getRowCount() != 0) {
					for(int i=0;i<table.getRowCount();i++) {
						if(table.getModel().getValueAt(i,1).equals("")||table.getModel().getValueAt(i,2).toString().equals("")) {
							JOptionPane.showMessageDialog(null, "请完善信息", "警告", JOptionPane.INFORMATION_MESSAGE);
							break;
						}else {
							try {
								name[i] = (String) table.getModel().getValueAt(i,1);
					    		score[i] = Float.valueOf(table.getModel().getValueAt(i,2).toString());
					    		infoCom = true;
							}catch(NumberFormatException except) {
								JOptionPane.showMessageDialog(null, "行序号为"+table.getModel().getValueAt(i,0)+"的成绩格式错误", "错误", JOptionPane.ERROR_MESSAGE);
								infoCom = false;
								break;
							}
						}
			    	}
					if(infoCom) {
						for(int i=0;i<table.getRowCount();i++) {
				    		float scoreTemp;
				    		String nameTemp;
				    		for(int j=0;j<table.getRowCount();j++) {
					    		if(score[j]<score[i]) {
					    			scoreTemp = score[i];
					    			score[i] = score[j];
					    			score[j] = scoreTemp;
					    			nameTemp = name[i];
					    			name[i] = name[j];
					    			name[j] = nameTemp;
					    		}
					    	}
				    	}
						for(int i=0;i<table.getRowCount();i++) {
							table.setValueAt(i+1, i, 0);
							table.setValueAt(name[i], i, 1);
							table.setValueAt(score[i], i, 2);
				    	}
					}
				}else {
					JOptionPane.showMessageDialog(null, "请添加数据", "警告", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		});
	}
}

二、打字程序

课题内容:

  设计一个打字程序。包括随机产生字符串,以及字符串比较和统计。通过此课题,熟练掌握数组、格式输出、字符串处理等。

课题要求:

(1)随机产生一字符串,每次产生的字符串内容、长度都不同;
(2)根据(1)的结果,输入字符串,判断输入是否正确,输出正确率;
(3)具有输入输出界面。

下图是本程序打开界面,主界面随机字符一栏自动初始化。用户可在提示输入处进行输入操作。

南邮-软件设计实验(Java GUI版)_第10张图片

不输入或输入为空时点击计算正确率按钮就会弹出如下弹框。

南邮-软件设计实验(Java GUI版)_第11张图片

用户根据提示输入,点击计算按钮即可生成正确率。

南邮-软件设计实验(Java GUI版)_第12张图片 南邮-软件设计实验(Java GUI版)_第13张图片

代码展示

A2_Frame.java
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.MessageFormat;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class A2_Frame extends JFrame implements ActionListener{
   JPanel mypanel0, mypanel1, mypanel2, mypanel3, mypanel4, mypanel5;
   JLabel label1, label2, label3, label4;
   JTextField randomS, input, output;
   JButton btn1, btn2;
   public A2_Frame() {
   	mypanel0 = new JPanel();
   	mypanel0.setLayout(new GridLayout(5, 1));
   	
   	mypanel1 = new JPanel();
   	mypanel2 = new JPanel();
   	mypanel3 = new JPanel();
   	mypanel4 = new JPanel();
   	mypanel5 = new JPanel();
   	
   	label1 = new JLabel("打字练习程序");
   	label1.setFont(new Font("Serif",0,18));
   	mypanel1.add(label1);
   	
   	label2 = new JLabel("随机字符:");
   	randomS = new JTextField(10);
   	randomS.setText(getRandomData());
   	randomS.setEditable(false);
   	mypanel2.add(label2);
   	mypanel2.add(randomS);
   	
   	label3 = new JLabel("请您输入:");
   	input = new JTextField(10);
   	mypanel3.add(label3);
   	mypanel3.add(input);
   	
   	btn1 = new JButton("生成字符串");
   	btn1.addActionListener(this);
   	btn2 = new JButton("计算正确率");
   	btn2.addActionListener(this);
   	mypanel4.add(btn1);
   	mypanel4.add(btn2);
   	
   	label4 = new JLabel("您的正确率:");
   	output = new JTextField(4);
   	mypanel5.add(label4);
   	mypanel5.add(output);
   	
   	mypanel0.add(mypanel1);
   	mypanel0.add(mypanel2);
   	mypanel0.add(mypanel3);
   	mypanel0.add(mypanel4);
   	mypanel0.add(mypanel5);
   	
   	add(mypanel0);
   	setTitle("打字练习");
   	setBounds(760 , 0, 400, 300);
   }
   
   /**
    * 获得随机字符串,该方法仅用于获得随机字符串,可以忽略
    *
    * @return
    */
   private String getRandomData(){
   	String myString = "";
   	String ss = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   	int x=4+(int)(Math.random()*12);
   	for(int i=0;i<x;i++) {
   		myString = myString + ss.toCharArray()[1+(int)(Math.random()*52)];
   	}
   	return myString;
   }

   @Override
   public void actionPerformed(ActionEvent event) {
   	if(event.getSource() == btn1) {
   		randomS.setText(getRandomData());
   	}else if(event.getSource() == btn2) {
   		String proStr = randomS.getText();
   		String inputStr = input.getText();
   		int temp = 0;
   		try{
   			for(int i=0;i<proStr.length();i++) {
   				if(proStr.toCharArray()[i] == inputStr.toCharArray()[i]) {
   					temp++;
   				}
   			}
   			output.setText(String.valueOf((int)(((float)temp/proStr.length())*10000)/100.0)+"%");
   		}catch(ArrayIndexOutOfBoundsException e) {
   			JOptionPane.showMessageDialog(null, "输入为空", "警告", JOptionPane.INFORMATION_MESSAGE);
   		}
   	}
   	
   }
}

三、文本编辑器

课题内容:

  设计一个简单的文本编辑器,该系统要求对一个文本文件中的内容进行各种常规操作,如:插入、删除、查找、替换等功能。通过此课题,熟练掌握文本文件的操作及用字符数组或字符指针实现字符串操作的功能。

课题要求:

(1)编辑文本;
(2)保存、打开指定位置的文本文件;
(3)具有输入输出界面。

本程序界面涵盖一个Label,一个TextArea,两个按钮,用户可以选择打开文件,或直接在文本域内输入,进而保存输入内容,在保存时可以输入需要保存的文件名称。
南邮-软件设计实验(Java GUI版)_第14张图片
南邮-软件设计实验(Java GUI版)_第15张图片

南邮-软件设计实验(Java GUI版)_第16张图片 南邮-软件设计实验(Java GUI版)_第17张图片

南邮-软件设计实验(Java GUI版)_第18张图片

代码展示

A3_Frame.java
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.filechooser.FileNameExtensionFilter;

public class A3_Frame extends JFrame implements ActionListener{
	JTextArea input;
	JLabel title;
	JPanel mypanel0, mypanel1, mypanel2, mypanel3;
	JButton openbtn, savebtn;
	JScrollPane sc;
	public A3_Frame(){
		mypanel0 = new JPanel();
		
		mypanel1 = new JPanel();
		mypanel2 = new JPanel();
		mypanel3 = new JPanel();
		
		title = new JLabel("文本编辑器");
		title.setFont(new Font("Serif",0,20));
		mypanel1.add(title);		
		
		input = new JTextArea(8,30);
		sc = new JScrollPane(input);
		mypanel2.add(sc);
		
		openbtn = new JButton("打开文件");
		openbtn.addActionListener(this);
		savebtn = new JButton("保存文件");
		savebtn.addActionListener(this);
		mypanel3.add(openbtn);
		mypanel3.add(savebtn);
		
		mypanel0.add(mypanel1);
		mypanel0.add(mypanel2);
		mypanel0.add(mypanel3);
		
		add(mypanel0);
		setTitle("文本编辑器");
		setBounds(1220,0,400,300);
	}
	@Override
	public void actionPerformed(ActionEvent event) {
		if(event.getSource() == openbtn) {
			JFileChooser chooser = new JFileChooser();
			FileNameExtensionFilter filter = new FileNameExtensionFilter("dat&txt File", "dat", "txt");
			chooser.setFileFilter(filter);
			int returnVal = chooser.showOpenDialog(null);
			if(returnVal == JFileChooser.APPROVE_OPTION){
				File filex=chooser.getSelectedFile();
				byte[] b = new byte[10];
				try {
					//使用BufferedReader读取
					BufferedReader br = new BufferedReader(new FileReader(filex));
					String line = "";
					while((line=br.readLine())!=null){
						input.append(line+"\n");
					}
					br.close();
				} catch (Exception e) {
				}
			}
		}else if(event.getSource() == savebtn) {
			String filename;
			String inputstr = JOptionPane.showInputDialog("请输入您所要保存的文件名:","output.dat");
			if(inputstr != null) {
				filename = inputstr;
				try {
					FileOutputStream fos = new FileOutputStream(filename);
					if(input.getText().equals("")) {
						JOptionPane.showMessageDialog(null, "输入内容为空", "提示", JOptionPane.INFORMATION_MESSAGE);
					}
					fos.write(input.getText().getBytes());
					fos.close();
				} catch (Exception e) {
					
				}
			}
		}
	}
}

四、加密

课题内容:

  设计一个加密程序。包括明文与密钥的转换。通过此课题,熟练掌握数组、格式输出、字符串处理、类型转换等。

课题要求:

(1)输入任意一段明文M,以及密钥K;
(2)根据以下公式将其转换为密文C。
Ci = mi + K ,其中i = 0,1,……n-1 , K 为密钥;
(3)具有输入输出界面。

用户可以选择功能:加密或解密(解密的前提是要先进行加密操作),每次操作下面两个文本域都会给打印出来。

南邮-软件设计实验(Java GUI版)_第19张图片

南邮-软件设计实验(Java GUI版)_第20张图片 南邮-软件设计实验(Java GUI版)_第21张图片
南邮-软件设计实验(Java GUI版)_第22张图片 南邮-软件设计实验(Java GUI版)_第23张图片

代码展示

A4_Frame.java
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class A4_Frame extends JFrame implements ActionListener{
	public static String[] mingwen = new String[100];
	public static String[] miwen = new String[100];
	JPanel mypanel0, mypanel1, mypanel2, mypanel21, mypanel3, mypanel4, mypanel41, mypanel5;
	JLabel label1, label2;
	JButton addSerbtn, decSerbtn;
	static JTextArea log;
	static JTextArea log2;
	JScrollPane sc, sc2;
	public A4_Frame() {
		mypanel0 = new JPanel();
		mypanel0.setLayout(new GridLayout(3, 1));
		mypanel1 = new JPanel();
		mypanel2 = new JPanel();
		mypanel2.setLayout(new GridLayout(1, 2));
		mypanel21 = new JPanel();
		mypanel3 = new JPanel();
		mypanel3.setLayout(new GridLayout(1, 2));
		mypanel4 = new JPanel();
		mypanel41 = new JPanel();
		mypanel5 = new JPanel(new GridLayout(2,1));
		
		label1 = new JLabel("加解密程序");
		label1.setFont(new Font("Serif",0,20));
		mypanel1.add(label1);
		
		addSerbtn = new JButton("我要加密");
		addSerbtn.addActionListener(this);
		decSerbtn = new JButton("我要解密");
		decSerbtn.addActionListener(this);
		mypanel2.setBorder(new EmptyBorder(0, 28, 0, 28));
		mypanel2.add(addSerbtn);
		mypanel2.add(decSerbtn);
		
		label2 = new JLabel("操作记录:");
		mypanel21.add(label2);
		
		log = new JTextArea(6,14);
		log.setEditable(false);
		sc = new JScrollPane(log);
		log2 = new JTextArea(6,14);
		log2.setEditable(false);
		sc2 = new JScrollPane(log2);
		mypanel4.add(sc);
		mypanel41.add(sc2);
		mypanel3.add(mypanel4);
		mypanel3.add(mypanel41);
		
		mypanel0.add(mypanel1);
		mypanel0.add(mypanel2);
		mypanel0.add(mypanel21);
		
		mypanel5.add(mypanel0);
		mypanel5.add(mypanel3);
		
		add(mypanel5);
		
		setTitle("加解密程序");
		setBounds(510, 300, 400, 300);
	}
	
	@Override
	public void actionPerformed(ActionEvent event) {
		if(event.getSource() == addSerbtn) {
			new childFrame("加密");
		}else if(event.getSource() == decSerbtn) {
			new childFrame("解密");
		}
	}
	
}

class childFrame extends JFrame implements ActionListener{
	
	JLabel title1, title2;
	JTextField input1, input2;
	JButton okbtn, canclebtn;
	JPanel mypanel0, mypanel1, mypanel2, mypanel3;
	String mystr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	String jiajiemi;
	public childFrame(String type) {
		jiajiemi = type;
		
		mypanel0 = new JPanel();
		mypanel0.setSize(3,1);
		
		mypanel1 = new JPanel();
		mypanel2 = new JPanel();
		mypanel3 = new JPanel();
		
		title1 = new JLabel("请输入密钥:");
		input1 = new JTextField(8);
		mypanel1.add(title1);
		mypanel1.add(input1);
		
		title2 = new JLabel("请输入明文:");
		input2 = new JTextField(8);
		mypanel2.add(title2);
		mypanel2.add(input2);
		
		okbtn = new JButton("确认");
		okbtn.addActionListener(this);
		canclebtn = new JButton("取消");
		canclebtn.addActionListener(this);
		mypanel3.add(okbtn);
		mypanel3.add(canclebtn);
		
		mypanel0.add(mypanel1);
		mypanel0.add(mypanel2);
		mypanel0.add(mypanel3);
		
		add(mypanel0);
		setTitle("信息输入");
		setBounds(600,300,240,160);
		setVisible(true);
	}
	@Override
	public void actionPerformed(ActionEvent event1) {
		if(jiajiemi.equals("加密")) {
			if(event1.getSource() == okbtn) {
				jiami();
			}else if(event1.getSource() == canclebtn) {
				setVisible(false);
			}
		}else {
			if(event1.getSource() == okbtn) {
				jiemi();
			}else if(event1.getSource() == canclebtn) {
				setVisible(false);
			}
		}
		
	}
	
	private void jiami() {
		String input[] = new String[2];
		int miyao = -1;
		input[0] = input1.getText();
		input[1] = input2.getText();
		try {
			miyao = Integer.parseInt(input[0]);
			if(A4_Frame.miwen[miyao-1]!=null) {
				JOptionPane.showMessageDialog(null, "该条密钥已被加密!请换条密钥!", "提示", JOptionPane.INFORMATION_MESSAGE);
			}else {
				Strfun(1, input[1], miyao);
				A4_Frame.mingwen[miyao-1] = input[1];
				A4_Frame.miwen[miyao-1] = Strfun(1,input[1],miyao);
				A4_Frame.log.append("明文加密成功!\n");
				A4_Frame.log2.append("密文:" + A4_Frame.miwen[miyao-1] + ",密钥:" + miyao + "\n");
			}
		}catch(Exception e) {
			JOptionPane.showMessageDialog(null, "密钥不能为空或字母!", "错误", JOptionPane.ERROR_MESSAGE);
		}
		setVisible(false);
	}
	
	private String Strfun(int chagetype, String input, int miyao) {
		String result = "";
		char temp = '0';
		
		for(int i=0;i<input.length();i++) {
			int j = 0;
			while(mystr.toCharArray()[j] != input.toCharArray()[i]) {
				j++;
			}
			if(chagetype == 1) {
				j = j + miyao;
				if(j>61) {
					j = j - 62;
				}
			}else {
				if(j<miyao) {
					j = 62 - miyao + j;
				}
			}
			temp = mystr.toCharArray()[j];
			result = result + temp;
		}
		return result;
	}

	private void jiemi() {
		int miyao = -1;
		String input[] = new String[2];
		input[0] = input1.getText();
		input[1] = input2.getText();
		try {
			miyao = Integer.parseInt(input[0]);
			if(A4_Frame.miwen[miyao-1] != null) {
				if(Strfun(0, input[1], miyao).equals(A4_Frame.mingwen[miyao-1])) {
					A4_Frame.log.append("第" + miyao + "条密文解密成功!\n");
					A4_Frame.log2.append("解密明文:" + A4_Frame.mingwen[miyao-1] + "\n");
				}else {
					JOptionPane.showMessageDialog(null, "解密失败!", "错误", JOptionPane.ERROR_MESSAGE);
					A4_Frame.log.append("第" + miyao + "条密文解密失败!\n");
					A4_Frame.log2.append("\n");
				}
			}else {
				JOptionPane.showMessageDialog(null, "解密明文不存在!", "错误", JOptionPane.ERROR_MESSAGE);
			}
		}catch(Exception e) {
			JOptionPane.showMessageDialog(null, "密钥不能为空或字母!", "错误", JOptionPane.ERROR_MESSAGE);
		}
		
		setVisible(false);
	}
}

五、进制转换器

课题内容:

  设计一个进制转换器程序。包括二进制、八进制、十进制、十六进制数互相转换。通过此课题,熟练掌握字符串、格式输出、进制换算的各种操作。

课题要求:

(1)可输入二进制、八进制、十进制、十六进制数;
(2)将已输入的数转换成其余进制的数;
(3)具有输入输出界面。

本程序可以实现任意机制之间的转换,进制转换选择可以通过两个下拉选择框实现
南邮-软件设计实验(Java GUI版)_第24张图片

下面四张图分别展示了二进制转任意进制、八进制转任意进制、十进制转任意进制、十六进制转任意进制。

南邮-软件设计实验(Java GUI版)_第25张图片 南邮-软件设计实验(Java GUI版)_第26张图片
南邮-软件设计实验(Java GUI版)_第27张图片 南邮-软件设计实验(Java GUI版)_第28张图片

代码展示

A5_Frame.java
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class A5_Frame extends JFrame implements ActionListener{
	
	JPanel mypanel0, mypanel1, mypanel2, mypanel3, mypanel4, mypanel5;
	JLabel title0, title1, title2, title3;
	JTextField number;
	JButton solveBtn;
	JTextArea log;
	JScrollPane sc;
	JComboBox<String> inChoose, outChoose;
	String[] jinzhiStr = {"二进制", "八进制", "十进制", "十六进制"};
	public A5_Frame() {
		mypanel0 = new JPanel();
		mypanel1 = new JPanel();
		mypanel2 = new JPanel();
		mypanel2.setLayout(new GridLayout(2, 1));
		mypanel3 = new JPanel();
		mypanel4 = new JPanel();
		mypanel5 = new JPanel();
		
		title0 = new JLabel("进制转换程序");
		title0.setFont(new Font("Serif",0,18));
		title1 = new JLabel("输入进制:");
		title2 = new JLabel("输入:");
		title2.setBorder(new EmptyBorder(0, 10, 0, 0));
		title3 = new JLabel("转换进制选择:");
		
		inChoose = new JComboBox<>(jinzhiStr);
		number = new JTextField(5);
		
		outChoose = new JComboBox<>(jinzhiStr);
		solveBtn = new JButton("转换");
		solveBtn.addActionListener(this);
		outChoose.setBorder(new EmptyBorder(0, 0, 0, 30));
		
		log = new JTextArea(6,24);
		log.append("转换记录:\n");
		sc = new JScrollPane(log);
		
		mypanel1.add(title0);
		mypanel3.add(title1);
		mypanel3.add(inChoose);
		mypanel3.add(title2);
		mypanel3.add(number);
		mypanel4.add(title3);
		mypanel4.add(outChoose);
		mypanel4.add(solveBtn);
		
		mypanel2.add(mypanel3);
		mypanel2.add(mypanel4);
		
		mypanel5.add(sc);
		
		mypanel0.add(mypanel1);
		mypanel0.add(mypanel2);
		mypanel0.add(mypanel5);
		
		add(mypanel0);
		setTitle("进制转换程序");
		setBounds(1010, 300, 400, 300);
	}
	@Override
	public void actionPerformed(ActionEvent event) {
		try {
			String inputNumber = number.getText();
			if(inputNumber.equals("")) {
				JOptionPane.showMessageDialog(null, "输入不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
			}else {
				int inputJinzhi = 2, outputJinzhi = 2;
				switch (inChoose.getSelectedItem().toString()) {
				case "二进制":
					inputJinzhi = 2;
					break;
				case "八进制":
					inputJinzhi = 8;
					break;
				case "十进制":
					inputJinzhi = 10;
					break;
				case "十六进制":
					inputJinzhi = 16;
					break;
				default:
					break;
				}
				switch (outChoose.getSelectedItem().toString()) {
				case "二进制":
					outputJinzhi = 2;
					break;
				case "八进制":
					outputJinzhi = 8;
					break;
				case "十进制":
					outputJinzhi = 10;
					break;
				case "十六进制":
					outputJinzhi = 16;
					break;
				default:
					break;
				}
				log.append(inChoose.getSelectedItem().toString()+"转"+outChoose.getSelectedItem().toString()+":"+ChangeNum(inputJinzhi, outputJinzhi, inputNumber)+"\n");
			}
		}catch(NumberFormatException e) {
			JOptionPane.showMessageDialog(null, "输入格式错误!", "错误", JOptionPane.ERROR_MESSAGE);
		}
		
	}
	private String ChangeNum(int inputJinzhi, int outputJinzhi, String inputNumber) {
		String result = "";
		if(inputJinzhi != 10) {
			result = _NTo10(inputJinzhi,inputNumber);
			result = _10ToN(outputJinzhi,result);
		}else {
			result = _10ToN(outputJinzhi,inputNumber);
		}
		return result;
	}
	
	private String _10ToN(int outputJinzhi, String inputNumber) {
		String number = "";
		if(outputJinzhi == 2){
			number = Integer.toBinaryString(Integer.parseInt(inputNumber));
		}else if(outputJinzhi == 8){
			number = Integer.toOctalString(Integer.parseInt(inputNumber));
		}else if(outputJinzhi == 16){
			number = Integer.toHexString(Integer.parseInt(inputNumber));
		}else if(outputJinzhi == 10) {
			number = inputNumber;
		}
		return number;
	}
	private String _NTo10(int inputJinzhi, String inputNmuber) {
		String number = "";
		number = Integer.valueOf(inputNmuber,inputJinzhi).toString();
		return number;
	}
}

B档

六、学生成绩核算系统的设计与实现

课题内容:

  设计一个学生成绩核算系统。能实现从文件中读取学生成绩资料,并提供成绩查询统计服务。通过此课题,熟练掌握文件、数组、结构体的各种操作以及友好界面的设计。

课题要求:

(1)按班级按课程从文件中读入相应的平时成绩、期中考试成绩和期末考试成绩。
(2)三个成绩对总评成绩的百分比被定义为常数,各占总成绩的30%、30%和40%。
(3)计算每位学生的总评成绩。
(4)计算该班级本课程的总平均成绩。
(5)计算处于优、良、中、及格、不及格的学生人数以及占总人数的百分比。其中100-90为优,89-80为良,79-70为中,69-60为及格,60分以下为不及格。
(6)按要求输出成绩在优、良、中、及格、不及格各区间的学生学号、成绩。

程序设计参考思路:

  1、建立文本文件 note.dat,第一行为学生的总人数,其后为每个学生的成绩,每个学生的信息占一行,格式为:
学号(9位) 平时成绩 期中考试成绩 期末考试成绩
例如: 15
B16040801 88 75.5 66
B16040802 91 79.5 76
B16040803 85 75 77
B16040804 79 82 80.5
B16040805 94 83.5 81.5
B16040806 80 69 68
B16040807 82 77 71
B16040808 77 57 58
B16040809 91 88 86
B16040810 96 89 90
B16040814 70 45.5 50
B16040812 74 65 66
B16040813 81 71 76
B16040814 83 75 77
B16040815 85 78 79
  2、从文件中读入相应的平时成绩、期中考试成绩和期末考试成绩时,数据的读入方式可用C语言中的文件读入方式进行,也可用C++中的流实现。
  3、 每次计算出的结果可在屏幕输出,并把每个学生的总评成绩输入到新文件out.dat文件中,
格式为: 学生学号(9位) 总评成绩 成绩等级
例如: B16040801 88 B
为查询方便,可把总评成绩所处等级(优、良、中、及格、不及格)同时保存在文件out.dat中,分别用字母A、B、C、D、E表示。
  4、数据结构(可用C++实现)
两个类:学生(student)和学生成绩(marks)
  (1)学生类
  数据成员: 学号、姓名、专业等
  数据类型
    属性(私有、保护、公有)
  方法:
    构造函数和析构函数
  设置学号 void SetId( long );
  读取学号 long GetId( ); 等等
  (2)学生成绩类 —— 从学生类派生
  数据成员:平时成绩、期中考试成绩、期末考试成绩、总评成绩、成绩等级
  数据类型
    属性(私有、保护、公有)
  方法:
    读入成绩 void In( ifstream& ); 或 void In( FILE* );
    输出成绩 void Out( ofstream& ); 或 void Out( FILE* );
    显示成绩 void print( );
    求总评成绩 void ComputeZP( );
    求等级 void ComputeDJ( );
    读取总评成绩 float GetZP( );
    读取等级 char GetDJ( ); 等等
  5、设计
基本思想:自顶向下、逐步细化
  主要功能:
  (1)总控模块
    功能:编制菜单,不断从菜单选择计算或查询功能执行,直到退出。
  程序流程图:~
  (2)计算
  (3)查询~
  6、实现
编程时要求每一个类建两个文件,即类的定义和实现文件。
注意包含相关的文件。
南邮-软件设计实验(Java GUI版)_第29张图片

南邮-软件设计实验(Java GUI版)_第30张图片 南邮-软件设计实验(Java GUI版)_第31张图片
南邮-软件设计实验(Java GUI版)_第32张图片 南邮-软件设计实验(Java GUI版)_第33张图片

南邮-软件设计实验(Java GUI版)_第34张图片

南邮-软件设计实验(Java GUI版)_第35张图片 南邮-软件设计实验(Java GUI版)_第36张图片
南邮-软件设计实验(Java GUI版)_第37张图片 南邮-软件设计实验(Java GUI版)_第38张图片

南邮-软件设计实验(Java GUI版)_第39张图片

代码展示

B1_Frame.java
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.StringTokenizer;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class B1_Frame extends JFrame implements ActionListener{
	JMenuBar jmb;
	JMenu file, edit;
	JMenuItem open, save, solve_Grade, select_grade, rank, select_stuNum, Grade_lay;
	boolean fileOpened = false, solved = false;
	JTable table;
	JScrollPane sc;
	String[][] stulist = new String[20][6];
	int datatGroup = 0;
	// 默认表格模型
    private DefaultTableModel model = null;
	public B1_Frame() {
		
		jmb = new JMenuBar();
		file = new JMenu("文件");
		edit = new JMenu("功能");
		jmb.add(file);
		jmb.add(edit);
		
		open = new JMenuItem("打开");
		open.addActionListener(this);
		save = new JMenuItem("保存");
		save.addActionListener(this);
		save.setEnabled(false);
		solve_Grade = new JMenuItem("计算等级");
		solve_Grade.addActionListener(this);
		select_grade = new JMenuItem("按等级查询");
		select_grade.addActionListener(this);
		rank = new JMenuItem("按总评排序");
		rank.addActionListener(this);
		select_stuNum = new JMenuItem("按学号查询");
		select_stuNum.addActionListener(this);
		Grade_lay = new JMenuItem("等级分布查询");
		Grade_lay.addActionListener(this);
		
		file.add(open);
		file.add(save);
		
		edit.add(solve_Grade);
		edit.add(select_grade);
		edit.add(rank);
		edit.add(select_stuNum);
		edit.add(Grade_lay);
		edit_menu_enableF();

        String[][] datas = {};
        String[] titles = { "序号", "学号", "平时成绩", "期中考试成绩", "期末考试成绩"};
        model = new DefaultTableModel(datas, titles);
        table = new JTable(model);
        DefaultTableCellRenderer tcr = new DefaultTableCellRenderer();// 设置table内容居中
        tcr.setHorizontalAlignment(JLabel.CENTER);
        table.setDefaultRenderer(Object.class, tcr);
        table.setFont(new Font("Serif",0,16));
        table.setRowHeight(28);
		sc = new JScrollPane(table);
		
		add(sc);
		
		setTitle("学生成绩核算系统");
		setJMenuBar(jmb);
		setBounds(240, 600, 600, 480);
	}
	
	
	@Override
	public void actionPerformed(ActionEvent event) {
		if(event.getSource() == open) {
			openPro();
			save.setEnabled(true);
			fileOpened = true;
			solve_Grade.setEnabled(true);
		}else if(event.getSource() == save) {
			savePro();
		}else if(event.getSource() == solve_Grade) {
			if(!solved) {
				solve_GradePro();
				select_stuNum.setEnabled(true);
				rank.setEnabled(true);
				select_grade.setEnabled(true);
				Grade_lay.setEnabled(true);
			}
		}else if(event.getSource() == select_grade) {
			select_gradePro();
		}else if(event.getSource() == rank) {
			rankPro();
		}else if(event.getSource() == select_stuNum) {
			select_stuNumPro();
		}else if(event.getSource() == Grade_lay) {
			Grade_layPro();
		}
	}
	
	public void openPro() {
		JFileChooser chooser = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("dat&txt File", "dat", "txt");
		chooser.setFileFilter(filter);
		int returnVal = chooser.showOpenDialog(null);
		if(returnVal == JFileChooser.APPROVE_OPTION){
			File filex=chooser.getSelectedFile();
			byte[] b = new byte[10];
			try{
				String[] tempstr = new String[15];
				BufferedReader br = null;
				br = new BufferedReader(new FileReader(filex));
				String line = "";
				int i = 0;
				datatGroup = Integer.valueOf(br.readLine());
				while((line=br.readLine())!=null){
					tempstr[i] = line;
					i++;
				}
				for(i=0;i<datatGroup;i++) {
					handle(tempstr[i], i);
				}
				br.close();
			} catch (Exception e) {
			}
		}
		
		for(int i=0;i<datatGroup;i++) {
			model.addRow(new String[] { "", "", "", "" });
			table.setValueAt(i+1, i, 0);
			table.setValueAt(stulist[i][0], i, 1);
			table.setValueAt(stulist[i][1], i, 2);
			table.setValueAt(stulist[i][2], i, 3);
			table.setValueAt(stulist[i][3], i, 4);
		}
	}
	
	public void savePro() {
		if(fileOpened) {
			JFileChooser chooser = new JFileChooser();
			FileNameExtensionFilter filter = new FileNameExtensionFilter("dat", "txt");
			//设置文件类型
			chooser.setFileFilter(filter);
			//打开选择器面板
			int returnVal = chooser.showSaveDialog(new JPanel());
			//保存文件从这里入手,输出的是文件名
			if(returnVal == JFileChooser.APPROVE_OPTION) {
			String path = chooser.getSelectedFile().getPath();
			System.out.println(path);
			if(path != null) {
				File file = new File(path+".dat");
				System.out.println(file.getAbsolutePath());
				try {
					file.createNewFile();
					FileOutputStream fos = new FileOutputStream(file);
					for(int i=0;i<datatGroup;i++) {
						String line = stulist[i][0]+"\t"+stulist[i][1]+"\t"+stulist[i][2]+"\t"+stulist[i][3]+"\t"+stulist[i][4]+"\t"+stulist[i][5]+"\n";
						fos.write(line.getBytes());
					}
					fos.close();
				} catch (Exception e) {
					
				}
			}
			}
		}
	}
	
	public void solve_GradePro() {
		model.addColumn("总评");
		model.addColumn("等级");
		float overall_rating;
			for(int i=0;i<datatGroup;i++) {
				overall_rating = (float) ((int)(((float) (Float.valueOf(stulist[i][1])*0.3)+(float) (Float.valueOf(stulist[i][2])*0.3)+(float) (Float.valueOf(stulist[i][3])*0.4))*100)/100.0);
				if(overall_rating<60) {
					table.setValueAt(overall_rating, i, 5);
					table.setValueAt("E", i, 6);
					stulist[i][4] = String.valueOf(overall_rating);
					stulist[i][5] = "E";
				}else if(overall_rating>=60&&overall_rating<70) {
					table.setValueAt(overall_rating, i, 5);
					table.setValueAt("D", i, 6);
					stulist[i][4] = String.valueOf(overall_rating);
					stulist[i][5] = "D";
				}else if(overall_rating>=70&&overall_rating<80){
					table.setValueAt(overall_rating, i, 5);
					table.setValueAt("C", i, 6);
					stulist[i][4] = String.valueOf(overall_rating);
					stulist[i][5] = "C";
				}else if(overall_rating>=80&&overall_rating<90) {
					table.setValueAt(overall_rating, i, 5);
					table.setValueAt("B", i, 6);
					stulist[i][4] = String.valueOf(overall_rating);
					stulist[i][5] = "B";
				}else if(overall_rating>=90) {
					table.setValueAt(overall_rating, i, 5);
					table.setValueAt("A", i, 6);
					stulist[i][4] = String.valueOf(overall_rating);
					stulist[i][5] = "A";
				}
			}
		solved = true;
	} 
	
	public void select_gradePro() {
		String selectStr;
		selectStr = JOptionPane.showInputDialog("请输入您所要查询的等级:");
		if(selectStr != null) {
			while(table.getRowCount() > 0) {
				model.removeRow(0);
			}
			int xuhao = 0;
			if(selectStr.toCharArray()[0]>='a'&&selectStr.toCharArray()[0]<='z')
				selectStr = selectStr.toUpperCase();
			for(int j=0;j<datatGroup;j++) {
				if(stulist[j][5].equals(selectStr)) {
					model.addRow(new String[] {});
					table.setValueAt(xuhao+1, xuhao, 0);
					table.setValueAt(stulist[j][0], xuhao, 1);
					table.setValueAt(stulist[j][1], xuhao, 2);
					table.setValueAt(stulist[j][2], xuhao, 3);
					table.setValueAt(stulist[j][3], xuhao, 4);
					table.setValueAt(stulist[j][4], xuhao, 5);
					table.setValueAt(stulist[j][5], xuhao, 6);
					xuhao++;
				}
			}
		}
	}
	
	public void rankPro() {
		String[][] tempStr = new String[datatGroup][6];
		String[] temps = new String[6];
		tempStr = stulist;
		for(int i=0;i<datatGroup;i++) {
			for(int j=0;j<datatGroup;j++) {
				if(Float.valueOf(tempStr[i][4]) > Float.valueOf(tempStr[j][4])) {
					temps = tempStr[i];
					tempStr[i] = tempStr[j];
					tempStr[j] = temps;
				}
			}
		}
		while(table.getRowCount() > 0) {
			model.removeRow(0);
		}
		model.setColumnCount(0);
		model.addColumn("序号");
		model.addColumn("学号");
		model.addColumn("平时成绩");
		model.addColumn("期中考试成绩");
		model.addColumn("期末考试成绩");
		model.addColumn("总评");
		model.addColumn("等级");
		
		for(int i=0;i<datatGroup;i++) {
			model.addRow(new String[] {});
			table.setValueAt(i+1, i, 0);
			for(int j=0;j<6;j++) {
				table.setValueAt(tempStr[i][j], i, j+1);
			}
		}
	} 
	
	public void select_stuNumPro() {
		String selectStr;
		selectStr = JOptionPane.showInputDialog("请输入您所要查询的学号:");
		if(selectStr != null) {
			while(table.getRowCount() > 0) {
				model.removeRow(0);
			}
			int xuhao = 0;
			if(selectStr.toCharArray()[0]>='a'&&selectStr.toCharArray()[0]<='z')
				selectStr = selectStr.toUpperCase();
			for(int j=0;j<datatGroup;j++) {
				if(stulist[j][0].equals(selectStr)) {
					model.addRow(new String[] {});
					table.setValueAt(xuhao+1, xuhao, 0);
					table.setValueAt(stulist[j][0], xuhao, 1);
					table.setValueAt(stulist[j][1], xuhao, 2);
					table.setValueAt(stulist[j][2], xuhao, 3);
					table.setValueAt(stulist[j][3], xuhao, 4);
					table.setValueAt(stulist[j][4], xuhao, 5);
					table.setValueAt(stulist[j][5], xuhao, 6);
					xuhao++;
				}
			}
			if(xuhao == 0) {
				JOptionPane.showMessageDialog(null, "没有查询到您所要的内容!", "提示", JOptionPane.INFORMATION_MESSAGE);
			}
		}
	} 
	
	public void Grade_layPro() {
		model.setColumnCount(0);
		model.addColumn("等级");
		model.addColumn("人数");
		model.addColumn("百分比");
		float[] Percent = new float[5];
		int[] Num = {0, 0, 0, 0, 0};
		for(int i=0;i<datatGroup;i++) {
			switch(stulist[i][5]) {
			case "A":
				Num[0]++;
				break;
			case "B":
				Num[1]++;
				break;
			case "C":
				Num[2]++;
				break;
			case "D":
				Num[3]++;
				break;
			case "E":
				Num[4]++;
				break;
			}
		}
		String[] grade = {"A", "B", "C", "D", "E"};
		model.setRowCount(0);
		for(int i=0;i<5;i++) {
			model.addRow(new String[] {});
			Percent[i] = (float)((int)(((float)Num[i]/datatGroup)*1000))/1000;
			table.setValueAt(grade[i], i, 0);
			table.setValueAt(Num[i], i, 1);
			table.setValueAt(Percent[i], i, 2);
		}
		String class_ave;
		float ave = 0;
		for(int i=0;i<datatGroup;i++) {
			ave += Float.valueOf(stulist[i][4]);
		}
		ave /= datatGroup; 
		class_ave = "本班平均成绩" + (float)((int)(ave*100))/100;
		model.addRow(new String[] {});
		table.setValueAt(class_ave, 5, 1);
	}
	public void handle(String eString ,int i) {
		int j=0;
	    StringTokenizer st = new StringTokenizer(eString,",!' ';");
	    while(st.hasMoreElements()) {
	    	stulist[i][j] = st.nextElement().toString();
	    	j++;
	    }
	  }

	private void edit_menu_enableF() {
		solve_Grade.setEnabled(false);
		select_stuNum.setEnabled(false);
		rank.setEnabled(false);
		select_grade.setEnabled(false);
		Grade_lay.setEnabled(false);
	}
	
	private void edit_menu_enableT() {
		solve_Grade.setEnabled(true);
		select_stuNum.setEnabled(true);
		rank.setEnabled(true);
		select_grade.setEnabled(true);
		Grade_lay.setEnabled(true);
	}

}

七、模拟电信计费系统的设计与实现

课题内容:

  设计一个模拟电信计费系统。能实现从文件中读取通话以及费率资料,并提供计费、话费查询和话单查询等服务。通过此课题,熟练掌握文件读写、数组、结构体、格式输入输出的各种操作,以及友好界面的设计和一些算法思想的应用。

课题要求:

  (1) 计费功能。根据存放在源数据文件中的通话记录和长途费率文件对每一条通话记录计算其通话费用,并将结果保存在费用文件中。其中:
  通话费的计算方法如下:
  通话费=长途电话费+本地电话费
  长途电话费=费率(元/分钟)×通话时长(分钟)
     (通话时长不满1分钟的按1分钟计算)
  本地电话费为:3分钟以内0.3元,以后每1分钟递增0.2元。
  (2) 话费查询。输入一个电话号码,从费用文件中统计该电话号码的所有本地话费、长途话费,并从用户文件中查找其用户名,最后在屏幕上显示:
    用户名 电话号码 本地话费 长途话费 话费总计
  (3) 话单查询。输入一个电话号码,查询并在屏幕显示该用户的所有通话记录,格式为:
    用户名 主叫电话号码 被叫电话号码 通话时长

程序设计参考思路:

1、本系统的输入输出文件
本系统的输入文件有三个:
(1) 源数据文件(hd.dat)
  存放:主叫区号 主叫电话号码 被叫区号 被叫电话号码 通话时长(秒)
  每次通话作为一条记录,占源数据文件的一行。
  每条记录中各数据之间以空格间隔,例如:025 83491234 010 62320983 90
  每个电话号码可以有多次通话记录。
  如果主、被叫区号相同,则通话记录为本地通话记录;否则为长途通话记录。
(2) 长话费率文件(fl.dat)
  存放:区号 费率
  例如:010 1.20 表示从本地打往区号为010的地区每分钟收费1.20元。
(3) 用户文件(yh.dat)
  存放: 电话号码 用户姓名
  例如: 83491234 张明
本系统的输出文件有一个:
  费用文件(fy.dat)
存放:主叫电话号码 通话类型 话费金额
其中,通话类型表示本次通话是长途还是本地。
2、系统输入数据
hd.dat—有20条通话记录,分别是:
025 83491234 025 85319971 70
025 84927038 010 62140045 236
025 87216340 025 84521009 310
025 83491234 0571 82199516 100
025 58120321 021 81094532 50
025 83491234 025 85319971 80
025 84927038 025 83491234 145
025 58120321 025 87216340 47
025 87216340 010 62140045 93
025 83491234 010 62140045 792
025 84927038 0571 82199516 931
025 83491234 025 85319971 580
025 84927038 025 83491234 358
025 58120321 021 81094532 197
025 87216340 025 84521009 256
025 87216340 010 62140045 193
025 83492200 025 84521009 320
025 83491234 025 85319971 270
025 84927038 025 83491234 231
025 83492200 025 84927038 72
fl.dat 有4条记录
010 1.20
020 1.20
021 0.80
0571 1.00
yh.dat 有5条记录
83491234 张明
84927038 李小红
87216340 王励
83492200 赵强
58120321 杨冬
3、数据结构(可用C++实现)
三个类:话单(callist)、费用(charge)和用户(user)
两个常量:存放本地费率和递增量
(1)话单类
  数据成员: 主叫区号、主叫电话号码、被叫区号、被叫电话号码、通话时长
  数据类型: 属性(私有、保护、公有)
  方法: 构造函数和析构函数、从源数据文件读入通话数据、显示一次通话数据、取主叫区号、取主叫电话号码 等等
(2)费用类 —— 从话单类派生
  数据成员: 通话类型、通话费用
  数据类型: 属性(私有、保护、公有)
  方法: 构造函数和析构函数、从费用文件读入费用数据、向费用文件输出数据、屏幕显示费用、求通话费用、求通话类型、取(返回)通话类型、取通话费用 等等
(3)用户类
  数据成员: 姓名、电话号码
  数据类型: 属性(私有、保护、公有)
  方法: 设置用户的电话号码、查询用户名、设置用户名、查询用户的电话号码、显示用户名和电话号码 等等
4、设计
基本思想:自顶向下、逐步细化
主要功能:
  (1)总控模块
功能:程序流程图:~
  (2)计算通话费用
定义一个话单对象,循环处理。
程序流程图:~
  (3)费用查询
定义一个用户对象,根据电话号码查询用户信息从“计算通话费用”模块生成的费用文件中,按通话类型分别统计某一电话号码的所有费用项。可定义一个费用对象,循环累加。在屏幕显示查询结果。
  (4)话单查询
定义一个用户对象,根据电话号码查询用户信息从源数据(话单)文件中,查询某一电话号码的所有通话清单。在屏幕显示查询结果。可定义一个话单对象,查询并显示。
5、实现
  (1)进行话费查询前,必须先进行费用计算。
可以先判断费用文件是否存在,若不存在,则调用计算通话费用模块后再查询;否则直接查询。
或者用一个全局变量实现——全局变量初值为0,调用计算通话费用模块后该全局变量置为1。当要查询通话费时,首先检查该全局变量的值。
  (2)为了统计话费方便,在费用文件中设一“通话类型”,可以用两个不同的字符表示本地和长途,如0表示本地,1表示长途。
  (3)编程时要求每一个类建两个文件,即类的定义和实现文件。
  (4)编程时注意包含相关的文件。

南邮-软件设计实验(Java GUI版)_第40张图片 南邮-软件设计实验(Java GUI版)_第41张图片
南邮-软件设计实验(Java GUI版)_第42张图片 南邮-软件设计实验(Java GUI版)_第43张图片
南邮-软件设计实验(Java GUI版)_第44张图片 南邮-软件设计实验(Java GUI版)_第45张图片

南邮-软件设计实验(Java GUI版)_第46张图片

南邮-软件设计实验(Java GUI版)_第47张图片 南邮-软件设计实验(Java GUI版)_第48张图片
南邮-软件设计实验(Java GUI版)_第49张图片 南邮-软件设计实验(Java GUI版)_第50张图片
南邮-软件设计实验(Java GUI版)_第51张图片 南邮-软件设计实验(Java GUI版)_第52张图片
南邮-软件设计实验(Java GUI版)_第53张图片 南邮-软件设计实验(Java GUI版)_第54张图片

代码展示

B2_Frame.java
import java.awt.Font;
/*
 * 功能概述:
 * 1、打开话单文件-》按主叫号码查询话单
 * 2、打开费率文件-》计算话费-》保存话费-》打开话费文件、按主叫号码查询话费
 * 3、打开用户文件-》按用户名查询话单-》按用户名查询话费
 */
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class B2_Frame extends JFrame implements ActionListener{
	//GUI 组件
	JMenuBar jmb;
	JMenu file, edit, open, save;
	JMenuItem openTicket, openRate, openUser, openCost, saveCost, checkTicketByMaincall,
		solveCost, checkCostBymaincall, checkTicketByUsername, checkCostByUsername;
	boolean ticketOpened = false;
	static boolean rateOpened = false;
	boolean userlistOpened = false;
	boolean costSolved = false;
	boolean costFileSaved = false;
	JTable table;
	JScrollPane sc;
	// 默认表格模型
    private DefaultTableModel model = null;
    
    //数据
    ArrayList<Ticket> ticket = new ArrayList<Ticket>();
    Cost[] cost;
    Map<String, String> rate = new HashMap<>();
    Map<String, String> userList = new HashMap<>();
    
	public B2_Frame() {
		jmb = new JMenuBar();
		//一级菜单
		file = new JMenu("文件");
		edit = new JMenu("功能选择");
		jmb.add(file);
		jmb.add(edit);
		//二级菜单
		//文件操作
		open = new JMenu("打开");
		save = new JMenu("保存");
		file.add(open);
		file.add(save);
		
		//功能选择
		checkTicketByMaincall = new JMenuItem("按主叫号码查询话单");
		checkTicketByMaincall.addActionListener(this);
		solveCost = new JMenuItem("计算话费");
		solveCost.addActionListener(this);
		checkCostBymaincall= new JMenuItem("按主叫号码查询话费");
		checkCostBymaincall.addActionListener(this);
		checkTicketByUsername = new JMenuItem("按用户名查询话单");
		checkTicketByUsername.addActionListener(this);
		checkCostByUsername = new JMenuItem("按用户名查询话费");
		checkCostByUsername.addActionListener(this);
		edit.add(checkTicketByMaincall);
		edit.add(solveCost);
		edit.add(checkCostBymaincall);
		edit.add(checkTicketByUsername);
		edit.add(checkCostByUsername);
		//三级菜单
		openTicket = new JMenuItem("打开话单文件");
		openTicket.addActionListener(this);
		openRate = new JMenuItem("打开费率文件");
		openRate.addActionListener(this);
		openUser = new JMenuItem("打开用户文件");
		openUser.addActionListener(this);
		openCost = new JMenuItem("打开话费文件");
		openCost.addActionListener(this);
		open.add(openTicket);
		open.add(openRate);
		open.add(openUser);
		open.add(openCost);
		
		saveCost = new JMenuItem("保存话费文件");
		saveCost.addActionListener(this);
		save.add(saveCost);
		
		String[][] datas = {};
        String[] titles = {};
        model = new DefaultTableModel(datas, titles);
		table = new JTable(model);
		DefaultTableCellRenderer tcr = new DefaultTableCellRenderer();// 设置table内容居中
        tcr.setHorizontalAlignment(JLabel.CENTER);
        table.setDefaultRenderer(Object.class, tcr);
        table.setFont(new Font("Serif",0,16));
        table.setRowHeight(28);
		sc = new JScrollPane(table);
		
		add(sc);
		SetMeunUable();
		setJMenuBar(jmb);
		setTitle("电信计费系统");
		setBounds(1180, 600, 600, 480);
		
	}

	private void SetMeunUable() {
		openCost.setEnabled(false);
		saveCost.setEnabled(false);
		checkTicketByMaincall.setEnabled(false);
		solveCost.setEnabled(false);
		checkCostBymaincall.setEnabled(false);
		checkTicketByUsername.setEnabled(false);
		checkCostByUsername.setEnabled(false);
		
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		switch(event.getActionCommand()) {
		case "打开话单文件":
			OpenTicket();
			break;
		case "打开费率文件":
			OpenRate();
			break;
		case "打开用户文件":
			OpenUser();
			break;
		case "打开话费文件":
			OpenCost();
			break;
		case "保存话费文件":
			SaveCost();
			break;
		case "按主叫号码查询话单":
			checkTicketByMaincall();
			break;
		case "计算话费":
			SolveCost();
			break;
		case "按主叫号码查询话费":
			CheckCostBymaincall();
			break;
		case "按用户名查询话单":
			CheckTicketByUsername();
			break;
		case "按用户名查询话费":
			CheckCostByUsername();
			break;
		};
	}

	private void OpenTicket() {
		DoTicket doticket = new DoTicket();
		
		ticket = doticket.readTicketFromFile();
		if(ticket != null) {
			model.setColumnCount(0);
			model.setRowCount(0);
			model.addColumn("主叫区号");
			model.addColumn("主叫号码");
			model.addColumn("被叫区号");
			model.addColumn("被叫号码");
			model.addColumn("通话时长(s)");
			
			for(int i=0;i<ticket.size();i++) {
				model.addRow(new String[] { "", "", "", "", ""});
				table.setValueAt(ticket.get(i).getMainCallAC(), i, 0);
				table.setValueAt(ticket.get(i).getMainCallNum(), i, 1);
				table.setValueAt(ticket.get(i).getCalledAC(), i, 2);
				table.setValueAt(ticket.get(i).getCalledNum(), i, 3);
				table.setValueAt(ticket.get(i).getCallTime(), i, 4);
			}
			
			checkTicketByMaincall.setEnabled(true);
			if(rate != null)
				solveCost.setEnabled(true);
			if(userList.size() != 0) 
				checkTicketByUsername.setEnabled(true);;
		}
	}

	private void OpenRate() {
		DoTicket doticket = new DoTicket();
		rate = doticket.readRate();
		try {
			//使用迭代器,获取key;
			Iterator<String> iter = rate.keySet().iterator();
			int i = 0;

			model.setColumnCount(0);
			model.setRowCount(0);
			model.addColumn("区号");
			model.addColumn("费率");
			
			while(iter.hasNext()){
				String key=iter.next();
				String value = rate.get(key);
				model.addRow(new String[] { "", "", "", "", ""});
				table.setValueAt(key, i, 0);
				table.setValueAt(value, i, 1);
				i++;
			}
			if(ticket.size() != 0)
				solveCost.setEnabled(true);
		} catch(Exception e) {}
	}

	private void OpenUser() {
		DoUser douser = new DoUser();
		userList = douser.readUser();
		
		try {
			//使用迭代器,获取key;
			Iterator<String> iter = userList.keySet().iterator();
			int i = 0;

			model.setColumnCount(0);
			model.setRowCount(0);
			model.addColumn("电话号码");
			model.addColumn("用户名");
			
			while(iter.hasNext()){
				String key=iter.next();
				String value = userList.get(key);
				model.addRow(new String[] { "", "", "", "", ""});
				table.setValueAt(key, i, 0);
				table.setValueAt(value, i, 1);
				i++;
			}
			if(ticket.size() != 0)
				checkTicketByUsername.setEnabled(true);
			if(cost != null)
				checkCostByUsername.setEnabled(true);
			if(cost != null) {
				checkCostBymaincall.setEnabled(true);
				checkCostByUsername.setEnabled(true);
			}
		} catch(Exception e) {}
	}

	private void OpenCost() {
		DoCost docost = new DoCost();
		cost = docost.readCostFromFile();
		if(cost != null) {
			model.setColumnCount(0);
			model.setRowCount(0);
			model.addColumn("主叫号码");
			model.addColumn("通话类型");
			model.addColumn("话费金额");
			
			for(int i=0;i<cost.length;i++) {
				model.addRow(new String[] {});
				table.setValueAt(cost[i].getMainCallNum(), i, 0);
				table.setValueAt(cost[i].getCallType(), i, 1);
				table.setValueAt(cost[i].getCallCost(), i, 2);
			}
			
			if(userList.size() != 0)
				checkCostByUsername.setEnabled(true);
		}else {
			JOptionPane.showMessageDialog(null, "文件打开错误!", "错误", JOptionPane.ERROR_MESSAGE);
		}
		
	}

	private void SaveCost() {
		JFileChooser chooser = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("dat", "txt");
		//设置文件类型
		chooser.setFileFilter(filter);
		//打开选择器面板
		int returnVal = chooser.showSaveDialog(new JPanel());
		//保存文件从这里入手,输出的是文件名
		if(returnVal == JFileChooser.APPROVE_OPTION) {
			String path = chooser.getSelectedFile().getPath();
			if(path != null) {
				File file = new File(path+".dat");
				try {
					file.createNewFile();
					FileOutputStream fos = new FileOutputStream(file);
					for(int i=0;i<cost.length;i++) {
						String line = cost[i].getMainCallNum()+"\t"+cost[i].getCallType()+"\t"+cost[i].getCallCost()+"\n";
						fos.write(line.getBytes());
					}
					fos.close();
					openCost.setEnabled(true);
				} catch (Exception e) {}
			}
		}
	}

	private void checkTicketByMaincall() {
		String mainCallNum;
		ArrayList<Ticket> checkTicketbyMC = new ArrayList<Ticket>();
		mainCallNum = JOptionPane.showInputDialog("请输入您所要查询的主叫号码:");
		if(mainCallNum != null) {
			while(table.getRowCount() > 0) {
				model.removeRow(0);
			}
			for(int i=0;i<ticket.size();i++) {
				if(ticket.get(i).getMainCallNum().equals(mainCallNum)) {
					checkTicketbyMC.add(ticket.get(i));
				}
			}
			if(checkTicketbyMC.size() > 0) {
				model.setColumnCount(0);
				model.setRowCount(0);

				model.addColumn("主叫号码");
				model.addColumn("用户名");
				model.addColumn("被叫号码");
				model.addColumn("通话时长(s)");
				for(int j=0;j<checkTicketbyMC.size();j++) {
					model.addRow(new String[] {});
					table.setValueAt(checkTicketbyMC.get(j).getMainCallNum(), j, 0);
					table.setValueAt(userList.get(checkTicketbyMC.get(j).getMainCallNum()), j, 1);
					table.setValueAt(checkTicketbyMC.get(j).getCalledNum(), j, 2);
					table.setValueAt(checkTicketbyMC.get(j).getCallTime(), j, 3);
				}
				
			}else
				JOptionPane.showMessageDialog(null, "没找到对应的话单!", "提示", JOptionPane.INFORMATION_MESSAGE);
			
		}
		
	}

	private void SolveCost() {
		DoTicket doticket = new DoTicket();
		cost = doticket.solveCost(ticket, rate);
		
		model.setColumnCount(0);
		model.setRowCount(0);
		model.addColumn("主叫号码");
		model.addColumn("通话类型");
		model.addColumn("话费金额");
		
		for(int i=0;i<cost.length;i++) {
			model.addRow(new String[] {});
			table.setValueAt(cost[i].getMainCallNum(), i, 0);
			table.setValueAt(cost[i].getCallType(), i, 1);
			table.setValueAt(cost[i].getCallCost(), i, 2);
		}
		
		saveCost.setEnabled(true);
		if(userList.size() != 0) {
			checkCostByUsername.setEnabled(true);
			checkCostBymaincall.setEnabled(true);
		}
	}

	private void CheckCostBymaincall() {
		String mainCallNum;
		ArrayList<Cost> checkCostbyMC = new ArrayList<Cost>();
		mainCallNum = JOptionPane.showInputDialog("请输入您所要查询的主叫号码:");
		if(mainCallNum != null) {
			while(table.getRowCount() > 0) {
				model.removeRow(0);
			}
			for(int i=0;i<cost.length;i++) {
				if(cost[i].getMainCallNum().equals(mainCallNum)) {
					checkCostbyMC.add(cost[i]);
				}
			}
			if(userList.size() == 0) {
				JOptionPane.showMessageDialog(null, "请打开用户文件再查!", "提示", JOptionPane.INFORMATION_MESSAGE);
			}else if(checkCostbyMC.size() > 0 ) {
				float localCost = 0, longCost = 0, overall = 0;
				model.setColumnCount(0);
				model.setRowCount(0);

				model.addColumn("主叫号码");
				model.addColumn("用户名");
				model.addColumn("通话类型");
				model.addColumn("通话金额");
				int j=0;
				for(;j<checkCostbyMC.size();j++) {
					model.addRow(new String[] {});
					table.setValueAt(checkCostbyMC.get(j).getMainCallNum(), j, 0);
					table.setValueAt(userList.get(checkCostbyMC.get(j).getMainCallNum()), j, 1);
					table.setValueAt(checkCostbyMC.get(j).getCallType(), j, 2);
					table.setValueAt(checkCostbyMC.get(j).getCallCost(), j, 3);
					if(checkCostbyMC.get(j).getCallType().equals("本地通话")) {
						localCost +=  checkCostbyMC.get(j).getCallCost();
					}else {
						longCost += checkCostbyMC.get(j).getCallCost();
					}
				}
				localCost = (float)((int)(localCost*100))/100;
				longCost = (float)((int)(longCost*100))/100;
				overall += localCost + longCost;
				model.addRow(new String[] {});
				table.setValueAt("本地话费:" + localCost, j, 0);
				table.setValueAt("长途话费:" + longCost, j, 1);
				table.setValueAt("总计话费:" + overall, j, 2);
			}else
				JOptionPane.showMessageDialog(null, "没找到对应的话费!", "提示", JOptionPane.INFORMATION_MESSAGE);
		}
		
	}

	private void CheckTicketByUsername() {
		String userName, mainCallNum = null;
		ArrayList<Ticket> checkTicketbyUN = new ArrayList<Ticket>();
		userName = JOptionPane.showInputDialog("请输入您所要查询的用户名:");
		if(userName != null) {
			while(table.getRowCount() > 0) {
				model.removeRow(0);
			}
			//使用迭代器,获取key;
			Iterator<String> iter = userList.keySet().iterator();
			while(iter.hasNext()){
				String key=iter.next();
				String value = userList.get(key);
				if(value.equals(userName)) {
					mainCallNum = key;
					break;
				}
			}
			if(mainCallNum != null) {
				for(int i=0;i<ticket.size();i++) {
					if(ticket.get(i).getMainCallNum().equals(mainCallNum)) {
						checkTicketbyUN.add(ticket.get(i));
					}
				}
				if(checkTicketbyUN.size() > 0) {
					model.setColumnCount(0);
					model.setRowCount(0);
					model.addColumn("用户名");
					model.addColumn("主叫号码");
					model.addColumn("被叫号码");
					model.addColumn("通话时长(s)");
					for(int j=0;j<checkTicketbyUN.size();j++) {
						model.addRow(new String[] {});
						table.setValueAt(userName, j, 0);
						table.setValueAt(checkTicketbyUN.get(j).getMainCallNum(), j, 1);
						table.setValueAt(checkTicketbyUN.get(j).getCalledNum(), j, 2);
						table.setValueAt(checkTicketbyUN.get(j).getCallTime(), j, 3);
					}
					
				}else
					JOptionPane.showMessageDialog(null, "没找到此用户对应的话单!", "提示", JOptionPane.INFORMATION_MESSAGE);
			}else {
				JOptionPane.showMessageDialog(null, "没找到此用户!", "提示", JOptionPane.INFORMATION_MESSAGE);
			}
			
		}
		
	}

	private void CheckCostByUsername() {
		String userName, mainCallNum = null;
		ArrayList<Cost> checkCostbyUN = new ArrayList<Cost>();
		userName = JOptionPane.showInputDialog("请输入您所要查询的用户名:");
		if(userName != null) {
			while(table.getRowCount() > 0) {
				model.removeRow(0);
			}
			//使用迭代器,获取key;
			Iterator<String> iter = userList.keySet().iterator();
			while(iter.hasNext()){
				String key=iter.next();
				String value = userList.get(key);
				if(value.equals(userName)) {
					mainCallNum = key;
					break;
				}
			}
			if(mainCallNum != null) {
				for(int i=0;i<cost.length;i++) {
					if(cost[i].getMainCallNum().equals(mainCallNum)) {
						checkCostbyUN.add(cost[i]);
					}
				}
				if(checkCostbyUN.size() > 0) {
					float localCost = 0, longCost = 0, overall = 0;
					model.setColumnCount(0);
					model.setRowCount(0);
					model.addColumn("用户名");
					model.addColumn("主叫号码");
					model.addColumn("通话类型");
					model.addColumn("通话金额");
					int j=0;
					for(;j<checkCostbyUN.size();j++) {
						model.addRow(new String[] {});
						table.setValueAt(userName, j, 0);
						table.setValueAt(mainCallNum, j, 1);
						table.setValueAt(checkCostbyUN.get(j).getCallType(), j, 2);
						table.setValueAt(checkCostbyUN.get(j).getCallCost(), j, 3);
						if(checkCostbyUN.get(j).getCallType().equals("本地通话")) {
							localCost +=  checkCostbyUN.get(j).getCallCost();
						}else {
							longCost += checkCostbyUN.get(j).getCallCost();
						}
					}
					localCost = (float)((int)(localCost*100))/100;
					longCost = (float)((int)(longCost*100))/100;
					overall += localCost + longCost;
					model.addRow(new String[] {});
					table.setValueAt("本地话费:" + localCost, j, 0);
					table.setValueAt("长途话费:" + longCost, j, 1);
					table.setValueAt("总计话费:" + overall, j, 2);
					
				}else
					JOptionPane.showMessageDialog(null, "没找到此用户对应的话费!", "提示", JOptionPane.INFORMATION_MESSAGE);
			}else {
				JOptionPane.showMessageDialog(null, "没找到此用户!", "提示", JOptionPane.INFORMATION_MESSAGE);
			}
			
		}
		
	}

	
}

//1、readTick 2、先读取费率 3、计算cost 4、输出费用至文件  5、读取费用文件
class DoTicket{
	//读取费率文件	(被叫区号	费率)
	public Map<String, String> readRate() {
		Map<String,String> rate = new HashMap<String, String>();
		JFileChooser chooser = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("dat&txt File", "dat", "txt");
		chooser.setFileFilter(filter);
		String[] tempstr = new String[4];
		int returnVal = chooser.showOpenDialog(null);
		if(returnVal == JFileChooser.APPROVE_OPTION){
			File filex=chooser.getSelectedFile();
			byte[] b = new byte[10];
			try{
				BufferedReader br = null;
				br = new BufferedReader(new FileReader(filex));
				String line = "";
				int i = 0;
				while((line=br.readLine())!=null){
					tempstr[i] = line;
					i++;
				}
				br.close();
				String[] tempst = new String[2];
				int max = i;
				for(i=0;i<max;i++) {
					int j = 0;
					StringTokenizer st = new StringTokenizer(tempstr[i],",!' ';");
				    while(st.hasMoreElements()) {
				    	tempst[j] = st.nextElement().toString();
				    	j++;
				    }
				    rate.put(tempst[0], tempst[1]);
				}
				return rate;
			} catch (Exception e) {
				JOptionPane.showMessageDialog(null, "文件选择错误!", "错误", JOptionPane.ERROR_MESSAGE);
			} 
		}
		return null;
	}
	
	//读取通话文件	(主叫区号	主叫号码	被叫区号	被叫号码	通话时长)
	public ArrayList<Ticket> readTicketFromFile() {
		int j=0;
		Ticket ticket;
		JFileChooser chooser = new JFileChooser();
		ArrayList<Ticket> tickets = new ArrayList<Ticket>();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("dat&txt File", "dat", "txt");
		chooser.setFileFilter(filter);
		int returnVal = chooser.showOpenDialog(null);
		if(returnVal == JFileChooser.APPROVE_OPTION){
			File filex=chooser.getSelectedFile();
			byte[] b = new byte[10];
			try{
				BufferedReader br = null;
				br = new BufferedReader(new FileReader(filex));
				String line = "";
				int i = 0;
				ArrayList a = new ArrayList<String>();
				while((line=br.readLine())!=null){
					a.add(line);
				}
				
				for(i=0;i<a.size();i++) {
					j = 0;
					ticket = new Ticket();
				    StringTokenizer st = new StringTokenizer(a.get(i).toString(),",!' ';");
				    while(st.hasMoreElements()) {
				    	switch(j) {
				    	case 0:
				    		ticket.setMainCallAC(st.nextElement().toString());
				    		break;
				    	case 1:
				    		ticket.setMainCallNum(st.nextElement().toString());break;
				    	case 2:
				    		ticket.setCalledAC(st.nextElement().toString());break;

				    	case 3:
				    		ticket.setCalledNum(st.nextElement().toString());break;
				    	case 4:
				    		ticket.setCallTime(Integer.valueOf(st.nextElement().toString()));break;
				    	}
				    	j++;
				    }
				    tickets.add(ticket);
				}
				br.close();
				
			} catch (IOException e) {}
		}
		if(j == 5) {
			return tickets;
		}else {
			JOptionPane.showMessageDialog(null, "文件选择错误!", "错误", JOptionPane.ERROR_MESSAGE);
			return null;
		}
	}

	//计算话费(主叫号码	通话类型	通话费用)
	public Cost[] solveCost(ArrayList<Ticket> ticket, Map<String, String> rate) {
		Cost[] cost = null;//maincallNum,calltype,callcost
		String mainCallAC, mainCallNum, calledAC, calledNum;
		int callTime;
		if(ticket != null) {
			cost = new Cost[ticket.size()];
			for(int i=0;i<ticket.size();i++) {
				float result;
				cost[i] = new Cost();
				mainCallAC = ticket.get(i).getMainCallAC();
				mainCallNum = ticket.get(i).getMainCallNum();
				calledAC = ticket.get(i).getCalledAC();
				calledNum = ticket.get(i).getCalledNum();
				callTime = ticket.get(i).getCallTime();
				callTime = callTime%60 == 0 ? callTime/60 : (callTime/60+1);
				cost[i].setMainCallNum(mainCallNum);
				if(mainCallAC.equals(calledAC)) {
					cost[i].setCallType("本地通话");
					result = callTime > 3 ? (float)((callTime-3)*0.2+0.3) : (float)0.3;
					cost[i].setCallCost(result);
				}else {
					cost[i].setCallType("长途通话");
					result = (float)(callTime*Float.valueOf(rate.get(calledAC)));
					result = (float)((int)(result*100))/100;
					cost[i].setCallCost(result);
				}
			}
		}
		return cost;
	}
	
}

class DoCost{
	
	//读取话费文件	(主叫号码	通话类型	通话费用)
	public Cost[] readCostFromFile() {
		int j = 0;
		Cost[] cost = null;
		JFileChooser chooser = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("dat&txt File", "dat", "txt");
		chooser.setFileFilter(filter);
		int returnVal = chooser.showOpenDialog(null);
		if(returnVal == JFileChooser.APPROVE_OPTION){
			File filex=chooser.getSelectedFile();
			byte[] b = new byte[10];
			try{
				ArrayList<String> array = new ArrayList<String>();
				BufferedReader br = null;
				br = new BufferedReader(new FileReader(filex));
				String line = "";
				while((line=br.readLine())!=null){
					array.add(line);
				}
				cost = new Cost[array.size()];
				for(int i=0;i<array.size();i++) {
					StringTokenizer st = new StringTokenizer(array.get(i).toString(),",!' ' \t ;");
					cost[i] = new Cost();
					j = 0;
				    while(st.hasMoreElements()) {
				    	switch(j) {
				    	case 0:
				    		cost[i].setMainCallNum(st.nextElement().toString());break;
				    	case 1:
				    		cost[i].setCallType(st.nextElement().toString());break;
				    	case 2:
				    		cost[i].setCallCost(Float.valueOf(st.nextElement().toString()));break;
				    	}
				    	j++;
				    }
				}
				br.close();

			} catch (IOException e) {
			}
		}
		if(j == 3) {
			return cost;
		}else {
			JOptionPane.showMessageDialog(null, "文件选择错误!", "错误", JOptionPane.ERROR_MESSAGE);
			return null;
		}
	}
	
	//保存话费文件
	public void writeCostToFile(Cost[] cost) {
		if(cost != null) {
			String filename;
			String inputstr = JOptionPane.showInputDialog("请输入您所要保存的文件名:","output.dat");
			if(inputstr != null) {
				filename = inputstr;
				try {
					FileOutputStream fos = new FileOutputStream(filename);
					for(int i=0;i<cost.length;i++) {
						String line = cost[i].getMainCallNum()+"\t"+cost[i].getCallType()+"\t"+cost[i].getCallCost()+"\n";
						fos.write(line.getBytes());
					}
					fos.close();
				} catch (Exception e) {
				}
			}
		}
	}
	
}

class DoUser{
	//读取用户文件 (电话号码	用户名)
	public Map<String, String> readUser() {
		Map<String, String> userlist = new HashMap<String, String>();
		JFileChooser chooser = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("dat&txt File", "dat", "txt");
		chooser.setFileFilter(filter);
		ArrayList<String> array = new ArrayList<String>();
		int returnVal = chooser.showOpenDialog(null);
		if(returnVal == JFileChooser.APPROVE_OPTION){
			File filex=chooser.getSelectedFile();
			byte[] b = new byte[10];
			try{
				BufferedReader br = null;
				br = new BufferedReader(new FileReader(filex));
				String line = "";
				while((line=br.readLine())!=null){
					array.add(line);
				}
				br.close();
			} catch (Exception e) {
			}
		}
		String[] tempst = new String[2];
		try {
			for(int i=0;i<array.size();i++) {
				int j = 0;
				StringTokenizer st = new StringTokenizer(array.get(i),",!' ';");
				while(st.hasMoreElements()) {
					tempst[j] = st.nextElement().toString();
					j++;
				}
				userlist.put(tempst[0], tempst[1]);
			}
			return userlist;
		}catch(Exception e) {
			JOptionPane.showMessageDialog(null, "文件选择错误!", "错误", JOptionPane.ERROR_MESSAGE);
			return null;
		}
	}
	
}

class Ticket{
	private String mainCallAC, mainCallNum, calledAC, calledNum;
	private int callTime;
	
	public String getMainCallAC() {
		return mainCallAC;
	}
	public void setMainCallAC(String mainCallAC) {
		this.mainCallAC = mainCallAC;
	}
	public String getMainCallNum() {
		return mainCallNum;
	}
	public void setMainCallNum(String mainCallNum) {
		this.mainCallNum = mainCallNum;
	}
	public String getCalledAC() {
		return calledAC;
	}
	public void setCalledAC(String calledAC) {
		this.calledAC = calledAC;
	}
	public String getCalledNum() {
		return calledNum;
	}
	public void setCalledNum(String calledNum) {
		this.calledNum = calledNum;
	}
	public int getCallTime() {
		return callTime;
	}
	public void setCallTime(int callTime) {
		this.callTime = callTime;
	}
	public String toString() {
		return "mainCallAC:"+ mainCallAC+",mainCallNum:"+mainCallNum+",calledAC:"+ 
				calledAC+",calledNum:" +calledNum+",callTime:"+callTime;
	}
}
class Cost extends Ticket{
	private String callType;
	private float callCost;
	public String getCallType() {
		return callType;
	}
	public void setCallType(String callType) {
		this.callType = callType;
	}
	public float getCallCost() {
		return callCost;
	}
	public void setCallCost(float callCost) {
		this.callCost = callCost;
	}
}

class User{
	private String userName, userNum;

	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserNum() {
		return userNum;
	}
	public void setUserNum(String userNum) {
		this.userNum = userNum;
	}
}
  • 特此声明:作者写博文实属不易,如感文章有用,留个赞呗~

你可能感兴趣的:(课程实验)