Ý tưởng và chủ đề nghiên cứu: Chủ đề nghiên cứu: Xây dựng phần mềm quản lý câu lạc bộ tin học khoa CNTT. Ý tưởng: xây dựng 1 phần mềm để người quản lý có thể quản lý được thông tin và các hoạt động của các CLB trong câu lạc bộ tin học khoa CNTT; giúp cho các bạn sinh viên có thêm 1 sân chơi, 1 nơi học tập, trao đổi thông tin nhanh chóng và chính xác để phát huy được hết phẩm chất, năng lực của từng sinh viên. Các kiến thức, kỹ năng đã có để thực hiện chủ đề nghiên cứu: cách làm việc với môi trường và công cụ làm việc với Java cộng với các kiến thức về OOP, cách sử dụng các hàm, thao tác với mảng, dữ liệu. Các kỹ năng then chốt phải học trong chủ đề nghiên cứu: lập trình với cấu trúc Collection và lập trình với giao diện đồ họa GUI (Graphical User Interface).
Phần mở đầu
Ý tưởng và chủ đề nghiên cứu:
- Chủ đề nghiên cứu: Xây dựng phần mềm quản lý câu lạc bộ tin học khoa CNTT.
Ý tưởng xây dựng phần mềm quản lý thông tin và hoạt động của các câu lạc bộ trong khoa CNTT nhằm tạo ra một sân chơi bổ ích cho sinh viên Phần mềm này sẽ giúp sinh viên dễ dàng học tập, trao đổi thông tin nhanh chóng và chính xác, từ đó phát huy tối đa phẩm chất và năng lực cá nhân của từng sinh viên.
Để thực hiện chủ đề nghiên cứu về Java, cần có kiến thức và kỹ năng về cách làm việc với môi trường lập trình và các công cụ hỗ trợ Điều này bao gồm hiểu biết về lập trình hướng đối tượng (OOP), cách sử dụng các hàm, cũng như thao tác với mảng và dữ liệu.
Trong lĩnh vực nghiên cứu, việc nắm vững các kỹ năng then chốt là điều cần thiết, đặc biệt là lập trình với cấu trúc Collection và lập trình với giao diện đồ họa GUI (Graphical User Interface) Những kỹ năng này không chỉ giúp cải thiện khả năng lập trình mà còn nâng cao trải nghiệm người dùng thông qua việc thiết kế giao diện trực quan và hiệu quả Việc học hỏi và thực hành những kỹ năng này sẽ tạo nền tảng vững chắc cho sự nghiệp lập trình viên trong tương lai.
Phần kết quả nghiên cứu
Giới thiệu
Khách hàng yêu cầu xây dựng “Phần mềm quản lý câu lạc bộ tin học” Sản phẩm ứng dụng hoạt động được trong môi trường Java.
Nhiệm vụ, công việc chính khi thực hiện Bài tập lớn và kết quả đạt được:
T Nhiệm vụ Kết quả đạt được
1 Thu thập yêu cầu của khách hàng
3 Phân tích hệ thống Mô hình hóa chức năng hệ thống
Mô hình hóa dữ liệu
Sản phẩm được xây dựng theo mô hình bản mẫu:
Khảo sát hệ thống
Các vấn đề cần giải quyết trong bài toán:
- Admin: Quản lý câu lạc bộ, các hoạt động, thành viên, thông tin, đánh giá thành viên.
Sinh viên nên tích cực tham gia các hoạt động ngoại khóa để giải quyết những vấn đề liên quan đến học tập Đồng thời, việc tìm hiểu thông tin về các câu lạc bộ và nhu cầu sinh hoạt thể thao của sinh viên cũng rất quan trọng để nâng cao trải nghiệm học đường.
2.2.2 Tài liệu đặc tả yêu cầu
Hình 2.1: Biểu đồ usecase hệ thống
Hình 2.2: Biểu đồ usecase chính
Hình 2.3: Biểu đồ usecase thứ cấp
2.2.2.1 Mô tả Use case Đăng Nhập
Cho phép người dùng đăng nhập vào hệ thống.
1) Use case này bắt đầu khi người dùng mở hệ thống Hệ thống sẽ hiển thị màn hình đăng nhập.
2) Người dùng nhập đầy đủ thông tin đăng nhập và nhấn nút đăng nhập.
Hệ thống kiểm tra thông tin tài khoản trong bảng TAIKHOAN Nếu đúng thì cho phép đăng nhập hệ thống Use case kết thúc.
1) Tại bước 2 luồng cơ bản nếu thông tin đăng nhập không đúng hoặc không tồn tại thì hệ thống thông báo và trở về bước 2 luồng cơ bản.
2) Tại bất kì thời điểm nào trông quá trình thực hiện usecase nếu không kết nối được với cơ sở dữ liệu thì hệ thống hiển thị thông báo lỗi và usecase kết thúc.
Các yêu cầu đặc biệt
2.2.2.2 Mô tả Use case Đăng Ký
Cho phép người dùng đăng đăng ký tài khoản mới trên hệ thống.
1) Use case này bắt đầu khi người dùng nhấn vào nút “Đăng ký” trên màn hình đăng nhập Hệ thống sẽ hiển thị màn hình đăng ký.
2) Người dùng nhập đầy đủ thông tin đăng ký và nhấn nút đăng ký Hệ thống kiểm tra tính hợp lệ của thông tin Nếu đúng thì hệ thống cập nhân thông tin vào bảng THANHVIEN và bảng TAIKHOAN và chuyển đến màn hình đăng nhập Use case kết thúc.
1) Tại bước 2 luồng cơ bản nếu thông tin đăng ký không hợp lệ hoặc đã tồn tại thì hệ thống thông báo và trở về bước 2 luồng cơ bản.
2) Tại bất kì thời điểm nào trông quá trình thực hiện usecase nếu không kết nối được với cơ sở dữ liệu thì hệ thống hiển thị thông báo lỗi và usecase kết thúc.
Các yêu cầu đặc biệt
Nếu Usecase thành công thì thì thông tin tài khoản sẽ được thêm vào cơ sở dữ liệu.
2.2.2.3 Mô tả Use case Quên Mật Khẩu
Cho phép người dùng Thay đổi mật khẩu tài khoản.
1) Use case này bắt đầu khi người dùng nhấn vào nút “Quên mật khẩu” trên màn hình đang nhập Hệ thống sẽ hiển thị màn hình Xác thực thông tin.
2) Người dùng nhập đầy đủ thông tin tìa khoản và nhấn nút “Xác nhận”.
Hệ thống kiểm tra thông tin tài khoản trong bảng TAIKHOAN và bảng THANHVIEN Nếu đúng thì chuyển đến màn hình cập nhật tài khoản.
3) Người dùng nhập mạt khẩu mới Hệ thống kiểm tra tính hợp lệ Nếu hợp lệ thì cập nhật thông tin tài khoản trong bảng TAIKHOAN và chuyển về màn hình đăng nhập Usecase kết thúc.
1) Tại bước 2 luồng cơ bản nếu thông tin xác nhận không đúng hoặc không tồn tại thì hệ thống thông báo và trở về bước 2 luồng cơ bản.
2) Tại bước 3 của luồng cơ bản nếu thông tin không hợp lệ thì hệ thống thông báo và chuyển về bước 3 của luồng cơ bản.
3) Tại bất kì thời điểm nào trông quá trình thực hiện usecase nếu không kết nối được với cơ sở dữ liệu thì hệ thống hiển thị thông báo lỗi và usecase kết thúc.
Các yêu cầu đặc biệt
Nếu usecase thực hiện thành công thì thông tin tài khoản sẽ được cập nhạt trong cơ sở dữ liệu.
2.2.2.4 Mô tả Use case Hỏi Đáp
Cho phép người dùng Hỏi đáp trong hệ thống.
1) Use case này bắt đầu khi người dùng nhấn vào nút “Đăng bài” trong trang chủ Hệ thống sẽ hiển thị màn hình chức năng.
2) Người dùng nhập đầy đủ thông tin bài đăng nhấn nút “Đăng bài” Hệ thống kiểm tra tính hợp lệ của bài đăng Nếu hợp lệ thì cập nhạt bài đăng vào bảng BAIVIET và cho phép đăng bài lên bảng tin Use case kết thúc.
1) Tại bất kì thời điểm nào trông quá trình thực hiện usecase nếu không kết nối được với cơ sở dữ liệu thì hệ thống hiển thị thông báo lỗi và usecase kết thúc.
Các yêu cầu đặc biệt
Tiền điều kiện Đã đăng nhập
Nếu usecase thành công thì hệ thống sẽ cập nhật thông tin bài viết trong cơ sở dữ liệu.
2.2.2.5 Mô tả Use case Xem Thông Tin
Cho phép người dùng Xem thông tin trong hệ thống.
1) Use case này bắt đầu khi người dùng nhán vào nút “Tài khoản” trong trang chủ Hệ thống sẽ hiển thị menu tài khoản.
2) Người dùng nhấn nút “Xem thông tin tài khoản” Hệ thống hiển thị màn hình thông tin tài khoản tham chiếu từ bảng THANHVIEN. Usecase kết thúc.
1) Tại bất kì thời điểm nào trông quá trình thực hiện usecase nếu không kết nối được với cơ sở dữ liệu thì hệ thống hiển thị thông báo lỗi và usecase kết thúc.
Các yêu cầu đặc biệt
Tiền điều kiện Đã đăng nhập
2.2.2.6 Mô tả Use case Quản Lý Thành Viên
Cho phép Admin quản lí danh sách thành viên.
Ca sử dụng này bắt đầu khi Admin kích vào mục “Quản lí thành viên”.
Hệ thống sẽ truy xuất đến bảng THANHVIEN để hiển thị thông tin và cho phép Admin có quyền chỉnh sửa thông qua trang web dành cho Admin.
1) Thêm Thành Viên: a Khi Admin kích vào mục thêm mới thành viên Hệ thống hiển thị màn hình yêu cầu nhập các thông tin bao gồm : Mã Thành Viên, Tên Thành Viên, Giới Tính, Số Điện Thoại Di Động, Ngày Sinh, Email, Câu lạc bộ. b Admin viết các thông tin: Tên Thành Viên, Giới Tính, Số ĐiệnThoại Di Động, Ngày Sinh, Email, Câu lạc bộ và kích vào nút “ThêmMới Thành Viên”.Hệ thống sẽ nhận thông tin 1 thành viên mới và hiện lên màn hình.
2) Sửa Thành Viên: a Admin kích vào nút “Sửa” trên một dòng Sinh Viên Hệ thống sẽ lấy ra các thông tin Thành Viên Cũ được chọn bao gồm: Mã Thành Viên, Tên Thành Viên, Giới Tính, Số Điện Thoại Di Động, Ngày Sinh, Email và Câu lạc bộ. b Admin nhập thông tin mới như Tên Thành Viên, Giới Tính, Số Điện Thoại Di Động, Ngày Sinh, Email, Câu lạc bộ và kích vào nút
“Cập Nhật” Hệ thống sẽ nhận thông tin mới của 1 thành viên và hiện lên màn hình.
Phân tích hệ thống
2.3.1 Mô hình hóa chức năng hệ thống
Các actor trong hệ thống:
- Admin: Quản lý câu lạc bộ, các hoạt động, thành viên, thông tin, đánh giá thành viên.
Sinh viên nên tích cực tham gia các hoạt động câu lạc bộ để giải quyết vấn đề học tập và tìm hiểu thông tin hữu ích Việc này không chỉ giúp nâng cao kiến thức mà còn đáp ứng nhu cầu sinh hoạt thể thao của sinh viên.
- CSDL: Lưu trữ dữ liệu của hệ thống.
Các usecase trong hệ thống:
Tên Usecase Chức năng Ghi chú
(Tác nhân) Đăng nhập Cho phép sinh viên / Admin đăng nhập vào hệ thống.
Sinh viên/Admin Đăng ký Cho phép sinh viên đăng đăng ký tài khoản để là thành viên của câu lạc bộ.
Quên Mật Khẩu Cho phép sinh viên đổi mật khẩu khi quân mật khẩu đăng nhập,
Hỏi Đáp Cho phép sinh viên đặt câu giải đáp những thắc mắc về câu lạc bộ, các hoạt động.
Xem Thông Tin Cho phép sinh viên xem thông tin về câu lạc bộ, các thành viên, các hoạt động
Cho phép admin quản lý (thêm, sửa, xóa) các thành viên trong câu lạc bộ.
Cho phép admin quản lý (thêm, sửa, xóa) các cuộc thi, các hoạt động diễn ra trong câu lạc bộ.
Cho phép admin quản lý (thêm, sửa, xóa) các câu lạc bộ trong câu lạc bộ tin học.
Cho phép admin đánh giá thành viên trong câu lạc bộ.
Hình 2.4: Biểu đồ usecase của hệ thống
2.3.2 Mô hình hóa dữ liệu và cài đặt hệ thống
Hính 2.5: Class Câu lạc bộ
Hình 2.6: Class Thành Viên
Hình 2.7: Class Cuộc Thi
Hình 2.8: Class Admin và class Đánh Giá Thành Viên
Hình 2.9: Class Tài Khoản và class Hỏi Đáp
Hình 2.10: Mối quan hệ giữa ThanhVien và CLB
- Mỗi thành viên có thể có 1 hay nhiều câu lạc bộ và mỗi câu lạc bộ có thể có
Hình 2.11: Mối quan hệ giữa ThanhVien và TaiKhoan
- Mỗi thành viên chỉ có thể có 1 tài khoản và mỗi tài khoản chỉ thuộc về 1 thành viên.
Hình 2.12: Mối quan hệ giữa ThanhVien và CuocThi
- Mỗi thành viên có thể tham gia 0, 1 hay nhiều cuộc thi và mỗi cuộc thi có thể có 1 hay nhiều thành viên tham gia.
Hình 2.13: Mối quan hệ giữa ThanhVien và HoiDap
- Mỗi thành viên có thể hỏi 0, 1 hay nhiều câu hỏi và một câu hỏi có thể được hỏi bởi 1 hay nhiều thành viên.
Hình 2.14: Mối quan hệ giữa ThanhVien và DangGiaThanhVien
- Mỗi thành viên có thể có 0, 1 hay nhiều đánh giá về mình và một đánh giá chỉ thuộc về 1 thành viên. n
Hình 2.15: Mối quan hệ giữa Admin và CLB
- Một câu lạc bộ có thể có 1 hay nhiều admin và một admin có thể quản lý 1 hay nhiều câu lạc bộ.
Hình 2.16: Mối quan hệ giữa Admin và TaiKhoan
- Mỗi admin chỉ có thể có 1 tài khoản và mỗi tài khoản chỉ thuộc về 1 admin.
Hình 2.17: Mối quan hệ giữa Admin và CuocThi
- Môt admin có thể tham gia tổ chức 0, 1 hay nhiều cuộc thi và một cuộc thi có thể được 1 hay nhiều admin tổ chức.
Hình 2.18: Mối quan hệ giữa Admin và HoiDap
- Một admin có thể trả lời 1 hay nhiều câu hỏi và một câu hỏi có thể đặt ra cho 1 hay nhiều admin.
Hình 2.19: Mối quan hệ giữa Admin và DanhGiaThanhVien
- Một admin có thể có 0, 1 hay nhiều đánh giá về thành viên và một đánh giá có thể từ 1 hay nhiều admin đưa ra.
Hình 2.20: Sơ đồ lớp của hệ thống
Thực hiện bài toán
2.4.1.1 Giao diện của thành viên
Hình 2.21: Giao diện đăng ký
Hình 2.22: Giao diện đăng nhập
Hình 2.23: Giao diện quên mật khẩu
Hình 2.24: Giao diện đổi mật khẩu
Hình 2.25: Giao diện đổi mật khẩu cấp 2
Hình 2.26: Giao diện thông tin tài khoản
Hình 2.27: Giao diện xem câu lạc bộ
Hình 2.28: Giao diện tìm kiếm thành viên
Hình 2.29: Giao diện thông báo cuộc thi
Hình 2.30: Giao diện chat
Hình 2.31: Giao diện đăng nhập
Hình 2.32: Giao diện quản lý câu lạc bộ
Hình 2.33: Giao diện quản lý cuộc thi
Hình 2.34: Giao diện quản lý thành viên
Hình 2.35: Giao diện chat
2.4.2 Chức năng quản lý clb và trò chuyện
- Quản lý Câu lạc bộ
// Hiển thị câu lạc bộ private void showclb() {
CLBList = Modify_CLB.findAll(); tableModel.setRowCount(0);
CLBList.forEach(infor_CLB -> { tableModel.addRow(new Object[]{tableModel.getRowCount() + 1, infor_CLB.getTenCLB(), infor_CLB.getThanhVien()});
//Thêm câu lạc bộ private void AddCLBActionPerformed(java.awt.event.ActionEvent evt) { // kiểm tra nhập dữ liệu
StringBuilder sb = new StringBuilder(); if(txtTenCLB.getText().trim().equals("")){ sb.append("Tên câu lạc bộ không dược để trống!");
JOptionPane.showMessageDialog(this,sb.toString(),
Infor_CLB std = new Infor_CLB(tenclb);
Modify_CLB.insertclub(std); showclb();
//Sửa câu lạc bộ private void UpdateCLBActionPerformed(java.awt.event.ActionEvent evt) {
// Kiểm tra hợp lệ int selectedIndex = tblCLB.getSelectedRow();
System.out.println(selectedIndex); if (tblCLB.getSelectedRow() == -1) {
JOptionPane.showMessageDialog(this, "Bạn cần chọn câu lạc bộ để thay thế!");
//Nhập duwx liệu để sửa Infor_CLB std = CLBList.get(selectedIndex);
String input = JOptionPane.showInputDialog(this, "Nhập tên để sửa: "); if (input.trim().equals("")) {
JOptionPane.showMessageDialog(this, "Bạn cần nhập tên câu lạc bộ để thay thế!");
} else { int option = JOptionPane.showConfirmDialog(this, "Bạn chắc chắn muốn sửa câu lạc bộ này chứ?"); if (option == 0) {
//Sửa câu lạc bộ Modify_CLB.updateclub(input, std.getMaCLB()); showclb();
//Xóa câu lạc bộ private void RemoveCLBActionPerformed(java.awt.event.ActionEvent evt) {
//Kiểm tra hợp lệ int selectedIndex = tblCLB.getSelectedRow(); if (tblCLB.getSelectedRow() == -1) {
JOptionPane.showMessageDialog(this, "Bạn cần chọn câu lạc bộ để xóa!");
//Lấy phần tử cần xóa if (selectedIndex >= 0) {
Infor_CLB std = CLBList.get(selectedIndex); if (std.getThanhVien() == 0) { int option = JOptionPane.showConfirmDialog(this, "Bạn chắc chắn muốn xóa câu lạc bộ này chứ?"); if (option == 0) {
// Xóa câu lạc bộ Modify_CLB.deleteclub(std.getMaCLB()); showclb();
JOptionPane.showMessageDialog(this, "Câu lạc bộ còn thành viên không thể xóa!");
// Làm mới cửa sổ private void resetActionPerformed(java.awt.event.ActionEvent evt) { txtTenCLB.setText(""); showclb();
- Trao đổi giữa admin và thành viên
// Lớp chat public class ChatMessageSocket { private Socket socket; private JTextPane txpMessageBoard; private PrintWriter out; // Đối tượng gửi private BufferedReader reader; // Đối tượng nhận
The constructor for the `ChatMessageSocket` class initializes a socket connection and a text message board It takes a `Socket` and a `JTextPane` as parameters, establishing output and input streams for communication The output stream is set up using `PrintWriter`, while the input stream is handled with `BufferedReader` The method concludes by calling the `receive()` function to start processing incoming messages.
//Hàm nhận dữ liệu từ socket private void receive(){
Thread th = new Thread(){ public void run(){ while(true){ try {
String line = reader.readLine(); if(line != null){ txpMessageBoard.setText(txpMessageBoard.getText() + "\ n" + line);
//Hàm gửi public void Send(String msg){
String curent = txpMessageBoard.getText(); txpMessageBoard.setText(curent + "\n" + msg); out.println(msg); out.flush();
} public void close(){ try { out.close(); reader.close(); socket.close();
// Hàm mở server private void btnListenActionPerformed(java.awt.event.ActionEvent evt) { try { int port = Integer.parseInt(txtPort.getText());
ServerSocket serverSocket = new ServerSocket(port);
Thread th = new Thread(){ public void run(){ try {
// Kiểm tra xem server có sẵn sàng nhận dữ liệu hay không txpMessageBoard.setText(txpMessageBoard.getText() + "\ nListening ");
Socket socket = serverSocket.accept(); mSocket = new ChatMessageSocket(socket,txpMessageBoard);
} catch (Exception e) { txpMessageBoard.setText("Error: " + e.getMessage()); e.printStackTrace();
JOptionPane.showMessageDialog(this, "Error: " + e.getMessage()); e.printStackTrace();
//Hàm gửi tin nhắn private void btnSendActionPerformed(java.awt.event.ActionEvent evt) { // kiểm tra tin nhắn if(txtMessage.getText().equals("")){ return;
// Gửi tin nhắn tới thành viên mSocket.Send(View_DangNhap.UserName + ": " + txtMessage.getText()); txtMessage.setText("");
//Hàm kết nối tới server private void btnConnetActionPerformed(java.awt.event.ActionEvent evt) { try { int port = Integer.parseInt(txtPort.getText());
Socket socket = new Socket(txtServerHost.getText(), port); mSocket = new ChatMessageSocket(socket, txpMessageBoard); txpMessageBoard.setText(txpMessageBoard.getText() + "\ nConnected!");
JOptionPane.showMessageDialog(this, "Error: " + e.getMessage()); e.printStackTrace();
//Hàm gửi tin nhắn tới admin private void btnSendActionPerformed(java.awt.event.ActionEvent evt) { if(txtMessage.getText().equals("")){ return;
} mSocket.Send(View_DangNhap.UserName + ": " + txtMessage.getText()); txtMessage.setText("");
2.4.3 Chức năng của thành viên: xem clb, xem thành viên, tìm kiếm thành viên
// Hàm đổ dữ liệu danh sách clb private void showCLB(){
CLBList = Modify_CLB.findAll(); tableModel.setRowCount(0);
CLBList.forEach((clb) -> { tableModel.addRow(new Object[]{tableModel.getRowCount() + 1, clb.getTenCLB(), clb.getThanhVien()});
// Hàm đổ dữ liệu thành viên + Hoàn tác trong giao diện View_ThanhVien private void showThanhVien() {
TVList = Modify_ThanhVien.findAll(); tableModel.setRowCount(0);
TVList.forEach((tv) -> { tableModel.addRow(new Object[]{tv.getTen(), tv.getGioiTinh(), tv.getNgaySinh(), tv.getSdt(), tv.getEmail()});
// Hàm đổ tên clb ra combobox private void showComboCLB(){
CLBList.forEach((clb) -> { cbCLB.addItem(clb.TenCLB);
// Khai báo 1 biến DefaultTableModel tableModel; để đổ dữ liệu ra bảng thật // Khởi tạo cho tableModel tableModel = (DefaultTableModel) tblThanhVien.getModel();
// Hàm tìm kiếm thành viên theo tên
+ Show ra 1 inputDialog để người dùng nhập tên cần tìm.
Nếu input để trống, sẽ hiển thị thông báo; nếu có input, sẽ gọi hàm findByName() trong Modify_ThanhVien để tìm danh sách tên tương ứng và sử dụng tableModel để hiển thị dữ liệu ra bảng trong giao diện.
If no matching names are found, a notification will appear stating that the data does not exist In the code snippet, a prompt asks the user to enter a name for the search, and if the input is empty, the process will handle it accordingly.
JOptionPane.showMessageDialog(this, "Không có dữ liệu tìm kiếm"); showThanhVien();
TVList = Modify_ThanhVien.findByName(input); tableModel.setRowCount(0);
TVList.forEach((tv) -> { tableModel.addRow(new Object[]{tv.getTen(), tv.getGioiTinh(), tv.getNgaySinh(), tv.getSdt(), tv.getEmail()});
JOptionPane.showMessageDialog(this, "Dữ liệu tìm kiếm không tồn tại"); showThanhVien();
// Hàm tìm kiếm thành viên theo CLB
+ Lấy ra tên clb từ combobox, tạo 1 List chứa danh sách các câu lạc bộ,dùng vòng lặp để chạy List.
+ Nếu tên clb được chọn trong combobox trùng với tên clb thì lấy ra id của clb được chọn tương ứng.
To display data in the interface, execute the findByClubID() method within Modify_ThanhVien and utilize tableModel to populate the table.
//dinh nghia clb duoc select va ma clb duoc chon
Infor_CLB chon_clb = null; int ma_clb = 0; for (Infor_CLB club : CLBList) { if(club.TenCLB.equals(cbCLB.getSelectedItem().toString())){ chon_clb = club;
} if(chon_clb != null){ ma_clb = chon_clb.getMaCLB();
TVList = Modify_ThanhVien.findByClubID(ma_clb); tableModel.setRowCount(0);
TVList.forEach((tv) -> { tableModel.addRow(new Object[]{tv.getTen(), tv.getGioiTinh(), tv.getNgaySinh(), tv.getSdt(), tv.getEmail()});
2.4.4 Chức năng của thành viên: đăng ký, đăng nhập, quên mật khẩu, thông tin tài khoản, đổi mật mã cấp hai, đổi mật khẩu, đăng xuất
Nhập thông tin qua các trường JTextField, JPasswordField và JComboBox trong JFrame để thực hiện các thao tác thêm, sửa, xóa dữ liệu của chương trình.
+ Tạo các biến để lấy ra thông tin từ form để thực hiện Validate.
+ Tạo 1 List của các CLB trong database, sau đó thêm thuộc tính "Tên CLB" của từng đối tượng trong List vào combobox.
Để kiểm tra xem tài khoản đăng ký đã tồn tại hay chưa, chúng ta tạo một biến dạng boolean Nếu tài khoản chưa tồn tại và thỏa mãn điều kiện Validate, ta sẽ gọi hàm Register() trong Modify_ThanhVien để thực hiện quá trình đăng ký Sau đó, gọi hàm TangThanhVien trong Modify_CLB để tăng số lượng thành viên trong CLB tương ứng.
String gioitinh = cbGioiTinh.getSelectedItem().toString();
String taikhoan = txtTaiKhoan.getText(); char[] matkhau = pwMatKhau.getPassword(); char[] xacnhanmk = pwXacNhanMK.getPassword(); char[] macaphai = pwMKCapHai.getPassword();
String mk = String.valueOf(matkhau);
String xnmk = String.valueOf(xacnhanmk);
String mc2 = String.valueOf(macaphai);
JFrame frame = new JFrame("JOptionPane showMessageDialog example");
//xac nhan password sai thi thong bao if (ten.equals("") || ngaysinh.equals("") || txtSDT.getText().equals("") || email.equals("") || taikhoan.equals("") || mk.equals("") || xnmk.equals("") || mc2.equals("")) {
JOptionPane.showMessageDialog(frame, "Vui lòng nhập đầy đủ thông tin");
} else if (!mk.equals(xnmk)) {
JOptionPane.showMessageDialog(frame, "Xác nhận mật khẩu không đúng");
//lay ra clb duoc chon tuong ung voi combobox
Infor_CLB chon_clb = null; int ma_clb = 0; for (Infor_CLB club : CLBList) { if (club.TenCLB.equals(cbCLB.getSelectedItem().toString())) { chon_clb = club;
} if (chon_clb != null) { ma_clb = chon_clb.getMaCLB();
Infor_ThanhVien sv = new Infor_ThanhVien(ma_clb, ten, gioitinh, ngaysinh, sdt, email, taikhoan, mk, mc2); boolean check = true;
TVList = Modify_ThanhVien.findAll(); for (Infor_ThanhVien tv : TVList) { if (tv.TaiKhoan.equals(sv.TaiKhoan)) { check = false;
JOptionPane.showMessageDialog(frame, "Đăng ký thành công"); //them 1 thanh vien -> +1 so luong thanh vien o bang clb tuong ung Modify_CLB.TangThanhVien(chon_clb);
JOptionPane.showMessageDialog(frame, "Tài khoản đã tồn tại"); }
+ Tạo các biến để lấy ra thông tin từ form để thực hiện Validate.
+ Tạo 1 biến boolean để kiểm tra sự tồn tại của tài khoản, nếu tài khoản chưa có -> không thể đăng nhập.
Nếu tài khoản được xác thực và kiểm tra thành công, hệ thống sẽ thông báo đăng nhập thành công và chuyển hướng người dùng đến cửa sổ dành cho sinh viên.
String username = txtTaiKhoan.getText(); char[] pw = pwMatKhau.getPassword();
String password = String.valueOf(pw);
//check tai khoan boolean check = false;
TVList = Modify_ThanhVien.findAll(); for (Infor_ThanhVien tv : TVList) { if(tv.TaiKhoan.equals(username) && tv.MatKhau.equals(password)){ check = true;
} if(username.equals("") || password.equals("")){
JOptionPane.showMessageDialog(null, "Vui lòng điền đầy đủ thông tin");
JOptionPane.showMessageDialog(null, "Tài khoản hoặc mật khẩu không đúng");
JOptionPane.showMessageDialog(null, "Đăng nhập thành công"); //dang nhap thanh cong, chuyen cua so
UserName = username; close(); if(username.equals("admin")){
View_QuanLyCLB qlclb = new View_QuanLyCLB(); qlclb.setVisible(true);
View_CLB clb = new View_CLB(); clb.setVisible(true);
+ Tạo các biến để lấy ra thông tin từ form để thực hiện Validate.
+ Tạo 1 biến boolean để kiểm tra sự tồn tại của tài khoản, nếu tài khoản chưa có -> không thể thực hiện chức năng.
To reset the password, ensure all conditions are met and call the `quenMatKhau()` function within `Modify_ThanhVien`.
String tk = txtTaikhoan.getText(); char[] macaphai = pwMaCapHai.getPassword();
String mc2 = String.valueOf(macaphai); char[] matkhau = pwMKMoi.getPassword();
String mk = String.valueOf(matkhau); char[] xacnhanmk = pwXacNhanMK.getPassword();
String xnmk = String.valueOf(xacnhanmk);
TVList = Modify_ThanhVien.findAll(); boolean check = false, pass2 = false; for (Infor_ThanhVien tv : TVList) { if(tv.TaiKhoan.equals(tk)){ check = true;
} for (Infor_ThanhVien tv : TVList) { if(tv.MaCapHai.equals(mc2)){ pass2 = true;
} if(tk.equals("") || mk.equals("") || xnmk.equals("") || mc2.equals("")){ JOptionPane.showMessageDialog(null, "Vui lòng điền đầy đủ thông tin");
} else if(!mk.equals(xnmk)){
JOptionPane.showMessageDialog(null, "Mật khẩu không trùng khớp");
JOptionPane.showMessageDialog(null, "Tài khoản không tồn tại"); } else if(!pass2){
JOptionPane.showMessageDialog(null, "Sai mật khẩu cấp hai");
Modify_ThanhVien.quenMatKhau(tk, mk);
JOptionPane.showMessageDialog(null, "Thao tác thành công"); clear();
4.1, Hàm show thông tin của user vừa đăng nhập:
- Lấy ra tên tài khoản từ biến Static "UserName" từ View_DangNhap để lấy thông tin tài khoản từ Database.
- Set dữ liệu cho các trường textfield, combobox và label từ đối tượng vừa lấy được từ username. private void ShowInfor(){
String username = View_DangNhap.UserName;
TVList = Modify_ThanhVien.findByUsername(username);
Infor_ThanhVien member = new Infor_ThanhVien(); member = TVList.get(0); txtTen.setText(member.getTen()); txtNgaySinh.setText(member.getNgaySinh()); txtSdt.setText(member.getSdt()); txtEmail.setText(member.getEmail()); cbGioiTinh.setSelectedItem(member.GioiTinh);
CLBList = Modify_CLB.findAll(); for (Infor_CLB club : CLBList) { if(club.MaCLB == member.Ma_CLB){
} if(!Club_name.equals("")){ lbTenCLB.setText(Club_name);
4.2, Hàm cập nhật thông tin:
- Validate thông tin có trong các trường thông tin của username vừa đăng nhập.
- Tạo 1 JOptionPane để xác nhận xem người dùng có muốn đổi thông tin không.
If agreed, the updateTaiKhoan() function in Modify_ThanhVien will be executed; if not, no action will occur In the jButton1ActionPerformed method, if CheckData() does not return an empty string, the process will continue as intended.
String[] choice = {"Đồng ý", "Không"}; int x = JOptionPane.showOptionDialog(null, "Bạn có chắc muốn sửa thông tin?", "Thông báo", 0, JOptionPane.QUESTION_MESSAGE, null, choice, EXIT_ON_CLOSE);
String username = View_DangNhap.UserName;
TVList = Modify_ThanhVien.findByUsername(username); mem = TVList.get(0); mem.Ten = txtTen.getText(); mem.GioiTinh = cbGioiTinh.getSelectedItem().toString(); mem.NgaySinh = txtNgaySinh.getText(); mem.Email = txtEmail.getText(); mem.Sdt = txtSdt.getText();
JOptionPane.showMessageDialog(null, "Cập nhật thông tin thành công");
5, Đổi mật mã cấp hai
+ Tạo biến lấy thông tin từ form, validate dữ liệu.
+ Nếu thỏa mãn hết điều kiện thì khi click đổi thì show ra JoptionPane để xác nhận.
If you agree, call the updatePassTwo() function in Modify_ThanhVien; if you do not agree, nothing will happen.
//lấy thông tin từ form
String username = this.menuTaiKhoan.getText(); char[] pw = pwMatKhau.getPassword(); char[] old_pw2 = pwOldP2.getPassword(); char[] pw2 = pwPass2.getPassword(); char[] cpw2 = pwConfirmPass2.getPassword();
String password = String.valueOf(pw);
String old_pass2 = String.valueOf(old_pw2);
String password_two = String.valueOf(pw2);
String confirm = String.valueOf(cpw2);
TVList = Modify_ThanhVien.findByUsername(username);
Infor_ThanhVien mem = TVList.get(0); if (password.equals("") || password_two.equals("") || confirm.equals("")) {
JOptionPane.showMessageDialog(null, "Vui lòng nhập đầy đủ thông tin");
} else if(!mem.MaCapHai.equals(old_pass2)) {
JOptionPane.showMessageDialog(null, "Mã cấp hai cũ không đúng"); } else if (!password_two.equals(confirm)) {
JOptionPane.showMessageDialog(null, "Xác nhận mã cấp hai không đúng");
} else if(!mem.MatKhau.equals(password)) {
JOptionPane.showMessageDialog(null, "Mật khẩu không chính xác"); } else {
String [] choice = {"Đồng ý", "Không"}; int x = JOptionPane.showOptionDialog(null, "Bạn có chắc muốn sửa thông tin?", "Thông báo", 0, JOptionPane.QUESTION_MESSAGE, null, choice, EXIT_ON_CLOSE); if(x == 0){
Modify_ThanhVien.updatePassTwo(username, password_two); JOptionPane.showMessageDialog(null, "Đổi mật mã cấp hai thành công"); close();
View_CLB clb = new View_CLB(); clb.setVisible(true);
+ Tạo biến lấy thông tin từ form, validate dữ liệu.
+ Nếu thỏa mãn hết điều kiện thì khi click đổi thì gọi hàm doiMatKhau() trong Modify_ThanhVien để thao tác.
+ Chuyển hướng người dùng đến trang đăng nhập nếu thành công. private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here:
//lay du lieu tu form
String username = txtUsername.getText(); char[] new_password = pwNew.getPassword();
String new_pw = String.valueOf(new_password); char[] old_password = pwOld.getPassword();
String old_pw = String.valueOf(old_password); char[] confirm_password = pwConfirm.getPassword();
String confirm_pw = String.valueOf(confirm_password);
//tao bien boolean check tai khoan da ton tai chua boolean check_username = false; for (Infor_ThanhVien mem : TVList) { if(mem.TaiKhoan.equals(username)){ check_username = true;
To verify the validity of a username and password, a boolean variable named `check_password` is initialized to false The system iterates through a list of members, `TVList`, checking if the provided username matches any existing account and if the corresponding password matches the stored password If both conditions are met, `check_password` is set to true, indicating successful authentication.
} if(username.equals("") || old_pw.equals("") || new_pw.equals("") || confirm_pw.equals("")){
JOptionPane.showMessageDialog(null, "Vui lòng điền đầy đủ thông tin");
} else if(!new_pw.equals(confirm_pw)){
JOptionPane.showMessageDialog(null, "Xác nhận mật khẩu không đúng");
JOptionPane.showMessageDialog(null, "Tài khoản không tồn tại"); } else if(!check_password){
JOptionPane.showMessageDialog(null, "Tài khoản hoặc mật khẩu không đúng");
Modify_ThanhVien.doiMatKhau(username, new_pw);
JOptionPane.showMessageDialog(null, "Đổi mật khẩu thành công");
//chuyen huong nguoi dung ra trang dang nhap close();
View_DangNhap dn = new View_DangNhap(); dn.setVisible(true);
+ đưa ra 1 JOptionPane để xác nhận ý kiến người dùng.
Nếu người dùng đồng ý, cửa sổ hiện tại sẽ đóng và họ sẽ được chuyển hướng đến trang đăng nhập Ngược lại, nếu không đồng ý, người dùng sẽ ở lại trang hiện tại.
String [] choice = {"Đồng ý", "Không"}; int x = JOptionPane.showOptionDialog(null, "Bạn có chắc muốn đăng xuất ?", "Thông báo", 0, JOptionPane.QUESTION_MESSAGE, null, choice, EXIT_ON_CLOSE); if(x == 0){ close();
View_DangNhap logout = new View_DangNhap(); logout.setVisible(true);
2.4.5 Chức năng quản lý thành viên của admin
Kiểm tra định dạng thông tin nhập vào là một bước quan trọng trong lập trình Hàm CheckData() sử dụng biểu thức chính quy để xác minh xem ngày sinh có đúng định dạng hay không Nếu ngày sinh không khớp với định dạng (VD: 01/01/2001), hàm sẽ trả về thông báo yêu cầu người dùng nhập lại đúng định dạng.
} if (!Pattern.matches("[0]{1}\\d{9,10}", txtSdt.getText())) { return "Vui lòng nhập đúng định dạng số điện thoại (VD: 0912345678).";
} if (!Pattern.matches("^(.+)@(.+)$", txtEmail.getText())) { return "Vui lòng nhập đúng định dạng email (VD: example@gmail.com).";
} if (!Pattern.matches("[a-zA-Z]{3,}", txtTaiKhoan.getText())) { return "Tài khoản cần có ít nhất 3 kí tự.";
} if (!Pattern.matches("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#&()– [{}]:;',?/*~$^+=]).{8,20}$", txtMatKhau.getText())) { return "Mật khẩu có từ 8-20 kí tự Có ít nhất 1 số, 1 chữ, 1 chữ viết hoa và 1 kí tự đặc biệt ( VD: ! ( ) @ # & )";
+ Lấy thông tin được nhập vào textbox và combobox.
+ Kiểm tra các trường thông tin có nhập đầy đủ và đúng định dạng hay không
+ Lưu thành viên mới vào CSDL và hiển thị lên giao diện. private void btnThemActionPerformed(java.awt.event.ActionEvent evt) { CLBList = Modify_CLB.findAll();
Infor_CLB chon_clb = null; for (Infor_CLB club : CLBList) { if(club.TenCLB.equals(cbCLB.getSelectedItem().toString())){ chon_clb = club;
String error = ""; if (txtTenThanhVien.getText().trim().equals("")) { error += "Không để trống thành viên!\n";
} if (txtNgaySinh.getText().trim().equals("")) { error += "Không để trống Ngày sinh!\n";
} if (txtSdt.getText().trim().equals("")) { error += "Không để trống số điện thoại\n";
} if (txtEmail.getText().trim().equals("")) { error += "Không để trống Email!\n";
} if (txtTaiKhoan.getText().trim().equals("")) { error += "Không để trống tài khoản!\n";
} if (txtMatKhau.getText().trim().equals("")) { error += "Không để trống mật khẩu!\n";
} if (txtMatKhauHai.getText().trim().equals("")) { error += "Không để trống mật khẩu cấp 2!";
} if (error != "") { sb.append(error);
JOptionPane.showMessageDialog(this, sb.toString(), "Invalidation", JOptionPane.ERROR_MESSAGE);
} else { int MaCLB = chon_clb.getMaCLB();
String GioiTinh = cbCLB.getSelectedItem().toString();
Infor_ThanhVien tv = new Infor_ThanhVien(MaCLB, Ten, GioiTinh, NgaySinh, Sdt, Email, TK, MK, MCH);
Modify_CLB.SoThanhVien(MaCLB); showtv();
+ Lấy thông tin thành viên được chọn trong table
+ Lấy thông tin được nhập vào textbox và combobox
+ Kiểm tra các trường thông tin có nhập đầy đủ và đúng định dạng hay không
+ Sửa thành viên mới và lưu vào CSDL và hiển thị lên giao diện. private void btnSuaActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here:
//dinh nghia clb duoc select va ma clb duoc chon
Infor_CLB chon_clb = null; for (Infor_CLB club : CLBList) { if(club.TenCLB.equals(cbCLB.getSelectedItem().toString())){ chon_clb = club;
} if (txtTenThanhVien.getText().trim().equals("")) { error += "Không để trống thành viên!\n";
} if (txtNgaySinh.getText().trim().equals("")) { error += "Không để trống Ngày sinh!\n";
} if (txtSdt.getText().trim().equals("")) { error += "Không để trống số điện thoại\n";
} if (txtEmail.getText().trim().equals("")) { error += "Không để trống Email!\n";
} if (txtTaiKhoan.getText().trim().equals("")) { error += "Không để trống tài khoản!\n";
} if (txtMatKhau.getText().trim().equals("")) { error += "Không để trống mật khẩu!\n";
} if (txtMatKhauHai.getText().trim().equals("")) { error += "Không để trống mật khẩu cấp 2!";
} if (error != "") { sb.append(error);
JOptionPane.showMessageDialog(this, sb.toString(), "Invalidation", JOptionPane.ERROR_MESSAGE);
} else { int selectedIndex = tblThanhVien.getSelectedRow(); if (selectedIndex >= 0) {
Infor_ThanhVien std = tvList.get(selectedIndex); int option = JOptionPane.showConfirmDialog(this, "Bạn chắc chắn muốn sửa thành viên này chứ?"); int MaSV = std.getMaSV(); int MaCLB = chon_clb.getMaCLB();
String GioiTinh = cbbGT.getSelectedItem().toString();
Infor_ThanhVien tv = new Infor_ThanhVien(MaSV, MaCLB, Ten, GioiTinh, NgaySinh, Sdt, Email, TK, MK, MCH); if (option == 0) {
Modify_ThanhVien.SuaTV(tv); showtv();
Enter the member's name into the input box, and the system will search for members with matching names, displaying the results in a table format.
String input = JOptionPane.showInputDialog(this, "Nhập tên thành viên:
The code snippet provided checks if the input is not null and has a length greater than zero, then retrieves a list of members based on the input using the `Modify_ThanhVien.timten` method It resets the table model's row count to zero and populates the table with the details of each member, including their ID, name, gender, date of birth, phone number, email, account, password, and secondary ID.