Java的图形化点菜系统(文件流、TCP及线程实现)

版权声明:版权声明:本文为博主原创文章,博客地址:http://blog.csdn.net/qq_37808895,未经博主允许不得转载。 https://blog.csdn.net/qq_37808895/article/details/88620342

简介:主要实现功能有菜单的图形化界面,支持增删改查,并加有滚动条显示(线程实现的动画),支持菜单保存和读取功能(文件),界面还算美化。另外在此次之上加上了客户用餐点菜功能的实现,原理就是基于ServerSocket提供的TCP连接服务的聊天室类似的功能,还没有完善。聊天室软件的博客后面会一同发表。

<1>菜单类

成员包括序号菜名和价格,定义了一个对比接口和toString方法,以便显示菜名

package Menu;
import java.util.Comparator;
public class Menu {
	public int num;
	public String name;
	public int price;
	public Menu(){
		this(0,"",0);
	}
	public Menu(String str){
		/*int spaceindex=str.indexOf(32);
		int priceindex=str.indexOf(157);
		for(int i=0;i<spaceindex;i++)
			String str1=str;*/
		String str1=str.substring(0,str.indexOf(" "));//空格
		String str2=str.substring(str.indexOf(" ")+1,str.indexOf("¥"));//¥
		String str3=str.substring(str.indexOf("¥")+1,str.length());
		this.num=Integer.parseInt(str1);
		this.name=str2;
		this.price=Integer.parseInt(str3);
	}
	public Menu(int num,String name,int price){
		this.num=num;
		this.name=name;
		this.price=price;
	}
	public String toString(){
		return num+" "+name+"¥"+price;
	}
	public interface Equalable<T>{
		public boolean equals(T t1,T t2);
	}
}

<2>菜单面板类

字体排版方面稍微做了修改(强迫症,做UI多好)
后面与框架进行对接

package Menu;
import java.awt.*
import javax.swing.*
public class MenuJPanel extends JPanel{
	private JTextField[] text_num,text_name,text_price;
	private JLabel label_num,label_name,label_price;
	public int num;
	public String name;
	public int price;
	public MenuJPanel(){
		this.setBorder(new TitledBorder(BorderFactory.createTitledBorder(
				BorderFactory.createLineBorder(Color.BLACK,2)),
				"菜单",TitledBorder.CENTER,TitledBorder.TOP,new Font("",0,26)));	
		this.setBackground(Color.LIGHT_GRAY);
		
		this.setLayout(new GridLayout(1,6));
		
		String str[][]={{"0"},{"宫保鸡丁"},{"30"}};
		
		label_num=new JLabel("序号:");
		label_num.setFont(new Font("",Font.BOLD,22));
		label_name=new JLabel("菜名:");
		label_name.setFont(new Font("",Font.BOLD,22));
		label_price=new JLabel("价格:");
		label_price.setFont(new Font("",Font.BOLD,22));
		
		this.add(label_num);
		text_num=new JTextField[str[0].length];
		
		for(int i=0;i<text_num.length;i++){
			this.add(text_num[i]=new JTextField(str[0][i]));
		    text_num[i].setFont(new Font("楷体",Font.BOLD,18));
		    text_num[i].setForeground(new Color(0,0,139));
		}
		
		
		this.add(label_name);
		text_name=new JTextField[str[1].length];
		for(int i=0;i<text_name.length;i++){
			this.add(text_name[i]=new JTextField(str[1][i]));
		    text_name[i].setFont(new Font("楷体",Font.BOLD,18));
		    text_name[i].setForeground(new Color(0,0,139));
		}
		this.add(label_price);
		text_price=new JTextField[str[2].length];
		for(int i=0;i<text_price.length;i++){
			this.add(text_price[i]=new JTextField(str[2][i]));
			text_price[i].setFont(new Font("楷体",Font.BOLD,18));
			text_price[i].setForeground(new Color(0,0,139));
		}	
	}
	//点击信息栏显示在上方列表处
	public void set(Menu m){
		if(m==null)
			return;
		for(int i=0;i<text_num.length;i++)
			this.text_num[i].setText(""+m.num);
		for(int i=0;i<text_name.length;i++)
			this.text_name[i].setText(""+m.name);
		for(int i=0;i<text_price.length;i++)
			this.text_price[i].setText(""+m.price);
	}
	public Menu get(){
		for(int i=0;i<text_num.length;i++)
			num=Integer.parseInt(this.text_num[i].getText());
		for(int i=0;i<text_name.length;i++)
			name=this.text_name[i].getText();
		for(int i=0;i<text_price.length;i++)
			price=Integer.parseInt(this.text_price[i].getText());
		return new Menu(num,name,price);
	}
	



	
}

