学习笔记02(java云笔记)

总结一下我的java大作业

首先是题目要求
用JavaSocket编程开发云笔记本。
基本功能:该软件支持客户端从服务器下载用户之前保存的笔记。笔记以文本文档的形式保存在服务器中,笔记在客户端的界面上显示。该软件支持用户在客户端修改笔记,并通过保存按钮更新服务器的笔记文件,同一个用户可以在服务器中保存多个笔记。
要实现:“新建笔记”、“保存笔记”、“打开笔记”、“删除笔记”、“查询笔记、“笔记下载到本地”等功能。
总体思路:
1.服务器端:我写了三个服务器类,分别功能是登录和注册,加载初始数据,处理各个事件。
2.客户端:正常的笔记本客户端,只不过要加一些和服务器的交互。
这个是我项目的目录 主体是Client和Server
Client: MyNote2 是笔记本的界面。Register和Login分别是注册和登录界面和对应的点击事件。
Server:LoginServer 处理登录和注册。
MyNoteServer1 处理初始的数据加载。
MyNoteServer2 处理客户端和服务器端的交互。
其中前两个服务器类在完成任务后就会关闭。第三个服务器一直使用,利用了while死循环和 read函数的阻塞,关闭需要手动关闭。

客户端部分

在这里插入图片描述
登录界面张这个样子,很简单
登陆界面和注册界面张这个样子,很简单的布局。
在这里插入图片描述
笔记本的主界面张这个样子。左侧是JList,右侧是JTabbedPane。
我觉得学习到的两个点就是这两个组件的使用。

关于Jlist

1.样式
下面展示一下样式部分的代码。

		ListCellRenderer<Object> renderer = new MyListCellRenderer();
		jList.setCellRenderer(renderer);

//左侧列表数据的样式
	class MyListCellRenderer implements ListCellRenderer<Object>{
        JLabel jlabel =new JLabel();
		@Override // value 是列表的数据
		public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
				boolean cellHasFocus) {
			jlabel.setText(value.toString());
			jlabel.setBorder(BorderFactory.createEmptyBorder(10,4,10,4));
			jlabel.setFont(new Font("微软雅黑",Font.BOLD,20));
			jlabel.setOpaque(true);
			if(isSelected) {
				jlabel.setBackground(list.getSelectionBackground());
				jlabel.setForeground(list.getSelectionForeground());
			}else {
				jlabel.setBackground(list.getBackground());
				jlabel.setForeground(list.getForeground());
			}
			return jlabel;
		}
	}

JList中的元素为cell,我在调整样式时,也是对cell进行操作,把所有的cell都看成JLabel,对JLabel进行调整,然后返回。
2.点击

	jList.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if(jList.getSelectedIndex()!=-1) {
					if(e.getClickCount()==1) {
						oneClick(jList.getSelectedIndex());
					}
					if(e.getClickCount()==2) {
						twoClick(jList.getSelectedIndex());
					}
				}
			}

分别为单击和双击的函数我自己写的,传入的参数是当前点击的JList的index。
3.其他
要把JList放入滑动条JScrollPane中才可以正常使用

关于JTabbedPane

在我的项目中关于JTabbedPane的操作比较简单。
主要是添加,移除,获取JTabbedPane中的组件,当然每一个选项卡中的组件都是Textarea。
分别是
add(); add方法有很多重载。传入的参数也是不同的。
remove(index);
getSelectedComponent(index);
都是void类型的函数

关于输入框

在开始用时,点击取消或者关闭,都会返回一个空值。而且不输入任何东西时,关闭会有异常,这里分享一下我的解决方法。

s = JOptionPane.showInputDialog("查询内容:");
if(s==null) {
	return ;
}else if(s.equals("")) {
	JOptionPane.showMessageDialog(null, "输入不能为空");
	s = JOptionPane.showInputDialog("查询内容:");
}else {
	System.out.println("123");
}

最后的else块中是像完成的操作。

服务器端部分

登录&注册

我的思路,客户端传需要的账号密码到服务器端(和一个flag),服务器端根据flag的进行不同操作,并返回一个flag1给客户端,客户端根据不同的flag1进行不同的操作。登录or注册后就关掉这个服务器了,防止占用端口。
下面展示代码。

