文件传输助手(swing单机版)

不久前收到社团新的考核任务,用Java写一个单机版的文件传输助手。功能要实现登录,注册,发送文字图片,历史记录等等…。经过一段时间的我努力大概完成了考核任务。
涉及的关键字有:Swing控件,I/Ol流,集合框架,Java事件处理机制。

一.注册

设置登录注册主界面

package frame;

import javax.swing.*;

public class LoginFrame extends JFrame {
    //创建登录窗口
    public void Frame() {
        JFrame jFrame = new JFrame();
        jFrame.setTitle("文件传输助手--登录");
        jFrame.setSize(300, 130);
        jFrame.setDefaultCloseOperation(3);//关闭窗口时结束程序
        jFrame.setLocation(500, 200);
        jFrame.setResizable(false);
        JPanel panel = new JPanel();
        jFrame.add(panel);
        placeComponents(panel,jFrame);
        jFrame.setVisible(true);
    }

    //在窗口中添加文本域,按钮等
    public void placeComponents(JPanel panel,JFrame jFrame) {
        panel.setLayout(null);

        //创建文本域用于用户输入
        JLabel userLabel = new JLabel("用户名:");
        userLabel.setBounds(10, 20, 80, 25);
        panel.add(userLabel);
        JTextField userText = new JTextField(20);
        userText.setBounds(100, 20, 165, 25);
        panel.add(userText);

        //输入密码的文本域
        JLabel passwordLabel = new JLabel("密码:");
        passwordLabel.setBounds(10, 50, 80, 25);
        panel.add(passwordLabel);
        JPasswordField passwordText = new JPasswordField(20);
        passwordText.setBounds(100, 50, 165, 25);
        panel.add(passwordText);

        // 创建登录按钮
        JButton loginButton = new JButton("登录");
        loginButton.setBounds(60, 80, 80, 25);
        panel.add(loginButton);
        panel.setVisible(true);

        //创建注册按钮
        JButton registerButton = new JButton("注册");
        registerButton.setBounds(160, 80, 80, 25);
        panel.add(registerButton);
        panel.setVisible(true);


        //通过登录按钮打开MainFrame主窗口
        MainJframe mainJframe = new MainJframe(userText, passwordText,jFrame);
        loginButton.addActionListener(mainJframe);//为按钮加监听

        //通过注册按钮打开RegisterFrame注册窗口
        RegisterFrame registerFrame = new RegisterFrame();
        registerButton.addActionListener(registerFrame);

    }


}

  • 主界面的制作用到的是JFrame,以及JLabel,JButton,JTextField等组件。注意要将各组件先添加到Jpanel容器里再将Jpanel添加到窗口中,避免出现覆盖。( 至于MainJframe,RegisterFrame是聊天主界面和注册界面,下面会讲到。)在这里插入图片描述

设置注册界面

package frame;

import sent.UserImformationSent;

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

public class RegisterFrame implements ActionListener {
    @Override
    //注册按钮监听
    //创建注册按钮
    public void actionPerformed(ActionEvent actionEvent) {
        JFrame jFrame3 = new JFrame();
        jFrame3.setTitle("文件传输助手--注册");
        jFrame3.setSize(300, 130);
        jFrame3.setLocation(500, 200);
        jFrame3.setResizable(false);

        JPanel panel = new JPanel();
        jFrame3.add(panel);
        placeComponents(panel,jFrame3);

        jFrame3.setVisible(true);

    }

    //在窗口中添加文本域,按钮等
    public void placeComponents(JPanel panel,JFrame jFrame3) {
        panel.setLayout(null);

        //创建文本域用于用户输入
        JLabel userLabel = new JLabel("用户名:");
        userLabel.setBounds(10, 20, 80, 25);
        panel.add(userLabel);
        JTextField userText = new JTextField(20);
        userText.setBounds(100, 20, 165, 25);
        panel.add(userText);

        // 输入密码的文本域
        JLabel passwordLabel = new JLabel("密码:");
        passwordLabel.setBounds(10, 50, 80, 25);
        panel.add(passwordLabel);
        JPasswordField passwordText = new JPasswordField(20);
        passwordText.setBounds(100, 50, 165, 25);
        panel.add(passwordText);
		
		//注册按钮
        JButton registerButton = new JButton("注册");
        registerButton.setBounds(110, 80, 80, 25);
        panel.add(registerButton);
        panel.setVisible(true);

		//为注册按钮添加监听
        UserImformationSent userImformationSent = new UserImformationSent(userText,passwordText,jFrame3);
        registerButton.addActionListener(userImformationSent);

    }


}
  • 注册窗口制作布局和登录主界面的大同小异。(其实每个窗口及组件都是差不多的)

