diff --git a/Announcement.java b/Announcement.java new file mode 100644 index 0000000..faadd6e --- /dev/null +++ b/Announcement.java @@ -0,0 +1,94 @@ +package DBD_env_unification; + +import java.sql.Timestamp; + +public class Announcement { + private int textNumber; + private String title; + private String managerName; + private String type; + private Timestamp createDate; + private int views; + private String content; + + // 생성자 + public Announcement(int textNumber, String title, String managerName, String type, + Timestamp createDate, int views, String content) { + this.textNumber = textNumber; + this.title = title; + this.managerName = managerName; + this.type = type; + this.createDate = createDate; + this.views = views; + this.content = content; + } + + // Getter 및 Setter + public int getTextNumber() { + return textNumber; + } + + public void setTextNumber(int textNumber) { + this.textNumber = textNumber; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getManagerName() { + return managerName; + } + + public void setManagerName(String managerName) { + this.managerName = managerName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public int getViews() { + return views; + } + + public void setViews(int views) { + this.views = views; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + // 출력 메서드 (옵션) + public void printAnnouncement() { + System.out.println("Text Number: " + textNumber); + System.out.println("Title: " + title); + System.out.println("Manager Name: " + managerName); + System.out.println("Type: " + type); + System.out.println("Create Date: " + createDate); + System.out.println("Views: " + views); + System.out.println("Content: " + content); + System.out.println("---------------------------------------------------"); + } +} diff --git a/AnnouncementListFrame.java b/AnnouncementListFrame.java new file mode 100644 index 0000000..936310a --- /dev/null +++ b/AnnouncementListFrame.java @@ -0,0 +1,106 @@ +package DBD_env_unification; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; + +public class AnnouncementListFrame extends JFrame { + private ArrayList announcements; // List에서 ArrayList로 변경 + private MainPageFrame mainPageFrame; + + public AnnouncementListFrame(MainPageFrame mainPageFrame, ArrayList announcements) { + super("공지사항 목록"); + this.mainPageFrame = mainPageFrame; + this.announcements = announcements; + + setLayout(new BorderLayout()); + + // 제목 라벨 설정 + JLabel titleLabel = new JLabel("공지사항 목록", SwingConstants.CENTER); + titleLabel.setFont(new Font("맑은 고딕", Font.BOLD, 24)); + titleLabel.setForeground(Color.BLACK); + add(titleLabel, BorderLayout.NORTH); + + // 공지사항 목록을 표시할 JList + DefaultListModel listModel = new DefaultListModel<>(); + for (Announcement announcement : announcements) { + listModel.addElement(announcement.getTitle()); // 제목만 추가 + } + + JList announcementList = new JList<>(listModel); + announcementList.setFont(new Font("맑은 고딕", Font.PLAIN, 16)); + announcementList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + JScrollPane scrollPane = new JScrollPane(announcementList); + add(scrollPane, BorderLayout.CENTER); + + // 창이 닫힐 때 메인 페이지 프레임을 다시 보이게 설정 + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent windowEvent) { + mainPageFrame.setVisible(true); // MainPageFrame을 다시 보이게 함 + } + }); + + // "뒤로 가기" 버튼 추가 + JButton backButton = new JButton("뒤로 가기"); + backButton.setFont(new Font("맑은 고딕", Font.PLAIN, 16)); + backButton.addActionListener(e -> { + // 뒤로 가기 버튼 클릭 시, MainPageFrame을 다시 보이게 하고 현재 프레임을 닫기 + mainPageFrame.setVisible(true); + dispose(); + }); + add(backButton, BorderLayout.SOUTH); + + // 공지사항 선택 시 본문을 보여주는 액션 + announcementList.addListSelectionListener(e -> { + if (!e.getValueIsAdjusting()) { + int selectedIndex = announcementList.getSelectedIndex(); + if (selectedIndex != -1) { + Announcement selectedAnnouncement = announcements.get(selectedIndex); + showAnnouncementDetails(selectedAnnouncement); + } + } + }); + + + + // 프레임 설정 + setSize(500, 400); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setLocationRelativeTo(null); // 화면 가운데에 표시 + setVisible(true); + } + + // 선택한 공지사항의 본문을 보여주는 메서드 + private void showAnnouncementDetails(Announcement announcement) { + JFrame detailFrame = new JFrame("공지사항 상세보기"); + detailFrame.setLayout(new BorderLayout()); + + // 본문을 보여주는 JTextArea + JTextArea contentArea = new JTextArea(announcement.getContent()); + contentArea.setFont(new Font("맑은 고딕", Font.PLAIN, 14)); + contentArea.setLineWrap(true); + contentArea.setWrapStyleWord(true); + contentArea.setCaretPosition(0); + contentArea.setEditable(false); + + JScrollPane scrollPane = new JScrollPane(contentArea); + detailFrame.add(scrollPane, BorderLayout.CENTER); + + // 공지사항 상세정보 패널 + JPanel infoPanel = new JPanel(); + infoPanel.setLayout(new GridLayout(4, 1)); + + // 공지사항 정보 출력 + infoPanel.add(new JLabel("작성자: " + announcement.getManagerName())); + infoPanel.add(new JLabel("작성일: " + announcement.getCreateDate().toString())); + infoPanel.add(new JLabel("조회수: " + announcement.getViews())); + + detailFrame.add(infoPanel, BorderLayout.NORTH); + + // 상세보기 창 설정 + detailFrame.setSize(600, 400); + detailFrame.setLocationRelativeTo(null); // 화면 가운데에 표시 + detailFrame.setVisible(true); + } +} diff --git a/DatabaseAuthInformation.java b/DatabaseAuthInformation.java new file mode 100644 index 0000000..d1719cf --- /dev/null +++ b/DatabaseAuthInformation.java @@ -0,0 +1,156 @@ +package DBD_env_unification; + +import java.io.*; + +/* + * Written by Seonghun Lee on 6. Sep. 2020. + * + * This class parses the mysql database authentication file and stores the DB connection information. + * Setting the class member variables is only permitted in the parsing stage (parse_auth_info). + * */ +public class DatabaseAuthInformation { + private String host; + private String port; + private String database_name; + private String username; + private String password; + + /* + * Class Constructor with no argument. + * It initializes all member values as null. + * */ + public DatabaseAuthInformation() { + this.host = null; + this.port = null; + this.database_name = null; + this.username = null; + this.password = null; + } + + /* + * Parsing function based on given DB authentication file. + * This function check the file verification first, and then parse the given file. + * + * Parameter + * - auth_filepath: String + * Path of the local DB authentication file. + * + * Return + * - Boolean + * Return true for successful data parsing, and false otherwise. + * Wrong file path or any missing on DB connection information is also regarded as fail. + * */ + public boolean parse_auth_info(String auth_filepath) { + String host = null; + String port = null; + String database_name = null; + String username = null; + String password = null; + + /* Parse */ + try { + File file = new File(auth_filepath); + BufferedReader br = new BufferedReader(new FileReader(file)); + String line; + while ((line = br.readLine()) != null) { + if(line.length() == 0) continue; + if(line.charAt(0) == '#') continue; + + int line_length = line.length(); + if(line.substring(0, 4).equals("host")) host = line.substring(5, line_length); + else if(line.substring(0, 4).equals("port")) port = line.substring(5, line_length); + else if(line.substring(0, 8).equals("database")) database_name = line.substring(9, line_length); + else if(line.substring(0, 8).equals("username")) username = line.substring(9, line_length); + else if(line.substring(0, 8).equals("password")) password = line.substring(9, line_length); + } + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + /* Verification */ + boolean flag_verified = true; + if(host == null) flag_verified = false; + if(port == null) flag_verified = false; + if(database_name == null) flag_verified = false; + if(username == null) flag_verified = false; + if(password == null) flag_verified = false; + if(!flag_verified) { + return false; + } + + /* Apply parsed values */ + this.host = host; + this.port = port; + this.database_name = database_name; + this.username = username; + this.password = password; + + return true; + } + + /* + * Getter for host member variable. + * + * Return + * - String + * Return the host member variable. + * */ + public String getHost() { + return host; + } + + /* + * Getter for port member variable. + * + * Return + * - String + * Return the port member variable. + * */ + public String getPort() { + return port; + } + + /* + * Getter for database name member variable. + * + * Return + * - String + * Return the database name member variable. + * */ + public String getDatabase_name() { + return database_name; + } + + /* + * Getter for username member variable. + * + * Return + * - String + * Return the username member variable. + * */ + public String getUsername() { + return username; + } + + /* + * Getter for password member variable. + * + * Return + * - String + * Return the password member variable. + * */ + public String getPassword() { + return password; + } + + /* + * Print all member variable for debug purpose. + * + * Return + * - None + * */ + public void debug_print() { + System.out.println("Host: " + this.host + ":" + this.port + "/" + this.database_name + "@" + this.username + ":" + this.password); + } +} diff --git a/EditInfoFrame.java b/EditInfoFrame.java new file mode 100644 index 0000000..7a660a7 --- /dev/null +++ b/EditInfoFrame.java @@ -0,0 +1,134 @@ +package DBD_env_unification; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class EditInfoFrame extends JFrame { + private JTextField idField, nameField, mailField, departmentField, positionField; + private JPasswordField passwordField; + private JButton saveButton; + private MainPageFrame mainPageFrame; + private User user; + + public EditInfoFrame(MainPageFrame mainPageFrame, User user, String user_id) { + super("내 정보 수정"); + this.mainPageFrame = mainPageFrame; + this.user = user; + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + mainPageFrame.setVisible(true); + } + }); + + setLayout(new BorderLayout(10, 10)); + JPanel infoPanel = new JPanel(new GridBagLayout()); + infoPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets = new Insets(5, 5, 5, 5); + + // ID (읽기 전용) + gbc.gridx = 0; + gbc.gridy = 0; + infoPanel.add(new JLabel("ID:"), gbc); + idField = new JTextField(user_id); + idField.setEditable(false); + gbc.gridx = 1; + infoPanel.add(idField, gbc); + + // 이름 + gbc.gridx = 0; + gbc.gridy = 1; + infoPanel.add(new JLabel("이름:"), gbc); + nameField = new JTextField(user.getName()); + gbc.gridx = 1; + infoPanel.add(nameField, gbc); + + // 메일 + gbc.gridx = 0; + gbc.gridy = 2; + infoPanel.add(new JLabel("메일:"), gbc); + mailField = new JTextField(user.getEmail()); + gbc.gridx = 1; + infoPanel.add(mailField, gbc); + + // 비밀번호 + gbc.gridx = 0; + gbc.gridy = 3; + infoPanel.add(new JLabel("비밀번호:"), gbc); + passwordField = new JPasswordField(); + gbc.gridx = 1; + infoPanel.add(passwordField, gbc); + + // 학과 (읽기 전용) + gbc.gridx = 0; + gbc.gridy = 4; + infoPanel.add(new JLabel("학과:"), gbc); + departmentField = new JTextField(user.getDepartment()); + departmentField.setEditable(false); + gbc.gridx = 1; + infoPanel.add(departmentField, gbc); + + // 지위 (읽기 전용) + gbc.gridx = 0; + gbc.gridy = 5; + infoPanel.add(new JLabel("지위:"), gbc); + positionField = new JTextField(user.getStatus()); + positionField.setEditable(false); + gbc.gridx = 1; + infoPanel.add(positionField, gbc); + + // 저장 버튼 + saveButton = new JButton("저장"); + gbc.gridx = 0; + gbc.gridy = 6; + gbc.gridwidth = 2; + gbc.anchor = GridBagConstraints.CENTER; + infoPanel.add(saveButton, gbc); + + // 패널 추가 + add(infoPanel, BorderLayout.CENTER); + +// 저장 버튼 동작 + saveButton.addActionListener(e -> { + saveChanges(); // 정보 저장 처리 + + // 저장 후 현재 프레임 닫기 + dispose(); + + // 메인 프레임 다시 띄우기 + mainPageFrame.setVisible(true); + }); + + // 프레임 설정 + setSize(400, 300); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setLocationRelativeTo(null); // 화면 가운데 표시 + setVisible(true); + } + + private void saveChanges() { + String updatedName = nameField.getText(); + String updatedMail = mailField.getText(); + String updatedPassword = new String(passwordField.getPassword()); + + boolean updateComplete = user.updateUser("NAME", updatedName); + updateComplete = updateComplete && user.updateUser("Mail", updatedMail); + if(!updatedPassword.isEmpty()){ + updateComplete = updateComplete && user.updateUser("Password", updatedPassword); + } + + if(!updateComplete){ + JOptionPane.showMessageDialog(this, + "회원정보를 변경하는 데 실패하였습니다.\n다시 시도해 주세요.", + "저장 실패", + JOptionPane.ERROR_MESSAGE); + } + } +} + diff --git a/LoginFrame.java b/LoginFrame.java new file mode 100644 index 0000000..52a17e3 --- /dev/null +++ b/LoginFrame.java @@ -0,0 +1,89 @@ +package DBD_env_unification; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public class LoginFrame extends JFrame { + private Library library; + public LoginFrame(Library library) { + // 프레임 기본 설정 + super("Login"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(400, 300); + setLayout(null); + + // 제목 라벨 + JLabel titleLabel = new JLabel("Library System"); + titleLabel.setFont(new Font("Serif", Font.BOLD, 20)); + titleLabel.setHorizontalAlignment(SwingConstants.CENTER); + titleLabel.setBounds(50, 20, 300, 30); + add(titleLabel); + + // ID 라벨과 입력 필드 + JLabel idLabel = new JLabel("ID:"); + idLabel.setFont(new Font("Arial", Font.PLAIN, 14)); + idLabel.setBounds(50, 70, 80, 25); + add(idLabel); + + JTextField idField = new JTextField(); + idField.setBounds(150, 70, 200, 25); + add(idField); + + // Password 라벨과 입력 필드 + JLabel passwordLabel = new JLabel("Password:"); + passwordLabel.setFont(new Font("Arial", Font.PLAIN, 14)); + passwordLabel.setBounds(50, 110, 80, 25); + add(passwordLabel); + + JPasswordField passwordField = new JPasswordField(); + passwordField.setBounds(150, 110, 200, 25); + add(passwordField); + + // 버튼 스타일 + JButton loginButton = new JButton("Login"); + JButton registerButton = new JButton("Register"); + + loginButton.setBounds(50, 160, 130, 35); + loginButton.setBackground(new Color(59, 89, 182)); + loginButton.setForeground(Color.WHITE); + loginButton.setFocusPainted(false); + loginButton.setFont(new Font("Tahoma", Font.BOLD, 12)); + loginButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + String id = idField.getText(); + String password = new String(passwordField.getPassword()); + if(library.login(id, password)){ + new MainPageFrame(library); + dispose(); // 로그인 창 닫기 + }else{ + JOptionPane.showMessageDialog(LoginFrame.this, + "아이디 또는 비밀번호가 일치하지 않습니다.", + "Login Failed", + JOptionPane.ERROR_MESSAGE); + } + } + }); + add(loginButton); + + registerButton.setBounds(220, 160, 130, 35); + registerButton.setBackground(new Color(76, 175, 80)); + registerButton.setForeground(Color.WHITE); + registerButton.setFocusPainted(false); + registerButton.setFont(new Font("Tahoma", Font.BOLD, 12)); + registerButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + new RegisterFrame(getThis(), library); // 회원가입 창 띄우기 + } + }); + add(registerButton); + setVisible(true); + } + + public LoginFrame getThis(){ + return this; + } + +} diff --git a/MainPageFrame.java b/MainPageFrame.java new file mode 100644 index 0000000..cb877d5 --- /dev/null +++ b/MainPageFrame.java @@ -0,0 +1,133 @@ +package DBD_env_unification; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +public class MainPageFrame extends JFrame { + private Library library; + + public MainPageFrame(Library library) { + // 프레임 기본 설정 + super("Library System - Main Page"); + this.library = library; + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(500, 500); + setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + + // 배경 색상 설정 + getContentPane().setBackground(new Color(245, 245, 245)); // 배경을 밝은 회색으로 설정 + + // 제목 라벨 설정 (글자 색깔을 검은색으로 변경) + JLabel titleLabel = new JLabel("Library System - Main Menu"); + titleLabel.setFont(new Font("맑은 고딕", Font.BOLD, 24)); // 한글 지원 폰트 사용 + titleLabel.setForeground(Color.BLACK); // 제목 색깔을 검은색으로 설정 + titleLabel.setHorizontalAlignment(SwingConstants.CENTER); + + // 제목 위치 설정 (위쪽 여백을 추가하여 위로 이동) + gbc.gridwidth = 2; + gbc.gridx = 0; + gbc.gridy = 0; + gbc.insets = new Insets(40, 0, 20, 0); // 위쪽 간격을 40으로 늘리고 아래쪽 간격을 20으로 설정 + add(titleLabel, gbc); + + // 버튼 스타일 설정 (어두운 파란색 계열로 통일) + JButton searchButton = createStyledButton("도서 검색"); + JButton modifyInfoButton = createStyledButton("내 정보 수정"); + JButton borrowReturnButton = createStyledButton("대출/반납/연장"); + JButton boardButton = createStyledButton("게시판"); + JButton noticeButton = createStyledButton("공지사항"); + JButton storageButton = createStyledButton("개인 보관함"); + + noticeButton.addActionListener(e -> { + // AnnouncementListFrame을 띄우는 코드 + new AnnouncementListFrame(getThis(), library.showAnnouncement() ); // announcements는 공지사항 리스트입니다. + setVisible(false); + }); + + modifyInfoButton.addActionListener(e -> { + // myInfoFrame을 띄우는 코드 + new MyInfoFrame(this); + setVisible(false); + }); + + storageButton.addActionListener(e -> { + // userStorageFrame을 띄우는 코드 + new UserStorageFrame(this); + setVisible(false); + }); + + // 각 버튼의 배치 (세로 간격을 띄움) + gbc.gridwidth = 1; + gbc.gridx = 0; + gbc.gridy = 1; + gbc.insets = new Insets(10, 10, 20, 10); // 버튼 간 세로 간격을 20으로 설정 + add(searchButton, gbc); + + gbc.gridx = 1; + add(modifyInfoButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 2; + add(borrowReturnButton, gbc); + + gbc.gridx = 1; + add(boardButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 3; + add(noticeButton, gbc); + + gbc.gridx = 1; + add(storageButton, gbc); + + // 프레임 보이기 + setVisible(true); + } + + // 스타일링된 버튼 생성 메서드 (색상 통일) + private JButton createStyledButton(String text) { + JButton button = new JButton(text); + button.setFont(new Font("맑은 고딕", Font.BOLD, 16)); // 한글 지원 폰트 사용 + button.setForeground(Color.WHITE); // 텍스트는 하얀색 + button.setBackground(new Color(21, 101, 192)); // 어두운 파란색 계열로 변경 + button.setFocusPainted(false); + button.setPreferredSize(new Dimension(180, 50)); + + // 버튼 둥글게 만들기 + button.setBorder(BorderFactory.createLineBorder(new Color(21, 101, 192), 2, true)); // 어두운 파란색 테두리 + button.setContentAreaFilled(false); // 배경을 투명하게 + button.setOpaque(true); // 배경이 투명하지 않도록 설정 + + // 버튼에 테두리 추가 + button.setBorder(BorderFactory.createCompoundBorder( + button.getBorder(), + BorderFactory.createEmptyBorder(5, 5, 5, 5) + )); + + // 마우스 오버 효과 + button.addMouseListener(new java.awt.event.MouseAdapter() { + @Override + public void mouseEntered(java.awt.event.MouseEvent evt) { + button.setBackground(new Color(26, 115, 176)); // 마우스를 올리면 색상 밝아짐 + } + + @Override + public void mouseExited(java.awt.event.MouseEvent evt) { + button.setBackground(new Color(21, 101, 192)); // 마우스를 떼면 원래 색상 + } + }); + + + return button; + } + + private MainPageFrame getThis(){ + return this; + } + + public Library getLibrary(){ + return library; + } +} diff --git a/MyInfoFrame.java b/MyInfoFrame.java new file mode 100644 index 0000000..dce3a38 --- /dev/null +++ b/MyInfoFrame.java @@ -0,0 +1,85 @@ +package DBD_env_unification; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class MyInfoFrame extends JFrame { + private JTextField idField; + private JPasswordField passwordField; + private JButton authButton; + + public MyInfoFrame(MainPageFrame mainPageFrame) { + super("내 정보 수정"); + + // 전체 레이아웃 설정 + setLayout(new BorderLayout(10, 10)); + JPanel authPanel = new JPanel(); + authPanel.setLayout(new GridBagLayout()); + authPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); + + // GridBagConstraints 설정 + GridBagConstraints gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets = new Insets(5, 5, 5, 5); // 컴포넌트 간 간격 + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + mainPageFrame.setVisible(true); + } + }); + + // ID 레이블 및 텍스트 필드 + gbc.gridx = 0; + gbc.gridy = 0; + authPanel.add(new JLabel("ID:"), gbc); + + idField = new JTextField(15); + gbc.gridx = 1; + authPanel.add(idField, gbc); + + // 비밀번호 레이블 및 텍스트 필드 + gbc.gridx = 0; + gbc.gridy = 1; + authPanel.add(new JLabel("비밀번호:"), gbc); + + passwordField = new JPasswordField(15); + gbc.gridx = 1; + authPanel.add(passwordField, gbc); + + // 인증 버튼 + authButton = new JButton("인증"); + gbc.gridx = 0; + gbc.gridy = 2; + gbc.gridwidth = 2; // 버튼을 두 열에 걸치게 배치 + gbc.fill = GridBagConstraints.CENTER; + + // 버튼 크기 및 스타일 설정 + authButton.setPreferredSize(new Dimension(100, 30)); + authButton.addActionListener(e -> { + String id = idField.getText(); + String password = new String(passwordField.getPassword()); + if (mainPageFrame.getLibrary().login(id, password)) { + dispose(); + new EditInfoFrame(mainPageFrame, mainPageFrame.getLibrary().getUser(), id); + } else { + JOptionPane.showMessageDialog(this, + "ID 또는 비밀번호가 잘못되었습니다.", + "인증 오류", + JOptionPane.WARNING_MESSAGE); + } + }); + authPanel.add(authButton, gbc); + + // 패널 추가 + add(authPanel, BorderLayout.CENTER); + + // 프레임 설정 + setSize(400, 250); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setLocationRelativeTo(null); // 화면 가운데에 표시 + setVisible(true); + } +} diff --git a/RegisterFrame.java b/RegisterFrame.java new file mode 100644 index 0000000..95aa72d --- /dev/null +++ b/RegisterFrame.java @@ -0,0 +1,158 @@ +package DBD_env_unification; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.sql.*; +import java.util.ArrayList; + +public class RegisterFrame extends JFrame { + private Library library; + private Connection conn; + public RegisterFrame(LoginFrame loginFrame, Library library) { + // 프레임 기본 설정 + super("Register"); + this.library = library; + this.conn = library.getConn(); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // 창 닫기 설정 + setSize(400, 400); + setLayout(null); + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + loginFrame.setVisible(true); + } + }); + + // 제목 라벨 + JLabel titleLabel = new JLabel("Register New User"); + titleLabel.setFont(new Font("Serif", Font.BOLD, 20)); + titleLabel.setHorizontalAlignment(SwingConstants.CENTER); + titleLabel.setBounds(50, 20, 300, 30); + add(titleLabel); + + // 사용자 정보 입력 필드 + JLabel idLabel = new JLabel("ID:"); + idLabel.setBounds(50, 70, 80, 25); + add(idLabel); + + JTextField idField = new JTextField(); + idField.setBounds(150, 70, 200, 25); + add(idField); + + JLabel passwordLabel = new JLabel("Password:"); + passwordLabel.setBounds(50, 110, 80, 25); + add(passwordLabel); + + JPasswordField passwordField = new JPasswordField(); + passwordField.setBounds(150, 110, 200, 25); + add(passwordField); + + JLabel nameLabel = new JLabel("Name:"); + nameLabel.setBounds(50, 150, 80, 25); + add(nameLabel); + + JTextField nameField = new JTextField(); + nameField.setBounds(150, 150, 200, 25); + add(nameField); + + JLabel mailLabel = new JLabel("Mail:"); + mailLabel.setBounds(50, 190, 80, 25); + add(mailLabel); + + JTextField mailField = new JTextField(); + mailField.setBounds(150, 190, 200, 25); + add(mailField); + + JLabel departmentLabel = new JLabel("Department:"); + departmentLabel.setBounds(50, 230, 80, 25); + add(departmentLabel); + + ArrayList departmentList = library.getDepartmentListFromDatabase(); + + // JComboBox 생성 + JComboBox departmentComboBox = new JComboBox<>(); + departmentComboBox.setBounds(150, 230, 200, 25); // 위치와 크기 설정 + add(departmentComboBox); + // 학부 목록을 JComboBox에 추가 + for (String department : departmentList) { + departmentComboBox.addItem(department); + } + + JLabel statusLabel = new JLabel("Status:"); + statusLabel.setBounds(50, 270, 80, 25); + add(statusLabel); + + // DB에서 status 값 가져오기 + ArrayList statusList = library.getStatusListFromDatabase(); + // 상태를 선택할 수 있는 JComboBox + JComboBox statusComboBox = new JComboBox<>(); + statusComboBox.setBounds(150, 270, 200, 25); + add(statusComboBox); + + for (String status : statusList) { + statusComboBox.addItem(status); + } + + // 회원가입 버튼 + JButton registerButton = new JButton("Register"); + registerButton.setBounds(150, 320, 100, 30); + registerButton.setBackground(new Color(76, 175, 80)); + registerButton.setForeground(Color.WHITE); + registerButton.setFocusPainted(false); + registerButton.setFont(new Font("Tahoma", Font.BOLD, 12)); + registerButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // 입력 값 가져오기 + String id = idField.getText(); + String password = new String(passwordField.getPassword()); + String name = nameField.getText(); + String mail = mailField.getText(); + String department = (String) departmentComboBox.getSelectedItem(); + String status = (String) statusComboBox.getSelectedItem(); + + // Library 객체의 회원가입 메서드 호출 + try { + // 입력값이 비어 있는지 체크 + if (id.isEmpty() || password.isEmpty() || name.isEmpty() || mail.isEmpty()) { + JOptionPane.showMessageDialog(RegisterFrame.this, + "모든 필드를 입력해주세요.", + "Error", + JOptionPane.ERROR_MESSAGE); + } else if (library.isUserIdDuplicate(id)) { //중복 ID 확인 + // 중복된 ID가 있을 경우 경고 메시지 출력 + JOptionPane.showMessageDialog(RegisterFrame.this, + "중복된 사용자 ID입니다. 다른 ID를 사용해주세요.", + "ID 중복 오류", + JOptionPane.WARNING_MESSAGE); + return; + }else { + // 모든 필드가 비어있지 않고 중복 ID가 아니면 회원가입 진행 + library.registerUser(id, name, mail, password, department, status); + JOptionPane.showMessageDialog(RegisterFrame.this, + "회원가입이 완료되었습니다.", + "Success", + JOptionPane.INFORMATION_MESSAGE); + dispose(); // 회원가입 창 닫기 + loginFrame.setVisible(true); + } + } catch (Exception ex) { + JOptionPane.showMessageDialog(RegisterFrame.this, + "회원가입 중 오류가 발생했습니다.", + "Error", + JOptionPane.ERROR_MESSAGE); + } + } + }); + + add(registerButton); + + setVisible(true); + } + + + + +} diff --git a/User.java b/User.java index 0f5b7d6..824dc4e 100644 --- a/User.java +++ b/User.java @@ -15,9 +15,11 @@ public class User { private String status; private List loanIds = new ArrayList(); // 대출 중인 자료 list private List overdueIds = new ArrayList(); // 연체 자료 list + private Connection con; public User(String user_id, Connection con){ + this.con = con; String query = "select User_ID, NAME, Mail, Department, Status from user where User_ID = ?"; try (PreparedStatement preparedStatement = con.prepareStatement(query)) @@ -49,16 +51,6 @@ public User(String user_id, Connection con){ initExtendList(con); } - public void printUser(Connection con){ - System.out.println("사용자 정보"); - System.out.println("ID: "+user_id); - System.out.println("name: "+name); - System.out.println("email: "+email); - System.out.println("dep: "+department); - System.out.println("status: "+status); - printLoanList(con); - } - public void borrowBook(int book_id, Connection con) { String checkStatusQuery = "SELECT Book_status FROM book WHERE Data_ID = ?"; @@ -252,7 +244,6 @@ public void ExtendBook(int loan_id, Connection con) { } - public void deleteUser(Connection conn) { Scanner scanner = new Scanner(System.in); @@ -265,7 +256,9 @@ public void deleteUser(Connection conn) { try { // 사용자 ID와 비밀번호 확인 - if (!isUserCredentialsValid(conn, password)) { + + if (!isUserCredentialsValid(conn, user_id, password)) { + System.out.println("잘못된 사용자 ID 또는 비밀번호입니다."); return; } @@ -287,6 +280,7 @@ public void deleteUser(Connection conn) { e.printStackTrace(); } } + // 대출 현황 리스트 만들기 public void initLoanList(Connection con) { @@ -367,6 +361,7 @@ public void printLoanList(Connection con) { System.out.println("Failed to select : " + e.getMessage()); } } + } @@ -491,59 +486,34 @@ public void payFine(int loanId, Connection con){ overdueIds.remove((Integer) loanId); } -} - - public void updateUser(Connection conn) { - Scanner scanner = new Scanner(System.in); - - // 입력받기 - System.out.print("사용자 ID: "); - String userId = scanner.nextLine(); - - System.out.print("비밀번호: "); - String password = scanner.nextLine(); + public boolean updateUser(String field, String new_value) { try { - // 사용자 ID와 비밀번호 확인 - if (!isUserCredentialsValid(conn,password)) { - System.out.println("잘못된 사용자 ID 또는 비밀번호입니다."); - return; - } - - // 수정할 필드와 값 입력받기 - System.out.print("수정할 필드명 (Name, Mail, Password, Department, Status 중 하나): "); - String field = scanner.nextLine(); - - System.out.print("새로운 값: "); - String newValue = scanner.nextLine(); // UPDATE 쿼리 작성 String sql = "UPDATE user SET " + field + " = ? WHERE User_ID = ?"; - try (PreparedStatement pstmt = conn.prepareStatement(sql)) { - pstmt.setString(1, newValue); - pstmt.setString(2, userId); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setString(1, new_value); + pstmt.setString(2, user_id); // 레코드 업데이트 int rows = pstmt.executeUpdate(); - if (rows > 0) { - System.out.println("회원 정보가 성공적으로 수정되었습니다."); - } else { - System.out.println("회원 정보 수정에 실패했습니다."); - } + return rows > 0; } } catch (SQLException e) { e.printStackTrace(); + return false; } } // 사용자 인증 함수 호출 - public boolean isUserCredentialsValid(Connection conn, String password) { + public boolean isUserCredentialsValid(Connection conn,String userId, String password) { String sql = "{? = CALL isUserCredentialsValid(?, ?)}"; // MySQL 함수 호출 구문 try (CallableStatement stmt = conn.prepareCall(sql)) { // 첫 번째 인자는 반환 값이므로 등록 stmt.registerOutParameter(1, Types.BOOLEAN); // 두 번째, 세 번째 인자는 입력 값 - stmt.setString(2, user_id); + stmt.setString(2, userId); stmt.setString(3, password); // 함수 실행 @@ -557,7 +527,6 @@ public boolean isUserCredentialsValid(Connection conn, String password) { } } - //개인 보관함에 추가 public void addToStorage(Connection conn, String userId, int dataId, String folder) { String checkSql = "SELECT isDataExists(?)"; // isDataExists 함수 호출 String addSql = "{CALL addToStorage(?, ?, ?)}"; // addToStorage 프로시저 호출 @@ -585,36 +554,45 @@ public void addToStorage(Connection conn, String userId, int dataId, String fold } } - //유저의 개인 보관함을 폴더별로 보여준다 - public void showUsersStorage(Connection conn, String userId) { - String sql = "{CALL showUsersStorage(?)}"; // MySQL 함수 호출 구문 + // 사용자 저장소를 가져오는 메서드 + public List showUsersStorage() { + String sql = "{CALL GetFilesByUserAndFolder(?)}"; // MySQL 함수 호출 구문 + List storageItems = new ArrayList<>(); String currentFolder = ""; - try (CallableStatement stmt = conn.prepareCall(sql)) { - stmt.setString(1, userId); + try (CallableStatement stmt = con.prepareCall(sql)) { + stmt.setString(1, user_id); ResultSet rs = stmt.executeQuery(); - // 결과 출력 while (rs.next()) { + String storageID = Integer.toString(rs.getInt("Storage_ID")); String title = rs.getString("Title"); String author = rs.getString("Author"); - String publisher = rs.getString("Publisher"); + String type = rs.getString("Type"); String folder = rs.getString("Storage_folder"); - if(!currentFolder.equals(folder)){ - System.out.println(folder); + + // 폴더가 변경되었을 경우 새로운 폴더를 표시 + if (!currentFolder.equals(folder)) { + storageItems.add("-1"); + storageItems.add("== " + folder + " =="); currentFolder = folder; } - System.out.println("Title: " + title + ", Author: " + author + ", Publisher: " + publisher); + + // 도서 정보를 항목으로 추가 + storageItems.add(storageID); + storageItems.add("Title: " + title + ", Author: " + author + ", Type: " + type); + } } catch (SQLException e) { e.printStackTrace(); } - } + return storageItems; + } //개인 보관함에서 삭제 - public void deleteStorage(Connection conn, int storageId) { + public void deleteStorage(int storageId) { String sql = "DELETE FROM storage WHERE Storage_ID = ?"; // MySQL 함수 호출 구문 - try (CallableStatement stmt = conn.prepareCall(sql)) { + try (CallableStatement stmt = con.prepareCall(sql)) { stmt.setInt(1, storageId); stmt.executeUpdate(); @@ -622,4 +600,37 @@ public void deleteStorage(Connection conn, int storageId) { e.printStackTrace(); } } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } } + diff --git a/UserStorageFrame.java b/UserStorageFrame.java new file mode 100644 index 0000000..c873cc6 --- /dev/null +++ b/UserStorageFrame.java @@ -0,0 +1,152 @@ +package DBD_env_unification; +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + +public class UserStorageFrame extends JFrame { + private JList storageList; + private DefaultListModel listModel; + private User user; + private ArrayList storage_id_list; + + private MainPageFrame mainPageFrame; // 이전 화면을 참조 + + public UserStorageFrame(MainPageFrame mainPageFrame) { + super("User Storage"); + + this.mainPageFrame = mainPageFrame; // 이전 화면 참조 저장 + this.user = mainPageFrame.getLibrary().getUser(); + this.storage_id_list = new ArrayList<>(); + + // 프레임 설정 + setSize(600, 400); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setLayout(new BorderLayout()); + + // 배경 색상 설정 + getContentPane().setBackground(new Color(240, 240, 240)); // 밝은 회색 배경 + + // 제목 라벨 + JLabel titleLabel = new JLabel("User Storage", SwingConstants.CENTER); + titleLabel.setFont(new Font("맑은 고딕", Font.BOLD, 24)); // 제목 라벨에 한글 폰트 사용 + titleLabel.setForeground(new Color(59, 89, 182)); // 파란색 텍스트 + titleLabel.setPreferredSize(new Dimension(getWidth(), 50)); + add(titleLabel, BorderLayout.NORTH); + + // 버튼들 (삭제 및 뒤로가기) + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 10)); // 버튼들을 중앙에 배치하고 간격 조정 + + // 뒤로가기 버튼 + JButton backButton = new JButton("Back"); + styleButton(backButton); // 버튼 스타일 적용 + backButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // 뒤로가기 버튼 동작 + mainPageFrame.setVisible(true); // 이전 화면 보이기 + dispose(); // 현재 화면 종료 + } + }); + + // 삭제 버튼 + JButton deleteButton = new JButton("Delete Selected"); + styleButton(deleteButton); // 버튼 스타일 적용 + deleteButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + deleteSelectedItem(); // 선택된 항목 삭제 + } + }); + + // 버튼들을 패널에 추가 + buttonPanel.add(backButton); + buttonPanel.add(deleteButton); + + // 버튼 패널을 화면 하단에 추가 + add(buttonPanel, BorderLayout.SOUTH); + + // 리스트 모델 설정 + listModel = new DefaultListModel<>(); + storageList = new JList<>(listModel); + storageList.setFont(new Font("맑은 고딕", Font.PLAIN, 16)); // JList에 한글 폰트 사용 + + // 텍스트 색상 설정 (배경과 대비를 높이기 위해) + storageList.setForeground(Color.BLACK); // 텍스트는 검은색 + storageList.setBackground(Color.WHITE); // 리스트 배경은 흰색 + + // 선택된 항목의 색상 설정 + storageList.setSelectionBackground(new Color(59, 89, 182)); // 선택된 항목은 파란색 배경 + storageList.setSelectionForeground(Color.WHITE); // 선택된 항목 텍스트는 흰색 + + storageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + storageList.setBorder(BorderFactory.createLineBorder(new Color(200, 200, 200), 1)); + + JScrollPane scrollPane = new JScrollPane(storageList); + scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + // 데이터 불러오기 + loadUserStorage(); + + // 리스트 추가 + add(scrollPane, BorderLayout.CENTER); + + // 프레임 표시 + setLocationRelativeTo(null); // 화면 가운데 배치 + setVisible(true); + } + + private void loadUserStorage() { + List storageItems = user.showUsersStorage(); + + for (int i = 0; i < storageItems.size(); i++) { + String item = storageItems.get(i); + + // 홀수 번째 항목에 Storage_ID 추가 + if (i % 2 == 1) { + listModel.addElement(item); // Storage_ID + } else { + storage_id_list.add(item); + } + } + } + + private void deleteSelectedItem() { + // 선택된 항목의 인덱스 가져오기 + int selectedIndex = storageList.getSelectedIndex(); + + if (selectedIndex != -1) { // 항목이 선택되었을 경우 + String selectedItem = listModel.get(selectedIndex); + int selectedStorageId = Integer.parseInt(storage_id_list.get(selectedIndex)); + + // 폴더 항목인 경우 삭제하지 않음 + if (selectedItem.startsWith("==")) { + JOptionPane.showMessageDialog(this, "폴더는 삭제할 수 없습니다.", "삭제 실패", JOptionPane.ERROR_MESSAGE); + return; + } + + // 선택된 항목을 리스트에서 제거 + listModel.remove(selectedIndex); + + // 실제 데이터에서 항목 삭제 (예: 데이터베이스에서 삭제) + user.deleteStorage(selectedStorageId); // 이 메서드는 실제 데이터베이스나 사용자 저장소에서 항목을 삭제하는 메서드입니다. + } else { + JOptionPane.showMessageDialog(this, "선택된 항목이 없습니다.", "삭제 실패", JOptionPane.ERROR_MESSAGE); + } + } + + // 버튼 스타일을 설정하는 메서드 + private void styleButton(JButton button) { + button.setFont(new Font("맑은 고딕", Font.PLAIN, 16)); // 버튼 폰트 설정 + button.setPreferredSize(new Dimension(180, 40)); // 버튼 크기 설정 + button.setBackground(new Color(59, 89, 182)); // 버튼 배경색 파란색 + button.setForeground(Color.WHITE); // 버튼 텍스트는 흰색 + button.setFocusPainted(false); // 포커스 효과 없애기 + button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20)); // 버튼 안쪽 여백 추가 + button.setCursor(new Cursor(Cursor.HAND_CURSOR)); // 마우스 커서 손 모양으로 변경 + button.setFont(new Font("맑은 고딕", Font.BOLD, 16)); // 폰트 굵기 설정 + } +} diff --git a/main.java b/main.java new file mode 100644 index 0000000..3079e36 --- /dev/null +++ b/main.java @@ -0,0 +1,50 @@ +package DBD_env_unification; +import java.sql.*; +import java.util.Scanner; + +public class main { + public static void main(String[] args) { + // DB 인증 정보를 담은 객체 생성 및 파일에서 정보 파싱 + DatabaseAuthInformation dbAuth = new DatabaseAuthInformation(); + boolean isParsed = dbAuth.parse_auth_info("C:\\Users\\fossj\\IdeaProjects\\java-MySQL-gradle\\src\\main\\resources\\mysql.auth"); + + if (!isParsed) { + System.out.println("DB 인증 정보를 파싱하는 데 실패했습니다."); + return; + } + // DB 연결 정보 설정 + String url = "jdbc:mysql://" + dbAuth.getHost() + ":" + dbAuth.getPort() + "/" + dbAuth.getDatabase_name() + + "?useSSL=false&serverTimezone=UTC"; // SSL 설정과 타임존 추가 + String username = dbAuth.getUsername(); + String password = dbAuth.getPassword(); + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + // 간단한 SELECT 쿼리 실행 + String query = "SELECT * FROM storage"; // 테이블 이름과 컬럼명은 실제 DB 구조에 맞게 수정하세요. + + // 메인 프레임 생성 + + try{ + conn = DriverManager.getConnection(url, username, password); + stmt = conn.createStatement(); + rs = stmt.executeQuery(query); + + Library library = new Library(conn); + LoginFrame loginFrame = new LoginFrame(library); + // 결과 출력 + while (rs.next()) { + String id = rs.getString("Data_ID"); // 예시: 학번 + String userid = rs.getString("User_ID"); // 예시: 이름 + String major = rs.getString("Storage_folder"); // 예시: 전공 + int storage_id = rs.getInt("Storage_ID"); + System.out.println("ID: " + userid + ", 책: " + id + ", 폴더: " + major + ", 저장 id: " + storage_id); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + +} \ No newline at end of file