server = new ServerSocket(8888);
    		socket=server.accept();
    		while(true) {
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                int flag = br.read();
                if(flag==49) {
                    String name1 = br.readLine();
                    String pwd1 = br.readLine();
            		flag1=login(name1,pwd1);
                    //判断账号密码
            		//传回客户端一个登录状态
            		PrintWriter  pw = new PrintWriter(socket.getOutputStream(), true);
            		pw.println(flag1);
            		if(flag1==1) {
            			break;
            		}
                }else if(flag==50) {
        	        String name1 = br.readLine();
        	        String pwd1 = br.readLine();
        			int flag2 = Register(name1, pwd1);
        	        //判断账号密码
        			//传回客户端一个登录状态
        			PrintWriter  pw = new PrintWriter(socket.getOutputStream(), true);
        			pw.println(flag2);
        			if(flag2==1) {
        				File file=new File("F:\\wzhwzh"+"\\"+name1);
        				file.mkdir();
        				break;
        			}
                }

login和Register是我写的两个函数,用于判断登录和注册状态,用的是MySQL数据库,也是基础的查询和插入,主要熟悉了一下jdbc的使用。

初始化数据

客户端传进来用户的账号,根据账号找到所在的文件(我给每一个用户一个文件夹,里面有txt文件来保存笔记),然后将这些文件传入客户端的JList列表就可以了,这个时候只传了文件名,文件的内容会在打开JList的cell时加载进来。加载完成后,就可以关掉这个服务器了,不要占用端口。
下面展示代码。

	server = new ServerSocket(8888);
	    		socket=server.accept();
	    		br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
	    		String username=br.readLine();
	    		System.out.println("服务器1打开了");
	            // 接收客户端传来的用户名
	            // 传回文件名字
	    		File file = new File("F:\\wzhwzh"+"\\"+username);
	    		File[] array = file.listFiles();
	    		int l=array.length;
	    		PrintWriter  pw = new PrintWriter(socket.getOutputStream(), true);
	    		System.out.println(l);
	    		pw.print(l);
	    		for(int i=0;i<l;i++) {
	    			System.out.println(array[i].getName());
	    			pw.println(array[i].getName());
	    		}

事件处理

下面展示一些 内联代码片

private Socket s = null;
	private ServerSocket ss;
	private FileInputStream fis=null;
	private FileOutputStream fos = null;
    private OutputStream os=null;
    private BufferedReader br=null;
    private InputStream is = null;
    private String username;
	public void run() {
	    try {
			ss = new ServerSocket(8888);
			s = ss.accept();
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
			username=br.readLine();
	    	while(true) {
				int flag = br.read();
				System.out.println(flag);
				if(flag==49) { 
					String path = br.readLine();
					//找到文件
					File file = new File(path);
					path = "F:\\wzhwzh"+"\\"+username+"\\"+file;
					file = new File(path);
					fis = new FileInputStream(path);
					//把文件内容传给客户端
					os = s.getOutputStream();
					if(file.exists()&&file.length()==0) {
						os.write(1);
					}else {
						os.write(2);
						int len=0;
						byte[] bytes = new byte[1024];
						while((len=fis.read(bytes))!=-1) {
							os.write(bytes,0,len); 
						}
					}
				}else if(flag == 50) {
					String filename = br.readLine();
					filename+=".txt";
					System.out.println(filename);
					File file = new File("F:\\wzhwzh"+"\\"+username+"\\"+filename);
					file.createNewFile();
					System.out.println("创建成功了");
				}else if(flag == 51) {
					String filename = br.readLine();
					System.out.println(filename);
					byte[] bytes = new byte[1024];
					is=s.getInputStream();
					is.read(bytes);
					fos = new FileOutputStream("F:\\wzhwzh"+"\\"+username+"\\"+filename);
					fos.write(bytes);
				}else if(flag == 52) {
					String name1 = br.readLine();
					String name2 = br.readLine()+".txt";
					System.out.println(name1);
					System.out.println(name2);
					File file=new File("F:\\wzhwzh"+"\\"+username+"\\"+name1);
					if(file.renameTo(new File("F:\\wzhwzh"+"\\"+username+"\\"+name2))) {
						System.out.println("成功");
					}
				}else if (flag == 53) {
					String name = br.readLine();
					System.out.println(name);
					File file = new File("F:\\wzhwzh"+"\\"+username+"\\"+name);
					if(file.exists()) {
						System.out.println("文件存在");
						fis.close();
						if(file.delete()) {
							System.out.println("删除成功");
						}
					}
				}else if(flag == 54) {
					String s1 = br.readLine();
					File file = new File("F:\\wzhwzh"+"\\"+username);
					File[] files = file.listFiles();
					ArrayList<String> list = new ArrayList<String>();
					for(int i=0;i<files.length;i++) {
						if(files[i].getName().contains(s1)) {
							list.add(files[i].getName());
						}else {
							fis = new FileInputStream("F:\\wzhwzh"+"\\"+username+"\\"+files[i].getName());
							byte[] bytes = new byte[1024];
							fis.read(bytes);
							System.out.println(new String(bytes,"UTF-8"));
							if(new String(bytes,"UTF-8").contains(s1)) {
								list.add(files[i].getName());
							}
						}
					}
					PrintWriter  pw = new PrintWriter(s.getOutputStream(), true);
					pw.print(list.size());
					for(int i=0;i<list.size();i++) {
						pw.println(files[i].getName());
					}
				}
	    	}
			//首先获取客户端传来的文件名
		} catch (Exception e) {
			e.printStackTrace();
		}finally {}
	}

事件处理我用的是最笨的方法,因为 read函数阻塞的机制,如果没有数据传入它就会死等。所以我设计了while死循环,并且把客户端的事件都增加了一个部分,就是传入一个flag标志,这样服务器端就可以根据flag来判断应该执行哪个功能。
1-加载文件 2-新建笔记 3-保存笔记
4-改名 5-删除笔记 6-查询
查询功能我觉得我写的不够好,也是思路最简单的方法,因为我们要求是对名字和内容进行查询,所以用了if-else来判断,而且由于是在服务器中查询,客户端中新写的笔记但没保存进服务器时就会

结束

有一个很大的教训,就是我完成项目的时间太长了,我每天的作业量很小,然后写了很长时间,这样导致我在后期写的时候忘了我前期写的代码,而且很难找到。
功能的实现也是用的最简单的思路,效率很低。
这次的收获是学习了javaSocket,java图形界面,简单使用了jdbc,java对文件的操作。
也收获了一些简单的测试,在后期也可以自己解决一些出现的bug。
最重要的是有一个学习的过程,也是发现问题到解决问题的过程。
总体来说,收获还是很大的,这次大作业也为以后进一步学习java知识和开发技术打下了基础。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值