<3>滚动条面板类

为了达到动画滚动条的效果,参照书上的动画实现线程,利用了字符线程平移
下面注释掉的是添加按键控制线程中断和启动,以测试启动程序自动滚动的效果

package Menu;
import java.awt.*
import javax.swing.*
public class RollbyJPanel extends JPanel implements ActionListener,Runnable{
	JTextField text_word,text_sleep,text_state;
	JButton button_start,button_interrupt;
	Thread thread;
	int sleeptime;
	RollbyJPanel(String text){
		this.setLayout(new GridLayout(2,1));
		text_word=new JTextField(String.format("%115s", text));
		this.add(text_word);
		JPanel panel_sub = new JPanel();
		this.add(panel_sub);
		//panel_sub.add(new JLabel("sleep"));
		this.sleeptime=70;//产生随机数作为间隔时间
		//text_sleep=new JTextField(""+sleeptime,5);//线程睡眠时间文本行
		//panel_sub.add(text_sleep);
		//text_sleep.addActionListener(this);
		text_word.setFont(new Font("楷体",Font.BOLD,30));
		text_word.setForeground(new Color(0,0,139));
		//button_start=new JButton("启动");
		//panel_sub.add(button_start);
		//button_start.addActionListener(this);
		//button_interrupt=new JButton("中断");
		//panel_sub.add(button_interrupt);
		//button_interrupt.addActionListener(this);
		
		thread=new Thread(this);
		thread.start();
		//button_interrupt.setEnabled(false);
		//panel_sub.add(new JLabel("state"));
		//text_state=new JTextField(""+thread.getState(),10);
		//text_state.setEditable(false);
		//panel_sub.add(text_state);
	}
		
	public void run(){
		while(true)
			try{
				String str=text_word.getText();
				text_word.setText(str.substring(1)+str.substring(0,1));
				Thread.sleep(sleeptime);
			}
		catch(InterruptedException ex){break;}
		
	}
	
	public void actionPerformed(ActionEvent ev){
		//if(ev.getSource()==button_start){
			thread=new Thread(this);
			thread.start();
			//text_state.setText(""+thread.getState());
			//button_start.setEnabled(false);
			//button_interrupt.setEnabled(true);
		//}
		/*if(ev.getSource()==button_interrupt){
			thread.interrupt();
			text_state.setText(""+thread.getState());
			button_start.setEnabled(true);
			button_interrupt.setEnabled(false);
		}
		if(ev.getSource()==text_sleep){
			try{
				sleeptime=Integer.parseInt(text_sleep.getText());}
			catch(NumberFormatException nfex){
				JOptionPane.showMessageDialog(this,
						"\""+text_sleep.getText()+"\"不能转换成文字,请重新输入!");}
			
		}*/
	}
}

<4>点菜服务端类

显示客人(用户端)的点菜结果

package Menu;

import java.awt.Color;
import java.awt.Font;
import javax.swing.*;
import java.io.*;
import java.net.*;
public class OrderTCPServerJFrame extends JFrame{
	private String name;
	private JTextArea text_receiver;
	private PrintWriter cout;//格式化字符输出流
	public OrderTCPServerJFrame(String name,Socket socket)throws IOException{
		super("点菜窗口     "+name);
		this.setBounds(1295, 220, 400, 600);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.text_receiver=new JTextArea();
		this.text_receiver.setBackground(Color.gray);
		this.text_receiver.setFont(new Font("楷体",Font.BOLD,22));
		this.text_receiver.setEnabled(false);
		this.getContentPane().add(new JScrollPane(this.text_receiver));
		
		this.setVisible(true);
		
		
		this.name=name;
		this.cout=new PrintWriter(socket.getOutputStream(),true);//获得Socket的输出流传输
		this.cout.println(name);
		//将Socket的字节输入流转换成字符流,默认GBK字符集,再创建缓冲字符输出流
		BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
		String line="连接"+br.readLine()+"成功";
		while(line!=null&&!line.endsWith("bye")){
			this.text_receiver.append(line+"\r\n");//显示对方发过来的内容
			line=br.readLine();//从输入流接收对方发过来的字符串
		}
		br.close();
		this.cout.close();
		socket.close();
		
		
	}
	public OrderTCPServerJFrame(String name,String host,int port)throws IOException{
		this(name,new Socket(host,port));
	}
	
