实验目标

本实验为此系列的最后一次实验,目标在实验 (6) 的基础上增加多线程功能,使得档案系统能允许多个用户同时进行登录操作,同时实现线程之间必要的同步互斥功能。

模块解析

此次实验模块与实验 (6) 基本相同,区别在于对 Server 类进行了修改,使其继承于 Thread 类,利用while(true) 循环和 accept() 方法的结合不断接收Socket对象,不断建立新线程,实现多个用户的同时登录。在登录、增添删除修改用户、上传下载文件的操作上利用 synchronized 关键字实现线程间的操作加锁,避免同时操作产生错误。

推荐一个教学视频:https://www.bilibili.com/video/av54953654,讲解了Java多线程编程的知识。

源代码

test

·ClientTest

3个测试代码范例。

package test;import java.net.*;
import java.io.*;public class ClientTest {// 此类用于与ServerTest类测试连接public static void main(String[] args) {try {// 1.创建客户端对象Socket, 构造方法绑定服务器的IP地址和端口号Socket socket = new Socket("127.0.0.1", 8888);// 2.建立网络字节流InputStream与OutputStream的对象InputStream is = socket.getInputStream();OutputStream os = socket.getOutputStream();// 3.向服务端发送测试信息BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));bw.write("测试客户端和服务器通信,服务器接收到消息返回到客户端\n");bw.flush();// 4.读取服务器返回的消息BufferedReader br = new BufferedReader(new InputStreamReader(is));String mess = br.readLine();System.out.println("服务器:" + mess);// 5.释放资源socket.close();} catch (IOException e) {e.printStackTrace();}}}

·ServerTest

package test;import java.io.*;
import java.net.*;public class ServerTest {// 此类用于与ClientTest类测试连接@SuppressWarnings("static-access")public static void main(String[] args) {try {// 1.创建服务端对象serverSocket和系统指定端口号ServerSocket serversocket = new ServerSocket(8888);System.out.println("启动服务器....");// 2.使用ServerSocket对象中的方法accept, 获取收到请求的客户端对象SocketSocket socket = serversocket.accept();System.out.println("客户端:" + socket.getInetAddress().getLocalHost() + "已连接到服务器");// 3.使用网络字节输入流读取客户端发送来的消息BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));String mess = br.readLine();System.out.println("客户端:" + mess);// 4.使用网络字节输出流向客户端回写信息BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bw.write(mess + "\n");bw.flush();// 5.释放资源serversocket.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}

·SQLtest

package test;import java.sql.*;public class SQLtest { // 该类用于测试数据库连接public static void main(String[] args) {Connection connection;Statement statement;ResultSet resultSet;// 加载数据库驱动类String driverName = "com.mysql.cj.jdbc.Driver"; // 新版本写法cj.// 声明数据库的URLString url = "jdbc:mysql://localhost:3306/document?useSSL=false&serverTimezone=UTC"; // 新版本显式关闭useSSL,添加时区// 数据库用户String user = "root";String password = "123456";try {// 1. 加载驱动Class.forName(driverName);// 2. 建立数据库连接connection = DriverManager.getConnection(url, user, password);// 3. 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 4. 执行SQL语句String sql = "select * from user_info ";// 5. 处理对象resultSet = statement.executeQuery(sql);while (resultSet.next()) {String username = resultSet.getString("UserName");String pwd = resultSet.getString("Password");String role = resultSet.getString("Role");System.out.println(username + ";" + pwd + ";" + role);}// 6. 释放资源resultSet.close();statement.close();connection.close();} catch (ClassNotFoundException e) {System.out.println("数据驱动错误");} catch (SQLException e) {System.out.println("数据库错误");}}}

common

·DataProcessing

package common;import java.sql.*;
import java.util.Enumeration;
import java.util.Hashtable;public class DataProcessing {private static boolean connectedToDatabase = false;private static Connection connection;private static Statement statement;private static ResultSet resultSet;public static void connectToDatabase(String driverName, String url, String user, String password)throws SQLException, ClassNotFoundException {// 加载驱动Class.forName(driverName);// 建立数据库连接connection = DriverManager.getConnection(url, user, password);connectedToDatabase = true;}public static void disconnectFromDatabase() throws SQLException {if (connectedToDatabase) {// 释放资源resultSet.close();statement.close();connection.close();connectedToDatabase = false;}}public static Doc searchDoc(String ID) throws SQLException {Doc doc = null;if (!connectedToDatabase)throw new SQLException("数据库未连接!");// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "select * from doc_info where FileID='" + ID + "'"; // 获取FileID列中值为ID的数据,变量前后用+和'"、"'连接// 处理对象resultSet = statement.executeQuery(sql);// 获取数据库信息if (resultSet.next()) {String FileID = resultSet.getString("FileID");String Creator = resultSet.getString("Creator");Timestamp timestamp = Timestamp.valueOf(resultSet.getString("Timestamp")); // string转TimestampString Description = resultSet.getString("Description");String FileName = resultSet.getString("FileName");doc = new Doc(FileID, Creator, timestamp, Description, FileName);}return doc;}public static boolean insertDoc(String ID, String creator, Timestamp timestamp, String description, String filename)throws SQLException {if (!connectedToDatabase)throw new SQLException("数据库未连接!");// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "INSERT INTO doc_info VALUES('" + ID + "','" + creator + "','" + timestamp + "','" + description+ "','" + filename + "')";// 更新列表statement.executeUpdate(sql);return true;}public static Enumeration<Doc> getAllDocs() throws SQLException {if (!connectedToDatabase)throw new SQLException("数据库未连接!");// 建立哈希表Hashtable<String, Doc> docs = new Hashtable<String, Doc>();// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "select * from doc_info "; // 获取doc_info所有值// 处理对象resultSet = statement.executeQuery(sql);// 获取数据库信息while (resultSet.next()) {// 遍历存放String FileID = resultSet.getString("FileID");String Creator = resultSet.getString("Creator");Timestamp timestamp = Timestamp.valueOf(resultSet.getString("Timestamp")); // string转TimestampString Description = resultSet.getString("Description");String FileName = resultSet.getString("FileName");docs.put(FileID, new Doc(FileID, Creator, timestamp, Description, FileName));}// 返回枚举容器Enumeration<Doc> e = docs.elements();return e;}public static User searchUser(String name) throws SQLException {User user = null;if (!connectedToDatabase)throw new SQLException("未连接到数据库!");// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "select * from user_info where UserName='" + name + "'"; // 获取UserName列中值为name的数据,变量前后用+和'"、"'连接// 处理对象resultSet = statement.executeQuery(sql);// 获取数据库信息if (resultSet.next()) {String UserName = resultSet.getString("UserName");String Password = resultSet.getString("Password");String Role = resultSet.getString("Role");user = new User(UserName, Password, Role);}return user;}public static User searchUser(String name, String password) throws SQLException {User user = null;if (!connectedToDatabase)throw new SQLException("未连接到数据库!");// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "select * from user_info where UserName='" + name + "'"; // 获取UserName列中值为name的数据,变量前后用+和'"、"'连接// 处理对象resultSet = statement.executeQuery(sql);// 获取数据库信息if (resultSet.next()) {String UserName = resultSet.getString("UserName");String Password = resultSet.getString("Password");String Role = resultSet.getString("Role");user = new User(UserName, Password, Role);if (Password.equals(password)) {return user;} else {return null;}}return null;}public static Enumeration<User> getAllUser() throws SQLException {if (!connectedToDatabase)throw new SQLException("未连接到数据库!");// 建立哈希表Hashtable<String, User> users = new Hashtable<String, User>();// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "select * from user_info "; // 获取user_info所有值// 处理对象resultSet = statement.executeQuery(sql);// 获取数据库信息while (resultSet.next()) {// 遍历存放String UserName = resultSet.getString("UserName");String Password = resultSet.getString("Password");String Role = resultSet.getString("Role");users.put(UserName, new User(UserName, Password, Role));}// 返回枚举容器Enumeration<User> e = users.elements();return e;}public static boolean updateUser(String name, String password, String role) throws SQLException {if (!connectedToDatabase)throw new SQLException("未连接到数据库!");// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "UPDATE user_info SET Password='" + password + "',Role='" + role + "'WHERE UserName='" + name+ "'"; // 更改user_info相关数据// 更新列表statement.executeUpdate(sql);return true;}public static boolean insertUser(String name, String password, String role) throws SQLException {if (!connectedToDatabase)throw new SQLException("未连接到数据库!");// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "INSERT INTO user_info VALUES('" + name + "','" + password + "','" + role + "')";// 更新列表statement.executeUpdate(sql);return true;}public static boolean deleteUser(String name) throws SQLException {if (!connectedToDatabase)throw new SQLException("未连接到数据库!");// 创建语句对象statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);// 执行SQL语句String sql = "DELETE FROM user_info WHERE UserName='" + name + "'";// 更新列表statement.executeUpdate(sql);return true;}
}

·SQLconnection

package common;import java.sql.SQLException;public class SQLconnection {// 加载数据库驱动类static String DriverName = "com.mysql.cj.jdbc.Driver"; // 新版本写法cj.// 声明数据库的URLstatic String Url = "jdbc:mysql://localhost:3306/document?useSSL=false&serverTimezone=UTC"; // 新版本显式关闭useSSL,添加时区// 数据库用户static String User = "root";static String Password = "123456";// 连接数据库函数public static void Connect() throws ClassNotFoundException, SQLException {DataProcessing.connectToDatabase(DriverName, Url, User, Password);}// 断开数据库函数public static void Disconnect() throws SQLException {DataProcessing.disconnectFromDatabase();}}

·Doc

package common;import java.sql.Timestamp;public class Doc {private String ID;private String creator;private Timestamp timestamp;private String description;private String filename;public Doc(String ID, String creator, Timestamp timestamp, String description, String filename) {this.setID(ID);this.setCreator(creator);this.setTimestamp(timestamp);this.setDescription(description);this.setFilename(filename);}public String getID() {return ID;}public void setID(String ID) {this.ID = ID;}public String getCreator() {return creator;}public void setCreator(String creator) {this.creator = creator;}public Timestamp getTimestamp() {return timestamp;}public void setTimestamp(Timestamp timestamp) {this.timestamp = timestamp;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getFilename() {return filename;}public void setFilename(String filename) {this.filename = filename;}public String toString() {return "ID:" + this.ID + " Creator:" + this.creator + " Time:" + this.timestamp + " Filename:" + this.filename+ " Description:" + this.description;}}

·User

package common;import java.io.*;
import java.sql.*;
import javax.swing.JOptionPane;public class User {private String name;private String password;private String role;String uploadpath = "f:\\uploadfile\\";String downloadpath = "f:\\downloadfile\\";User(String name, String password, String role) {this.setName(name);this.setPassword(password);this.setRole(role);}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getRole() {return role;}public void setRole(String role) {this.role = role;}public String toString() {return "Name: " + this.name + " Password: " + this.password + " Role: " + this.role;}public boolean downloadFile(String fileID) {Doc doc;try {// 获取哈希表信息doc = DataProcessing.searchDoc(fileID);// 输入文件对象File input_file = new File(uploadpath + doc.getFilename());// 输入过滤器流,建立在文件流上BufferedInputStream input = new BufferedInputStream(new FileInputStream(input_file));// 输出文件对象File output_file = new File(downloadpath + doc.getFilename());// 创建文件output_file.createNewFile();// 输出过滤器流,建立在文件流上BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(output_file));// 用字节数组存取数据byte[] bytes = new byte[1024];// 文件写入操作int length = 0;while ((length = input.read(bytes)) != -1) {output.write(bytes, 0, length);}// 关闭流input.close();output.close();return true;} catch (SQLException | IOException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}return false;}public boolean uploadFile(String fileID, String filepath, String filedescription) {// 输入文件对象File input_file = new File(filepath);// 获取文件名String filename = input_file.getName();// 获取当前时间Timestamp timestamp = new Timestamp(System.currentTimeMillis());try {if (DataProcessing.insertDoc(fileID, this.getName(), timestamp, filedescription, filename)) {// 输入过滤器流,建立在文件流上BufferedInputStream input = new BufferedInputStream(new FileInputStream(input_file));// 输出文件对象File output_file = new File(uploadpath + input_file.getName());// 创建文件output_file.createNewFile();// 输出过滤器流,建立在文件流上BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(output_file));// 用字节数组存取数据byte[] bytes = new byte[1024];// 文件写入操作int length = 0;while ((length = input.read(bytes)) != -1) {output.write(bytes, 0, length);}// 关闭流input.close();output.close();return true;} elsereturn false;} catch (SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());} catch (IOException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}return false;}// 修改密码public boolean changeSelfInfo(String password) {try {if (DataProcessing.updateUser(name, password, role)) {this.password = password;return true;} elsereturn false;} catch (SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}return false;}}

·Administrator

package common;public class Administrator extends User {public Administrator(String name, String password, String role) {super(name, password, role);}}

·Browser

package common;public class Browser extends User {public Browser(String name, String password, String role) {super(name, password, role);}}

·Operator

package common;public class Operator extends User {public Operator(String name, String password, String role) {super(name, password, role);}}

·StringUtil

package common;public class StringUtil {// 判断字符串是否为空// 去括号trim()public static boolean isEmpty(String str) {if (str == null || "".equals(str.trim())) {return true;} else {return false;}}// 判断字符串非空public static boolean isNotEmpty(String str) {if (str != null && !"".equals(str.trim())) {return true;} else {return false;}}}

CS

·Clinet

package CS;import java.io.*;
import java.net.*;public class Client {// 用户Socket对象private static Socket client;// 网络字符输入输出流IOprivate static ObjectInputStream input;private static ObjectOutputStream output;// 从服务端接收的信息private static String messageFromServer;// 连接服务器public static void ConnectToServer() throws UnknownHostException, IOException {System.out.println("\n正在尝试连接服务器...\n");// Socket构造函数参数为IP地址与端口号client = new Socket("127.0.0.1", 8888);System.out.println("已连接至:" + client.getInetAddress().getHostName());}// 构造IO流public static void GetStreams() throws IOException {output = new ObjectOutputStream(client.getOutputStream());output.flush();input = new ObjectInputStream(client.getInputStream());System.out.println("IO构造完成\n");}// 断开连接public static void CloseConnection() throws IOException {output.close();input.close();client.close();}// 用户向服务器发送消息public static void SendMessage(String message) throws IOException {// 写入输出流output.writeObject(message);output.flush();}// 接收服务器回传的消息public static void ReceiveMessage() throws ClassNotFoundException, IOException {// 读入输入流messageFromServer = (String) input.readObject();System.out.println("SERVER>>> " + messageFromServer);}}

·Server

package CS;import java.io.*;
import java.net.*;
import java.util.ArrayList;public class Server extends Thread { // 将Server继承于Thread类,实现多线程// 网络字节输出流(输出至不同用户)private static ArrayList<ObjectOutputStream> outputToClients;// 网络字节输入流private ObjectInputStream input;// 服务器的ServerSocket对象private static ServerSocket server;// 接收连接用户的Socket对象connectionprivate Socket connection;// 线程编号private static int counter = 0;// 线程名称private String name;// 构造方法public Server(Socket connection, String name) {this.connection = connection;this.name = name;try {// 构建input流input = new ObjectInputStream(connection.getInputStream());} catch (IOException e) {e.printStackTrace();}}// 运行态方法public void run() {try {// 接收用户的信息String messageFromClient;// 构建output流ObjectOutputStream output = new ObjectOutputStream(connection.getOutputStream());outputToClients.add(output);System.out.println("IO构造完成\n");do {// 读取用户信息messageFromClient = (String) input.readObject();System.out.println(this.name + ":" + messageFromClient);// 回传消息output.writeObject(messageFromClient);output.flush();} while (!messageFromClient.equals("登出")); // 只要未登出反复循环监听// 回传登出消息output.writeObject(messageFromClient);output.flush();} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {try {// 创建服务器对象server = new ServerSocket(8888);outputToClients = new ArrayList<ObjectOutputStream>();// 反复循环实现不断接收用户的效果while (true) {// 反复等待Socket connection = server.accept();System.out.println("\n等待连接...\n");// 编号增加counter++;System.out.println("Thread " + counter + ":已连接" + connection.getInetAddress().getHostName());// 新增线程Thread t = new Server(connection, "Thread " + counter);// 使线程进入就绪态,一旦有CPU资源,将直接进入run()方法t.start();}} catch (Exception e) {e.printStackTrace();}}
}

Server 类要继承于 Thread 类,同时使用 while 循环反复接收用户。

frame

·LoginFrame

package frame;import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.sql.SQLException;
import javax.swing.*;
import javax.swing.border.*;
import CS.Client;
import common.*;@SuppressWarnings("serial")
public class LoginFrame extends JFrame {private JPanel contentPane;private JLabel Username_Label;private JLabel Password_Label;private JTextField Username_Txt;private JPasswordField Password_Txt;private JButton Confirm_Button;private JButton Cancel_Button;/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {LoginFrame frame = new LoginFrame();frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/*** Create the frame.*/public LoginFrame() {// 框架setTitle("\u7CFB\u7EDF\u767B\u5F55");setResizable(false);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 565, 372);// 中间容器contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));setContentPane(contentPane);// 用户名标签Username_Label = new JLabel("\u7528\u6237\u540D\uFF1A");Username_Label.setBounds(128, 89, 80, 40);Username_Label.setFont(new Font("黑体", Font.PLAIN, 20));// 密码标签Password_Label = new JLabel("\u5BC6\u7801\uFF1A");Password_Label.setBounds(148, 142, 60, 37);Password_Label.setFont(new Font("黑体", Font.PLAIN, 20));// 用户名文本域Username_Txt = new JTextField();Username_Txt.setBounds(222, 99, 176, 24);Username_Txt.setColumns(10);// 密码文本域Password_Txt = new JPasswordField();Password_Txt.setBounds(222, 150, 176, 24);// 确认按钮Confirm_Button = new JButton("\u786E\u5B9A");Confirm_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 登录事件LoginInActionPerformed(e);}});Confirm_Button.setFont(new Font("黑体", Font.PLAIN, 20));Confirm_Button.setBounds(173, 216, 85, 27);// 取消按钮Cancel_Button = new JButton("\u53D6\u6D88");Cancel_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 取消事件ResetValueActionPerformed(e);}});Cancel_Button.setFont(new Font("黑体", Font.PLAIN, 20));Cancel_Button.setBounds(313, 216, 85, 27);// 设置布局与添加部件// 绝对布局contentPane.setLayout(null);contentPane.add(Username_Label);contentPane.add(Password_Label);contentPane.add(Username_Txt);contentPane.add(Password_Txt);contentPane.add(Confirm_Button);contentPane.add(Cancel_Button);// 连接数据库// 应在构造函数中连接,不应在主函数连接,否则登出后无法连接try {SQLconnection.Connect();} catch (ClassNotFoundException | SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}}// 登录private synchronized void LoginInActionPerformed(ActionEvent evt) {String username = this.Username_Txt.getText();String password = new String(this.Password_Txt.getPassword()); // 获取输入内容if (StringUtil.isEmpty(username)) {JOptionPane.showMessageDialog(null, "未输入用户名!"); // 显示对话框return;}if (StringUtil.isEmpty(password)) {JOptionPane.showMessageDialog(null, "未输入密码!"); // 显示对话框return;}try {if (DataProcessing.searchUser(username, password) == null) {JOptionPane.showMessageDialog(null, "用户名与密码不匹配!"); // 显示对话框return;} else {// 连接服务器,发送登录消息Client.ConnectToServer();Client.GetStreams();Client.SendMessage(username + "登录");Client.ReceiveMessage();// 导入用户User user = DataProcessing.searchUser(username, password);// 令当前界面消失this.dispose();// 跳转至主界面,新建对象并传入用户参数MainFrame mainframe = new MainFrame(user);mainframe.setVisible(true);}} catch (HeadlessException | SQLException | IOException | ClassNotFoundException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());return;}}// 重置文本域private void ResetValueActionPerformed(ActionEvent evt) {// 设置为空this.Username_Txt.setText("");this.Password_Txt.setText("");}
}

·MainFrame

package frame;import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.sql.SQLException;
import javax.swing.*;
import javax.swing.border.*;
import CS.Client;
import common.*;@SuppressWarnings("serial")
public class MainFrame extends JFrame {private JPanel contentPane;private JMenuBar menuBar;private JMenu UserManager_Menu;private JMenu FileManager_Menu;private JMenu SelfInfo_Menu;private JMenu Others_Menu;private JButton AddUser_Button;private JButton DelUser_Button;private JButton UpdateUser_Button;private JButton UploadFile_Button;private JButton DownloadFile_Button;private JButton ChangeSelfInfo_Button;private JButton Exit_Button;/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {// 实验6无法实现单独调用界面, 不能实现用户与服务器的消息传递!// 请从登录界面开始跳转// 单独调用连接数据库try {SQLconnection.Connect();} catch (ClassNotFoundException | SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}// 单独启动默认管理者MainFrame frame = new MainFrame(new Administrator("kate", "123", "Administrator"));frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/*** Create the frame.*/public MainFrame(User user) {// 传入角色参数// 框架setResizable(false);// 根据角色设置标题SetTitle(user.getRole());setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 1171, 699);// 中间容器contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));setContentPane(contentPane);contentPane.setLayout(null);// 菜单栏menuBar = new JMenuBar();menuBar.setBounds(0, 0, 1165, 33);contentPane.add(menuBar);// 用户管理下拉菜单UserManager_Menu = new JMenu("\u7528\u6237\u7BA1\u7406");UserManager_Menu.setFont(new Font("黑体", Font.PLAIN, 18));menuBar.add(UserManager_Menu);// 增添用户按钮AddUser_Button = new JButton("\u589E\u6DFB\u7528\u6237");AddUser_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 增添用户事件AddUserActionPerformed(user, e);}});AddUser_Button.setFont(new Font("黑体", Font.PLAIN, 16));UserManager_Menu.add(AddUser_Button);// 删除用户按钮DelUser_Button = new JButton("\u5220\u9664\u7528\u6237");DelUser_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 删除用户事件DelUserActionPerformed(user, e);}});DelUser_Button.setFont(new Font("黑体", Font.PLAIN, 16));UserManager_Menu.add(DelUser_Button);// 修改用户按钮UpdateUser_Button = new JButton("\u4FEE\u6539\u7528\u6237");UpdateUser_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 修改用户事件UpdateUserActionPerformed(user, e);}});UpdateUser_Button.setFont(new Font("黑体", Font.PLAIN, 16));UserManager_Menu.add(UpdateUser_Button);// 档案管理下拉菜单FileManager_Menu = new JMenu("\u6863\u6848\u7BA1\u7406");FileManager_Menu.setFont(new Font("黑体", Font.PLAIN, 18));menuBar.add(FileManager_Menu);// 上传文件按钮UploadFile_Button = new JButton("\u4E0A\u4F20\u6587\u4EF6");UploadFile_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 上传文件事件UploadFileActionPerformed(user, e);}});UploadFile_Button.setFont(new Font("黑体", Font.PLAIN, 16));FileManager_Menu.add(UploadFile_Button);// 下载文件按钮DownloadFile_Button = new JButton("\u4E0B\u8F7D\u6587\u4EF6");DownloadFile_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 下载文件事件DownloadFileActionPerformed(user, e);}});DownloadFile_Button.setFont(new Font("黑体", Font.PLAIN, 16));FileManager_Menu.add(DownloadFile_Button);// 个人信息管理下拉菜单SelfInfo_Menu = new JMenu("\u4E2A\u4EBA\u4FE1\u606F\u7BA1\u7406");SelfInfo_Menu.setFont(new Font("黑体", Font.PLAIN, 18));menuBar.add(SelfInfo_Menu);// 修改密码按钮ChangeSelfInfo_Button = new JButton("\u5BC6\u7801\u4FEE\u6539");ChangeSelfInfo_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 修改密码事件ChangeSelfActionPerformed(user, e);}});ChangeSelfInfo_Button.setFont(new Font("黑体", Font.PLAIN, 16));SelfInfo_Menu.add(ChangeSelfInfo_Button);// 其他类下拉菜单Others_Menu = new JMenu("\u5176\u4ED6");Others_Menu.setFont(new Font("黑体", Font.PLAIN, 18));menuBar.add(Others_Menu);// 退出按钮Exit_Button = new JButton("\u9000\u51FA");Exit_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 退出事件ExitActionPerformed(e);}});Exit_Button.setFont(new Font("黑体", Font.PLAIN, 16));Others_Menu.add(Exit_Button);// 设置各按钮权限SetRights(user.getRole());}// 增添用户private void AddUserActionPerformed(User user, ActionEvent evt) {// 选项编号 0UserFrame userframe = new UserFrame(user, 0);userframe.setVisible(true);}// 删除用户private void DelUserActionPerformed(User user, ActionEvent evt) {// 选项编号 1UserFrame userframe = new UserFrame(user, 1);userframe.setVisible(true);}// 修改用户private void UpdateUserActionPerformed(User user, ActionEvent evt) {// 选项编号 2UserFrame userframe = new UserFrame(user, 2);userframe.setVisible(true);}// 上传文件private void UploadFileActionPerformed(User user, ActionEvent evt) {// 选项编号0FileFrame fileframe = new FileFrame(user, 0);fileframe.setVisible(true);}// 下载文件private void DownloadFileActionPerformed(User user, ActionEvent evt) {// 选项编号1FileFrame fileframe = new FileFrame(user, 1);fileframe.setVisible(true);}// 修改密码private void ChangeSelfActionPerformed(User user, ActionEvent evt) {SelfInfoFrame selfframe = new SelfInfoFrame(user);selfframe.setVisible(true);}// 设置标题private void SetTitle(String role) {if (role.equalsIgnoreCase("administrator")) {setTitle("档案管理员界面");} else if (role.equalsIgnoreCase("browser")) {setTitle("档案浏览员界面");} else if (role.equalsIgnoreCase("operator")) {setTitle("档案录入员界面");}}// 设置用户权限private void SetRights(String role) {if (role.equalsIgnoreCase("administrator")) {AddUser_Button.setEnabled(true);DelUser_Button.setEnabled(true);UpdateUser_Button.setEnabled(true);DownloadFile_Button.setEnabled(true);UploadFile_Button.setEnabled(false);ChangeSelfInfo_Button.setEnabled(true);Exit_Button.setEnabled(true);} else if (role.equalsIgnoreCase("browser")) {AddUser_Button.setEnabled(false);DelUser_Button.setEnabled(false);UpdateUser_Button.setEnabled(false);DownloadFile_Button.setEnabled(true);UploadFile_Button.setEnabled(false);ChangeSelfInfo_Button.setEnabled(true);Exit_Button.setEnabled(true);} else if (role.equalsIgnoreCase("operator")) {AddUser_Button.setEnabled(false);DelUser_Button.setEnabled(false);UpdateUser_Button.setEnabled(false);DownloadFile_Button.setEnabled(true);UploadFile_Button.setEnabled(true);ChangeSelfInfo_Button.setEnabled(true);Exit_Button.setEnabled(true);}}// 退出private void ExitActionPerformed(ActionEvent evt) {// 断开数据库连接try {SQLconnection.Disconnect();} catch (SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}// 发送登出消息try {Client.SendMessage("登出");// 最后再接收服务器登出消息Client.ReceiveMessage();Client.CloseConnection();} catch (IOException | ClassNotFoundException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());return;} finally {// 在finally里返回登录界面,无论是否断开服务器连接都能返回this.dispose();LoginFrame loginframe = new LoginFrame();loginframe.setVisible(true);}}}

·UserFrame

package frame;import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.sql.SQLException;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;import CS.Client;import java.util.Enumeration;
import common.*;@SuppressWarnings("serial")
public class UserFrame extends JFrame {// 中间容器private JPanel contentPane;// 多页面容器private JTabbedPane tabbedPane;// 增添用户页面及组件private JPanel AddUser_Panel;private JLabel Username_Label1;private JLabel Password_Label1;private JLabel Role_Label1;private JTextField Username_Txt1;private JPasswordField Password_Txt1;@SuppressWarnings("rawtypes")private JComboBox Role_ComboBox1;private JButton Confirm_Button1;private JButton Return_Button1;// 删除用户页面及组件private JPanel DelUser_Panel;private JScrollPane scrollPane;private JTable Users_table;private JButton Confirm_Button2;private JButton Return_Button2;// 修改用户页面及组件private JPanel UpdateUser_Panel;private JLabel Username_Label2;private JLabel Password_Label2;private JLabel Role_Label2;private JTextField Username_Txt2;private JPasswordField Password_Txt2;@SuppressWarnings("rawtypes")private JComboBox Role_ComboBox2;private JButton Confirm_Button3;private JButton Return_Button3;/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {// 实验6无法实现单独调用界面, 不能实现用户与服务器的消息传递!// 请从登录界面开始跳转// 单独调用连接数据库try {SQLconnection.Connect();} catch (ClassNotFoundException | SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}UserFrame frame = new UserFrame(new Administrator("kate", "123", "Administrator"), 0);frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/*** Create the frame.*/@SuppressWarnings({ "unchecked", "rawtypes" })public UserFrame(User user, int choice) {// 传入用户及页面选项: 0 增添用户 1 删除用户 2 修改用户// 框架setResizable(false);setTitle("\u7528\u6237\u7BA1\u7406\u754C\u9762");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 587, 441);// 中间容器contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));setContentPane(contentPane);contentPane.setLayout(null);// 多页面容器tabbedPane = new JTabbedPane(JTabbedPane.TOP);tabbedPane.setBounds(14, 49, 553, 309);contentPane.add(tabbedPane);// 添加用户页面AddUser_Panel = new JPanel();// 增添选项卡tabbedPane.addTab("\u65B0\u589E\u7528\u6237", null, AddUser_Panel, null);AddUser_Panel.setLayout(null);// 用户名标签Username_Label1 = new JLabel("\u7528\u6237\u540D");Username_Label1.setFont(new Font("黑体", Font.PLAIN, 18));Username_Label1.setBounds(114, 38, 61, 32);AddUser_Panel.add(Username_Label1);// 密码标签Password_Label1 = new JLabel("\u5BC6\u7801");Password_Label1.setFont(new Font("黑体", Font.PLAIN, 18));Password_Label1.setBounds(132, 93, 43, 32);AddUser_Panel.add(Password_Label1);// 角色标签Role_Label1 = new JLabel("\u89D2\u8272");Role_Label1.setFont(new Font("黑体", Font.PLAIN, 18));Role_Label1.setBounds(132, 150, 43, 32);AddUser_Panel.add(Role_Label1);// 用户名文本域Username_Txt1 = new JTextField();Username_Txt1.setBounds(197, 44, 181, 24);Username_Txt1.setColumns(10);AddUser_Panel.add(Username_Txt1);// 密码文本域Password_Txt1 = new JPasswordField();Password_Txt1.setBounds(197, 99, 181, 24);AddUser_Panel.add(Password_Txt1);// 角色选项栏Role_ComboBox1 = new JComboBox();Role_ComboBox1.setEditable(true);Role_ComboBox1.setModel(new DefaultComboBoxModel(new String[] { "", "Administrator", "Browser", "Operator" }));Role_ComboBox1.setBounds(197, 156, 181, 24);AddUser_Panel.add(Role_ComboBox1);// 增添按钮Confirm_Button1 = new JButton("\u589E\u6DFB");Confirm_Button1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 增添用户事件AddUserActionPerformed(user, e);}});Confirm_Button1.setFont(new Font("黑体", Font.PLAIN, 18));Confirm_Button1.setBounds(132, 222, 113, 27);AddUser_Panel.add(Confirm_Button1);// 返回按钮Return_Button1 = new JButton("\u8FD4\u56DE");Return_Button1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 返回事件ReturnActionPerformed(e);}});Return_Button1.setFont(new Font("黑体", Font.PLAIN, 18));Return_Button1.setBounds(329, 222, 113, 27);AddUser_Panel.add(Return_Button1);// 删除用户页面DelUser_Panel = new JPanel();tabbedPane.addTab("\u5220\u9664\u7528\u6237", null, DelUser_Panel, null);DelUser_Panel.setLayout(null);// 删除按钮Confirm_Button2 = new JButton("\u5220\u9664");Confirm_Button2.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 删除事件DelUserActionPerformed(user, e);}});Confirm_Button2.setBounds(132, 222, 113, 27);Confirm_Button2.setFont(new Font("黑体", Font.PLAIN, 18));DelUser_Panel.add(Confirm_Button2);// 返回按钮Return_Button2 = new JButton("\u8FD4\u56DE");Return_Button2.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 返回事件ReturnActionPerformed(e);}});Return_Button2.setBounds(329, 222, 113, 27);Return_Button2.setFont(new Font("黑体", Font.PLAIN, 18));DelUser_Panel.add(Return_Button2);// 可下拉容器域scrollPane = new JScrollPane();scrollPane.setBounds(62, 37, 432, 159);DelUser_Panel.add(scrollPane);// 用户列表Users_table = new JTable();// 构造表格ConstructUserTable();// 加入可下拉区域scrollPane.setViewportView(Users_table);// 修改用户页面UpdateUser_Panel = new JPanel();UpdateUser_Panel.setLayout(null);tabbedPane.addTab("\u4FEE\u6539\u7528\u6237", null, UpdateUser_Panel, null);// 用户名标签Username_Label2 = new JLabel("\u7528\u6237\u540D");Username_Label2.setFont(new Font("黑体", Font.PLAIN, 18));Username_Label2.setBounds(114, 38, 61, 32);UpdateUser_Panel.add(Username_Label2);// 密码标签Password_Label2 = new JLabel("\u5BC6\u7801");Password_Label2.setFont(new Font("黑体", Font.PLAIN, 18));Password_Label2.setBounds(132, 93, 43, 32);UpdateUser_Panel.add(Password_Label2);// 角色标签Role_Label2 = new JLabel("\u89D2\u8272");Role_Label2.setFont(new Font("黑体", Font.PLAIN, 18));Role_Label2.setBounds(132, 150, 43, 32);UpdateUser_Panel.add(Role_Label2);// 用户名文本域Username_Txt2 = new JTextField();Username_Txt2.setColumns(10);Username_Txt2.setBounds(197, 44, 181, 24);UpdateUser_Panel.add(Username_Txt2);// 密码文本域Password_Txt2 = new JPasswordField();Password_Txt2.setBounds(197, 99, 181, 24);UpdateUser_Panel.add(Password_Txt2);// 角色选项栏Role_ComboBox2 = new JComboBox();Role_ComboBox2.setModel(new DefaultComboBoxModel(new String[] { "", "Administrator", "Browser", "Operator" }));Role_ComboBox2.setEditable(true);Role_ComboBox2.setBounds(197, 156, 181, 24);UpdateUser_Panel.add(Role_ComboBox2);// 修改按钮Confirm_Button3 = new JButton("\u4FEE\u6539");Confirm_Button3.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 修改用户事件UpdateUserActionPerformed(user, e);}});Confirm_Button3.setFont(new Font("黑体", Font.PLAIN, 18));Confirm_Button3.setBounds(132, 222, 113, 27);UpdateUser_Panel.add(Confirm_Button3);// 返回按钮Return_Button3 = new JButton("\u8FD4\u56DE");Return_Button3.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 返回事件ReturnActionPerformed(e);}});Return_Button3.setFont(new Font("黑体", Font.PLAIN, 18));Return_Button3.setBounds(329, 222, 113, 27);UpdateUser_Panel.add(Return_Button3);// 设置页面SetPane(choice);}// 用户表格构造private void ConstructUserTable() {// 表头数据String[] columnNames = { "\u7528\u6237\u540D", "\u5BC6\u7801", "\u89D2\u8272" };// 表格数据String[][] rowData = new String[20][3];Enumeration<User> u;try {// 获取哈希表信息u = DataProcessing.getAllUser();// 行数int row = 0;// 将哈希表信息导入至表格数据while (u.hasMoreElements()) {User user = u.nextElement();rowData[row][0] = user.getName();rowData[row][1] = user.getPassword();rowData[row][2] = user.getRole();row++;}} catch (SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}// 构造表格Users_table.setModel(new DefaultTableModel(rowData, columnNames) {boolean[] columnEditables = new boolean[] { false, false, false };public boolean isCellEditable(int row, int column) {return columnEditables[column];}});}// 增添private synchronized void AddUserActionPerformed(User user, ActionEvent evt) {// 获取输入内容String username = this.Username_Txt1.getText();String password = new String(this.Password_Txt1.getPassword());String role = (String) this.Role_ComboBox1.getSelectedItem();if (StringUtil.isEmpty(username)) {JOptionPane.showMessageDialog(null, "未输入用户名!");return;}if (StringUtil.isEmpty(password)) {JOptionPane.showMessageDialog(null, "未输入密码!");return;}if (StringUtil.isEmpty(role)) {JOptionPane.showMessageDialog(null, "未选择身份!");return;}try {if (DataProcessing.insertUser(username, password, role)) {// 发送增添用户的消息try {Client.SendMessage("增添用户");Client.ReceiveMessage();} catch (IOException | ClassNotFoundException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());return;}// 更新表格数据ConstructUserTable();JOptionPane.showMessageDialog(null, "添加成功!");return;} else {JOptionPane.showMessageDialog(null, "添加失败!用户名已存在!");return;}} catch (HeadlessException | SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}}// 删除private synchronized void DelUserActionPerformed(User user, ActionEvent evt) {// 获取所选行序号,若未选择其值为-1int selectedrow = Users_table.getSelectedRow();// 未选择用户的情况if (selectedrow == -1) {JOptionPane.showMessageDialog(null, "未选择用户!");return;} else {// 获取所选行的用户名String username = (String) Users_table.getValueAt(selectedrow, 0);// 若选择空行if (StringUtil.isEmpty(username)) {return;}// 选择自身用户的情况if (username.equals(user.getName())) {JOptionPane.showMessageDialog(null, "不能删除自身用户!");return;}// 显示确认界面: 信息, 标题, 选项个数int value = JOptionPane.showConfirmDialog(null, "确定要删除用户吗?", "用户删除确认界面", 2);// Yes=0 No=1if (value == 0) {try {if (DataProcessing.deleteUser(username)) {// 发送删除用户消息try {Client.SendMessage("删除用户");Client.ReceiveMessage();} catch (IOException | ClassNotFoundException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());return;}// 更新表格数据ConstructUserTable();JOptionPane.showMessageDialog(null, "删除成功!");return;} else {JOptionPane.showMessageDialog(null, "删除失败!");return;}} catch (SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}} else if (value == 1) {return;}}}// 修改private synchronized void UpdateUserActionPerformed(User user, ActionEvent evt) {String username = this.Username_Txt2.getText();String password = new String(this.Password_Txt2.getPassword());String role = (String) this.Role_ComboBox2.getSelectedItem();if (StringUtil.isEmpty(username)) {JOptionPane.showMessageDialog(null, "未输入用户名!");return;}if (StringUtil.isEmpty(password)) {JOptionPane.showMessageDialog(null, "未输入密码!");return;}if (StringUtil.isEmpty(role)) {JOptionPane.showMessageDialog(null, "未选择身份!");return;}try {if (DataProcessing.searchUser(username, password) == null) {JOptionPane.showMessageDialog(null, "用户名与密码不匹配!");return;} else {// 显示确认界面:信息,标题,选项个数int value = JOptionPane.showConfirmDialog(null, "确定要修改信息吗?", "信息修改确认界面", 2);// Yes=0 No=1if (value == 0) {if (DataProcessing.updateUser(username, password, role)) {// 发送修改用户信息try {Client.SendMessage("修改用户");Client.ReceiveMessage();} catch (IOException | ClassNotFoundException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());return;}// 更新表格数据ConstructUserTable();JOptionPane.showMessageDialog(null, "修改成功!");return;} else {JOptionPane.showMessageDialog(null, "修改失败!");return;}} else if (value == 1) {return;}}} catch (HeadlessException | SQLException e) {e.printStackTrace();JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}}// 设置页面private void SetPane(int value) {if (value == 0) {tabbedPane.setSelectedComponent(AddUser_Panel);} else if (value == 1) {tabbedPane.setSelectedComponent(DelUser_Panel);} else if (value == 2) {tabbedPane.setSelectedComponent(UpdateUser_Panel);}}// 返回private void ReturnActionPerformed(ActionEvent evt) {this.dispose();}}

·FileFrame

package frame;import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.sql.SQLException;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;import CS.Client;import java.text.SimpleDateFormat;
import java.util.Enumeration;
import common.*;@SuppressWarnings("serial")
public class FileFrame extends JFrame {// 中间容器private JPanel contentPane;// 多页面容器private JTabbedPane tabbedPane;// 上传文件页面及组件private JPanel Upload_Panel;private JLabel FileID_Label;private JLabel Filedescription_Label;private JLabel Filename_Label;private JTextField FileID_Txt;private JTextArea Filedescription_Txt;private JTextField Filepath_Txt;private JButton Upload_Button;private JButton OpenFile_Button;private JButton Return_Button1;// 下载文件页面及组件private JPanel Download_Panel;private JButton Download_Button;private JButton Return_Button2;private JScrollPane scrollPane;private JTable Files_table;/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {// 实验6无法实现单独调用界面, 不能实现用户与服务器的消息传递!// 请从登录界面开始跳转// 单独调用连接数据库try {SQLconnection.Connect();} catch (ClassNotFoundException | SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}FileFrame frame = new FileFrame(new Administrator("jack", "123", "operator"), 0);frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/*** Create the frame.*/public FileFrame(User user, int choice) {// 传入用户及页面选项: 0上传文件 1下载文件// 框架setTitle("\u6587\u4EF6\u7BA1\u7406\u754C\u9762");setResizable(false);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 802, 581);// 中间容器contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));setContentPane(contentPane);contentPane.setLayout(null);// 多页面容器tabbedPane = new JTabbedPane(JTabbedPane.TOP);tabbedPane.setBounds(38, 35, 713, 469);contentPane.add(tabbedPane);// 上传页面Upload_Panel = new JPanel();tabbedPane.addTab("\u6587\u4EF6\u4E0A\u4F20", null, Upload_Panel, null);Upload_Panel.setLayout(null);// 档案号标签FileID_Label = new JLabel("\u6863\u6848\u53F7");FileID_Label.setFont(new Font("黑体", Font.PLAIN, 20));FileID_Label.setBounds(125, 33, 60, 36);Upload_Panel.add(FileID_Label);// 文件描述标签Filedescription_Label = new JLabel("\u6863\u6848\u63CF\u8FF0");Filedescription_Label.setFont(new Font("黑体", Font.PLAIN, 20));Filedescription_Label.setBounds(105, 90, 80, 36);Upload_Panel.add(Filedescription_Label);// 文件名标签Filename_Label = new JLabel("\u6863\u6848\u6587\u4EF6\u540D");Filename_Label.setFont(new Font("黑体", Font.PLAIN, 20));Filename_Label.setBounds(85, 314, 100, 36);Upload_Panel.add(Filename_Label);// 档案号文本域FileID_Txt = new JTextField();FileID_Txt.setBounds(215, 40, 272, 27);Upload_Panel.add(FileID_Txt);FileID_Txt.setColumns(10);// 文件描述文本域Filedescription_Txt = new JTextArea();Filedescription_Txt.setBounds(215, 96, 272, 199);Upload_Panel.add(Filedescription_Txt);Filedescription_Txt.setColumns(10);// 文件名文本域Filepath_Txt = new JTextField();Filepath_Txt.setColumns(10);Filepath_Txt.setBounds(215, 321, 272, 27);Upload_Panel.add(Filepath_Txt);// 上传按钮Upload_Button = new JButton("\u4E0A\u4F20");Upload_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 上传文件事件UploadActionPerformed(user, e);}});Upload_Button.setBounds(215, 380, 95, 27);Upload_Button.setFont(new Font("黑体", Font.PLAIN, 20));Upload_Panel.add(Upload_Button);// 返回按钮Return_Button1 = new JButton("\u8FD4\u56DE");Return_Button1.setBounds(395, 380, 95, 27);Return_Button1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 返回事件ReturnActionPerformed(e);}});// 打开按钮OpenFile_Button = new JButton("\u6253\u5F00");OpenFile_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 打开文件事件OpenFileActionPerformed(e);}});OpenFile_Button.setFont(new Font("黑体", Font.PLAIN, 18));OpenFile_Button.setBounds(532, 319, 95, 27);Upload_Panel.add(OpenFile_Button);Return_Button1.setFont(new Font("黑体", Font.PLAIN, 20));Upload_Panel.add(Return_Button1);// 下载页面Download_Panel = new JPanel();tabbedPane.addTab("\u6587\u4EF6\u4E0B\u8F7D", null, Download_Panel, null);tabbedPane.setEnabledAt(1, true);Download_Panel.setLayout(null);// 下载按钮Download_Button = new JButton("\u4E0B\u8F7D");Download_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 下载文件事件DownloadActionPerformed(user, e);}});Download_Button.setFont(new Font("黑体", Font.PLAIN, 20));Download_Button.setBounds(215, 380, 95, 27);Download_Panel.add(Download_Button);// 返回按钮Return_Button2 = new JButton("\u8FD4\u56DE");Return_Button2.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 返回事件ReturnActionPerformed(e);}});Return_Button2.setFont(new Font("黑体", Font.PLAIN, 20));Return_Button2.setBounds(395, 380, 95, 27);Download_Panel.add(Return_Button2);// 可下拉容器scrollPane = new JScrollPane();scrollPane.setBounds(35, 32, 637, 322);Download_Panel.add(scrollPane);// 下载文件列表Files_table = new JTable();// 构造表格ConstructFileTable();// 加入可下拉区域scrollPane.setViewportView(Files_table);// 设置权限及页面setPane(user, choice);}// 表格构造private void ConstructFileTable() {// 表头数据String[] columnNames = { "\u6863\u6848\u53F7", "\u521B\u5EFA\u8005", "\u65F6\u95F4", "\u6587\u4EF6\u540D","\u6587\u4EF6\u63CF\u8FF0" };// 表格数据String[][] rowData = new String[20][5];Enumeration<Doc> f;try {// 获取哈希表信息f = DataProcessing.getAllDocs();// 行数int row = 0;// 将哈希表信息导入至表格while (f.hasMoreElements()) {Doc doc = f.nextElement();rowData[row][0] = doc.getID();rowData[row][1] = doc.getCreator();rowData[row][2] = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(doc.getTimestamp()); // Time转StringrowData[row][3] = doc.getFilename();rowData[row][4] = doc.getDescription();row++;}} catch (SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}// 构造表格Files_table.setModel(new DefaultTableModel(rowData, columnNames) {boolean[] columnEditables = new boolean[] { false, false, false, false, false };public boolean isCellEditable(int row, int column) {return columnEditables[column];}});}// 打开文件private void OpenFileActionPerformed(ActionEvent evt) {// 弹出文件选择框FileDialog OpenFileDialog = new FileDialog(this, "选择上传文件");OpenFileDialog.setVisible(true);// 获取文件路径String filepath = OpenFileDialog.getDirectory() + OpenFileDialog.getFile();Filepath_Txt.setText(filepath);}// 上传文件private synchronized void UploadActionPerformed(User user, ActionEvent evt) {String filepath = Filepath_Txt.getText();String fileID = FileID_Txt.getText();String filedescription = Filedescription_Txt.getText();if (StringUtil.isEmpty(filepath)) {JOptionPane.showMessageDialog(null, "未选择文件!");return;}if (StringUtil.isEmpty(fileID)) {JOptionPane.showMessageDialog(null, "未输入档案号!");return;}if (StringUtil.isEmpty(filedescription)) {JOptionPane.showMessageDialog(null, "未输入文件描述!");return;}if (user.uploadFile(fileID, filepath, filedescription)) {// 发送上传文件消息try {Client.SendMessage("上传文件");Client.ReceiveMessage();} catch (IOException | ClassNotFoundException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());return;}// 更新表格数据ConstructFileTable();JOptionPane.showMessageDialog(null, "上传成功!");return;} else {JOptionPane.showMessageDialog(null, "上传失败!");return;}}// 下载文件private synchronized void DownloadActionPerformed(User user, ActionEvent evt) {// 获取所选行序号, 若未选择其值为-1int selectedrow = Files_table.getSelectedRow();// 未选择文件的情况if (selectedrow == -1) {JOptionPane.showMessageDialog(null, "未选择文件!");return;} else {// 获取档案号String fileID = (String) Files_table.getValueAt(selectedrow, 0);// 若选择空行if (StringUtil.isEmpty(fileID)) {return;}// 显示确认界面: 信息, 标题, 选项个数int value = JOptionPane.showConfirmDialog(null, "确定要下载文件吗?", "文件下载确认界面", 2);// Yes=0 No=1if (value == 0) {if (user.downloadFile(fileID)) {// 发送下载文件消息try {Client.SendMessage("下载文件");Client.ReceiveMessage();} catch (IOException | ClassNotFoundException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());return;}JOptionPane.showMessageDialog(null, "下载成功!");return;} else {JOptionPane.showMessageDialog(null, "下载失败!");return;}} else if (value == 1) {return;}}}// 设置页面private void setPane(User user, int choice) {if (!user.getRole().equalsIgnoreCase("operator")) {FileID_Txt.setEditable(false);Filedescription_Txt.setEditable(false);Filepath_Txt.setEditable(false);Upload_Button.setEnabled(false);OpenFile_Button.setEnabled(false);}if (choice == 0) {tabbedPane.setSelectedComponent(Upload_Panel);} else if (choice == 1) {tabbedPane.setSelectedComponent(Download_Panel);}}// 返回private void ReturnActionPerformed(ActionEvent evt) {this.dispose();}
}

·SelfInfoFrame

package frame;import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.sql.SQLException;
import javax.swing.*;
import javax.swing.border.EmptyBorder;import CS.Client;
import common.*;@SuppressWarnings("serial")
public class SelfInfoFrame extends JFrame {private JPanel contentPane;private JLabel Username_Label;private JLabel OldPassword_Label;private JLabel NewPassword_Label;private JLabel ConfirmPassword_Label;private JLabel Role_Label;private JTextField Username_Txt;private JPasswordField OldPassword_Txt;private JPasswordField NewPassword_Txt;private JPasswordField ConfirmPassword_Txt;private JTextField Role_Txt;private JButton Confirm_Button;private JButton Return_Button;/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {// 实验6无法实现单独调用界面, 不能实现用户与服务器的消息传递!// 请从登录界面开始跳转// 单独调用连接数据库try {SQLconnection.Connect();} catch (ClassNotFoundException | SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}SelfInfoFrame frame = new SelfInfoFrame(new Administrator("kate", "123", "Administrator"));frame.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/*** Create the frame.*/public SelfInfoFrame(User user) {// 传入用户参数// 框架setResizable(false);setTitle("\u4E2A\u4EBA\u4FE1\u606F\u7BA1\u7406");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(100, 100, 502, 384);// 中间容器contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));setContentPane(contentPane);contentPane.setLayout(null);// 用户名标签Username_Label = new JLabel("\u7528\u6237\u540D:");Username_Label.setFont(new Font("黑体", Font.PLAIN, 18));Username_Label.setBounds(100, 51, 72, 30);contentPane.add(Username_Label);// 旧密码标签OldPassword_Label = new JLabel("\u539F\u5BC6\u7801:");OldPassword_Label.setFont(new Font("黑体", Font.PLAIN, 18));OldPassword_Label.setBounds(100, 93, 72, 30);contentPane.add(OldPassword_Label);// 新密码标签NewPassword_Label = new JLabel("\u65B0\u5BC6\u7801:");NewPassword_Label.setFont(new Font("黑体", Font.PLAIN, 18));NewPassword_Label.setBounds(100, 135, 72, 30);contentPane.add(NewPassword_Label);// 确认密码标签ConfirmPassword_Label = new JLabel("\u786E\u8BA4\u65B0\u5BC6\u7801:");ConfirmPassword_Label.setFont(new Font("黑体", Font.PLAIN, 18));ConfirmPassword_Label.setBounds(63, 178, 109, 30);contentPane.add(ConfirmPassword_Label);// 角色标签Role_Label = new JLabel("\u89D2\u8272:");Role_Label.setFont(new Font("黑体", Font.PLAIN, 18));Role_Label.setBounds(118, 221, 57, 30);contentPane.add(Role_Label);// 用户名文本域Username_Txt = new JTextField();// 自动设置文本为用户名Username_Txt.setText(user.getName());Username_Txt.setEditable(false);Username_Txt.setBounds(186, 56, 154, 24);contentPane.add(Username_Txt);Username_Txt.setColumns(10);// 旧密码文本域OldPassword_Txt = new JPasswordField();OldPassword_Txt.setBounds(186, 98, 154, 24);contentPane.add(OldPassword_Txt);// 新密码文本域NewPassword_Txt = new JPasswordField();NewPassword_Txt.setBounds(186, 140, 154, 24);contentPane.add(NewPassword_Txt);// 确认密码文本域ConfirmPassword_Txt = new JPasswordField();ConfirmPassword_Txt.setBounds(186, 183, 154, 24);contentPane.add(ConfirmPassword_Txt);// 角色文本域Role_Txt = new JTextField();// 自动设置用户身份Role_Txt.setText(user.getRole());Role_Txt.setEditable(false);Role_Txt.setColumns(10);Role_Txt.setBounds(186, 226, 154, 24);contentPane.add(Role_Txt);// 确认按钮Confirm_Button = new JButton("\u786E\u8BA4");Confirm_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 修改密码事件ChangeSelfInfoActionPerformed(user, e);}});Confirm_Button.setFont(new Font("黑体", Font.PLAIN, 18));Confirm_Button.setBounds(118, 288, 113, 27);contentPane.add(Confirm_Button);// 返回按钮Return_Button = new JButton("\u8FD4\u56DE");Return_Button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// 返回事件ReturnActionPerformed(e);}});Return_Button.setFont(new Font("黑体", Font.PLAIN, 18));Return_Button.setBounds(278, 288, 113, 27);contentPane.add(Return_Button);}// 修改密码private synchronized void ChangeSelfInfoActionPerformed(User user, ActionEvent evt) {String oldpassword = new String(OldPassword_Txt.getPassword());String newpassword = new String(NewPassword_Txt.getPassword());String confirmpassword = new String(ConfirmPassword_Txt.getPassword());// 检查是否为空if (StringUtil.isEmpty(oldpassword)) {JOptionPane.showMessageDialog(null, "未输入旧密码!");return;}if (StringUtil.isEmpty(newpassword)) {JOptionPane.showMessageDialog(null, "未输入新密码!");return;}if (StringUtil.isEmpty(confirmpassword)) {JOptionPane.showMessageDialog(null, "请输入确认密码!");return;}// 密码匹配try {if (DataProcessing.searchUser(user.getName(), oldpassword) == null) {JOptionPane.showMessageDialog(null, "用户名与原密码不匹配!");return;}if (!newpassword.equals(confirmpassword)) {JOptionPane.showMessageDialog(null, "两次输入的新密码不相同!");return;}// 修改密码if (user.changeSelfInfo(newpassword)) {// 发送修改密码消息try {Client.SendMessage("修改密码");Client.ReceiveMessage();} catch (IOException | ClassNotFoundException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());return;}// 清空this.OldPassword_Txt.setText("");this.NewPassword_Txt.setText("");this.ConfirmPassword_Txt.setText("");JOptionPane.showMessageDialog(null, "修改成功!");return;} else {JOptionPane.showMessageDialog(null, "修改失败!");return;}} catch (HeadlessException | SQLException e) {JOptionPane.showMessageDialog(null, e.getLocalizedMessage());}}// 返回private void ReturnActionPerformed(ActionEvent evt) {this.dispose();}
}

在一些事件函数前面加上了 synchronized 关键字,这样就可以防止多个线程同时触发该事件操作产生错误。(即实现“加锁”)

写在最后

声明:本文内容来源于武汉理工大学2019-2020学年Java编程实验,仅供学习参考。如有不足错误地方,还请指出。
代码不要无脑抄 ,很多细节没有详细讲解,读者需自行理解。

Java面向对象与多线程实验专栏到此完结,笔者希望能够帮助到大家,祝愿读者在编程之路上不断进步!

武汉理工大学-Java面向对象与多线程综合实验-(7)多线程基础相关推荐

  1. 武汉理工大学桂林老师java_武汉理工大学-Java面向对象与多线程综合实验-(1)封装、继承与多态...

    实验目标 实现一个档案管理系统的用户管理模块的初步模型.功能包括:密码机制的登录界面:普通用户对自身信息的查询.修改:管理员用户对其他用户信息的增添.删除.修改. 模块解析 用户分为:Administ ...

  2. c语言设计实验报告答案,武汉理工大学《C语言程序设计》实验报告答案

    武汉理工大学<C语言程序设计>实验报告答案 注:在Visual C++ 6.0编译环境中亲自调试通过,但不保证在Turbo C中通过. 实验二 选择结构的程序设计 (题目当初没抄下来,这是 ...

  3. java面向对象计算机与CD实验,Java面向对象上机实验指导书.doc

    Java面向对象上机实验指导书 山东建筑大学实验报告 课 程 :Java面向对象程序设计语言 院 (部):商学院 专 业 :电子商务 班 级 : 学生姓名: 学 号: 指导教师:陈明志 完成时间:20 ...

  4. 段鹏飞java_面向对象与多线程综合实验-网络编程

    教师:段鹏飞 实验5-实验目的 了解Java网络编程基础知识;掌握java.net包中关于网络的基本类及其属性和方法;掌握基于Socket的客户和服务器编程方法. 实验内容(必做) 编写程序,将前面课 ...

  5. [面向对象与多线程综合实验]数据挖掘系统

    开源项目:wut-data-mining-system 开发时间:2020.11 - 2020.12 文章目录 一.快速开始 二.系统简介 三.需求分析 四.任务分配 五.功能要求 六.项目结构 七. ...

  6. 武汉理工大学计算机组成与系统结构 Educoder实验

    文章目录 前言 实验资料 一.计算机数据表示实验 第1关:汉字国标码转区位码实验 第2关:汉字机内码获取实验 第3关:偶校验编码设计 第4关:偶校验解码电路设计 第5关:16位海明编码电路设计 第6关 ...

  7. Java面向对象雇员类设计实验

    目录 一.实验目的 二.雇员类设计实验的内容及步骤 三.实验代码 Person类 Employee类: Manager类 Add类 Employee_Test类 四.运行结果 一.实验目的 1.了解和 ...

  8. 【分治法】中位数问题和Gray码问题——武汉理工大学算法设计与分析课程实验

    1. 中位数问题 « 问题描述 设X[ 0 : n - 1]和Y[ 0 : n – 1 ]为两个数组,每个数组中含有n个已排好序的数.找出X和Y的2n个数的中位数. « 编程任务 利用分治策略试设计一 ...

  9. 【动态规划】最大K乘积问题和游艇租用问题——武汉理工大学算法设计与分析课程实验

    1.  最大K乘积问题 « 问题描述 设I是一个n位十进制整数.如果将I划分为k段,则可得到k个整数.这k个整数的乘积称为I的一个k乘积.试设计一个算法,对于给定的I和k,求出I的最大k乘积. 例如十 ...

最新文章

  1. C/C++中inline/static inline/extern inline的区别及使用
  2. 【机器学习基础】xgboost系列丨xgboost建树过程分析及代码实现
  3. 【Flink】Flink 的 slotSharingGroup 有什么用
  4. cenos7部署samba
  5. 芯原股份正式加入UCIe产业联盟
  6. 6.27java斗地主
  7. java中抽象类继承抽象类_邮政编码作为Java中抽象类的示例
  8. 番外4. Python OpenCV 中鼠标事件相关处理与常见问题解决方案
  9. 解决Python爬取百度页面出现中文乱码问题
  10. Navicat数据传输
  11. android qq apk,仿QQ获取手机中的APK并分享的实现
  12. 不规则形状或图片添加阴影效果
  13. canal学习2--canal Adapter使用
  14. 什么是CC攻击?网站遭到CC攻击该如何防御?
  15. I Ching,Chaos 及其它
  16. 并网型虚拟同步发电机控制Matlab/simulink仿真
  17. [Java Path Finder][JPF学习笔记][7]JPF输出详细程度设置
  18. 16,verilog之锁存器和触发器
  19. 计算机摄像头原理,一款笔记本电脑摄像头原理图和PCB
  20. 解决重新启动电脑打印机自动打印上一次打印作业的方法

热门文章

  1. 学python多久能上线部署网站_从开发到上线,实战持续交付
  2. android从活动返回碎片,Android碎片
  3. NOAA官网下载数据
  4. 有哪些免费好用的开源建站程序/系统,推荐下?
  5. 在芬兰留学是一种什么体验?
  6. 大量海归来抢工作了!图解大数据:为何80%留学生选择回国
  7. 数字源表典型应用及检验项目有哪些呢?
  8. 如何使用 win32com 操作excel 入坑
  9. DIY定制你个人专属锁屏,将手机锁屏密码设置成文字、表情、照片
  10. Arcengine图层栏制作图层树,把想显示的图层放在图层组中显示