Part 1. 로그인에서 로그인 부분을 설명하였고, Part 2. 슬라이딩 퍼즐에 관련하여 설명하겠습니다.
Swing을 이용하여 슬라이딩 퍼즐 GUI를 만들었습니다.
Puzzle DTO
package Puzzle_pkg;
public class PuzzleData {
private String ID,Time,Rank;
public PuzzleData() {}
public PuzzleData(String ID, String Time){
this.ID = ID;
this.Time = Time;
}
public PuzzleData(String ID, String Time, String Rank){
this.ID = ID;
this.Time = Time;
this.Rank = Rank;
}
public PuzzleData(String ID){
this.ID = ID;
}
public String GetID(){
return ID;
}
public void SetID(String ID){
this.ID = ID;
}
public String GetTime(){
return Time;
}
public void SetTime(String Rank){
this.Time = Rank;
}
public String GetRank(){
return Rank;
}
public void SetRank(String Rank){
this.Rank = Rank;
}
}
Puzzle DAO
package Puzzle_pkg;
import java.util.*;
import java.sql.*;
public class PuzzleDB{
Connection conn = null;
ResultSet rs = null;
Statement st = null;
PreparedStatement ps = null;
public PuzzleDB() { // 생성자로 데이터베이스 연결
try {
final String url = "jdbc:mariadb://localhost:3306/puzzledb";
final String id = "root";
final String pw = "1234";
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, id, pw);
}catch(ClassNotFoundException cnfe) {
System.out.println("DB 드라이버 로딩 실패:"+ cnfe.toString());
}catch(SQLException sqle){
System.out.println("DB 접속실패"+ sqle.toString());
}catch(Exception e){
System.out.println("Unkown error");
e.printStackTrace();
}
}
public void DBClose() { // 커넥션 연결 종료
try {
if(rs != null) rs.close();
if(st != null) st.close();
if(ps != null) ps.close();
} catch (Exception e) {
System.out.println(e + " => DBClose fail");
}
}
//퍼즐 정보 저장
public void InsertPuzzleDB(PuzzleData puzzledata) { // puzzle table -> puzzle data insert
try {
String sql = "insert into puzzle values(?, ?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, puzzledata.GetID());
ps.setString(2, puzzledata.GetTime());
ps.setString(3, null);
ps.executeUpdate();
} catch(SQLException e) {
e.printStackTrace();
} finally {
DBClose();
}
}
// 퍼즐 정보 목록
public Vector<PuzzleData> PuzzleDBlist() // puzzle table -> puzzle data list
{
Vector<PuzzleData> Ar = new Vector<PuzzleData>();
try{
st = conn.createStatement();
String sql = "Select DENSE_RANK() OVER (ORDER BY Time ASC ) as RANK, ID, Time from puzzle";
rs = st.executeQuery(sql);
while (rs.next()) {
Ar.add(new PuzzleData(rs.getString(1), rs.getString(2), rs.getString(3)));
}
}catch (SQLException e) {
e.printStackTrace();
} finally {
DBClose();
}
return Ar;
}
Vector 사용하여 데이터형을 PuzzleData(DTO)로 정하였고, DB에 있는 퍼즐 정보를 불러와 저장하는 메소드입니다.
// 퍼즐 정보 업데이트
public void UpdatePuzzleDB(PuzzleData puzzledata) // puzzle table -> puzzle data update
{
try {
String Updata = "update puzzle set Rank = ?, where Time = ?;";
ps = conn.prepareStatement(Updata);
ps.setString(1, puzzledata.GetRank());
ps.setString(2, puzzledata.GetTime());
ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
} finally {
DBClose();
}
}
퍼즐 정보를 수정하는 메소드입니다.
// 퍼즐 정보 삭제
public void Delete(String ID) // puzzle table -> puzzle data delete
{
String Delete = "delete from puzzle where ID = ?;";
try {
ps = conn.prepareStatement(Delete);
ps.setString(1, ID);
ps.executeUpdate();
}catch (SQLException e) {
e.printStackTrace();
} finally {
DBClose();
}
}
}
퍼즐 정보를 삭제하는 메소드입니다.
Puzzle Swing
package Puzzle_pkg;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import Login_pkg.LoginData;
import Login_pkg.LoginDB;
public class Puzzle_Swing extends JFrame {
PuzzleDB Pdb = new PuzzleDB();
LoginData Ldata = new LoginData();
LoginDB Ldb = new LoginDB();
private JButton changebtn; // 빈칸과 바꿀 칸 변경
private JButton[][] numbtn = new JButton[4][4]; // 15 까지의 버튼
private int[][] numcount = new int[4][4]; // 15까지의 숫자
private int row = 0, col = 0;
private static String timerBuffer; //경과 시간 문자열이 저장될 버퍼 정의
private static int oldTime; //타이머 시작 시각을 기억하고 있는 변수
public Puzzle_Swing() {
stopwatch(1); // 시간 측정 시작
// 배치
setTitle("슬라이딩 퍼즐");
setSize(350, 350);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new GridLayout(4, 4));
int k = 1;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
numbtn[i][j] = new JButton(String.valueOf(k));
numbtn[i][j].setFont(new Font("굴림체", Font.BOLD, 30));
c.add(numbtn[i][j]);
numbtn[i][j].addKeyListener(new MyKeyListener());
k++;
}
}
getNum();
display();
setVisible(true);
}
// 0~16 난수발생
public void getNum() {
int[] num = new int[16];
int n = 0;
boolean Check = false;
for (int i = 0; i < 16; i++) {
Check = true;
while (Check) {
n = (int) (Math.random() * 16);
Check = false;
for (int j = 0; j < i; j++) {
if (n == num[j]) // 같은 수 저장 방지
{
Check = true;
break;
}
}
}
num[i] = n;
numcount[i / 4][i % 4] = n;
if (n == 15) { // 랜덤 칸 생성
row = i / 4;
col = i % 4;
}
}
}
// 디스플레이
public void display() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i == row && j == col) {
numbtn[i][j].setText(String.valueOf(""));
numbtn[i][j].setEnabled(false);
} else {
System.out.println("numcount["+i+"]"+"["+j+"] "+numcount[i][j]+" ");
numbtn[i][j].setText(String.valueOf(numcount[i][j] + 1));
numbtn[i][j].setEnabled(true);
}
}
}
}
// 종료 여부 확인 numbtn 과 k 가 같으면 종료
public boolean isEnd() {
int k = 1;
try {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (Integer.parseInt(numbtn[i][j].getText()) != k)
return false;
System.out.println("k :"+k);
k++;
}
}
}catch(NumberFormatException e) {
}
return true;
}
private class MyKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
boolean isEnd = false;
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_UP: // 방향키 ↑ 클릭 시 동작
if (row == 0) { // 바깥 나감 방지
break;
} else {
changebtn = numbtn[row - 1][col]; // 변경할 위 버튼
numbtn[row][col].setText(String.valueOf(changebtn.getText())); // 변경할 버튼 숫자 변경
numbtn[row][col].setEnabled(true);
row = row - 1; // 위에를 다시 가리킴
changebtn = numbtn[row][col]; // 빈칸 버튼 지정
numbtn[row][col].setText("");
numbtn[row][col].setEnabled(false);
isEnd(); // 게임 종료 확인
if (isEnd) { // isEnd를 true로 변경하면 키보드 입력 시 테스트가 바로 가능 함.
String getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
int s = Ldb.LoginOX(new LoginData(getID));
if(s== -1) {
JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
while(true) {
getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
s = Ldb.LoginOX(new LoginData(getID));
if(s == 1) {
break;
}
else JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
}
JOptionPane.showMessageDialog(null, "등록 완료 ID: "+getID+", 걸린 시간: "+timerBuffer);
Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
System.exit(0);
}
else {
JOptionPane.showMessageDialog(null, "등록 완료 ID: "+getID+", 걸린 시간: "+timerBuffer);
Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
System.exit(0);
}
}
break;
}
case KeyEvent.VK_DOWN: // 방향키 ↓ 클릭 시 동작
if (row == 3) { // 바깥 나감 방지
break;
} else {
changebtn = numbtn[row + 1][col]; // 변경할 아래 버튼
numbtn[row][col].setText(String.valueOf(changebtn.getText())); // 변경할 버튼 숫자 변경
System.out.println("row : " + row + " col : " + col);
numbtn[row][col].setEnabled(true);
row = row + 1; // 아래를 다시 가리킴
changebtn = numbtn[row][col]; // 빈칸 버튼 지정
numbtn[row][col].setText("");
numbtn[row][col].setEnabled(false);
isEnd(); // 게임 종료 확인
if (isEnd) {
String getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
int s = Ldb.LoginOX(new LoginData(getID));
if(s== -1) {
JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
while(true) {
getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
s = Ldb.LoginOX(new LoginData(getID));
if(s == 1) {
break;
}
else JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
}
JOptionPane.showMessageDialog(null, "등록 완료 ID: "+getID+", 걸린 시간: "+timerBuffer);
Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
System.exit(0);
}
else {
JOptionPane.showMessageDialog(null, "Your message: "+getID);
Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
System.exit(0);
}
}
break;
}
case KeyEvent.VK_RIGHT: // 방향키 → 클릭 시 동작
if (col == 3) { // 바깥 나감 방지
break;
} else {
changebtn = numbtn[row][col + 1]; // 변경할 오른쪽 버튼
numbtn[row][col].setText(String.valueOf(changebtn.getText())); // 변경할 버튼 숫자 변경
System.out.println("row : " + row + " col : " + col);
numbtn[row][col].setEnabled(true);
col = col + 1; // 오른쪽을 다시 가리킴
changebtn = numbtn[row][col]; // 빈칸 버튼 지정
numbtn[row][col].setText("");
numbtn[row][col].setEnabled(false);
isEnd(); // 게임 종료 확인
if (isEnd) {
String getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
int s = Ldb.LoginOX(new LoginData(getID));
if(s== -1) {
JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
while(true) {
getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
s = Ldb.LoginOX(new LoginData(getID));
if(s == 1) {
break;
}
else JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
}
JOptionPane.showMessageDialog(null, "등록 완료 ID: "+getID+", 걸린 시간: "+timerBuffer);
Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
System.exit(0);
}
else {
JOptionPane.showMessageDialog(null, "Your message: "+getID);
Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
System.exit(0);
}
}
}
break;
case KeyEvent.VK_LEFT: // 방향키 ← 클릭 시 동작
if (col == 0) { // 바깥 나감 방지
break;
} else {
changebtn = numbtn[row][col - 1]; // 변경할 왼쪽 버튼
numbtn[row][col].setText(String.valueOf(changebtn.getText())); // 변경할 버튼 숫자 변경
System.out.println("row : " + row + " col : " + col);
numbtn[row][col].setEnabled(true);
col = col - 1; // 왼쪽을 다시 가리킴
changebtn = numbtn[row][col]; // 빈칸 버튼 지정
numbtn[row][col].setText("");
numbtn[row][col].setEnabled(false);
isEnd(); // 게임 종료 확인
if (isEnd) {
String getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
int s = Ldb.LoginOX(new LoginData(getID));
if(s== -1) {
JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
while(true) {
getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
s = Ldb.LoginOX(new LoginData(getID));
if(s == 1) {
break;
}
else JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
}
JOptionPane.showMessageDialog(null, "등록 완료 ID: "+getID+", 걸린 시간: "+timerBuffer);
Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
System.exit(0);
}
else {
JOptionPane.showMessageDialog(null, "Your message: "+getID);
Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
System.exit(0);
}
}
break;
}
}
stopwatch(0); // 시간 측정 종료
}
}
public static void stopwatch(int onOff) {
if (onOff == 1) //타이머 on
oldTime = (int) System.currentTimeMillis() / 1000;
if (onOff == 0) // 타이머 off, 시분초 timerBuffer 에 저장
secToHHMMSS( ((int) System.currentTimeMillis() / 1000) - oldTime );
}
// 정수로 된 시간을 초단위(sec)로 입력 받고, 문자열로 시분초를 저장
public static void secToHHMMSS(int secs) {
int hour, min, sec;
sec = secs % 60;
min = secs / 60 % 60;
hour = secs / 3600;
timerBuffer = String.format("%02d%02d%02d", hour, min, sec);
}
}
package Login_pkg;
public class LoginData {
private String ID;
private String Password;
public LoginData() { }
public LoginData(String ID, String Password){
this.ID = ID;
this.Password = Password;
System.out.println("ID"+ID);
}
public LoginData(String ID){
this.ID = ID;
}
public String GetID(){
return ID;
}
public void SetID(String Password){
this.Password = Password;
}
public String GetPassword(){
return Password;
}
public void SetPasswordD(String Password){
this.Password = Password;
}
}
LoginDAO
package Login_pkg;
import java.sql.*;
public class LoginDB {
private Connection conn = null;
private ResultSet rs = null;
private Statement st = null;
private PreparedStatement ps = null;
int count = 0;
public LoginDB() { // 생성자로 데이터 베이스 연결
final String url = "jdbc:mariadb://localhost:3306/puzzledb";
final String id = "root";
final String pw = "1234";
try{
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, id, pw);
}catch(ClassNotFoundException cnfe) {
System.out.println("DB 드라이버 로딩 실패:"+ cnfe.toString());
}catch(SQLException sqle){
System.out.println("DB 접속실패"+ sqle.toString());
}catch(Exception e){
System.out.println("Unkown error");
e.printStackTrace();
}
}
public void DBClose(){ // 커넥션 연결 종료
try{
if(rs != null) rs.close();
if(st != null) st.close();
if(ps != null) ps.close();
}catch(Exception e) { System.out.println(e + "=> DBClose 실패");}
}
DB 연결 부분을 생성자로 구현하여, 클래스 객체 생성시 DB와 연결합니다.
// 회원 정보 저장
public void InsertLogin(LoginData logindata){
String sql = "insert into login values(?, ?, ?)";
try{
ps = conn.prepareStatement(sql);
st = conn.createStatement();
rs = st.executeQuery("Select * From login order by position*1");
while(rs.next())
{
int Number1 = rs.getInt("position");
if(Number1 == count) count++;
}
ps.setInt(1, count);
ps.setString(2, logindata.GetID());
ps.setString(3, logindata.GetPassword());
ps.executeUpdate();
count++;
}catch(SQLException e)
{
e.printStackTrace();
}finally
{
DBClose();
}
}
회원정보번호가 중복되지 않게 전역변수를 count로 만들고, DB의 position(회원정보번호)를 가져와 Number1 변수에 저장하여 count와 비교해 값을 증가시킨다. 마지막 while 루프를 돌게되면 count 값은 position보다 1이 증가한 값이 되게 됩니다.
// 회원 정보 삭제
public void Delete(String ID){ // login table -> Login ID data delete
String sql = "Delete from login where ID =?";
try{
ps = conn.prepareStatement(sql);
ps.setString(1, ID);
ps.executeUpdate();
}catch(SQLException e)
{
e.printStackTrace();
} finally
{
DBClose();
}
}
// ID, Password 확인
public int LoginTry(LoginData logindata){ // login table -> Login ID, Password Confirm
String sql = "select * from login where ID = ? and Password = ?";
try{
ps = conn.prepareStatement(sql);
ps.setString(1, logindata.GetID());
ps.setString(2, logindata.GetPassword());
rs = ps.executeQuery();
if(rs.next())
{
return 1;
}
}catch(Exception e)
{
e.printStackTrace();
}
return -1;
}
GUI 에서 입력한 ID, Password가 DB에 있는지 확인하는 메소드이다. 성공 시 1을 리턴하고, 실패시 -1을 리턴합니다.
// ID 확인
public int LoginOX(LoginData logindata){ // login_management table -> Login ID Confirm
String sql = "select * from login where ID = ?";
try{
ps = conn.prepareStatement(sql);
ps.setString(1, logindata.GetID());
rs = ps.executeQuery();
if(rs.next())
{
return 1;
}
}catch(Exception e)
{
e.printStackTrace();
}
return -1;
}
}
회원의 ID가 DB에 있는지 확인하는 메소드이다. 성공 시 1을 리턴하고, 실패시 -1을 리턴합니다.
LoginWindowBulder
package Login_pkg;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import java.awt.Color;
import Puzzle_pkg.Puzzle_Swing;
import Ranking_pkg.Ranking;
public class Login_WindowBuilder {
private JFrame frame;
private JTextField IDtext;
private JPasswordField passwordtext;
LoginDB db = new LoginDB();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Login_WindowBuilder window = new Login_WindowBuilder();
window.frame.setVisible(true);
window.frame.setResizable(false);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Login_WindowBuilder()
{
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 401, 346);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setBounds(0, 0, 385, 307);
frame.getContentPane().add(panel);
panel.setLayout(null);
JLabel IDLabel = new JLabel("ID : ");
IDLabel.setBounds(71, 122, 66, 33);
IDLabel.setHorizontalAlignment(SwingConstants.CENTER);
IDLabel.setFont(new Font("맑은 고딕", Font.BOLD, 18));
panel.add(IDLabel);
JLabel PassWordLabel = new JLabel("PW : ");
PassWordLabel.setBounds(71, 173, 66, 29);
PassWordLabel.setHorizontalAlignment(SwingConstants.CENTER);
PassWordLabel.setFont(new Font("맑은 고딕", Font.BOLD, 18));
panel.add(PassWordLabel);
IDtext = new JTextField();
IDtext.setBounds(149, 125, 145, 33);
IDtext.setToolTipText("ID 입력");
panel.add(IDtext);
IDtext.setColumns(10);
passwordtext = new JPasswordField();
passwordtext.setBounds(149, 172, 145, 33);
passwordtext.setToolTipText("PassWord 입력");
panel.add(passwordtext);
JLabel lblNewLabel = new JLabel("로그인 창");
lblNewLabel.setBounds(12, 10, 361, 81);
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel.setFont(new Font("돋움체", Font.BOLD, 30));
panel.add(lblNewLabel);
JButton Loginbutton = new JButton("로그인");
Loginbutton.setBackground(Color.WHITE);
Loginbutton.setBounds(71, 243, 111, 47);
Loginbutton.addActionListener(new ActionListener() { // 로그인 버튼 클릭 시 동작
public void actionPerformed(ActionEvent arg0) {
String ID = IDtext.getText();
char[] PS1 = passwordtext.getPassword();
String PS = String.valueOf(PS1);
int s = db.LoginTry(new LoginData(ID,PS));
System.out.println(s);
if(s == 1) {
JOptionPane.showMessageDialog(null, "로그인 성공");
frame.dispose(); // 로그인 GUI 창 종료
Puzzle_Swing window = new Puzzle_Swing();
window.setVisible(true); // 슬라이딩 퍼즐 GUI 화면 나타남
window.setResizable(false); // GUI 창 크기 조절 불가능
Ranking window2 = new Ranking();
window2.frame.setVisible(true); // 랭킹 GUI 화면 나타남
window2.frame.setResizable(false); // GUI 창 크기 조절 불가능
} else JOptionPane.showMessageDialog(null, "로그인 실패");
}
});
Loginbutton.setFont(new Font("맑은 고딕", Font.PLAIN, 15));
panel.add(Loginbutton);
JButton button = new JButton("회원 가입");
button.setBackground(Color.WHITE);
button.setBounds(211, 243, 111, 47);
button.addActionListener(new ActionListener() { // 회원 가입 버튼 클릭 시 동작
public void actionPerformed(ActionEvent e) {
String ID = IDtext.getText();
char[] PS1 = passwordtext.getPassword();
String PS = String.valueOf(PS1);
System.out.println();
System.out.println(passwordtext.getPassword());
if(ID.length() != 0 && PS.length() != 0){
db.InsertLogin(new LoginData(ID, PS));
IDtext.setText(""); passwordtext.setText("");
JOptionPane.showMessageDialog(null, "등록 완료");
}else JOptionPane.showMessageDialog(null, "ID , PW 입력 바람.");
}
});
button.setFont(new Font("맑은 고딕", Font.PLAIN, 15));
panel.add(button);
}
}
SimpleDateFormat클래스를 이용하여 yyyy년 mm월 dd일로 출력 되게끔 포맷하였습니다.
// 도서대여 정보 저장
public void InsertBorrowing(BorrowingData borrowingdata) { // borrowing_management -> borrowing book data insert
BookData bookdata = new BookData();
Calendar cal = Calendar.getInstance();
Date t1 = new Date(); // 현재 날짜
String time1 = sdf.format(t1); // 현재 날짜 포멧
cal.add(Calendar.DAY_OF_MONTH,+14); // 현재 날짜 + 14일 (반납 날짜)
try {
String sql = "insert into borrowing_management values(?, ?, ?, ?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, borrowingdata.GetMemberID());
ps.setInt(2, borrowingdata.GetNum());
ps.setString(3, mb.Bringbookname(new BookData(borrowingdata.GetNum(), ""))); // DB의 도서 테이블의 도서명 확인
ps.setString(4, time1);
ps.setString(5, sdf.format(cal.getTime()));
mb.BorrowingInsert(new BookData(borrowingdata.GetNum(),"대여 불가")); // DB의 도서 테이블의 대여정보 B 대여 불가로 변경
ps.executeUpdate();
} catch(SQLException e) {
e.printStackTrace();
} finally {
DBClose();
}
}
// 도서대여 정보 목록
public Vector<BorrowingData> Booklist() // borrowing_management -> borrowing book data list
{
Vector<BorrowingData> Ar = new Vector<BorrowingData>();
try{
st = conn.createStatement();
String sql = "Select * From borrowing_management order by MemberID*1";
rs = st.executeQuery(sql);
while (rs.next())
{
Ar.add(new BorrowingData(rs.getString("MemberID"), rs.getInt("Number") ,rs.getString("Book") ,rs.getString("RentalDate"), rs.getString("ReturnDate")));
}
}catch (SQLException e) {
e.printStackTrace();
} finally {
DBClose();
}
return Ar;
}
Vector 사용하여 데이터형을 BorrowingData(DTO)로 정하였고, DB에 있는 도서 정보를 불러와 저장하는 메소드입니다.
// 도서 반납
public void ReturnBook(int num){ // borrowing_management -> borrowing book data delete
String Del = "delete from borrowing_management where Number = ?";
try{
ps = conn.prepareStatement(Del);
ps.setInt(1, num);
mb.BorrowingInsert(new BookData(num,"","","","","대여 가능")); // DB 도서 테이블 도서 반납 시 B 대여 가능으로 변경
System.out.println(num);
ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
}finally {
DBClose();
}
}
}
도서 반납하는 메소드이다. 도서 반납 시 DB의 도서테이블에 있는 B 변수를 대여 가능으로 수정합니다.
Borrowing_management WindowBulder
package borrowing_management;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import BorrowingData_p.BorrowingData;
import BookData_p.BookData;
import BorrowingDB_p.BorrowingDB;
import LoginDB_p.LoginDB;
import LoginData_p.LoginData;
import Login_WindowBuilder.WindowBuilder_Login;
import BookDataDB_p.BookDataDB;
public class Borrowing_ {
public JFrame frame;
private JTable table;
private JTextField IDtext;
private JTextField Numtext;
String colNames[] = {"회원 ID","도서 번호","도서명","대여 날짜","반납 날짜"};
private DefaultTableModel model = new DefaultTableModel(colNames, 0);
public Borrowing_() {
initialize();
select();
}
BorrowingDB BorrowingDB = new BorrowingDB();
LoginDB LoginDB = new LoginDB();
BookDataDB BookDB = new BookDataDB();
public void select() { // 대여 목록 출력
Vector<BorrowingData> Ar = new Vector<BorrowingData>();
Ar = BorrowingDB.Booklist();
for(int i=0; i< Ar.size();i++)
{
model.addRow(new Object[]{Ar.get(i).GetMemberID(),Ar.get(i).GetNum(),Ar.get(i).GetBookD(),Ar.get(i).GetRetalDate(),Ar.get(i).GetReturnDate()});
}
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 1091, 491);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setBounds(0, 0, 1075, 452);
frame.getContentPane().add(panel);
panel.setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setFont(new Font("함초롱바탕", Font.PLAIN, 18));
scrollPane.setBounds(306, 106, 757, 329);
panel.add(scrollPane);
table = new JTable(model){
public boolean isCellEditable(int row, int column) { // 클릭 비활성화
return false;
}
};
table.setFillsViewportHeight(true);
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) { // 테이블 마우스 더블 클릭 시 대여정보 입력칸에 값이 나타남
DefaultTableModel model2 = (DefaultTableModel)table.getModel();
int row = table.getSelectedRow();
IDtext.setText(String.valueOf(model2.getValueAt(row, 0)));
Numtext.setText(String.valueOf(model2.getValueAt(row, 1)));
}
});
table.setBackground(Color.WHITE);
table.setFont(new Font("함초롱바탕", Font.PLAIN, 16));
//테이블 가운데 정렬
DefaultTableCellRenderer cell = new DefaultTableCellRenderer();
cell.setHorizontalAlignment(SwingConstants.CENTER);
TableColumnModel centerModel = table.getColumnModel();
for(int i=0;i < centerModel.getColumnCount(); i++) centerModel.getColumn(i).setCellRenderer(cell);
//테이블 컬럼의 이동을 방지
table.getTableHeader().setReorderingAllowed(false);
table.getColumnModel().getColumn(0).setPreferredWidth(20);
table.getColumnModel().getColumn(0).setResizable(false);
table.getColumnModel().getColumn(1).setPreferredWidth(162);
table.getColumnModel().getColumn(3).setPreferredWidth(40);
scrollPane.setViewportView(table);
JButton BorrowingBookButton = new JButton("도서 대여");
BorrowingBookButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
BorrowingBookButton.addActionListener(new ActionListener() { // 도서 대여 버튼 클릭 시 동작
public void actionPerformed(ActionEvent arg0) {
int confirmborrowing = BookDB.ConfirmBorrowing((new BookData(Integer.parseInt(Numtext.getText()),"대여 불가"))); // 대여도서인지 확인
int confirmbook = BookDB.ConfirmBook(new BookData(Integer.parseInt(Numtext.getText()),"")); // 도서번호 확인
int loginox = LoginDB.LoginOX(new LoginData(IDtext.getText(),"")); // 회원 ID 확인
if(confirmborrowing == 1) {
JOptionPane.showMessageDialog(null, "대여중인 도서 입니다.");
return;
}
if(confirmbook != 1) {
JOptionPane.showMessageDialog(null, "도서번호 입력이 잘못 되었습니다.");
return;
}
if(loginox != 1) {
JOptionPane.showMessageDialog(null, "회원 ID 가 맞지 않습니다.");
return;
}
BorrowingDB.InsertBorrowing((new BorrowingData(IDtext.getText(), Integer.parseInt(Numtext.getText()),"","","")));
model.setRowCount(0);
JOptionPane.showMessageDialog(null, "등록 완료");
IDtext.setText(""); Numtext.setText("");
select();
}
});
BorrowingBookButton.setBounds(473, 11, 107, 33);
panel.add(BorrowingBookButton);
JButton BooklistButton = new JButton("새로고침");
BooklistButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
BooklistButton.addActionListener(new ActionListener() { // 새로고침 버튼 클릭 시 동작
public void actionPerformed(ActionEvent arg0) {
model.setRowCount(0);
select();
}
});
BooklistButton.setBounds(136, 10, 107, 35);
panel.add(BooklistButton);
JButton ReturnBookButton = new JButton("도서 반납");
ReturnBookButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
ReturnBookButton.addActionListener(new ActionListener() { // 도서 반납 클릭 시 동작
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(null, "반납 하시겠습니까?", "확인", JOptionPane.YES_NO_OPTION); // 팝업
if(result == JOptionPane.CANCEL_OPTION) { // 팝업 취소 버튼 클릭
return;
}
else if(result == JOptionPane.YES_NO_OPTION){
System.out.println(e.getActionCommand());
DefaultTableModel model2 = (DefaultTableModel)table.getModel();
BorrowingDB.ReturnBook((int)model2.getValueAt(table.getSelectedRow(), 1));
System.out.println((int)model2.getValueAt(table.getSelectedRow(), 1));
model2.removeRow(table.getSelectedRow());
model.setRowCount(0);
IDtext.setText(""); Numtext.setText("");
JOptionPane.showMessageDialog(null, "반납 완료");
select();
}
else {
JOptionPane.showMessageDialog(null, "취소");
}
}
});
ReturnBookButton.setBounds(602, 10, 107, 35);
panel.add(ReturnBookButton);
JButton exitButton = new JButton("종료");
exitButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
exitButton.addActionListener(new ActionListener() { // // 종료 버튼 클릭 시 동작
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(null, "정말 종료 하시겠습니까?", "확인", JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.CANCEL_OPTION) {
return;
}
else if(result == JOptionPane.YES_NO_OPTION){
frame.dispose();
}
else {
return;
}
}
});
exitButton.setBounds(966, 10, 97, 35);
panel.add(exitButton);
JButton textFieldResetButton = new JButton("입력 초기화");
textFieldResetButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
textFieldResetButton.addActionListener(new ActionListener() { // 입력 초기화 버튼 클릭 시 동작
public void actionPerformed(ActionEvent e) {
IDtext.setText(""); Numtext.setText("");
}
});
textFieldResetButton.setBounds(17, 10, 107, 35);
panel.add(textFieldResetButton);
JLabel IDlabe = new JLabel("회원 ID");
IDlabe.setHorizontalAlignment(SwingConstants.CENTER);
IDlabe.setFont(new Font("맑은 고딕", Font.BOLD, 20));
IDlabe.setBounds(12, 202, 93, 23);
panel.add(IDlabe);
JLabel Namelabel = new JLabel("도서번호");
Namelabel.setFont(new Font("맑은 고딕", Font.BOLD, 20));
Namelabel.setBounds(17, 254, 81, 23);
panel.add(Namelabel);
IDtext = new JTextField();
IDtext.setToolTipText("도서 번호 입력");
IDtext.setFont(new Font("맑은 고딕", Font.PLAIN, 17));
IDtext.setColumns(10);
IDtext.setBounds(105, 199, 186, 30);
panel.add(IDtext);
Numtext = new JTextField();
Numtext.setToolTipText("도서번호 입력");
Numtext.setFont(new Font("맑은 고딕", Font.PLAIN, 17));
Numtext.setColumns(10);
Numtext.setBounds(105, 252, 186, 30);
panel.add(Numtext);
}
}
package BookData_p;
public class BookData{ // name 책이름, author 저자, num 도서번호, publish1 출판, publish2 출간, Borrowing 대여확인
private String name,author, publish1, publish2;
private int num;
private String Borrowing;
public BookData() {}
public BookData(String name, String Borrowing){
this.name = name;
this.Borrowing = Borrowing;
}
public BookData(int num, String Borrowing){
this.num = num;
this.Borrowing = Borrowing;
}
public BookData(int num, String name, String author, String publish1, String publish2, String Borrowing)
{
this.num = num;
this.name = name;
this.author = author;
this.publish1 = publish1;
this.publish2 = publish2;
this.Borrowing = Borrowing;
}
public int GetNum()
{
return num;
}
public void SetNum(int num)
{
this.num = num;
}
public String Getname()
{
return name;
}
public void Setname(String name)
{
this.name = name;
}
public String GetAuthor()
{
return author;
}
public void Setauthor(String author)
{
this.author = author;
}
public String Getpublish1()
{
return publish1;
}
public void Setpublish1(String publish1)
{
this.publish1 = publish1;
}
public String Getpublish2()
{
return publish2;
}
public void Setpublish2(String publish2)
{
this.publish2 = publish2;
}
public String GetBorrowing()
{
return Borrowing;
}
public void SetBorrowing(String publish2)
{
this.Borrowing = publish2;
}
}
BookDAO
package BookDataDB_p;
import java.util.*;
import java.sql.*;
import BookData_p.BookData;
public class BookDataDB{
private Connection conn = null;
private ResultSet rs = null;
private Statement st = null;
private PreparedStatement ps = null;
public BookDataDB() { // 생성자로 데이터베이스 연결
try {
final String url = "jdbc:mariadb://localhost:3306/bookdb";
final String id = "root";
final String pw = "1234";
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, id, pw);
}catch(ClassNotFoundException cnfe) {
System.out.println("DB 드라이버 로딩 실패:"+ cnfe.toString());
}catch(SQLException sqle){
System.out.println("DB 접속실패"+ sqle.toString());
}catch(Exception e){
System.out.println("Unkown error");
e.printStackTrace();
}
}
public void DBClose() { // 커넥션 연결 종료
try {
if(rs != null) rs.close();
if(st != null) st.close();
if(ps != null) ps.close();
} catch (Exception e) {
System.out.println(e + " => DBClose fail");
}
}
// 도서 정보 저장
public void InsertBook(BookData bookdata) { // book_management table -> book data insert
try {
String sql = "insert into book_management values(?, ?, ?, ?, ?,?)";
ps = conn.prepareStatement(sql);
ps.setInt(1, bookdata.GetNum());
ps.setString(2, bookdata.Getname());
ps.setString(3, bookdata.GetAuthor());
ps.setString(4, bookdata.Getpublish1());
ps.setString(5, bookdata.Getpublish2());
ps.setString(6, bookdata.GetBorrowing());
ps.executeUpdate();
} catch(SQLException e) {
e.printStackTrace();
} finally {
DBClose();
}
}
// 도서정보 목록
public Vector<BookData> Booklist() // book_management table -> book data list
{
Vector<BookData> Ar = new Vector<BookData>();
try{
st = conn.createStatement();
String sql = "Select * From book_management order by Number*1";
rs = st.executeQuery(sql);
while (rs.next()) {
Ar.add(new BookData(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6)));
}
}catch (SQLException e) {
e.printStackTrace();
} finally {
DBClose();
}
return Ar;
}
Vector 사용하여 데이터형을 BookData(DTO)으로 정하였고, DB에 있는 도서 정보를 불러와 저장하는 메소드입니다.
// 도서정보 업데이트
public void UpdateBook(BookData bookdata) // book_management table -> book data update
{
try {
String Updata = "update book_management set Book=? , author =?, publish1=?,publish2=?, B =? where Number = ?;";
ps = conn.prepareStatement(Updata);
ps.setString(1, bookdata.Getname());
ps.setString(2, bookdata.GetAuthor());
ps.setString(3, bookdata.Getpublish1());
ps.setString(4, bookdata.Getpublish2());
ps.setString(5, bookdata.GetBorrowing());
ps.setInt(6, bookdata.GetNum());
ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
} finally {
DBClose();
}
}
도서정보를 수정하는 메소드입니다.
//도서 정보 삭제
public void Delete(int Num) // book_management table -> book data delete
{
String Delete = "delete from book_management where Number = ?;";
try {
ps = conn.prepareStatement(Delete);
ps.setInt(1, Num);
ps.executeUpdate();
}catch (SQLException e) {
e.printStackTrace();
} finally {
DBClose();
}
}
도서 정보를 삭제하는 메소드이다.
// 도서 대여 정보 저장
public void BorrowingInsert(BookData bookdata) // book_management table -> borrowing book data insert
{
try {
String Updata = "update book_management set B =? where Number=?;";
ps = conn.prepareStatement(Updata);
ps.setString(1, bookdata.GetBorrowing());
ps.setInt(2, bookdata.GetNum());
ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
} finally {
DBClose();
}
}
도서대여 확인 하는 변수인 B(Borrowing)를 업데이트 하는 메소드입니다.
// 도서 대여 확인
public int ConfirmBorrowing(BookData bookdata){ // book_management table -> borrowing book data confirm
String sql = "select * from book_management where Number = ? and B = ?";
try{
ps = conn.prepareStatement(sql);
ps.setInt(1, bookdata.GetNum());
ps.setString(2, bookdata.GetBorrowing());
rs = ps.executeQuery();
if(rs.next()) {
return 1;
}else
{
}
}catch(Exception e) { e.printStackTrace();}
return -1;
}
도서가 대여되었는지 확인하는 메소드입니다.
// 도서번호 확인
public int ConfirmBook(BookData bookdata){ // book_management table -> borrowing book data confirm
String sql = "select * from book_management where Number = ?";
try{
ps = conn.prepareStatement(sql);
ps.setInt(1, bookdata.GetNum());
rs = ps.executeQuery();
if(rs.next())
{
return 1;
}
}catch(Exception e) { e.printStackTrace();}
return -1;
}
도서번호가 중복되었는지 확인하는 메소드입니다.
// 도서명 확인
public String Bringbookname(BookData bookdata){ // book_management table -> borrowing bookname data Bring
String sql = "select * from book_management where Number = ?";
try{
ps = conn.prepareStatement(sql);
ps.setInt(1, bookdata.GetNum());
rs = ps.executeQuery();
if(rs.next())
{
System.out.println(rs.getString(2));
return rs.getString(2);
}
}catch(Exception e) { e.printStackTrace();}
return "";
}
}
도서명을 가져오기 위한 메소드입니다.
BookWindowBuilder
package WindowBuilder_p;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import BookData_p.BookData;
import BookDataDB_p.BookDataDB;
import borrowing_management.Borrowing_;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class WindowBuilder {
public JFrame frame;
private JTable table;
private JTextField Numtext;
private JTextField Nametext;
private JTextField Authortext;
private JTextField publish1text;
private JTextField publish2text;
String colNames[] = {"도서 번호","도서명","저자","출판","출간","대여 현황"};
private DefaultTableModel model = new DefaultTableModel(colNames, 0);
public WindowBuilder() {
initialize();
select();
KeyF5();
}
BookDataDB db = new BookDataDB();
public void select() { // 도서 목록 출력
Vector<BookData> Ar = new Vector<BookData>();
Ar = db.Booklist();
for(int i=0; i< Ar.size();i++)
{
model.addRow(new Object[]{Ar.get(i).GetNum(),Ar.get(i).Getname(),Ar.get(i).GetAuthor(),Ar.get(i).Getpublish1(),Ar.get(i).Getpublish2(),Ar.get(i).GetBorrowing()});
}
}
public void KeyF5(){ // F5 클릭 시 새로고침
frame.getContentPane().addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
System.out.println(keyCode);
System.out.println(KeyEvent.VK_F5);
if(keyCode==KeyEvent.VK_F5)
{
model.setRowCount(0);
select();
}
}
});
frame.getContentPane().setFocusable(true);
frame.getContentPane().requestFocus();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 1079, 645);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setBounds(0, 0, 1063, 606);
frame.getContentPane().add(panel);
panel.setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setFont(new Font("함초롱바탕", Font.PLAIN, 18));
scrollPane.setBounds(306, 106, 745, 466);
panel.add(scrollPane);
table = new JTable(model){
public boolean isCellEditable(int row, int column) { // 클릭 비활성화
return false;
}
};
table.addMouseListener(new MouseAdapter() { // 테이블 마우스 더블 클릭 시 도서정보 입력칸에 값이 나타남
@Override
public void mouseClicked(MouseEvent e) {
DefaultTableModel model2 = (DefaultTableModel)table.getModel();
int row = table.getSelectedRow();
Numtext.setText(String.valueOf(model2.getValueAt(row, 0)));
Nametext.setText(String.valueOf(model2.getValueAt(row, 1)));
Authortext.setText(String.valueOf(model2.getValueAt(row, 2)));
publish1text.setText(String.valueOf(model2.getValueAt(row, 3)));
publish2text.setText(String.valueOf(model2.getValueAt(row, 4)));
}
});
table.setBackground(Color.WHITE);
table.setFont(new Font("함초롱바탕", Font.PLAIN, 16));
//테이블 가운데 정렬
DefaultTableCellRenderer cell = new DefaultTableCellRenderer();
cell.setHorizontalAlignment(SwingConstants.CENTER);
TableColumnModel centerModel = table.getColumnModel();
for(int i=0;i < centerModel.getColumnCount(); i++) centerModel.getColumn(i).setCellRenderer(cell);
//테이블 컬럼의 이동을 방지
table.getTableHeader().setReorderingAllowed(false);
table.getColumnModel().getColumn(0).setPreferredWidth(20);
table.getColumnModel().getColumn(0).setResizable(false);
table.getColumnModel().getColumn(1).setPreferredWidth(162);
table.getColumnModel().getColumn(3).setPreferredWidth(40);
scrollPane.setViewportView(table);
JButton InputGetbookButton = new JButton("도서 등록");
InputGetbookButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
InputGetbookButton.addActionListener(new ActionListener() { // 도서 등록 버튼 클릭 시 동작
public void actionPerformed(ActionEvent arg0) {
int confirmbook = db.ConfirmBook(new BookData(Integer.parseInt(Numtext.getText()),""));
if(confirmbook == 1) {
JOptionPane.showMessageDialog(null, "도서 번호가 중복 되었습니다.");
return;
}
if(Numtext.getText().length() == 0 || Nametext.getText().length() == 0 ||
Authortext.getText().length() == 0 || publish1text.getText().length() == 0 || publish2text.getText().length() == 0)
{
JOptionPane.showMessageDialog(null, "입력이 제대로 되어 있지 않습니다.");
return;
}
db.InsertBook(new BookData(Integer.parseInt(Numtext.getText()), Nametext.getText(), Authortext.getText(),
publish1text.getText(), publish2text.getText(), "대여 가능"));
model.setRowCount(0);
JOptionPane.showMessageDialog(null, "등록 완료");
Numtext.setText(""); Nametext.setText(""); Authortext.setText(""); publish1text.setText(""); publish2text.setText("");
select();
}
});
InputGetbookButton.setBounds(377, 11, 107, 33);
panel.add(InputGetbookButton);
JButton BooklistButton = new JButton("새로고침");
BooklistButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
BooklistButton.addActionListener(new ActionListener() { // 새로고침 버튼 클릭 시 동작
public void actionPerformed(ActionEvent arg0) {
model.setRowCount(0);
select();
}
});
BooklistButton.setBounds(136, 10, 107, 35);
panel.add(BooklistButton);
JButton InputUpdatebutton = new JButton("도서 수정");
InputUpdatebutton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
InputUpdatebutton.addActionListener(new ActionListener() { // 도서 수정 버튼 클릭 시 동작
public void actionPerformed(ActionEvent e) {
int confirmborrowing = db.ConfirmBorrowing((new BookData(Integer.parseInt(Numtext.getText()),"대여 불가"))); //대여 가능 도서 확인
if(Numtext.getText().length() == 0|| Nametext.getText().length() == 0 ||
Authortext.getText().length() == 0 || publish1text.getText().length() == 0 || publish2text.getText().length() == 0) // 도서정보 미 입력 확인
{
JOptionPane.showMessageDialog(null, "입력이 제대로 되어 있지 않습니다.");
return;
}
System.out.println("nUM: "+Numtext.getText().length());
if(confirmborrowing == 1) // ConfirmBorrowing 메소드 반환 값이 1이면 즉, 대여된 도서이면 대여 불가로 도서 정보 업데이트
{
db.UpdateBook(new BookData(Integer.parseInt(Numtext.getText()), Nametext.getText(), Authortext.getText(),
publish1text.getText(), publish2text.getText(), "대여 불가"));
Numtext.setText(""); Nametext.setText(""); Authortext.setText(""); publish1text.setText(""); publish2text.setText("");
model.setRowCount(0);
JOptionPane.showMessageDialog(null, "수정 완료");
select();
return;
} else { db.UpdateBook(new BookData(Integer.parseInt(Numtext.getText()), Nametext.getText(), Authortext.getText(),
publish1text.getText(), publish2text.getText(), "대여 가능"));
Numtext.setText(""); Nametext.setText(""); Authortext.setText(""); publish1text.setText(""); publish2text.setText("");
model.setRowCount(0);
JOptionPane.showMessageDialog(null, "수정 완료");
select(); }
}
});
InputUpdatebutton.setBounds(496, 10, 107, 34);
panel.add(InputUpdatebutton);
JButton TableDeleteButton = new JButton("도서 삭제");
TableDeleteButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
TableDeleteButton.addActionListener(new ActionListener() { // 도서 삭제 버튼 클릭 시
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(null, "장말 삭제 하시겠습니까?", "확인", JOptionPane.YES_NO_OPTION);
int confirmborrowing = db.ConfirmBorrowing(new BookData(Integer.parseInt(Numtext.getText()),"대여 불가"));
if(confirmborrowing == 1) // 대여 중인 도서 이면
{
JOptionPane.showMessageDialog(null, "대여 중이므로 삭제 불가능 합니다.");
return;
}else
if(result == JOptionPane.CANCEL_OPTION) { // 팝업 취소하면
return;
}
else if(result == JOptionPane.YES_NO_OPTION){
System.out.println(e.getActionCommand());
DefaultTableModel model2 = (DefaultTableModel)table.getModel();
db.Delete((int)model2.getValueAt(table.getSelectedRow(), 0));
model2.removeRow(table.getSelectedRow());
model.setRowCount(0);
Numtext.setText(""); Nametext.setText(""); Authortext.setText(""); publish1text.setText(""); publish2text.setText("");
JOptionPane.showMessageDialog(null, "삭제 완료");
select();
}
else {
JOptionPane.showMessageDialog(null, "삭제 취소");
}
}
});
TableDeleteButton.setBounds(615, 10, 107, 35);
panel.add(TableDeleteButton);
JButton exitButton = new JButton("종료");
exitButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
exitButton.addActionListener(new ActionListener() { // 종료 버튼 클릭 시 동작
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(null, "정말 종료 하시겠습니까?", "확인", JOptionPane.YES_NO_OPTION);
if(result == JOptionPane.CANCEL_OPTION) {
return;
}
else if(result == JOptionPane.YES_NO_OPTION){
System.exit(0);
}
else {
return;
}
}
});
exitButton.setBounds(954, 10, 97, 35);
panel.add(exitButton);
JButton textFieldResetButton = new JButton("입력 초기화");
textFieldResetButton.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
textFieldResetButton.addActionListener(new ActionListener() { // 입력 초기화 버튼 클릭 시 동작
public void actionPerformed(ActionEvent e) {
Numtext.setText(""); Nametext.setText(""); Authortext.setText(""); publish1text.setText(""); publish2text.setText("");
}
});
textFieldResetButton.setBounds(17, 10, 107, 35);
panel.add(textFieldResetButton);
JLabel Numlabel = new JLabel("도서 번호");
Numlabel.setFont(new Font("맑은 고딕", Font.BOLD, 20));
Numlabel.setBounds(12, 160, 93, 23);
panel.add(Numlabel);
JLabel Namelabel = new JLabel("도서명");
Namelabel.setFont(new Font("맑은 고딕", Font.BOLD, 20));
Namelabel.setBounds(33, 209, 60, 23);
panel.add(Namelabel);
Numtext = new JTextField();
Numtext.setToolTipText("도서 번호 입력");
Numtext.setFont(new Font("맑은 고딕", Font.PLAIN, 17));
Numtext.setColumns(10);
Numtext.setBounds(105, 157, 186, 30);
panel.add(Numtext);
Nametext = new JTextField();
Nametext.setToolTipText("도서명 입력");
Nametext.setFont(new Font("맑은 고딕", Font.PLAIN, 17));
Nametext.setColumns(10);
Nametext.setBounds(105, 210, 186, 30);
panel.add(Nametext);
Authortext = new JTextField();
Authortext.setFont(new Font("맑은 고딕", Font.PLAIN, 17));
Authortext.setToolTipText("저자 입력");
Authortext.setColumns(10);
Authortext.setBounds(105, 260, 186, 30);
panel.add(Authortext);
JLabel Authorlabel = new JLabel("저자");
Authorlabel.setHorizontalAlignment(SwingConstants.CENTER);
Authorlabel.setFont(new Font("맑은 고딕", Font.BOLD, 20));
Authorlabel.setBounds(33, 259, 60, 23);
panel.add(Authorlabel);
JLabel Publish1label = new JLabel("출판");
Publish1label.setHorizontalAlignment(SwingConstants.CENTER);
Publish1label.setFont(new Font("맑은 고딕", Font.BOLD, 20));
Publish1label.setBounds(33, 308, 60, 23);
panel.add(Publish1label);
publish1text = new JTextField();
publish1text.setFont(new Font("맑은 고딕", Font.PLAIN, 17));
publish1text.setToolTipText("출판 입력");
publish1text.setColumns(10);
publish1text.setBounds(105, 309, 186, 30);
panel.add(publish1text);
publish2text = new JTextField();
publish2text.setFont(new Font("맑은 고딕", Font.PLAIN, 17));
publish2text.setToolTipText("출간 입력");
publish2text.setColumns(10);
publish2text.setBounds(105, 360, 186, 30);
panel.add(publish2text);
JLabel Publish2label = new JLabel("출간");
Publish2label.setHorizontalAlignment(SwingConstants.CENTER);
Publish2label.setFont(new Font("맑은 고딕", Font.BOLD, 20));
Publish2label.setBounds(33, 359, 60, 23);
panel.add(Publish2label);
JButton button = new JButton("대여프로그램");
button.addActionListener(new ActionListener() { // 대여프로그램 버튼 클릭 시 동작
public void actionPerformed(ActionEvent e) {
Borrowing_ window = new Borrowing_(); // 대여프로그램 GUI 실행
window.frame.setVisible(true); // 대여프로그램 GUI 나타남
window.frame.setResizable(false); // GUI 창 크기 조절 불가능
}
});
button.setFont(new Font("맑은 고딕", Font.PLAIN, 12));
button.setBounds(377, 54, 107, 33);
panel.add(button);
}
}
실행화면
Part3. 대여프로그램에서는 대여프로그램 버튼 클릭시 나타나는 GUI 에 관련하여 설명하겠습니다.
예전에 JAVA 공부 초기에 JAVA GUI 툴인 Window Builder 알게 되었고, 써보기 위해 공부를 하기 시작하였습니다.
WindowBuilder 사용하여 GUI를 만들면 대부분 WindowBuilder가 자동으로 소스코드를 작성합니다.
공부 초기에 만든 프로그램이어서, 각 class 파일 마다 패키지를 만들어서 연결을 하였고,
데이터베이스는 MariaDB 를 사용하였고, HeidiSQL 을 사용하여 데이터베이스를 관리하였습니다.
Login DTO
package LoginData_p;
public class LoginData {
private String ID,Password;
public LoginData() {}
public LoginData(String ID, String Password){
this.ID = ID;
this.Password = Password;
}
public LoginData(String ID){
this.ID = ID;
}
public String GetID(){
return ID;
}
public void SetID(String Password){
this.Password = Password;
}
public String GetPassword(){
return Password;
}
public void SetPasswordD(String Password){
this.Password = Password;
}
}
Login DAO
package LoginDB_p;
import java.sql.*;
import LoginData_p.LoginData;
public class LoginDB {
private Connection conn = null;
private ResultSet rs = null;
private Statement st = null;
private PreparedStatement ps = null;
int count = 0;
public LoginDB() { // 생성자로 데이터베이스 연결
final String url = "jdbc:mariadb://localhost:3306/bookdb";
final String id = "root";
final String pw = "1234";
try{
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, id, pw);
}catch(ClassNotFoundException cnfe) {
System.out.println("DB 드라이버 로딩 실패:"+ cnfe.toString());
}catch(SQLException sqle){
System.out.println("DB 접속실패"+ sqle.toString());
}catch(Exception e){
System.out.println("Unkown error");
e.printStackTrace();
}
}
public void DBClose(){ // 커넥션 연결 종료
try{
if(rs != null) rs.close();
if(st != null) st.close();
if(ps != null) ps.close();
}catch(Exception e) { System.out.println(e + "=> DBClose 실패");}
}
DB 연결 부분을 생성자로 구현하여, 클래스 객체 생성시 DB와 연결합니다.
//회원 정보 저장
public void InsertLogin(LoginData logindata){
String sql = "insert into login_management values(?, ?, ?)";
try{
ps = conn.prepareStatement(sql);
st = conn.createStatement();
rs = st.executeQuery("Select * From login_management order by position*1");
while(rs.next())
{
int Number1 = rs.getInt("position");
if(Number1 == count) count++;
}
ps.setInt(1, count);
ps.setString(2, logindata.GetID());
ps.setString(3, logindata.GetPassword());
ps.executeUpdate();
count++;
}catch(SQLException e)
{
e.printStackTrace();
}finally
{
DBClose();
}
}
회원정보번호가 중복되지 않게 전역변수로 count 만들고, DB의 position(회원정보번호)를 가져와 Number1 변수에 저장하여 count와 비교해 값을 증가 시킨다. 마지막 while 루프를 돌게되면 count 값은 position 보다 1 이 증가한 값이 되게 됩니다.
//회원정보 삭제
public void Delete(String ID){ // login_management table -> Login ID data delete
String sql = "Delete from login_management where ID =?";
try{
ps = conn.prepareStatement(sql);
ps.setString(1, ID);
ps.executeUpdate();
}catch(SQLException e)
{
e.printStackTrace();
} finally
{
DBClose();
}
}
// ID, Password 확인 즉, 로그인 시도 시 회원 확인
public int LoginTry(LoginData logindata){ // login_management table -> Login ID, Password Confirm
String sql = "select * from login_management where ID = ? and Password = ?";
try{
ps = conn.prepareStatement(sql);
ps.setString(1, logindata.GetID());
ps.setString(2, logindata.GetPassword());
rs = ps.executeQuery();
if(rs.next())
{
return 1;
}
}catch(Exception e)
{
e.printStackTrace();
}
return -1;
}
GUI에서 입력한 ID, Password가 DB에 있는지 확인하는 메소드이다. 성공 시 1을 리턴하고, 실패시 -1을 리턴합니다.
// 도서대여시 회원아이디 확인
public int LoginOX(LoginData logindata){ // login_management table -> Login ID Confirm
String sql = "select * from login_management where ID = ?";
try{
ps = conn.prepareStatement(sql);
ps.setString(1, logindata.GetID());
rs = ps.executeQuery();
if(rs.next())
{
return 1;
}
}catch(Exception e)
{
e.printStackTrace();
}
return -1;
}
도서를 대여할 때 대여하는 회원의 ID가 login DB에 있는지 확인 하는 메소드이며, 성공 시 1을 리턴하고, 실패시 -1을 리턴합니다.
LoginWindowBuilder
package Login_WindowBuilder;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import LoginDB_p.LoginDB;
import LoginData_p.LoginData;
import WindowBuilder_p.WindowBuilder;
import java.awt.Color;
public class WindowBuilder_Login {
private JFrame frame;
private JTextField IDtext;
private JPasswordField passwordtext;
LoginDB db = new LoginDB();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WindowBuilder_Login window = new WindowBuilder_Login();
window.frame.setVisible(true);
window.frame.setResizable(false);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public WindowBuilder_Login()
{
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 401, 346);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setBounds(0, 0, 385, 307);
frame.getContentPane().add(panel);
panel.setLayout(null);
JLabel IDLabel = new JLabel("ID : ");
IDLabel.setBounds(71, 122, 66, 33);
IDLabel.setHorizontalAlignment(SwingConstants.CENTER);
IDLabel.setFont(new Font("맑은 고딕", Font.BOLD, 18));
panel.add(IDLabel);
JLabel PassWordLabel = new JLabel("PW : ");
PassWordLabel.setBounds(71, 173, 66, 29);
PassWordLabel.setHorizontalAlignment(SwingConstants.CENTER);
PassWordLabel.setFont(new Font("맑은 고딕", Font.BOLD, 18));
panel.add(PassWordLabel);
IDtext = new JTextField();
IDtext.setBounds(149, 125, 145, 33);
IDtext.setToolTipText("ID 입력");
panel.add(IDtext);
IDtext.setColumns(10);
passwordtext = new JPasswordField();
passwordtext.setBounds(149, 172, 145, 33);
passwordtext.setToolTipText("PassWord 입력");
panel.add(passwordtext);
JLabel lblNewLabel = new JLabel("로그인 창");
lblNewLabel.setBounds(12, 10, 361, 81);
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel.setFont(new Font("돋움체", Font.BOLD, 30));
panel.add(lblNewLabel);
JButton Loginbutton = new JButton("로그인");
Loginbutton.setBackground(Color.WHITE);
Loginbutton.setBounds(71, 243, 111, 47);
Loginbutton.addActionListener(new ActionListener() { // 로그인 버튼 클릭 시 동작
public void actionPerformed(ActionEvent arg0) {
String ID = IDtext.getText();
char[] PS1 = passwordtext.getPassword();
String PS = String.valueOf(PS1);
int s = db.LoginTry(new LoginData(ID,PS));
System.out.println(s);
if(s == 1) {
JOptionPane.showMessageDialog(null, "로그인 성공");
frame.dispose(); // 로그인 GUI 창 종료
WindowBuilder window = new WindowBuilder(); // 도서관리 GUI 실행
window.frame.setVisible(true); // 도서관리 GUI 화면 나타남
window.frame.setResizable(false); // GUI 창 크기 조절 불가능
} else JOptionPane.showMessageDialog(null, "로그인 실패");
}
});
Loginbutton.setFont(new Font("맑은 고딕", Font.PLAIN, 15));
panel.add(Loginbutton);
JButton button = new JButton("회원 가입");
button.setBackground(Color.WHITE);
button.setBounds(211, 243, 111, 47);
button.addActionListener(new ActionListener() { // 회원 가입 버튼 클릭 시 동작
public void actionPerformed(ActionEvent e) {
String ID = IDtext.getText();
char[] PS1 = passwordtext.getPassword();
String PS = String.valueOf(PS1);
System.out.println();
System.out.println(passwordtext.getPassword());
if(ID.length() != 0 && PS.length() != 0){
db.InsertLogin(new LoginData(ID, PS));
IDtext.setText(""); passwordtext.setText("");
JOptionPane.showMessageDialog(null, "등록 완료");
}else JOptionPane.showMessageDialog(null, "ID , PW 입력 바람.");
}
});
button.setFont(new Font("맑은 고딕", Font.PLAIN, 15));
panel.add(button);
}
}