	/*public static void main(String[] args)throws IOException{
		new OrderTCPServerJFrame("客人","127.0.0.1",2001);
	}*/
	
}


<5>点菜用户端

package Menu;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
public class OrderTCPSocketJFrame extends JFrame implements ActionListener{
	private String name;
	private JTextArea text_receiver;
	private JTextField text_sender;
	private PrintWriter cout;//格式化字符输出流
	private JButton[] buttons;
	
	public OrderTCPSocketJFrame(String name,Socket socket)throws IOException{
		super("点菜窗口     "+name);
		this.setBounds(610, 810, 700, 200);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.text_receiver=new JTextArea();
		this.text_receiver.setBackground(Color.gray);
		this.text_receiver.setFont(new Font("楷体",Font.BOLD,22));
		this.text_receiver.setEnabled(false);
		this.getContentPane().add(new JScrollPane(this.text_receiver));
		
		JToolBar toolbar=new JToolBar();
		this.getContentPane().add(toolbar,"South");
		toolbar.add(this.text_sender=new JTextField(30));
		this.text_sender.setFont(new Font("楷体",Font.BOLD,22));
		String[] buttonstr={"点菜","取消点菜","重新点菜"};
		buttons=new JButton[buttonstr.length];
		for(int i=0;i<buttonstr.length;i++){
			toolbar.add(buttons[i]=new JButton(buttonstr[i]));
			buttons[i].addActionListener(this);
			buttons[i].setFont(new Font("楷体",Font.BOLD,12));
		}
		this.setVisible(true);
		
		this.name=name;
		this.cout=new PrintWriter(socket.getOutputStream(),true);//获得Socket的输出流传输
		this.cout.println(name);
		//将Socket的字节输入流转换成字符流,默认GBK字符集,再创建缓冲字符输出流
		BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
		String line="连接"+br.readLine()+"成功";
		while(line!=null&&!line.endsWith("bye")){
			this.text_receiver.append(line+"\r\n");//显示对方发过来的内容
			line=br.readLine();//从输入流接收对方发过来的字符串
		}
		br.close();
		this.cout.close();
		socket.close();
		buttons[0].setEnabled(false);
		buttons[1].setEnabled(false);
		
		
		
	}
	public OrderTCPSocketJFrame(String name,String host,int port)throws IOException{
		this(name,new Socket(host,port));
	}
	public void actionPerformed(ActionEvent ev){
		if(ev.getActionCommand().equals("点菜")){
			this.cout.println(name+":"+text_sender.getText());
			text_receiver.append("您说:"+text_sender.getText()+"\n");
			text_sender.setText("");
		}
		if(ev.getActionCommand().equals("取消点菜")){
			text_receiver.append("您已取消点菜\n");
			this.cout.println(name+"取消点菜\n"+"bye\n");
			buttons[0].setEnabled(false);
			buttons[1].setEnabled(false);
		}
		if(ev.getActionCommand().equals("重新点菜")){
			text_receiver.append("请重新点菜\n");
			this.cout.println(name+"重新点菜\n"+"bye\n");
			buttons[0].setEnabled(true);
			buttons[1].setEnabled(true);
		}
	}
	/*public static void main(String[] args)throws IOException{
		
		new OrderTCPSocketJFrame("客人","127.0.0.1",2001);
	}*/
	
}


<6>启动服务端类

TCPServer创建服务端类,也可以和服务器类写在一起
主程序启动前运行此程序,否则不会打开服务端和客户端

package Menu;
import java.net.*;
import java.io.*;
public class OrderTCPServer {
	public OrderTCPServer(int port,String name)throws IOException{
		ServerSocket server = new ServerSocket(port);  //ServerSocket提供的TCP连接服务
		Socket client = server.accept();//等待接受客户端的TCP连接申请
		new OrderTCPServerJFrame(name,client);//服务器的聊天室,图形用户界面同客户端
		server.close();
	}
	public static void main(String[] args)throws IOException{
		new OrderTCPServer(2001,"主厨");
	}
}

<7>主程序类

菜单主程序,使用了分隔条面板JSplitPanel将各个面板分开