在这里插入图片描述

用户信息读取,存储

       //用户信息写入
    public boolean copyChars(JTextField userTextField, JPasswordField passwordField) {
        Copy copy = new Copy();
        String string1 = null;
        string1 = copy.copy("/Users/jamesqiu/文件传输助手/txt/userimformation.txt");

        //创建正则表达式对用户名进行匹配
        Pattern pattern = Pattern.compile("用户名:.*");
        Matcher matcher = pattern.matcher(string1);

        int temp = 0;//用于判断该用户名是否存在
        while (matcher.find()) {
            if (("用户名:"+userTextField.getText()).equals(matcher.group())) {
                temp++;
            }
        }

        if (temp==0){//若不存在则写入到用户信息中

            FileOutputStream fos = null;//创建文件字节输出流,将用户信息存到userimformation.txt
            String string2 = "用户名:" + userTextField.getText() + "\n" + "密码:" + passwordField.getText() + "\n";

            try {
                fos = new FileOutputStream("/Users/jamesqiu/文件传输助手/txt/userimformation.txt", true);
                fos.write(string2.getBytes());

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        if (temp!=0) {
            return false;
        }
        else {
            return true;
        }

    }

   package sent;

import io.OutPutCopyChars;

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

public class UserImformationSent implements ActionListener {
    JTextField userText;
    JPasswordField passwordText;
    JFrame jFrame3;

    public UserImformationSent(JTextField userText, JPasswordField passwordText,JFrame jFrame3) {
        this.userText = userText;
        this.passwordText = passwordText;
        this.jFrame3=jFrame3;
    }

    //用户信息录入
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        
        OutPutCopyChars outPutCopyChars = new OutPutCopyChars();
        boolean temp = outPutCopyChars.copyChars(userText,passwordText);
        
        if (temp==true)
        jFrame3.dispose();//返回true说明注册成功,注册窗口关闭
        else
            userText.setText("该用户已存在!");//返回flase用户已经存在
            passwordText.setText("");

    }
}

在这里插入图片描述

  • 到这里注册功能就基本实现了。

二.登录

用户信息比对

		//利用正则表达式进行比对
		Pattern userPattern = Pattern.compile("用户名:.*");
        Pattern passwordPattern = Pattern.compile("密码:.*");
        Pattern pattern = Pattern.compile("用户名:.*");
        Matcher userMatcher = userPattern.matcher(string);
        Matcher passwordMatcher = passwordPattern.matcher(string);
        Matcher matcher = pattern.matcher(string);

        //找出最后一个用户名的索引,用于后面用户名不存在的判断
        while (matcher.find()) {
            temp2=matcher.end();
        }

        while (userMatcher.find()) {
            //先匹配用户名
            if (userMatcher.group().equals("用户名:" + userText.getText())) {
                temp1 = userMatcher.end();
                //如果匹配到有该用户,则进行该用户的密码匹配
                while (passwordMatcher.find(temp1)) {
                    if (passwordMatcher.group().equals(("密码:" + passwordText.getText()))) {

                    。。。。。。
                    。。。。。。
                    。。。。。。



                    }
                    //密码匹配错误
                    else {
                        userText.setText("用户名或密码❌错误❌");
                        passwordText.setText("");
                        break;
                    }
            }
          }
            temp3=userMatcher.end();
        }

        //匹配完所有用户名任然没有,则用户名错误
        if (temp2==temp3){
            userText.setText("用户名或密码❌错误❌");
            passwordText.setText("");
        }
  • 用户名,密码的登录匹配依然是用的正则表达式,这里要注意的是在匹配到有该用户后要判断密码是否正确时要注意从该用户名的检索位置开始匹配,不然会出现匹配到别的用户的密码登录成功的情况。(因为我们的用户信息是按照这样来储存的)
    用户名:111
    密码:111
    用户名:222
    密码:222

    在这里插入图片描述

聊天主窗口

package frame;
import click.EmojiClick;
import io.Copy;
import sent.FileSent;
import sent.TextSent;
import sent.PhotoSent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainJframe extends JFrame implements ActionListener {

    private JTextField userText;//账号输入框对象
    private JPasswordField passwordText;//密码输入框对象
    private  JFrame jFrame;


    public MainJframe(JTextField userText, JPasswordField passwordText,JFrame jFrame) {
        this.userText = userText;
        this.passwordText = passwordText;
        this.jFrame = jFrame;
    }

    //登录按钮监听
    public void actionPerformed(ActionEvent e) {
        //获取用户名和密码分析,用于登录的比对
        Copy copy = new Copy();
        String string = null;
        int temp1 = 0;
        int temp2 = 0;
        int temp3 = 0;
        string = copy.copy("/Users/jamesqiu/文件传输助手/txt/userimformation.txt");

        //利用正则表达式进行比对
        Pattern userPattern = Pattern.compile("用户名:.*");
        Pattern passwordPattern = Pattern.compile("密码:.*");
        Pattern pattern = Pattern.compile("用户名:.*");
        Matcher userMatcher = userPattern.matcher(string);
        Matcher passwordMatcher = passwordPattern.matcher(string);
        Matcher matcher = pattern.matcher(string);

        //找出最后一个用户名的索引,用于后面用户名不存在的判断
        while (matcher.find()) {
            temp2=matcher.end();
        }

        while (userMatcher.find()) {
            //先匹配用户名
            if (userMatcher.group().equals("用户名:" + userText.getText())) {
                temp1 = userMatcher.end();
                //如果匹配到有该用户,则进行该用户的密码匹配
                while (passwordMatcher.find(temp1)) {
                    if (passwordMatcher.group().equals(("密码:" + passwordText.getText()))) {
                        //匹配成功则创建新窗口
                        //文件传输主窗口
                        JFrame jFrame2 = new JFrame();
                        jFrame2.setTitle("文件传输助手");
                        jFrame2.setSize(600, 400);
                        jFrame2.setDefaultCloseOperation(3);//窗体关闭时结束程序
                        jFrame2.setLocationRelativeTo(null);//居中
                        jFrame2.setResizable(false);

                        JPanel panel = new JPanel();
                        jFrame2.add(panel);
                        placeComponents(panel);

                        jFrame2.setVisible(true);
                        jFrame.dispose();
                        break;
                    }
                    //密码匹配错误
                    else {
                        userText.setText("用户名或密码❌错误❌");
                        passwordText.setText("");
                        break;
                    }
            }
          }
            temp3=userMatcher.end();
        }

        //匹配完所有用户名任然没有,则用户名错误
        if (temp2==temp3){
            userText.setText("用户名或密码❌错误❌");
            passwordText.setText("");
        }
    }

    //在窗口中添加文本域,按钮等
    public void placeComponents(JPanel panel) {

        panel.setLayout(null);

        //接收窗口

        JTextPane jTextPane2 = new JTextPane();
        jTextPane2.setBounds(0, 0, 600, 317);
        jTextPane2.setEditable(false);
        jTextPane2.setBackground(Color.gray);
        panel.add(jTextPane2);

        //实现滚动
        JScrollPane jScrollPane = new JScrollPane(jTextPane2);
        panel.setBackground(Color.WHITE);
        Dimension size=jTextPane2.getPreferredSize();
        jScrollPane.setBounds(0,0,600,317);
        panel.add(jScrollPane);

        //插入图片按钮
        //表情
        JButton jButton1 = new JButton("\uD83D\uDE00");
        jButton1.setBounds(0, 315, 40, 40);
        panel.add(jButton1);

        //图片
        JButton jButton2 = new JButton("\uD83C\uDF01");
        jButton2.setBounds(40, 315, 40, 40);
        panel.add(jButton2);

        //历史记录
        JButton jButton3 = new JButton("\uD83D\uDC63");
        jButton3.setBounds(80, 315, 40, 40);
        panel.add(jButton3);

        //文件
        JButton jButton4 = new JButton("\uD83D\uDCC4");
        jButton4.setBounds(120, 315, 40, 40);
        panel.add(jButton4);

        //发送窗口
        JTextPane jTextPane = new JTextPane();
        jTextPane.setBounds(0, 350, 520, 30);
        jTextPane.setBackground(Color.GRAY);
        panel.add(jTextPane);

        //发送按钮
        JButton enterButton = new JButton("发送");
        enterButton.setBounds(520, 350, 80, 30);
        panel.add(enterButton);

//监听实现

        //通过发送按钮实现内容发送
        TextSent loginToListener2 = new TextSent(jTextPane,jTextPane2);
        enterButton.addActionListener(loginToListener2);

        //通过聊天按钮打开历史记录窗口实现历史记录回显
        RecordsFrame recordsFrame = new RecordsFrame(jTextPane2);
        jButton3.addActionListener(recordsFrame);

        //通过相册按钮打开图片预览窗口实现图片发送
        PhotoSent photoSent = new PhotoSent(jTextPane2);
        jButton2.addActionListener(photoSent);

        //通过文件夹按钮打开文件预览窗口实现文件发送
        FileSent fileSent = new FileSent(jTextPane2);
        jButton4.addActionListener(fileSent);

        //通过表情按钮打开表情包窗口实现表发送
        EmojiClick emojiClick = new EmojiClick(jTextPane,jTextPane2);
        jButton1.addMouseListener(emojiClick);
        jButton1.addActionListener(emojiClick);
    }
}
  • 聊天主窗口的主体是两个作为输入输出的JTextPane,这个窗格不但可以显示文字,也可以显示图片而JTextArea却做不到。接着就是主要要实现的发图片,发文件,历史记录,表情的几个按钮,它们都是要装上监听。

外观设计请忽略!

在这里插入图片描述

三.显示日期

			Date date = new Date();
            SimpleDateFormat df_24 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  • 日期的话我们要以“2020-04-03 08:20:36”的格式显示,用到的是Date类。

四.文字发送

package sent;

import io.OutPutCopyChars;

import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TextSent implements ActionListener {
    private JTextPane jTextPane;
    private JTextPane jTextPane2;
    //private JTextArea jTextArea;
    private Object String;

    public TextSent(JTextPane jTextPane, JTextPane jTextPane2) {
        this.jTextPane = jTextPane;
        this.jTextPane2 =jTextPane2;
        this.String = String;
        //this.jTextArea = jTextArea;
    }

    //文本发送
    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        if (!jTextPane.getText().equals("")) {
            Date date = new Date();
            SimpleDateFormat df_24 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            String src;
            src = df_24.format(date) + "\n" + jTextPane.getText() + "\n" + "\n";

            //设置字体大小
            SimpleAttributeSet attrset = new SimpleAttributeSet();
            StyleConstants.setFontSize(attrset, 15);

            //获得文本对象
            Document docs = jTextPane2.getDocument();
            try {
                //对文本进行追加
                docs.insertString(docs.getLength(), src, attrset);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }

            //输出流保存聊天记录
            OutPutCopyChars copyChars = new OutPutCopyChars();
            copyChars.copyChars(src);

            jTextPane.setText("");
        }
        else
            jTextPane.setText("消息不能为空!");
    }
}

  • 文本的发送的话是要它在输出的jTextPane中显示,但是它的settext(),会直接覆盖原先的文本所以用不了,而又没有追加文本的方法。所以我百度了一下发现可以用文本对象Document来进行文本的追加。还有就是避免给我们后面历史记录的查找带来难度,我设置了发送的内容不能为空。(这里判断相等还是要用equals,一开始用了==没用,这里卡了一下。😁)
    在这里插入图片描述

