项目介绍
用 Java 实现单机版的文件传输助手项目。
涉及技术知识:
Swing 组件 I/O流 正则表达式 Java 事务处理机制基础功能:
登录、注册 发送文字 发送图片、文件 文字、图片、文件的信息记录 历史记录的保存、回显及清空 信息发送的日期 退出高级功能:
发送表情包 查看和查找历史记录 点击历史记录的文件图片能直接打开 拖拽输入信息、图片、文件功能总览:
功能实现
一、登录
进入登录界面
未输入账号,登录弹出提示
输入账号,但未输入密码登录时弹出提示
账号或者密码输入错误登录时弹出提示
登录成功时进入主界面
登录界面:
package frame; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPasswordField; import javax.swing.JTextField; import function.Login; /** * 文件传输助手登陆界面 * * @author:360°顺滑 * * @date:2020/04/27 * */ public class LoginFrame { public static JFrame loginJFrame; public static JLabel userNameLabel; public static JTextField userNameTextField; public static JLabel passwordLabel; public static JPasswordField passwordField; public static JButton loginButton; public static JButton registerButton; public static void main(String[] args) { // 创建窗体 loginJFrame = new JFrame("文件传输助手"); loginJFrame.setSize(500, 300); loginJFrame.setLocationRelativeTo(null); loginJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ImageIcon image = new ImageIcon("src/pictures/logo.png"); loginJFrame.setIconImage(image.getImage()); loginJFrame.setResizable(false); // 创建内容面板 Container container = loginJFrame.getContentPane(); container.setLayout(null); // 创建“账号”标签 userNameLabel = new JLabel("账号:"); userNameLabel.setFont(new Font("行楷", Font.BOLD, 25)); userNameLabel.setBounds(60, 25, 100, 100); container.add(userNameLabel); // 创建输入账号文本框 userNameTextField = new JTextField(); userNameTextField.setFont(new Font("黑体", Font.PLAIN, 23)); userNameTextField.setBounds(133, 61, 280, 33); container.add(userNameTextField); // 创建“密码”标签 passwordLabel = new JLabel("密码:"); passwordLabel.setFont(new Font("行楷", Font.BOLD, 25)); passwordLabel.setBounds(60, 90, 100, 100); container.add(passwordLabel); // 创建输入密码文本框 passwordField = new JPasswordField(); passwordField.setBounds(133, 127, 280, 33); passwordField.setFont(new Font("Arial", Font.BOLD, 23)); container.add(passwordField); // 创建登录按钮 loginButton = new JButton("登录"); loginButton.setBounds(170, 185, 70, 40); loginButton.setFont(new Font("微软雅黑", 1, 18)); loginButton.setBackground(Color.WHITE); loginButton.setFocusPainted(false); loginButton.setBorderPainted(false); container.add(loginButton); // 创建注册按钮 registerButton = new JButton("注册"); registerButton.setBounds(282, 185, 70, 40); registerButton.setFont(new Font("微软雅黑", 1, 18)); registerButton.setBackground(Color.WHITE); registerButton.setFocusPainted(false); registerButton.setBorderPainted(false); container.add(registerButton); // 显示窗体 loginJFrame.setVisible(true); addListen(); } // 为按钮添加监听器 public static void addListen() { // 为登录按钮添加监听事件 loginButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub // 创建Login对象并把LoginFrame的文本框内容作为参数传过去 Login login = new Login(userNameTextField, passwordField); // 判断是否符合登录成功的条件 if (login.isEmptyUserName()) { emptyUserName(loginJFrame); } else { if (login.isEmptyPassword()) { emptyPasswordJDialog(loginJFrame); } else { if (login.queryInformation()) { loginJFrame.dispose(); MainFrame mainFrame = new MainFrame(userNameTextField.getText()); mainFrame.init(); } else { failedLoginJDialog(loginJFrame); } } } } }); // 为注册按钮添加监听事件 registerButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub // 隐藏当前登录窗口 loginJFrame.setVisible(false); // 打开注册窗口 new RegisterFrame().init(); } }); } /* * 由于各个标签长度不同,所以为了界面美观,就写了三个弹出对话框而不是一个! * */ // 未输入账号时弹出提示对话框 public static void emptyUserName(JFrame jFrame) { JDialog jDialog = new JDialog(jFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocationRelativeTo(null); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel("未输入账号!"); jLabel.setFont(new Font("行楷", 0, 21)); jLabel.setBounds(82, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub jDialog.dispose(); } }); jDialog.setVisible(true); } // 未输入密码时弹出提示对话框 public static void emptyPasswordJDialog(JFrame jFrame) { JDialog jDialog = new JDialog(jFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocationRelativeTo(null); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel("未输入密码!"); jLabel.setFont(new Font("行楷", 0, 21)); jLabel.setBounds(82, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub jDialog.dispose(); } }); jDialog.setVisible(true); } // 账号或密码输入错误! public static void failedLoginJDialog(JFrame jFrame) { JDialog jDialog = new JDialog(jFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocationRelativeTo(null); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel("账号或密码输入错误!"); jLabel.setFont(new Font("行楷", 0, 20)); jLabel.setBounds(47, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub jDialog.dispose(); } }); jDialog.setVisible(true); } }
登录判断
package function; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JPasswordField; import javax.swing.JTextField; /** * 文件传输助手登录功能 * * @author:360°顺滑 * * @date: 2020/04/29 * */ public class Login { JTextField userNameTextField; JPasswordField passwordField; public Login(JTextField userNameTextField, JPasswordField passwordField) { this.userNameTextField = userNameTextField; this.passwordField = passwordField; } //判断账号是否为空方法 public boolean isEmptyUserName() { if (userNameTextField.getText().equals("")) return true; else return false; } //判断密码是否为空方法 public boolean isEmptyPassword() { //操作密码框文本要先将其转换为字符串 if ("".equals(new String(passwordField.getPassword()))) return true; else return false; } // 查询是否存在该账号密码 public boolean queryInformation() { File file = new File("src/txt/userInformation.txt"); FileReader fileReader = null; BufferedReader bufferedReader = null; boolean vis = false; try { fileReader = new FileReader(file); bufferedReader = new BufferedReader(fileReader); Pattern userNamePattern = Pattern.compile("用户名:.+"); Pattern passwordPattern = Pattern.compile("密码:.+"); String str1 = null; while ((str1 = bufferedReader.readLine()) != null) { Matcher userNameMatcher = userNamePattern.matcher(str1); if(userNameMatcher.find()) { if (("用户名:" + userNameTextField.getText()).equals(userNameMatcher.group())) { String str2 = bufferedReader.readLine(); Matcher passwordMatcher = passwordPattern.matcher(str2); if(passwordMatcher.find()) { if (("密码:" + new String(passwordField.getPassword())).equals(passwordMatcher.group())) { vis = true; break; } } } } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { bufferedReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { fileReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (vis) return true; else return false; } }
主界面
package frame; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.Box; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; import function.DropTargetFile; import function.FileSend; import function.RecordsEcho; import function.TextSend; /** * 文件传输助手主界面 * * @author 360°顺滑 * * @date:2020/04/29 ~ 2020/04/30 * */ public class MainFrame { String userName; public MainFrame() { }; public MainFrame(String userName) { this.userName = userName; } private JButton fileButton; private JButton historicRecordsButton; private JButton sendButton; private JTextPane showPane; private JTextPane inputPane; private JButton expressionButton; private JScrollPane scrollShowPane; private Box buttonBox; private Box inputBox; private Box sendBox; private Box totalBox; private ImageIcon image; static JFrame mainFrame; public void init() { // 显示文本窗格 showPane = new JTextPane(); showPane.setSize(600, 400); showPane.setBackground(Color.WHITE); showPane.setEditable(false); showPane.setBorder(null); showPane.setFont(new Font("宋体", 0, 25)); // 显示文本窗格添加滚动条 scrollShowPane = new JScrollPane(showPane); // 表情包按鈕并添加图标 Icon expressionIcon = new ImageIcon("src/pictures/expression.png"); expressionButton = new JButton(expressionIcon); expressionButton.setBackground(Color.WHITE); expressionButton.setFocusPainted(false); expressionButton.setBorderPainted(false); // 文件按钮并添加图标 Icon fileIcon = new ImageIcon("src/pictures/file.png"); fileButton = new JButton(fileIcon); fileButton.setBackground(Color.WHITE); fileButton.setFocusPainted(false); fileButton.setBorderPainted(false); // 历史记录按钮并添加图标 Icon historicRecordsIcon = new ImageIcon("src/pictures/historicRecords.png"); historicRecordsButton = new JButton(historicRecordsIcon); historicRecordsButton.setBackground(Color.WHITE); historicRecordsButton.setFocusPainted(false); historicRecordsButton.setBorderPainted(false); // 按钮Box容器添加三个按钮 buttonBox = Box.createHorizontalBox(); buttonBox.setPreferredSize(new Dimension(1000, 50)); buttonBox.add(Box.createHorizontalStrut(10)); buttonBox.add(expressionButton); buttonBox.add(Box.createHorizontalStrut(10)); buttonBox.add(fileButton); buttonBox.add(Box.createHorizontalStrut(10)); buttonBox.add(historicRecordsButton); // 添加 “历史记录”按钮到右边框的距离 到buttonBox容器中 buttonBox.add(Box.createHorizontalGlue()); // 输入文本窗格 inputPane = new JTextPane(); inputPane.setSize(600, 300); inputPane.setFont(new Font("宋体", 0, 24)); inputPane.setBackground(Color.WHITE); JScrollPane scrollInputPane = new JScrollPane(inputPane); // 输入区域的Box容器 inputBox = Box.createHorizontalBox(); inputBox.setPreferredSize(new Dimension(1000, 150)); inputBox.add(scrollInputPane); // 发送按钮 sendButton = new JButton("发送(S)"); sendButton.setFont(new Font("行楷", Font.PLAIN, 20)); sendButton.setBackground(Color.WHITE); sendButton.setFocusPainted(false); sendButton.setBorderPainted(false); // 发送Box容器并添加发送按钮 sendBox = Box.createHorizontalBox(); sendBox.setPreferredSize(new Dimension(1000, 50)); sendBox.setBackground(Color.white); sendBox.add(Box.createHorizontalStrut(710)); sendBox.add(Box.createVerticalStrut(5)); sendBox.add(sendButton); sendBox.add(Box.createVerticalStrut(5)); // 总的Box容器添加以上3个Box totalBox = Box.createVerticalBox(); totalBox.setPreferredSize(new Dimension(1000, 250)); totalBox.setSize(1000, 400); totalBox.add(buttonBox); totalBox.add(inputBox); totalBox.add(Box.createVerticalStrut(3)); totalBox.add(sendBox); totalBox.add(Box.createVerticalStrut(3)); // 设置主窗体 mainFrame = new JFrame("文件传输助手"); mainFrame.setSize(950, 800); mainFrame.setLocationRelativeTo(null); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 改变窗体logo image = new ImageIcon("src/pictures/logo.png"); mainFrame.setIconImage(image.getImage()); mainFrame.setLayout(new BorderLayout()); // 添加窗体以上两个主要容器 mainFrame.add(scrollShowPane, BorderLayout.CENTER); mainFrame.add(totalBox, BorderLayout.SOUTH); mainFrame.setVisible(true); // 添加监听器 addListen(); // 信息记录回显到展示面板 RecordsEcho echo = new RecordsEcho(userName, showPane); echo.read(); } // 提示对话框 public static void warnJDialog(String information) { JDialog jDialog = new JDialog(mainFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocation(770, 400); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel(information); jLabel.setFont(new Font("微软雅黑", 0, 18)); jLabel.setBounds(65, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); // 为弹出对话框按钮添加监听事件 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub jDialog.dispose(); } }); jDialog.setVisible(true); } // 添加监听事件 @SuppressWarnings("unused") public void addListen() { /* * 为输入文本添加目标监听器 */ // 创建拖拽目标监听器 DropTargetListener listener = new DropTargetFile(inputPane); // 在 inputPane上注册拖拽目标监听器 DropTarget dropTarget = new DropTarget(inputPane, DnDConstants.ACTION_COPY_OR_MOVE, listener, true); // 发送按钮监听事件 sendButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub TextSend textSend = new TextSend(showPane, inputPane, userName); textSend.sendText(); } }); // 输入框添加键盘事件 inputPane.addKeyListener(new KeyListener() { // 发生击键事件时被触发 @Override public void keyTyped(KeyEvent e) { } // 按键被释放时被触发 @Override public void keyReleased(KeyEvent e) { } // 按键被按下时被触发 @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub // 如果按下的是 Ctrl + Enter 组合键 则换行 if ((e.getKeyCode() == KeyEvent.VK_ENTER) && e.isControlDown()) { Document document = inputPane.getDocument(); try { document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // 否则发送 } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { TextSend textSend = new TextSend(showPane, inputPane, userName); textSend.sendText(); } } }); // 表情包按钮监听事件 expressionButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub new EmojiFrame(showPane, userName).init(); } }); // 文件按钮监听事件 fileButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub FileSend fileSend = new FileSend(userName, showPane, inputPane); fileSend.send(); } }); // 历史记录按钮监听事件 historicRecordsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub new HistoricRecordsFrame(userName, showPane).init(); } }); } }
登录之前如果没有账号就得先注册一个,那么进入注册功能!
二、注册
点击登录界面的注册按钮,进入注册界面
未输入账号进行注册时
输入账号但未输入密码或者确认密码进行注册时
密码和确认密码不一致时进行注册
账号已存在进行注册时
注册成功时
点击确定按钮或者关闭窗口后返回登录界面
如果取消注册,直接点击返回按钮就可以返回登录界面了
注册界面
package frame; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPasswordField; import javax.swing.JTextField; import function.Register; /** * * 文件传输助手注册界面 * * @author 360°顺滑 * * @date: 2020/04/27 ~ 2020/04/28 * */ public class RegisterFrame { public JFrame registerJFrame; public JLabel userNameLabel; public JTextField userNameTextField; public JLabel passwordLabel; public JPasswordField passwordField; public JLabel passwordAgainLabel; public JPasswordField passwordAgainField; public JButton goBackButton; public JButton registerButton; public void init() { // 创建窗体 registerJFrame = new JFrame("文件传输助手"); // registerJFrame.setTitle(); registerJFrame.setSize(540, 400); registerJFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); ImageIcon image = new ImageIcon("src/pictures/logo.png"); registerJFrame.setIconImage(image.getImage()); registerJFrame.setLocationRelativeTo(null); registerJFrame.setResizable(false); // 创建内容面板 Container container = registerJFrame.getContentPane(); container.setLayout(null); // 创建“账号”标签 userNameLabel = new JLabel("账号:"); userNameLabel.setFont(new Font("行楷", Font.BOLD, 25)); userNameLabel.setBounds(97, 25, 100, 100); container.add(userNameLabel); // 创建输入账号文本框 userNameTextField = new JTextField(); userNameTextField.setFont(new Font("黑体", Font.PLAIN, 23)); userNameTextField.setBounds(170, 61, 280, 33); container.add(userNameTextField); // 创建“密码”标签 passwordLabel = new JLabel("密码:"); passwordLabel.setFont(new Font("行楷", Font.BOLD, 25)); passwordLabel.setBounds(97, 90, 100, 100); container.add(passwordLabel); // 创建输入密码文本框 passwordField = new JPasswordField(); passwordField.setBounds(170, 125, 280, 33); passwordField.setFont(new Font("Arial", Font.BOLD, 23)); container.add(passwordField); // 创建“确认密码”标签 passwordAgainLabel = new JLabel("确认密码:"); passwordAgainLabel.setFont(new Font("行楷", Font.BOLD, 25)); passwordAgainLabel.setBounds(45, 150, 130, 100); container.add(passwordAgainLabel); // 创建确认密码文本框 passwordAgainField = new JPasswordField(); passwordAgainField.setBounds(170, 185, 280, 33); passwordAgainField.setFont(new Font("Arial", Font.BOLD, 23)); container.add(passwordAgainField); // 创建返回按钮 goBackButton = new JButton("返回"); goBackButton.setBounds(200, 260, 70, 40); goBackButton.setFont(new Font("微软雅黑", 1, 18)); goBackButton.setBackground(Color.WHITE); goBackButton.setFocusPainted(false); goBackButton.setBorderPainted(false); container.add(goBackButton); // 创建注册按钮 registerButton = new JButton("注册"); registerButton.setBounds(330, 260, 70, 40); registerButton.setFont(new Font("微软雅黑", 1, 18)); registerButton.setBackground(Color.WHITE); registerButton.setFocusPainted(false); registerButton.setBorderPainted(false); container.add(registerButton); // 显示窗体 registerJFrame.setVisible(true); addListen(); } // 为按钮添加监听事件 public void addListen() { // 为注册按钮添加监听事件 registerButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub // 创建register对象,同时将RegisterFrame的文本框内容作为参数传过去 Register register = new Register(userNameTextField, passwordField, passwordAgainField); // 判断输入账号是否为空 if (register.isEmptyUserName()) { emptyUserName(registerJFrame); } else { // 判断输入密码是否为空 if (register.isEmptyPassword()) { emptyPasswordJDialog(registerJFrame); } else { // 判断密码和确认密码是否一致 if (register.isSamePassWord()) { // 判断账号是否已存在 if (!register.isExistAccount()) { // 注册成功!!! register.saveInformation(); registerJFrame.dispose(); userNameTextField.setText(""); passwordField.setText(""); passwordAgainField.setText(""); new LoginFrame(); LoginFrame.loginJFrame.setVisible(true); successRegisterJDialog(registerJFrame); } else existAccountJDialog(registerJFrame); } else { differentPasswordJDialog(registerJFrame); passwordField.setText(""); passwordAgainField.setText(""); } } } } }); // 为返回按钮添加监听事件 goBackButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 销毁注册窗口 registerJFrame.dispose(); // 重新显示登录窗口 new LoginFrame(); LoginFrame.loginJFrame.setVisible(true); } }); } /* * 由于各个标签长度不同,所以为了界面美观,就写了三个弹出对话框而不是一个! * */ // 未输入账号时弹出提示对话框 public void emptyUserName(JFrame jFrame) { JDialog jDialog = new JDialog(jFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocationRelativeTo(null); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel("未输入用户名!"); jLabel.setFont(new Font("行楷", 0, 21)); jLabel.setBounds(73, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub jDialog.dispose(); } }); jDialog.setVisible(true); } // 未输入密码时弹出提示对话框 public void emptyPasswordJDialog(JFrame jFrame) { JDialog jDialog = new JDialog(jFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocationRelativeTo(null); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel("未输入密码!"); jLabel.setFont(new Font("行楷", 0, 21)); jLabel.setBounds(73, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub jDialog.dispose(); } }); jDialog.setVisible(true); } // 密码和确认密码不一致时弹出提示框 public void differentPasswordJDialog(JFrame jFrame) { JDialog jDialog = new JDialog(jFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocationRelativeTo(null); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel("输入密码不一致!"); jLabel.setFont(new Font("行楷", 0, 21)); jLabel.setBounds(63, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub jDialog.dispose(); } }); jDialog.setVisible(true); } // 已存在账号弹出提示对话框 public void existAccountJDialog(JFrame jFrame) { JDialog jDialog = new JDialog(jFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocationRelativeTo(null); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel("该账号已存在!"); jLabel.setFont(new Font("行楷", 0, 21)); jLabel.setBounds(73, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub jDialog.dispose(); } }); jDialog.setVisible(true); } // 成功注册对话框 public void successRegisterJDialog(JFrame jFrame) { JDialog jDialog = new JDialog(jFrame, "提示"); jDialog.setLayout(null); jDialog.setSize(300, 200); jDialog.setLocationRelativeTo(null); ImageIcon image = new ImageIcon("src/pictures/warn.png"); jDialog.setIconImage(image.getImage()); JLabel jLabel = new JLabel("注册成功!"); jLabel.setFont(new Font("行楷", 0, 21)); jLabel.setBounds(73, 0, 200, 100); jDialog.add(jLabel); JButton button = new JButton("确定"); button.setBounds(105, 80, 70, 40); button.setFont(new Font("微软雅黑", 1, 18)); button.setBackground(Color.WHITE); button.setFocusPainted(false); button.setBorderPainted(false); jDialog.add(button); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub // 销毁提示对话框 jDialog.dispose(); } }); jDialog.setVisible(true); } }
注册判断
package function; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JPasswordField; import javax.swing.JTextField; /** * 文件传输助手注册功能 * * @author:360°顺滑 * * @date:2020/04/28 ~ 2020/04/29 * */ public class Register { JTextField userNameTextField; JPasswordField passwordField; JPasswordField passwordAgainField; //将RegisterFrame参数传入进来 public Register(JTextField userNameTextField, JPasswordField passwordField, JPasswordField passwordAgainField) { this.userNameTextField = userNameTextField; this.passwordField = passwordField; this.passwordAgainField = passwordAgainField; } //判断账号是否为空方法 public boolean isEmptyUserName() { if (userNameTextField.getText().equals("")) return true; else return false; } //判断密码是否为空方法 public boolean isEmptyPassword() { //操作密码框文本要先将其转换为字符串 if ("".equals(new String(passwordField.getPassword())) || "".equals(new String(passwordAgainField.getPassword()))) return true; else return false; } //判断密码和输入密码是否一致方法 public boolean isSamePassWord() { //操作密码框文本要先将其转换为字符串 if (new String(passwordField.getPassword()).equals(new String(passwordAgainField.getPassword()))) return true; else return false; } //判断账号是否已存在方法 public boolean isExistAccount() { File file = new File("src/txt/userInformation.txt"); FileReader fileReader = null; BufferedReader bufferedReader = null; boolean vis = false; try { fileReader = new FileReader(file); bufferedReader = new BufferedReader(fileReader); //正则表达式 Pattern pattern = Pattern.compile("用户名:.+"); String str = null; while ((str = bufferedReader.readLine()) != null) { Matcher matcher = pattern.matcher(str); if (matcher.find()) { if (("用户名:" + userNameTextField.getText()).equals(matcher.group())) { vis = true; break; } } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } if (!vis) { return false; } else { return true; } } //保存信息到本地 public void saveInformation() { File file = new File("src/txt/userInformation.txt"); FileWriter fileWriter = null; BufferedWriter bufferedWriter = null; try { fileWriter = new FileWriter(file, true); bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.write("用户名:" + userNameTextField.getText()); bufferedWriter.newLine(); bufferedWriter.write("密码:" + new String(passwordField.getPassword())); bufferedWriter.newLine(); bufferedWriter.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (bufferedWriter != null) { try { bufferedWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (fileWriter != null) { try { fileWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
三、发送文字
输入文字后可以点击发送按钮发送,也可以通过键盘Enter键发送
发送空白信息时弹出提示,提示框代码在主界面类里
发送文本:
package function; import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JFrame; import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; import frame.MainFrame; /** * 实现发送消息,并保存到信息记录 * * @author 360°顺滑 * * @date 2020/05/01 * */ public class TextSend { JFrame mainFrame; JTextPane textShowPane; JTextPane textInputPane; String userName; public TextSend(JTextPane textShowPane, JTextPane textInputPane, String userName) { this.textShowPane = textShowPane; this.textInputPane = textInputPane; this.userName = userName; } public void sendText() { if (!("".equals(textInputPane.getText()))) { // 获取日期并设置日期格式 Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); SimpleAttributeSet attributeSet = new SimpleAttributeSet(); // 输入文本 String inputText = dateFormat.format(date) + "n"; Pattern pattern = Pattern.compile(".+[\.].+"); Matcher matcher = pattern.matcher(textInputPane.getText()); // 判断是否为文件 boolean isFile = false; // 判断是否为第一个文件 boolean isFirst = true; while (matcher.find()) { isFile = true; // 获得文件名 int index = matcher.group().lastIndexOf("\"); String fileName = matcher.group().substring(index + 1); // 图片的情况 if (matcher.group().endsWith(".png") || matcher.group().endsWith(".jpg") || matcher.group().endsWith(".jpeg") || matcher.group().endsWith("gif")) { Document document = textShowPane.getDocument(); try { if (isFirst) { isFirst = false; document.insertString(document.getLength(), inputText, new SimpleAttributeSet()); new RecordsEcho(userName, textShowPane).writeImage(matcher.group(), fileName); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } else { new RecordsEcho(userName, textShowPane).writeImage(matcher.group(), fileName); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else {// 文件的情况 Document document = textShowPane.getDocument(); try { if (isFirst) { isFirst = false; document.insertString(document.getLength(), inputText, new SimpleAttributeSet()); new RecordsEcho(userName, textShowPane).writeFile(matcher.group(), fileName); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } else { new RecordsEcho(userName, textShowPane).writeFile(matcher.group(), fileName); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } if (!isFile) { // 实现发送文本太长自动换行 String str = ""; for (int i = 0; i < textInputPane.getText().length(); i++) { if (i != 0 && i % 15 == 0) str += "n"; str += textInputPane.getText().charAt(i); } Document document = textShowPane.getDocument(); try { document.insertString(document.getLength(), inputText + str + "nn", attributeSet); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 把信息保存到对应的用户本地历史记录txt文件 SaveRecords records = new SaveRecords(userName, inputText + textInputPane.getText() + "nn"); records.saveRecords(); textInputPane.setText(""); } else { new MainFrame(); MainFrame.warnJDialog("不能发送空白信息!"); } } }
其实这个类不单单只是发送文本这么简单,因为后续实现了拖拽发送文件,拖拽后会在输入框自动输入文件路径,实现的代码有关联,就写在这里了。
四、发送图片 、文件和表情包
图片文件的发送主要是通过打开本地浏览发送的
发送文件、图片、表情包:
package function; import java.awt.Color; import java.awt.Desktop; import java.awt.Font; 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; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; /** * 实现打开文件按钮发送图片文件表情包 * * @author 360°顺滑 * * @date 2020/05/01 */ public class FileSend { String userName; String path; String fileName; JTextPane textShowPane; JTextPane textInputPane; public FileSend() {}; public FileSend(String userName, JTextPane textShowPane, JTextPane textInputPane) { this.userName = userName; this.textShowPane = textShowPane; this.textInputPane = textInputPane; } // 弹出选择框并判断发送的是文件还是图片 public void send() { // 点击文件按钮可以打开文件选择框 JFileChooser fileChooser = new JFileChooser(); int result = fileChooser.showOpenDialog(null); if (result == JFileChooser.APPROVE_OPTION) { // 被选择文件路径 path = fileChooser.getSelectedFile().getAbsolutePath(); // 被选择文件名称 fileName = fileChooser.getSelectedFile().getName(); // 选择的是图片 if (path.endsWith(".png") || path.endsWith(".jpg") || path.endsWith(".gif") || path.endsWith(".jpeg")) { sendImage(path, fileName); } else { sendFile(path, fileName); } } } // 发送图片 public void sendImage(String path, String fileName) { // 获取图片 ImageIcon imageIcon = new ImageIcon(path); // 如果图片比整个界面大则调整大小 int width, height; if (imageIcon.getIconWidth() > 950 || imageIcon.getIconHeight() > 400) { width = 600; height = 250; } else { width = imageIcon.getIconWidth(); height = imageIcon.getIconHeight(); } // 设置图片大小 imageIcon.setImage(imageIcon.getImage().getScaledInstance(width, height, 0)); // 获取日期 Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM--dd HH:mm:ss"); String input = dateFormat.format(date) + "n"; // 为图片名称添加按钮,用于打开图片 JButton button = new JButton(fileName); button.setFont(new Font("宋体", Font.PLAIN, 20)); button.setBackground(Color.WHITE); button.setBorderPainted(false); button.setFocusPainted(false); // 获取整个展示面板的内容,方便图片文件的插入 Document document = textShowPane.getDocument(); try { // 插入日期 document.insertString(document.getLength(), input, new SimpleAttributeSet()); // 插入图片 textShowPane.insertIcon(imageIcon); // 换行 document.insertString(document.getLength(), "n", new SimpleAttributeSet()); // 插入按钮,也就是图片名称 textShowPane.insertComponent(button); document.insertString(document.getLength(), "nn", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 为按钮添加点击事件 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub try { // 实现打开文件功能 File file = new File(path); Desktop.getDesktop().open(file); } catch (IOException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } } }); // 输入框重新清空 textInputPane.setText(""); // 保存路径到对应的账号信息里 String saveText = input + path + "nn"; SaveRecords records = new SaveRecords(userName, saveText); records.saveRecords(); } // 发送文件 public void sendFile(String path, String fileName) { // 获取固定文件图标 Icon fileImage = new ImageIcon("src/pictures/document.png"); // 获取日期 Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String input = dateFormat.format(date) + "n"; // 为名称添加按钮 JButton button = new JButton(fileName); button.setFont(new Font("宋体", Font.PLAIN, 20)); button.setBackground(Color.WHITE); button.setBorderPainted(false); button.setFocusPainted(false); // 获取面板内容 Document document = textShowPane.getDocument(); try { document.insertString(document.getLength(), input, new SimpleAttributeSet()); textShowPane.insertIcon(fileImage); textShowPane.insertComponent(button); document.insertString(document.getLength(), "nn", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } //为名称按钮添加监听事件,实现打开功能 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub try { // 实现打开文件功能 File file = new File(path); Desktop.getDesktop().open(file); } catch (IOException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } } }); textInputPane.setText(""); // 保存路径到对应的账号信息里 String saveText = input + path + "nn"; SaveRecords records = new SaveRecords(userName, saveText); records.saveRecords(); } //发送表情包功能 public void sendEmoji(String path) { // 获取图片 ImageIcon imageIcon = new ImageIcon(path); // 获取日期 Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM--dd HH:mm:ss"); String input = dateFormat.format(date) + "n"; // 获取整个展示面板的内容,方便图片文件的插入 Document document = textShowPane.getDocument(); try { // 插入日期 document.insertString(document.getLength(), input, new SimpleAttributeSet()); // 插入图片 textShowPane.insertIcon(imageIcon); document.insertString(document.getLength(), "nn", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 输入框重新清空 textInputPane.setText(""); } }
五、保存历史记录
发送文字、图片、文件和表情包的信息(文字或路径)都要保存到本地,以便历史信息的回显,查找历史信息。
package function; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; /** * 该类实现保存信息记录 * * * @author 360°顺滑 * * @date 2020/05/01 * */ public class SaveRecords { String userName; String input; public SaveRecords(String userName,String input) { this.userName = userName; this.input = input; } public void saveRecords() { String path = "src/txt/" + userName + ".txt"; File file = new File(path); // 文件不存在就创建一个 if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } FileWriter fileWriter = null; BufferedWriter bufferedWriter = null; try { fileWriter = new FileWriter(file,true); bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.write(input); bufferedWriter.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (bufferedWriter != null) { try { bufferedWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (fileWriter != null) { try { fileWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
六、历史记录回显
登录后进入主界面或者进入历史记录界面会看到该账号以前发送过的信息记录
历史记录回显:
package function; import java.awt.Color; import java.awt.Desktop; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; /** * * 该类实现历史记录回显 * * @author 360°顺滑 * * @date 2020/05/02 * */ public class RecordsEcho { private String userName; private JTextPane showPane; public RecordsEcho(String userName, JTextPane showPane) { this.userName = userName; this.showPane = showPane; } // 将用户的信息记录回显到展示面板 public void read() { // 对应账号的信息记录文本 File file = new File("src/txt/" + userName + ".txt"); // 文件不存在就创建一个 if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } FileReader fileReader = null; BufferedReader bufferedReader = null; try { fileReader = new FileReader(file); bufferedReader = new BufferedReader(fileReader); // 正则表达式 Pattern pattern = Pattern.compile(".+[\.].+"); String str = null; while ((str = bufferedReader.readLine()) != null) { Matcher matcher = pattern.matcher(str); // 如果是文件或图片 if (matcher.find()) { // 获得文件名 int index = str.lastIndexOf("\"); String fileName = str.substring(index + 1); // 图片的情况 if (str.endsWith(".png") || str.endsWith(".jpg") || str.endsWith(".jpeg") || str.endsWith("gif")) { Pattern pattern1 = Pattern.compile("[emoji_].+[\.].+"); Matcher matcher1 = pattern1.matcher(fileName); // 如果是表情包 if (matcher1.find()) { writeEmoji(str); } else { writeImage(str, fileName); } } else { // 文件的情况 writeFile(str, fileName); } } else { // 如果是文本则直接写入 writeText(str); } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { bufferedReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { fileReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // 把文本显示在展示面板 public void writeText(String str) { String s = ""; for (int i = 0; i < str.length(); i++) { if (i != 0 && i % 30 == 0) s += "n"; s += str.charAt(i); } Document document = showPane.getDocument(); try { document.insertString(document.getLength(), s + "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void writeEmoji(String path) { // 获取图片 ImageIcon imageIcon = new ImageIcon(path); // 获取整个展示面板的内容,方便图片文件的插入 Document document = showPane.getDocument(); try { // 插入图片 showPane.insertIcon(imageIcon); // 换行 document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 把图片显示在展示面板 public void writeImage(String path, String fileName) { // 获取图片 ImageIcon imageIcon = new ImageIcon(path); // 如果图片比整个界面大则调整大小 int width, height; if (imageIcon.getIconWidth() > 950 || imageIcon.getIconHeight() > 400) { width = 600; height = 250; } else { width = imageIcon.getIconWidth(); height = imageIcon.getIconHeight(); } // 设置图片大小 imageIcon.setImage(imageIcon.getImage().getScaledInstance(width, height, 0)); // 为图片名称添加按钮,用于打开图片 JButton button = new JButton(fileName); button.setFont(new Font("宋体", Font.PLAIN, 20)); button.setBackground(Color.WHITE); button.setBorderPainted(false); button.setFocusPainted(false); // 获取整个展示面板的内容,方便图片文件的插入 Document document = showPane.getDocument(); try { // 插入图片 showPane.insertIcon(imageIcon); // 换行 document.insertString(document.getLength(), "n", new SimpleAttributeSet()); // 插入按钮,也就是图片名称 showPane.insertComponent(button); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 为按钮添加点击事件 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub try { // 实现打开文件功能 File file = new File(path); Desktop.getDesktop().open(file); } catch (IOException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } } }); } // 把文件显示在展示面板中 public void writeFile(String path, String fileName) { // 获取固定文件图标 Icon fileImage = new ImageIcon("src/pictures/document.png"); // 为名称添加按钮 JButton button = new JButton(fileName); button.setFont(new Font("宋体", Font.PLAIN, 20)); button.setBackground(Color.WHITE); button.setBorderPainted(false); button.setFocusPainted(false); // 获取面板内容 Document document = showPane.getDocument(); try { showPane.insertIcon(fileImage); showPane.insertComponent(button); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub try { // 实现打开文件功能 File file = new File(path); Desktop.getDesktop().open(file); } catch (IOException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } } }); } }
七、发送表情包
通过主界面表情包按钮可以打开表情包窗口
点击表情包,可以发送表情包
表情包界面
package frame; import java.awt.Color; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; import function.SaveRecords; /** * 该类实现表情包窗体 * * @author 360°顺滑 * * @date 2020/05/03 * */ public class EmojiFrame { //展示面板 private JTextPane showPane; //表情包按钮 private JButton[] buttons = new JButton[55]; //表情包图片 private ImageIcon[] icons = new ImageIcon[55]; //表情包对话框 private JDialog emojiJDialog; //账号 private String userName; public EmojiFrame(JTextPane showPane,String userName) { this.showPane = showPane; this.userName = userName; } //表情包窗体 public void init() { //用对话框来装表情包 emojiJDialog = new JDialog(); emojiJDialog.setTitle("表情包"); emojiJDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); emojiJDialog.setLayout(new GridLayout(6, 9)); emojiJDialog.setBounds(490, 263, 500, 400); emojiJDialog.setBackground(Color.WHITE); ImageIcon image = new ImageIcon("src/pictures/emoji.png"); emojiJDialog.setIconImage(image.getImage()); //表情包用按钮来实现,主要是可以添加监听事件,点击后可以实现发送 for (int i = 1; i <= 54; i++) { String path = "src/pictures/emoji_" + i + ".png"; icons[i] = new ImageIcon(path); buttons[i] = new JButton(icons[i]); buttons[i].setBackground(Color.WHITE); buttons[i].setBorder(null); buttons[i].setBorderPainted(false); buttons[i].setSize(20, 20); buttons[i].setFocusPainted(false); emojiJDialog.add(buttons[i]); } emojiJDialog.setVisible(true); //添加监听事件 addListen(); } //监听事件 public void addListen() { //为每一个按钮添加监听事件 for(int i=1;i<=54;i++) { String path = "src/pictures/emoji_" + i + ".png"; buttons[i].addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub //获取图片 ImageIcon imageIcon = new ImageIcon(path); // 获取日期 Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String input = dateFormat.format(date) + "n"; Document document = showPane.getDocument(); try { //写入日期 document.insertString(document.getLength(), input, new SimpleAttributeSet()); //插入图片 showPane.insertIcon(imageIcon); //换行 document.insertString(document.getLength(), "nn", new SimpleAttributeSet()); } catch (BadLocationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // 保存路径到对应的账号信息里,因为用的是绝对路径,所以要根据实际来修改 String saveText = input + "D:\eclipse jee\FileTransfer\" + path + "nn"; SaveRecords records = new SaveRecords(userName, saveText); records.saveRecords(); emojiJDialog.setVisible(false); } }); } } }
发送表情包
//该方法写在FileSend类 //发送表情包功能 public void sendEmoji(String path) { // 获取图片 ImageIcon imageIcon = new ImageIcon(path); // 获取日期 Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM--dd HH:mm:ss"); String input = dateFormat.format(date) + "n"; // 获取整个展示面板的内容,方便图片文件的插入 Document document = textShowPane.getDocument(); try { // 插入日期 document.insertString(document.getLength(), input, new SimpleAttributeSet()); // 插入图片 textShowPane.insertIcon(imageIcon); document.insertString(document.getLength(), "nn", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 输入框重新清空 textInputPane.setText(""); }
八、查看历史
记录通过主界面的历史记录按钮可以打开历史记录窗口
历史记录界面
package frame; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTextPane; import function.ClearRecords; import function.FindRecords; import function.RecordsEcho; /** * 该类实现历史记录窗口 * * @author 360°顺滑 * * @date 2020/05/02 * */ public class HistoricRecordsFrame { private String userName; private JTextPane textShowPane; private JFrame historicRecordsFrame; private JButton findRecordsButton; private JButton clearRecordsButton; private JTextField searchTextField; private JTextPane recordsShowPane; private Box clearBox; public HistoricRecordsFrame(String userName,JTextPane textShowPane) { this.userName = userName; this.textShowPane = textShowPane; } public void init() { // 搜索文本框 searchTextField = new JTextField(); searchTextField.setFont(new Font("宋体", 0, 25)); // 查找记录按钮 findRecordsButton = new JButton("查找记录"); findRecordsButton.setFont(new Font("行楷", Font.PLAIN, 20)); findRecordsButton.setBackground(Color.WHITE); findRecordsButton.setBorderPainted(false); findRecordsButton.setFocusPainted(false); // 将搜索文本框和搜索按钮放入Box容器 Box searchBox = Box.createHorizontalBox(); searchBox.setPreferredSize(new Dimension(900, 47)); searchBox.setBackground(Color.white); searchBox.add(Box.createHorizontalStrut(35)); searchBox.add(searchTextField); searchBox.add(Box.createHorizontalStrut(20)); searchBox.add(findRecordsButton); searchBox.add(Box.createHorizontalStrut(25)); // 显示文本窗格 recordsShowPane = new JTextPane(); recordsShowPane.setSize(900, 600); recordsShowPane.setBackground(Color.WHITE); recordsShowPane.setEditable(false); recordsShowPane.setBorder(null); recordsShowPane.setFont(new Font("宋体", 0, 25)); // 显示文本窗格添加滚动条 JScrollPane scrollShowPane = new JScrollPane(recordsShowPane); // 清空记录按钮 clearRecordsButton = new JButton("清空记录"); clearRecordsButton.setFont(new Font("行楷", Font.PLAIN, 20)); clearRecordsButton.setBackground(Color.WHITE); clearRecordsButton.setBorderPainted(false); clearRecordsButton.setFocusable(false); // Box容器并添加清空记录按钮 clearBox = Box.createHorizontalBox(); clearBox.setPreferredSize(new Dimension(1000, 60)); clearBox.setBackground(Color.white); clearBox.add(Box.createVerticalStrut(5)); clearBox.add(clearRecordsButton); clearBox.add(Box.createVerticalStrut(5)); // 设置主窗体 historicRecordsFrame = new JFrame("历史记录"); historicRecordsFrame.setSize(900, 700); historicRecordsFrame.setLocationRelativeTo(null); historicRecordsFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // 改变窗体logo ImageIcon image = new ImageIcon("src/pictures/historicRecordsLogo.png"); historicRecordsFrame.setIconImage(image.getImage()); historicRecordsFrame.setLayout(new BorderLayout()); // 添加窗体以上两个主要容器 historicRecordsFrame.add(searchBox, BorderLayout.NORTH); historicRecordsFrame.add(scrollShowPane, BorderLayout.CENTER); historicRecordsFrame.add(clearBox, BorderLayout.SOUTH); historicRecordsFrame.setVisible(true); addListen(); RecordsEcho recordsEcho = new RecordsEcho(userName, recordsShowPane); recordsEcho.read(); } //添加按钮监听事件 public void addListen() { //清空历史记录监听事件 clearRecordsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub new ClearRecords(userName,textShowPane,recordsShowPane).clear(); } }); //查找记录监听事件 findRecordsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub FindRecords findRecords = new FindRecords(recordsShowPane,userName,searchTextField.getText()); findRecords.find(); } }); } }
历史记录回显的代码上面已经给了,这里就不贴了。
还有一点功能值得一提,就是点击历史记录中的图片文件可以直接打开!
九、查找历史记录
输入关键字点击查找记录按钮可以实现历史记录的查找,找不到则显示“无相关记录!”
查找历史记录
package function; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; /** * 该类实现查找历史记录 * * 这段代码说实话,写得有点糟,本来后期要优化,但是有点难搞,就这样吧,将就着看! * * * @author 360°顺滑 * * @date 2020/05/02 */ public class FindRecords { private JTextPane recordsShowPane; private String userName; private String keywords; public FindRecords(JTextPane recordsShowPane, String userName, String keywords) { this.recordsShowPane = recordsShowPane; this.userName = userName; this.keywords = keywords; } // 该方法包括查找文本、图片、文件,因为要交叉使用,所以写在一起了 public void find() { // 如果查找的不为空 if (!(keywords.equals(""))) { // 查找相关账号历史记录 File file = new File("src/txt/" + userName + ".txt"); FileReader fileReader = null; BufferedReader bufferedReader = null; try { fileReader = new FileReader(file); bufferedReader = new BufferedReader(fileReader); String str = ""; String str1 = null; // 先把所有文本找到 while ((str1 = bufferedReader.readLine()) != null) { if (str1.equals("")) str += "n"; else str = str + str1 + "n"; } // 正则表达式匹配要找的内容 Pattern pattern = Pattern.compile(".+n.*" + keywords + ".*nn"); Matcher matcher = pattern.matcher(str); // 标记有没有找到 boolean isExist = false; // 标记是否第一次找到 boolean oneFind = false; // 如果找到了 while (matcher.find()) { isExist = true; // 正则表达式匹配是否为文件图片路径 Pattern pattern1 = Pattern.compile(".+[\.].+"); Matcher matcher1 = pattern1.matcher(matcher.group()); // 如果是文件或者图片 if (matcher1.find()) { // 截取日期 int index3 = matcher.group().indexOf("n"); String date = matcher.group().substring(0, index3); // 获得文件名 int index1 = matcher.group().lastIndexOf("\"); int index2 = matcher.group().lastIndexOf("nn"); String fileName = matcher.group().substring(index1 + 1, index2); // 图片的情况 if (fileName.endsWith(".png") || fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || fileName.endsWith("gif")) { Pattern pattern2 = Pattern.compile("[emoji_].+[\.].+"); Matcher matcher2 = pattern2.matcher(fileName); // 如果是表情包则不需要添加名称 if (matcher2.find()) { if (!oneFind) { // 写入日期 recordsShowPane.setText(date + "n"); // 插入表情包和名称 RecordsEcho echo = new RecordsEcho(fileName, recordsShowPane); echo.writeEmoji(matcher1.group()); Document document = recordsShowPane.getDocument(); try { document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } oneFind = true; } else { // 不是第一次就直接写入 Document document = recordsShowPane.getDocument(); try { document.insertString(document.getLength(), date + "n", new SimpleAttributeSet()); RecordsEcho echo = new RecordsEcho(fileName, recordsShowPane); echo.writeEmoji(matcher1.group()); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // 不是表情包的图片 else { // 如果是第一次找到,要先清空再写入 if (!oneFind) { // 写入日期 recordsShowPane.setText(date + "n"); // 插入图片和名称 RecordsEcho echo = new RecordsEcho(fileName, recordsShowPane); echo.writeImage(matcher1.group(), fileName); // 换行 Document document = recordsShowPane.getDocument(); try { document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 标记不是第一次了 oneFind = true; } else { // 不是第一次找到就直接写入 Document document = recordsShowPane.getDocument(); try { document.insertString(document.getLength(), date + "n", new SimpleAttributeSet()); RecordsEcho echo = new RecordsEcho(fileName, recordsShowPane); echo.writeImage(matcher1.group(), fileName); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } else { // 文件的情况 // 第一次找到 if (!oneFind) { // 清空并写入日期 recordsShowPane.setText(date + "n"); // 插入文件图片以及名称 RecordsEcho echo = new RecordsEcho(fileName, recordsShowPane); echo.writeFile(matcher1.group(), fileName); // 换行 Document document = recordsShowPane.getDocument(); try { document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } oneFind = true; } else { // 不是第一次找到 Document document = recordsShowPane.getDocument(); try { document.insertString(document.getLength(), date + "n", new SimpleAttributeSet()); RecordsEcho echo = new RecordsEcho(fileName, recordsShowPane); echo.writeFile(matcher1.group(), fileName); document.insertString(document.getLength(), "n", new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } else { // 查找的是文本 String s = ""; for(int i = 0; i < matcher.group().length(); i++) { //因为查找到的字符串包含日期,所以要从20开始 if(i>20 && (i-20) % 30 == 0) s += "n"; s += matcher.group().charAt(i); } if (!oneFind) { recordsShowPane.setText(s); oneFind = true; } else { Document document = recordsShowPane.getDocument(); try { document.insertString(document.getLength(), s, new SimpleAttributeSet()); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } // 找不到的情况 if (!isExist) recordsShowPane.setText("nnn 无相关记录!"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { bufferedReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { fileReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } else { // 查找为空的情况 recordsShowPane.setText("nnn 无相关记录!"); } } }
十、清空历史记
录点击清空历史记录,所有信息都会被删除,包括本地信息。
清空历史信息
package function; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import javax.swing.JTextPane; /** * 该类实现清空历史记录的功能 * * @author 360°顺滑 * * @date 2020/05/03 * */ public class ClearRecords { private JTextPane textShowPane; private JTextPane recordsShowPane; private String userName; public ClearRecords(String userName,JTextPane textShowPane,JTextPane recordsShowPane) { this.userName = userName; this.textShowPane = textShowPane; this.recordsShowPane = recordsShowPane; } //把展示面板、输入面板、本地信息全部清空 public void clear() { textShowPane.setText(""); recordsShowPane.setText(""); String path = "src/txt/" + userName + ".txt"; File file = new File(path); FileWriter fileWriter = null; BufferedWriter bufferedWriter = null; try { fileWriter = new FileWriter(file); bufferedWriter = new BufferedWriter(fileWriter); bufferedWriter.write("");; bufferedWriter.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (bufferedWriter != null) { try { bufferedWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (fileWriter != null) { try { fileWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
十一、拖拽输入文本、图片和文件
通过拖拽将文本信息(复制粘贴)、图片文件路径输入到输入框中,发送后可以显示图片文件。同时,拖拽可以同时拖多个文件。
拖拽输入文本文件
package function; import java.awt.datatransfer.DataFlavor; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.io.File; import java.util.List; import javax.swing.JTextPane; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; /** * 该类实现拖拽文件,复制粘贴功能 * * 由于该功能第一次实现,所以部分代码是搬砖过来的 * * @author 360°顺滑 * * @date 2020/05/03 */ public class DropTargetFile implements DropTargetListener { /** 用于显示拖拽数据的面板 */ private JTextPane inputPane; public DropTargetFile(JTextPane inputPane) { this.inputPane = inputPane; } public void dragEnter(DropTargetDragEvent dtde) { } public void dragOver(DropTargetDragEvent dtde) { } public void dragExit(DropTargetEvent dte) { } public void dropActionChanged(DropTargetDragEvent dtde) { } public void drop(DropTargetDropEvent dtde) { boolean isAccept = false; try { /* * 判断拖拽目标是否支持文件列表数据(即拖拽的是否是文件或文件夹, 支持同时拖拽多个) */ if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { // 接收拖拽目标数据 dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); isAccept = true; // 以文件集合的形式获取数据 @SuppressWarnings("unchecked") List<File> files = (List<File>) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); // 把文件路径输出到文本区域 if (files != null && files.size() > 0) { StringBuilder filePaths = new StringBuilder(); for (File file : files) { filePaths.append(file.getAbsolutePath() + "n"); } Document document = inputPane.getDocument(); document.insertString(document.getLength(), filePaths.toString(), new SimpleAttributeSet()); } } } catch (Exception e) { e.printStackTrace(); } // 如果此次拖拽的数据是被接受的, 则必须设置拖拽完成(否则可能会看到拖拽目标返回原位置, 造成视觉上以为是不支持拖拽的错误效果) if (isAccept) { dtde.dropComplete(true); } } }