package Menu;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Comparator;
import java.util.Random;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
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.JSplitPane;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import Menu.Menu.Equalable;
public class MenuJFrame extends JFrame implements ActionListener, ListSelectionListener{
	protected JList<Menu>jlist;
	protected DefaultListModel<Menu>listmodel;
	protected MenuJPanel menu;
	protected RollbyJPanel rollby;
	protected JComboBox<String>comboxs[];
	private static Equalable equal[]={new EqualNum(),new EqualName()};
	private static Comparator comparators[]={new CompareNum(),new CompareName()};
	
	private JPanel toolbar;//工具栏
	private JMenuBar menubar;//菜单栏
	private JMenu Menu;
	private JMenuItem infoItem1;
	private JMenuItem infoItem2;
	
	protected JFileChooser fchooser;

	public MenuJFrame(MenuJPanel menu,Menu value[], RollbyJPanel rollby)throws IOException {
		super("菜单管理");
		this.setSize(700,600);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		//swing自带的菜单面板,添加保存功能
		this.menubar=new JMenuBar();
		this.Menu=new JMenu("文件");
		this.infoItem1=new JMenuItem("打开");
		Menu.add(infoItem1);
		this.infoItem1.addActionListener(this);
		this.infoItem2=new JMenuItem("保存");
		Menu.add(infoItem2);
		this.infoItem2.addActionListener(this);
		menubar.add(Menu);
		setJMenuBar(menubar);//设置菜单栏
		
		this.menu=menu;      //子类面板
		JPanel downpanel=new JPanel(new BorderLayout());
		JSplitPane split=new JSplitPane(JSplitPane.VERTICAL_SPLIT,this.menu,downpanel);
		//此处切割
		split.setDividerLocation(90);
		this.getContentPane().add(split);  //框架内容窗格添加分割窗格
		downpanel.setBackground(Color.LIGHT_GRAY);
		this.listmodel=new DefaultListModel<Menu>();  //创建空的列表框模型
		
		if(value!=null)
			for(int j=0;j<value.length;j++)
				this.listmodel.addElement(value[j]);  //列表框模型添加数据项
		this.jlist=new JList<Menu>(this.listmodel);//创建列表框,指定列表框模型
		this.jlist.addListSelectionListener(this);
		this.jlist.setFont(new Font("楷体",Font.BOLD,22));
		this.jlist.setBackground(Color.LIGHT_GRAY);
		downpanel.add(new JScrollPane(this.jlist));//面板添加包含列表框的滚动窗格    
		JPanel buttonpanel=new JPanel();
		downpanel.add(buttonpanel,"South");   //低端添加添加等操作按钮
		downpanel.add(rollby,"North");
		String str[][]={{"添加","修改","删除选择项"},{"查找关键字","排序关键字"},{"序号","价格"}};
		for(int i=0;i<str[0].length;i++){
			JButton button=new JButton(str[0][i]);
			button.addActionListener(this);
			buttonpanel.add(button);
		}
		this.comboxs=new JComboBox[str[1].length];
		for(int i=0;i<str[1].length;i++){
			buttonpanel.add(new JLabel(str[1][i]));
			buttonpanel.add(this.comboxs[i]=new JComboBox<String>(str[2]));
			this.comboxs[i].addActionListener(this);
		}
		
		this.setVisible(true);
	}
	public void valueChanged(ListSelectionEvent ev){
		this.menu.set(this.jlist.getSelectedValue());//按列表框选中项设置Menu面板各组件数据
	}
	//读取菜单保存文件
	public void readFrom(DefaultListModel<Menu>listmodel){
		try{
			FileReader fr=new FileReader("test.txt");
			BufferedReader br=new BufferedReader(fr);
			this.listmodel.removeAllElements();
			String s=br.readLine();	
			while(s!=null){
				this.listmodel.addElement(new Menu(s));
			s=br.readLine();
			}
			br.close();
			fr.close();
				
		}catch(IOException ioex){ioex.printStackTrace();}
	}
	//将修改后的菜单保存到本地文件
	public void writeTo(DefaultListModel<Menu>listmodel){
		try{
			FileWriter fw=new FileWriter("test.txt");
			BufferedWriter out=new BufferedWriter(fw);
			for(int i=0;i<this.listmodel.getSize();i++){
				out.write(this.listmodel.getElementAt(i).toString());
				out.newLine();
			}
			out.close();
			fw.close();
					
		}catch(IOException ioex){}
	}
	public void actionPerformed(ActionEvent ev){
		if(ev.getSource() instanceof JMenuItem){
			if(ev.getActionCommand().equals("读取")){
				this.readFrom(this.listmodel);
				JOptionPane.showMessageDialog(this, "读取成功");
				return;
			}
			if(ev.getActionCommand().equals("保存")){
				this.writeTo(this.listmodel);
				JOptionPane.showMessageDialog(this, "保存成功");
				return;
			}
		}
		else if(ev.getSource() instanceof JButton){
		if(ev.getActionCommand().equals("添加"))
			this.listmodel.addElement(this.menu.get());
		if(ev.getActionCommand().equals("修改")){
			int i=this.jlist.getSelectedIndex();//列表框中选中项序号
			if(i==-1)
				JOptionPane.showMessageDialog(this, "请选择列表框中数据项");
			else
				this.listmodel.setElementAt(this.menu.get(), i);
		}
			
		if(ev.getActionCommand().equals("删除选择项"))
			if(this.listmodel.getSize()==0)
				JOptionPane.showMessageDialog(this,"列表为空,不能删除");
			else{
				int i=this.jlist.getSelectedIndex();//列表框中选中项序号
				if(i==-1)
					JOptionPane.showMessageDialog(this, "请选择列表框中数据项");
				else
					this.listmodel.removeElementAt(i);
			}
		}
		if(ev.getSource()==this.comboxs[0]){
			int i=this.comboxs[0].getSelectedIndex();
			if(i<equal.length)
				search(this.menu.get(),equal[i]);
		}
		if(ev.getSource()==this.comboxs[1]){
			int i=this.comboxs[1].getSelectedIndex();
			if(i<comparators.length)
				sort(comparators[i]);
		}
		
	}
	//查找功能还没有完善
	public<T>void search(T obj,Equalable<?super T>eq){
		int n=this.listmodel.getSize();
		for(int i=0;i<n;i++)
			if(eq.equals(obj,(T)this.listmodel.elementAt(i))){
				this.jlist.setSelectedIndex(i);
				return;
			}
	}
	
