网络交互式-计算器程序:
-----兰州大学 Java课程设计
1.要求:
利用GUI编程技术、网络编程技术、输入输出流技术,编写一个基于C/S的计算器软件。前台为类似于图1的图形界面,主要解决输入界面问题,可以解决简单计算问题,将复杂函数计算如sin、开平方根等操作交给后台服务器计算,计算后结果返回客户端显示,并将客户端的IP地址,发来的计算请求记录在一个日志文件calculate.log。
2.实现:
主类:
服务器类:CalculatorServer
客户端类:CalculatorClient
辅类:
查看日志类:lookJFrame
图形面板类:mydraws & mycanvas
//客户端
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
class CalculatorClient extends JFrameimplements Runnable,ActionListener{
privateJTextField show;
privatePanel dispMain,dispLeft,dispRight;//主(左右面板)
privateJButton[] b;//数字
privateJButton jia,jian,cheng,chu,xy,cos,sin,ln,ce,equ,bfh,point,zf,sqrt;//加减乘除各种运算按钮
privateSocket socket;
privateDataInputStream in=null;
privateDataOutputStream out=null;
privateThread thread;
privateDouble result;
privateDouble d1,d2;
privateint j,action,op;
privateString opp;
privateJLabel labelconnect;
privateJButton buttonconnect;
privateJMenuItem close,version,look,edit,word,background,caltuxing;//菜单栏 菜单项设置
publicCalculatorClient(){
super("计算器客户端");
JMenuBar mb=new JMenuBar();//菜单栏
JMenu filemenu=new JMenu("计算器");
JMenu bigmenu=new JMenu("放大");
JMenu calmenu=new JMenu("画板");
JMenu vermenu=new JMenu("关于");
JMenu editmenu=new JMenu("编辑");
look=new JMenuItem("查看日志");
close=new JMenuItem("退出");
version=new JMenuItem("作者");
background=new JMenuItem("背景");
caltuxing=new JMenuItem("图形画板");
word=new JMenuItem("放大");
filemenu.add(look);
filemenu.add(close);
vermenu.add(version);
editmenu.add(background);
calmenu.add(caltuxing);
bigmenu.add(word);
mb.add(filemenu);
mb.add(editmenu);
mb.add(calmenu);
mb.add(bigmenu);
mb.add(vermenu);
this.setJMenuBar(mb);
look.addActionListener(this);
close.addActionListener(this);
background.addActionListener(this);
word.addActionListener(this);
version.addActionListener(this);
caltuxing.addActionListener(this);
socket=new Socket();
Image image =getToolkit().getImage(getClass().getResource("calculator.jpg"));
setIconImage(image);//左上角图片设置
setSize(360, 250);
setLocation(400, 300);
setBackground(Color.LIGHT_GRAY);//背景设置
setLayout(new FlowLayout(FlowLayout.CENTER));
setResizable(false);
show=new JTextField(31);
show.setText("");
show.setHorizontalAlignment(SwingConstants.RIGHT);//文本框内容右对齐
show.setEditable(false);
add(show);
dispMain=new Panel();
add(dispMain);
buttonconnect=new JButton("连接服务器");
labelconnect=new JLabel("");
add(buttonconnect);
add(labelconnect);
dispMain.setLayout(new GridLayout(1, 2, 10, 10));
dispLeft=new Panel();
dispMain.add(dispLeft);
dispLeft.setLayout(new GridLayout(4, 3, 3, 3));
dispRight=new Panel();
dispMain.add(dispRight);
dispRight.setLayout(new GridLayout(4, 3, 3, 3));
b=new JButton[10];
int l;
for(l=9;l>=0;l--){ //0-9数字按钮
b[l]=new JButton(String.valueOf(l));
b[l].setForeground(Color.BLUE);
dispLeft.add(b[l]);
b[l].addActionListener(this); //监听设置
b[l].setFocusPainted(false); //去掉焦点框
}
jia=new JButton("+");
jian=new JButton("-");
cheng=new JButton("*");
chu=new JButton("/");
xy=new JButton("x^y");
cos=new JButton("cos");
sin=new JButton("sin");
ln=new JButton("ln");//
ce=new JButton("CE");//清除
equ=new JButton("=");//等号
bfh=new JButton("%");//求模
point=new JButton(".");//小数点
zf=new JButton(" +/- ");//正负号
sqrt=new JButton("√");//根号
jia.setFocusPainted(false); //去掉焦点框
jian.setFocusPainted(false); //去掉焦点框
cheng.setFocusPainted(false); //去掉焦点框
chu.setFocusPainted(false); //去掉焦点框
xy.setFocusPainted(false); //去掉焦点框
cos.setFocusPainted(false); //去掉焦点框
sin.setFocusPainted(false); //去掉焦点框
ln.setFocusPainted(false); //去掉焦点框
ce.setFocusPainted(false); //去掉焦点框
equ.setFocusPainted(false); //去掉焦点框
bfh.setFocusPainted(false); //去掉焦点框
point.setFocusPainted(false); //去掉焦点框
zf.setFocusPainted(false); //去掉焦点框
sqrt.setFocusPainted(false); //去掉焦点框
buttonconnect.setFocusPainted(false); //去掉焦点框
//右面板 运算符按钮
dispRight.add(chu);
dispRight.add(sqrt);
dispRight.add(ln);
dispRight.add(cheng);
dispRight.add(sin);
dispRight.add(bfh);
dispRight.add(jian);
dispRight.add(cos);
dispRight.add(ce);
dispRight.add(jia);
dispRight.add(xy);
dispRight.add(equ);
//左面板正负号/小数点按钮
dispLeft.add(zf);
dispLeft.add(point);
//按钮监听设置
ce.addActionListener(this);
jia.addActionListener(this);
jian.addActionListener(this);
cheng.addActionListener(this);
chu.addActionListener(this);
equ.addActionListener(this);
point.addActionListener(this);
zf.addActionListener(this);
sqrt.addActionListener(this);
bfh.addActionListener(this);
sin.addActionListener(this);
cos.addActionListener(this);
xy.addActionListener(this);
ln.addActionListener(this);
buttonconnect.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
d1=0.0;d2=0.0;op=0;
}
public void run(){}
public void actionPerformed(ActionEvent e){
if(e.getSource()==look){new lookJFrame();}//查看日志
if(e.getSource()==caltuxing){ //图形画板
mydraws myapp=new mydraws();
myapp.setSize(380,300);
myapp.setLocation(400, 300);
myapp.setVisible(true);
}
if(e.getSource()==background){//背景设置
Color color=JColorChooser.showDialog(((Component)e.getSource()).getParent(),"自定义",Color.LIGHT_GRAY);
getContentPane().setBackground(color);
}
if(e.getSource()==word){//放大按钮
setSize(550,280);
show.setColumns(47);
inti=0;
for(i=0;i<=9;i++){
b[i].setFont(newFont("宋体",Font.PLAIN,20));
}
jia.setFont(newFont("宋体",Font.PLAIN,20));
jian.setFont(new Font("宋体",Font.PLAIN,20));
cheng.setFont(new Font("宋体",Font.PLAIN,20));
chu.setFont(new Font("宋体",Font.PLAIN,20));
xy.setFont(new Font("宋体",Font.PLAIN,20));
cos.setFont(new Font("宋体",Font.PLAIN,20));
sin.setFont(new Font("宋体",Font.PLAIN,20));
ln.setFont(new Font("宋体",Font.PLAIN,20));
ce.setFont(new Font("宋体",Font.PLAIN,20));
equ.setFont(new Font("宋体",Font.PLAIN,20));
bfh.setFont(new Font("宋体",Font.PLAIN,20));
point.setFont(new Font("宋体",Font.PLAIN,20));
zf.setFont(new Font("宋体",Font.PLAIN,20));
sqrt.setFont(new Font("宋体",Font.PLAIN,20));
}
if(e.getSource()==close){System.exit(0);}//关闭
//作者
if(e.getSource()==version){JOptionPane.showMessageDialog(null," 交互式计算器\n Java实验程序作业\n 作者: ****\n兰州大学12电子商务");}
//连接服务器
if(e.getSource()==buttonconnect){
try{
if(socket.isConnected()){}
else{
InetAddressaddress=InetAddress.getByName("127.0.0.1");//此类表示互联网协议(IP) 地址。
InetSocketAddresssocketAddress=new InetSocketAddress(address.getLocalHost(),4444);//getLocalHost()返回本地主机
socket.connect(socketAddress);// connect(SocketAddress endpoint) 将此套接字连接到服务器
in=newDataInputStream(socket.getInputStream());//socket返回输入流
out=newDataOutputStream(socket.getOutputStream());//socket返回输出流
labelconnect.setText("已连接到服务器");
thread.start();
}
}catch(IOException ee){}
}
//正负
if(e.getSource()==zf){
if(show.getText().toString().equals(""))
show.setText("-");
elseif(show.getText().toString().equals("-"))
show.setText("");
else{
try{
d1=Double.parseDouble(show.getText());
d1=-d1;
String dd=""+d1;
dd=dd.substring(0,dd.length()-2);
show.setText(dd);
}catch(Exception ee){}
}
}
//小数点
if(e.getSource()==point){
int f;
String sshow=show.getText();
if((f=sshow.indexOf('.'))!=-1)//若已存在小数点
JOptionPane.showMessageDialog(null,"小数点已存在!");
else{ //不存在小数点
if(sshow.equals(""))
show.setText("0.");
else{
if(sshow.equals("-"))
show.setText("-0.");
else
show.setText(show.getText()+".");
}
}
}
//清除
if(e.getSource()==ce){
show.setText("");
}
//加法运算符
if(e.getSource()==jia){
opp="+";
try{
d1=Double.parseDouble(show.getText());
op=0;
show.setText("");
}catch(Exceptionee){}
}
//减法运算符
if(e.getSource()==jian){
opp="-";
try{
d1=Double.parseDouble(show.getText());
op=1;
show.setText("");
}catch(Exceptionee){}
}
//乘法运算符
if(e.getSource()==cheng){
opp="*";
try{
d1=Double.parseDouble(show.getText());
op=2;
show.setText("");
}catch(Exceptionee){}
}
//除法运算符
if(e.getSource()==chu){
opp="/";
try{
d1=Double.parseDouble(show.getText());
op=3;
show.setText("");
}catch(Exceptionee){}
}
//服务器运算的运算符
//x的y次方
if(e.getSource()==xy){
opp="x^y";
try{
d1=Double.parseDouble(show.getText());
op=5;
show.setText("");
}catch(Exceptionee){}
}
//cos运算符
if(e.getSource()==cos){
opp="cos";
try{
d1=Double.parseDouble(show.getText());
op=6;
show.setText("");
}catch(Exceptionee){}
}
//sin运算符
if(e.getSource()==sin){
opp="sin";
try{
d1=Double.parseDouble(show.getText());
op=7;
show.setText("");
}catch(Exceptionee){}
}
//ln运算符
if(e.getSource()==ln){
opp="ln";
try{
d1=Double.parseDouble(show.getText());
op=8;
show.setText("");
}catch(Exceptionee){}
}
//百分比运算符
if(e.getSource()==bfh){
opp="%";
try{
d1=Double.parseDouble(show.getText());
op=9;
show.setText("");
}catch(Exceptionee){}
}
//根号运算符
if(e.getSource()==sqrt){
opp="√";
try{
d1=Double.parseDouble(show.getText());
op=4;
show.setText("");
}catch(Exceptionee){}
}
//等号
if(e.getSource()==equ){
inta,b=1; //a的值用于服务器端的计算,传到服务器端,不同的值代表不同的运算符
try{
d2=Double.parseDouble(show.getText());
switch(op){
case 0:
result=d1+d2;
break;
case 1:
result=d1-d2;
break;
case 2:
result=d1*d2;
break;
case 3:
if(d2==0){
JOptionPane.showMessageDialog(null,"除数不能为零,请重输");b=0;}
else
result=d1/d2;
break;
case 4:
if(d2<=0){
JOptionPane.showMessageDialog(null,"根号数值不能小于零,请重输");b=0;}
else
result=Math.sqrt(d2);
break;
case 5: //x^y
a=5;
out.writeInt(a);
out.writeDouble(d1);
out.writeDouble(d2);
try{
result=in.readDouble();
}catch(IOException e1){labelconnect.setText("与服务器已断开");}
break;
case 6: //cos
a=6;
out.writeInt(a);
out.writeDouble(d2);
try{
result=in.readDouble();
}catch(IOException e2){labelconnect.setText("与服务器已断开");}
break;
case 7: //sin
a=7;
out.writeInt(a);
out.writeDouble(d2);
try{
result=in.readDouble();
}catch(IOException e3){labelconnect.setText("与服务器已断开");}
break;
case 8: //ln
a=8;
if(d2<=0){
JOptionPane.showMessageDialog(null,"数值需大于零,请重输");b=0;}
else {
out.writeInt(a);
out.writeDouble(d2);
try{
result=in.readDouble();
}catch(IOExceptione4){labelconnect.setText("与服务器已断开");}
}
break;
case 9: //bfh
a=9;
out.writeInt(a);
out.writeDouble(d1);
out.writeDouble(d2);
try{
result=in.readDouble();
}catch(IOException e5){labelconnect.setText("与服务器已断开");}
break;
default:
}
if(b==1)
show.setText(String.valueOf(result));
else
show.setText("");
a=1; //a=1代表传到服务器处进行保存到日志中
out.writeInt(a);
out.writeDouble(d1);
out.writeDouble(d2);
out.writeUTF(opp);
out.writeDouble(result);
}catch(Exception ee1){}
}
数值0-9
if(e.getSource()==b[0]){
if(!(show.getText().equals("0")||show.getText().equals("-0")))
show.setText(show.getText()+"0");
}
if(e.getSource()==b[1]){
if(show.getText().equals("0"))
show.setText("1");
else{
if(show.getText().equals("-0"))
show.setText("-1");
else
show.setText(show.getText()+"1");
}
}
if(e.getSource()==b[2]){
if(show.getText().equals("0"))
show.setText("2");
else{
if(show.getText().equals("-0"))
show.setText("-2");
else
show.setText(show.getText()+"2");
}
}
if(e.getSource()==b[3]){
if(show.getText().equals("0"))
show.setText("3");
else{
if(show.getText().equals("-0"))
show.setText("-3");
else
show.setText(show.getText()+"3");
}
}
if(e.getSource()==b[4]){
if(show.getText().equals("0"))
show.setText("4");
else{
if(show.getText().equals("-0"))
show.setText("-4");
else
show.setText(show.getText()+"4");
}
}
if(e.getSource()==b[5]){
if(show.getText().equals("0"))
show.setText("5");
else{
if(show.getText().equals("-0"))
show.setText("-5");
else
show.setText(show.getText()+"5");
}
}
if(e.getSource()==b[6]){
if(show.getText().equals("0"))
show.setText("6");
else{
if(show.getText().equals("-0"))
show.setText("-6");
else
show.setText(show.getText()+"6");
}
}
if(e.getSource()==b[7]){
if(show.getText().equals("0"))
show.setText("7");
else{
if(show.getText().equals("-0"))
show.setText("-7");
else
show.setText(show.getText()+"7");
}
}
if(e.getSource()==b[8]){
if(show.getText().equals("0"))
show.setText("8");
else{
if(show.getText().equals("-0"))
show.setText("-8");
else
show.setText(show.getText()+"8");
}
}
if(e.getSource()==b[9]){
if(show.getText().equals("0"))
show.setText("9");
else{
if(show.getText().equals("-0"))
show.setText("-9");
else
show.setText(show.getText()+"9");
}
}
}
public static void main(String args[]){
new CalculatorClient();
}
}
//查看日志lookJFrame类
class lookJFrame extends JFrame{
private JTextArea txt;
private Container con;
public lookJFrame(){
super("计算器日志");
con=this.getContentPane();
final Imageimage=getToolkit().getImage(getClass().getResource("27.jpg"));
//final ImageIcon img=newImageIcon("H:/星空物语/java实验/Java图标/19.jpg");
txt=newJTextArea(){
publicvoid paintComponent(Graphics g){
g.drawImage(image, 0, 0, null);
super.paintComponent(g);
}};//文本域
txt.setOpaque(false);//设置为透明
add(txt);
try{
FileReaderfile=new FileReader("calculate.log");
BufferedReaderin=new BufferedReader(file);
Strings="calculate.log";
txt.append(s+"\n");
while((s=in.readLine())!=null){
txt.append(s+"\n");
}
in.close();
file.close();
}
catch(IOExceptionexp){
txt.setText("无此文件");
}
setSize(600, 400);
setLocation(270, 100);
setVisible(true);
}
}
//服务器端
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
public class CalculatorServer{
publicstatic void main(String args[]){
ServerSocketserver=null;
ServerThreadthread;
Socketclient=null;
System.out.println("\n---计算器 服务器---\n");
while(true){
try{
server=newServerSocket(4444);
}catch(IOExceptione1){
System.out.println("正在监听");
}
try{
client=server.accept();//server返回和客户端相连接的Socket
System.out.println("客户的地址:"+client.getInetAddress());
}catch(IOExceptione){
System.out.println("正在等待客户");
}
if(client!=null){
newServerThread(client).start();
}else{
continue;
}
}
}
}
class ServerThread extends Thread{
Socketsocket;
DataOutputStreamout=null;
DataInputStreamin=null;
Strings=null;
FileWriterfile;
BufferedWriteroutfile;
ServerThread(Sockett){
try{
file=newFileWriter("calculate.log",true);
outfile=new BufferedWriter(file);
}catch(Exception ee){}
socket=t;
try{
in=newDataInputStream(socket.getInputStream());//socket返回输入流
out=newDataOutputStream(socket.getOutputStream());//socket返回输出流
}catch(IOExceptione){}
}
publicvoid run(){
while(true){
inta=0;
doubleb=0,c=0,result=1.0;
try{
a=in.readInt();//接收数字(代表某操作符)
switch(a){
case 5://x^y
b=in.readDouble();//接收操作数1
c=in.readDouble();//接收操作数2
int i;
for(i=1;i<=c;i++){ result*=b;}
out.writeDouble(result);
break;
case 6://cos
c=in.readDouble();//接收操作数
result=Math.cos(c);
out.writeDouble(result);
break;
case 7://sin
c=in.readDouble();//接收操作数
result=Math.sin(c);
out.writeDouble(result);
break;
case 8://ln
c=in.readDouble();//接收操作数
result=Math.log(c);
out.writeDouble(result);
break;
case 9://%
b=in.readDouble();//接收操作数1
c=in.readDouble();//接收操作数2
result=b%c;
out.writeDouble(result);
break;
case 1:/写入文件中
b=in.readDouble();//接收操作数1
c=in.readDouble();//接收操作数2
String opp=in.readUTF();
Double rlt=in.readDouble();
Calendar cal=Calendar.getInstance();
SimpleDateFormat fmt=newSimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
StringsysDatetime=fmt.format(cal.getTime());
String ss=""; //sin cos √ ln 只需存储一个操作数,所以存到文件时要判断
if((opp.equals("sin"))||(opp.equals("cos"))||(opp.equals("√"))||(opp.equals("ln")))
ss="\n"+sysDatetime+" "+InetAddress.getLocalHost().getHostAddress().toString()+"--"+socket.getInetAddress().toString()+" "+opp+" "+c+" "+rlt;
else
ss="\n"+sysDatetime+" "+InetAddress.getLocalHost().getHostAddress().toString()+"--"+socket.getInetAddress().toString()+" "+b+" "+opp+" "+c+" "+rlt;
System.out.print(ss);
outfile.write(ss);
outfile.flush();
default:
}
}catch(IOException e){
System.out.println("\n客户离开");
break;
}
}
}
}