五.图片发送

package sent;

import io.OutPutCopyChars;

import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class PhotoSent implements ActionListener {

    private JTextPane jTextPane2;


    public PhotoSent(JTextPane jTextPane) {
        this.jTextPane2 = jTextPane;
    }

    //图片发送
    @Override
    public void actionPerformed(ActionEvent actionEvent) {

        JFileChooser jFileChooser = new JFileChooser(".");
        FileNameExtensionFilter filter = new FileNameExtensionFilter(
                "图片文件(*.png)", "png");
        jFileChooser.setFileFilter(filter);
        /*
        FileNameExtensionFilter filter2 = new FileNameExtensionFilter(
                "图片文件(*.jpg)", "jpg");
        jFileChooser.setFileFilter(filter2);

         */

        int val = jFileChooser.showOpenDialog(null);    //文件打开对话框
         if(val==jFileChooser.APPROVE_OPTION)
        {
            
            //保存图片路径
            String photoPath = null;
            photoPath = jFileChooser.getSelectedFile().getAbsolutePath();
            //创建图片对象
            ImageIcon imageIcon = new ImageIcon(photoPath);


            Date date = new Date();
            SimpleDateFormat df_24=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            String src;
            src = df_24.format(date) + "\n";


            //设置字体大小
            SimpleAttributeSet attrset = new SimpleAttributeSet();
            StyleConstants.setFontSize(attrset,15);

            //获得文本对象
            Document docs = jTextPane2.getDocument();
            try {
                //对文本进行追加
                docs.insertString(docs.getLength(), src, attrset);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }




            //获取图片
            jTextPane2.insertIcon(imageIcon);
            Document docs2 = jTextPane2.getDocument();
            try {
                //对文本进行追加
                docs.insertString(docs2.getLength(), "\n"+"\n", attrset);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }

            //保存图片路径
            OutPutCopyChars copyChars = new OutPutCopyChars();
            copyChars.copyChars(src,photoPath);

        }

    }
}

  • 图片的发送要用到JFileChooser去打开本地的文件浏览,然后获取你所选择图片的地址创建图片对象,最后用inserIcon的方法添加到输出窗格中。这里要将图片的地址保存是因为后面历史记录显示图片的时候回用到。
    在这里插入图片描述