	public<T>void sort(java.util.Comparator<?super T>c){
		for(int i=0;i<this.listmodel.getSize()-1;i++){
			int min=i;
			for(int j=i+1;j<this.listmodel.getSize();j++)
				if(c.compare((T)listmodel.getElementAt(j),(T)listmodel.getElementAt(min))<0)
					min=j;
			if(min!=i){
				Menu temp=this.listmodel.getElementAt(i);
				this.listmodel.setElementAt(this.listmodel.getElementAt(min),i);
				this.listmodel.setElementAt(temp,min);
			}
		}
		
	}
	

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		String str[][]={
				{"宫保鸡丁"},{"一品锅黄鱼锅子炒肉丝儿"},{"炒肉片"},{"鱼香肉丝"},{"淮南牛肉汤"},{"水煮肉片"},
				{"素炝春不老"},{"清焖莲子"},{"肉丁辣酱"},{"煮饽饽锅子"},{"菊花锅子"},{"汤圆子锅"},
				{"麻辣香锅"},{"砂锅"},{"黄焖鸡米饭"},{"什锦锅子"},{"白菜锅子"},
				{"炒银枝儿"},{"酸黄菜"},{"八宝榛子酱"}};
		String str1="宫保鸡丁,一品锅黄鱼锅子炒肉丝儿,炒肉片,鱼香肉丝,淮南牛肉汤,水煮肉片";
				
		
		Menu[] value={new Menu(),new Menu(),new Menu(),new Menu(),new Menu(),new Menu(),
				new Menu(),new Menu(),new Menu(),new Menu(),new Menu(),new Menu(),new Menu(),
				new Menu(),new Menu(),new Menu(),new Menu(),new Menu(),new Menu(),new Menu()};
		
		for(int i=1;i<21;i++){
			for(int j=0;j<str[0].length;j++){
				value[i-1]=new Menu(i,str[i-1][j],new Random().nextInt(40)+10);
				
			}	
		}
		
		new MenuJFrame(new MenuJPanel(),value,new RollbyJPanel("今日特惠:"+str1));
		
		new OrderTCPSocketJFrame("客人","127.0.0.1",2001);
	}
}

<8>最终效果图

在这里插入图片描述

选中进行增删改查操作
在这里插入图片描述

最后的文件保存
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37808895/article/details/88620342