版权声明:版权声明:本文为博主原创文章,博客地址: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>最终效果图
选中进行增删改查操作
最后的文件保存