六.表情发送

package click;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class EmojiClick implements ActionListener ,MouseListener{
    private String emojiPath;
    private JTextPane jTextPane1;
    private JTextPane jTextPane2;

    public EmojiClick(JTextPane jTextPane1,JTextPane jTextPane2) {
        this.jTextPane2 = jTextPane2;
        this.jTextPane1 = jTextPane1;
    }

    public EmojiClick(String emojiPath, JTextPane jTextPane1) {
        this.emojiPath = emojiPath;
        this.jTextPane1 = jTextPane1;
    }

    public void mouseClicked(MouseEvent mouseEvent) {
        //设置字体
        SimpleAttributeSet attrset = new SimpleAttributeSet();
        StyleConstants.setFontSize(attrset, 15);

       Document docs = jTextPane1.getDocument();
        try {
            docs.insertString(docs.getLength(),emojiPath, attrset);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void mousePressed(MouseEvent mouseEvent) {


    }

    @Override
    public void mouseReleased(MouseEvent mouseEvent) {
    }

    @Override
    public void mouseEntered(MouseEvent mouseEvent) {

    }

    @Override
    public void mouseExited(MouseEvent mouseEvent) {

    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {

        JFrame jFrame6 = new JFrame();
        jFrame6.setBounds(390,410,165,115);
        jFrame6.setResizable(false);


        JPanel jPanel = new JPanel();
        placeComponents(jPanel);
        jFrame6.add(jPanel);

        jFrame6.setVisible(true);



    }
    public void placeComponents(JPanel panel) {

        panel.setLayout(null);

        //设置字体
        SimpleAttributeSet attrset = new SimpleAttributeSet();
        StyleConstants.setFontSize(attrset, 15);


        JTextPane jTextPane = new JTextPane();
        jTextPane.setBounds(0, 0, 165, 115);
        jTextPane.setEditable(false);
        panel.add(jTextPane);


        //实现滚动
        JScrollPane jScrollPane = new JScrollPane(jTextPane);
        Dimension size=jTextPane.getPreferredSize();
        jScrollPane.setBounds(0,0,165,115);
        panel.add(jScrollPane);


        //添加表情包
        JButton jButton1 = new JButton("\uD83D\uDE00");
        jTextPane.insertComponent(jButton1);
        EmojiClick emojiClick1 = new EmojiClick("\uD83D\uDE00",jTextPane1);
        jButton1.addMouseListener(emojiClick1);

        JButton jButton2 = new JButton("\uD83D\uDE02");
        jTextPane.insertComponent(jButton2);
        EmojiClick emojiClick2 = new EmojiClick("\uD83D\uDE02",jTextPane1);
        jButton2.addMouseListener(emojiClick2);

        Document docs1 = jTextPane.getDocument();
        try {
            //添加转行符号
            docs1.insertString(docs1.getLength(),"\n", attrset);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        JButton jButton3 = new JButton("\uD83D\uDE05");
        jTextPane.insertComponent(jButton3);
        EmojiClick emojiClick3 = new EmojiClick("\uD83D\uDE05",jTextPane1);
        jButton3.addMouseListener(emojiClick3);

        JButton jButton4 = new JButton("\uD83D\uDE2D");
        jTextPane.insertComponent(jButton4);
        EmojiClick emojiClick4 = new EmojiClick("\uD83D\uDE2D",jTextPane1);
        jButton4.addMouseListener(emojiClick4);

        Document docs2 = jTextPane.getDocument();
        try {
            docs1.insertString(docs2.getLength(),"\n", attrset);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        JButton jButton5 = new JButton("\uD83D\uDE1C");
        jTextPane.insertComponent(jButton5);
        EmojiClick emojiClick5 = new EmojiClick("\uD83D\uDE1C",jTextPane1);
        jButton5.addMouseListener(emojiClick5);

        JButton jButton6 = new JButton("\uD83D\uDC4C");
        jTextPane.insertComponent(jButton6);
        EmojiClick emojiClick6 = new EmojiClick("\uD83D\uDC4C",jTextPane1);
        jButton6.addMouseListener(emojiClick6);

        Document docs3 = jTextPane.getDocument();
        try {
            docs1.insertString(docs3.getLength(),"\n", attrset);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        JButton jButton7 = new JButton("\uD83D\uDE09");
        jTextPane.insertComponent(jButton7);
        EmojiClick emojiClick7 = new EmojiClick("\uD83D\uDE09",jTextPane1);
        jButton7.addMouseListener(emojiClick7);

        JButton jButton8 = new JButton("\uD83D\uDE31");
        jTextPane.insertComponent(jButton8);
        EmojiClick emojiClick8 = new EmojiClick("\uD83D\uDE31",jTextPane1);
        jButton8.addMouseListener(emojiClick8);


        Document docs4 = jTextPane.getDocument();
        try {
            docs1.insertString(docs4.getLength(),"\n", attrset);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        JButton jButton9 = new JButton("\uD83D\uDC2E");
        jTextPane.insertComponent(jButton9);
        EmojiClick emojiClick9 = new EmojiClick("\uD83D\uDC2E",jTextPane1);
        jButton9.addMouseListener(emojiClick9);

        JButton jButton10 = new JButton("\uD83C\uDF7A");
        jTextPane.insertComponent(jButton10);
        EmojiClick emojiClick10 = new EmojiClick("\uD83C\uDF7A",jTextPane1);
        jButton10.addMouseListener(emojiClick10);

        Document docs5 = jTextPane.getDocument();
        try {

            docs1.insertString(docs5.getLength(),"\n", attrset);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        JButton jButton11 = new JButton("\uD83D\uDE48");
        jTextPane.insertComponent(jButton11);
        EmojiClick emojiClick11 = new EmojiClick("\uD83D\uDE48",jTextPane1);
        jButton11.addMouseListener(emojiClick11);

        JButton jButton12 = new JButton("\uD83D\uDE4F");
        jTextPane.insertComponent(jButton12);
        EmojiClick emojiClick12 = new EmojiClick("\uD83D\uDE4F",jTextPane1);
        jButton12.addMouseListener(emojiClick12);

    }
}


  • 表情包这里的话还是要新建一个窗口出来,表情想要能够添加鼠标点击监听的话必须要有一个载体,我这里选择的是按钮。(表情是用的emoji,所以还是文本的格式,它的发送和文本的发送是一样的。)
    在这里插入图片描述

七.文件发送

package sent;

import click.FileClick;
import io.OutPutCopyChars;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileSent implements ActionListener {

    private JTextPane jTextPane2;


    public FileSent(JTextPane jTextPane) {
        this.jTextPane2 = jTextPane;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        JFileChooser jFileChooser = new JFileChooser(".");
        int val = jFileChooser.showOpenDialog(null);    //文件打开对话框
        if (val == jFileChooser.APPROVE_OPTION) {

            File selectedFile = jFileChooser.getSelectedFile();// 获得选中的文件对象

            Date date = new Date();
            SimpleDateFormat df_24 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            String src;
            src = df_24.format(date) + "\n";

            //设置字体大小
            SimpleAttributeSet attrset = new SimpleAttributeSet();
            StyleConstants.setFontSize(attrset, 15);

            //获得文本对象
            Document docs1 = jTextPane2.getDocument();
            try {
                //对文本进行追加
                docs1.insertString(docs1.getLength(), src, attrset);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }

            //为文件路径添加按钮载体,并进行鼠标监听
            JButton jButton = new  JButton(selectedFile.getAbsolutePath());
            jTextPane2.insertComponent(jButton);
            FileClick fileClick = new FileClick(selectedFile.getAbsolutePath());
            jButton.addMouseListener(fileClick);


            Document docs2 = jTextPane2.getDocument();
            try {
                //对文本进行追加
                docs2.insertString(docs2.getLength(),"\n"+"\n", attrset);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }

            //将文件写入历史记录
            OutPutCopyChars outPutCopyChars = new OutPutCopyChars();
            outPutCopyChars.copyChars(src+selectedFile.getAbsolutePath()+"\n"+"\n");

        }
    }
}

  • 文件的话发送过去的是文件的路径,但是这里实现了点击文件的路径打开文件。那么就也要给文件的路径加上载体和监听。
    在这里插入图片描述

八.历史记录

历史记录-保存

package io;
import javax.swing.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class OutPutCopyChars {

    public OutPutCopyChars() {
    }

    //聊天记录纯文本写入
    public void copyChars(String src) {
        FileOutputStream fos = null;

        try {
            fos = new FileOutputStream("/Users/jamesqiu/文件传输助手/txt/recodes.txt", true);
            fos.write(src.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //聊天记录图片路径写入
    public void copyChars(String string, String photopath) {
        FileOutputStream fos = null;
        string = string + photopath + "\n" + "\n";

        try {
            fos = new FileOutputStream("/Users/jamesqiu/文件传输助手/txt/recodes.txt", true);
            fos.write(string.getBytes());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

历史记录-回显

package io;

import click.FileClick;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.*;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class InPutCopyChars {
    public InPutCopyChars() {
    }

    //
    public void copyChars(JTextPane jTextPane) {
        FileInputStream fileInputStream = null;


        try {
            fileInputStream = new FileInputStream("/Users/jamesqiu/文件传输助手/txt/recodes.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        byte[] flush = new byte[1024 * 10];
        int len = -1;
        while (true) {
            try {
                if (!((len = fileInputStream.read(flush)) != -1)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }

            String string = new String(flush, 0, len);

            //设置字体
            SimpleAttributeSet attrset = new SimpleAttributeSet();
            StyleConstants.setFontSize(attrset, 15);

            //创建图片路径的正则表达式
            Pattern pattern1 = Pattern.compile("/Users/jamesqiu/文件传输助手/./src/images/.*png");
            Matcher matcher1 = pattern1.matcher(string);
            //创建容器存放图片路径
            List<String> photoStringList = new ArrayList<String>();
            ImageIcon imageIcon = null;
            String newString = null;

            int temp1 = 0;
            int temp2 = 0;


            //创建文件路径的正则表达式
            Pattern pattern2 = Pattern.compile("/Users/jamesqiu/文件传输助手/./txt/.*txt");
            Matcher matcher2 = pattern2.matcher(string);
            //创建容器存放文件路径
            List<String> fileStringList = new ArrayList<String>();

            while (matcher2.find()){
                //当匹配到文件路径时就放入容器中
                fileStringList.add(matcher2.group());
            }

            while (matcher1.find()) {
                //当匹配到图片路径时就放入容器中
                photoStringList.add(matcher1.group());

            }
            if(photoStringList.size()!=0) {
                for (int i = 0; i < photoStringList.size(); i++) {
                    //将图片路径替换成"ه",作为标记符号
                    newString = string.replace(photoStringList.get(i), "ه");
                    string = newString;

                }
            }
            if (fileStringList.size()!=0) {
                for (int i = 0; i < fileStringList.size(); i++) {
                    //将图片路径替换成"&",作为标记符号
                    newString = string.replace(fileStringList.get(i), "♪");
                    string = newString;
                }
            }
            //将字符串转化成字符数组,逐个读取
            char[] chars = string.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                //当没有读到标记时,将字符输出到jTextPane中
                if (chars[i] != 'ه'&&chars[i]!='♪') {
                    Document docs1 = jTextPane.getDocument();
                    try {
                        //对文本进行追加
                        docs1.insertString(docs1.getLength(), String.valueOf(chars[i]), attrset);
                    } catch (BadLocationException e) {
                        e.printStackTrace();
                    }
                }
                //当读到标记时,就输出相应路径的图片
                else if(chars[i]=='ه') {
                    imageIcon = new ImageIcon(photoStringList.get(temp1));
                    jTextPane.insertIcon(imageIcon);
                    temp1++;

                }
                else if(chars[i]=='♪'){
                    JButton jButton = new JButton(fileStringList.get(temp2));
                    jTextPane.insertComponent(jButton);

                    FileClick fileClick = new FileClick(fileStringList.get(temp2));
                    jButton.addMouseListener(fileClick);

                    temp2++;

                }
            }

        }

    }
}


  • 历史记录的回显这块主要的问题是出在图片。起初我的想法是直接把文本和图片保存到一起,而这时txt文档是没有办法保存图片的,所以我就用了doc文档。但是每次将图片写入读取时都会出现乱码(能力有限解决不了)。后来我就换了一种思路,先将图片的路径保存,然后在读取历史的记录时用正则表达式去匹配路径,匹配到的路径存储到容器中,并将原字符串中的路径换成一个特殊符号如“©️”标记起来。最后把字符串换成字符一个个读取,读到我们的标记就添加图片。
  • 受到图片回显的启发,在解决文件按钮回显的时候也用了这种方法。
    -
    在这里插入图片描述

历史记录-清空

package sent;

import io.OutPutCopyChars;

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

public class RecordsDelete implements ActionListener {
    private JTextPane jTextPane1;
    private JTextPane jTextPane2;

    public RecordsDelete(JTextPane jTextPane1, JTextPane jTextPane2) {
        this.jTextPane1 = jTextPane1;
        this.jTextPane2 = jTextPane2;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {

        jTextPane1.setText("");
        jTextPane2.setText("");
        OutPutCopyChars outPutCopyChars = new OutPutCopyChars();
        outPutCopyChars.deleteChars("");
    }
}

在这里插入图片描述

历史记录-查找

package sent;

import io.Copy;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RecordsSearch implements ActionListener {
    private JTextField jTextFieldIn;
    private JTextPane jTextPaneOut;

    public RecordsSearch(JTextField jTextFieldIn, JTextPane jTextPaneOut) {
        this.jTextFieldIn = jTextFieldIn;
        this.jTextPaneOut = jTextPaneOut;
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        Copy copy = new Copy();
        //从输入框获取文本
        String stringIn = jTextFieldIn.getText();
        String stringOut = "无此记录!";

        //创建容器存储查找到的内容
        List<String> list = new ArrayList<String>();
        String string = copy.copy("/Users/jamesqiu/文件传输助手/txt/recodes.txt");

        SimpleAttributeSet attrset = new SimpleAttributeSet();
        StyleConstants.setFontSize(attrset, 15);

        //查找内容为空时会出现匹配所有内容,所以这里做个判断
        if(!stringIn.equals("")) {
            Pattern pattern = Pattern.compile(".*\n" + stringIn);
            Matcher matcher = pattern.matcher(string);
            while (matcher.find()) {
                list.add(matcher.group());
            }
        }
        if (list.size()==0) {//容器为空,即没有匹配到,所以直接输出无此内容。
            Document docs = jTextPaneOut.getDocument();
            try {

                docs.insertString(docs.getLength(), stringOut + "\n", attrset);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }
        }
        else {
            for (int i = 0; i < list.size(); i++) {
                    Document docs1 = jTextPaneOut.getDocument();
                    try {
                        //对文本进行追加
                        docs1.insertString(docs1.getLength(), list.get(i) + "\n", attrset);
                    } catch (BadLocationException e) {
                        e.printStackTrace();
                    }
            }
        }
    }
}


package io;

import java.io.*;

public class Copy {
    public Copy() {
    }

    //文本复制方法
    public String copy(String path) {
        String string = null;
        InputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        byte[] flush = new byte[1024 * 10];
        int len = -1;
        while (true) {
            try {
                if (!((len = fileInputStream.read(flush)) != -1)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
             string = new String(flush, 0, len);
        }
        return string;
    }
}



在这里插入图片描述

哈哈,肯定还有很多做的不好的地方。希望大佬们可以指出来,让我多学习学习。😁😁

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java Swing单机版个人通讯录是一款使用Java Swing框架开发的本地通讯录管理应用程序。该应用程序可以帮助用户方便地管理个人通讯录信息。 首先,用户进入应用程序后可以看到一个用户友好的界面。界面上有菜单栏和一个显示区域。用户可以通过菜单栏来进行各种操作,如添加联系人、删除联系人、编辑联系人信息等。 用户可以通过界面上的添加按钮来添加新的联系人。添加联系人时,用户需要输入联系人的姓名、电话号码、邮箱等信息。添加完成后,可以在显示区域中看到新添加的联系人。 用户可以通过界面上的搜索按钮来搜索特定的联系人。搜索时,用户可以通过输入联系人的姓名或电话号码来筛选联系人列表。搜索结果将会显示在显示区域中。 用户可以通过界面上的编辑按钮来编辑已有联系人的信息。编辑时,用户可以修改联系人的姓名、电话号码、邮箱等信息。 用户可以通过界面上的删除按钮来删除已有联系人。删除联系人时,用户需要确认删除操作以避免误删。 用户在使用本应用程序时,可以随时保存联系人列表到本地文件中,以便下一次启动应用程序时可以恢复之前保存的联系人信息。 总结来说,Java Swing单机版个人通讯录提供了一套简单易用的界面和功能,方便用户管理个人通讯录信息。它具有添加、编辑、删除和搜索联系人等常用功能,并支持保存和恢复联系人信息。这款应用程序可以帮助用户高效地管理自己的联系人,并提供便捷的通讯录查询功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值