Giter VIP home page Giter VIP logo

chatjava's Introduction

ChatJava

1차 개발기간 : 2023.10.20 ~ 2023.10.26 --> 리팩토링 및 기능 추가 예정


프로젝트 소개 :

  • ChatJava는 소켓프로그래밍, 디비를 활용한 프로그램입니다.

화면 구성 📺

회원가입

로그인 회원가입
회원가입- 우편번호주소 회원가입- 회원가입완료
회원가입- 필드검사 회원가입- (패스워드/아이디) 확인

채팅

채팅페이지 전송기능
회원탈퇴 닉네임 변경
닉네임변경2 글자색

프로토콜 설계

프로토콜 전송기능
Login 100
MESSAGE 200
CHANGE 202
DELETE 210

주요 기능

⭐️ 로그인

  • 회원가입, 로그인 2개의 기능 구현
  • 회원가입 시 디비에 저장 되어 있는 ID/Paswword 가져와서 정보가 맞으면 로그인 성공, 틀리면 로그인 실패

⭐️ 회원가입

  • 모든 필드을 충족 후 회원가입 가능 구현(유효성 검사)
  • 회원가입 시 ID/Password/Nickname 디비 저장.

⭐️ 채팅창

  • 전송/Enter 누르면 사용자에게 메세지 전송 기능 제공
  • 닉네임변경 기능을 이용하여 해당 사용자 닉네임 변경 기능 제공
  • 글자색 버튼 기능으로 채팅창 내 글자색 변경 가능
  • 회원 탈퇴을 이용하여 저장 되어 있는 회원정보 삭제 기능 제공
  • 추후 회원 리스트 CRUD 추가 및 업로드 예정

시작 가이드

Requirements

Installation

$ git clone https://github.com/Ohsaam/ChatJava.git
$ cd ChatJava

Stacks 🐈

Environment

  • Visual Studio Code
  • Git
  • Github

Development

아키텍쳐

📦com
 ┣ 📂database
 ┃ ┣ 📂zipcodeview
 ┃ ┃ ┗ 📜DBConnectionMgr.java
 ┃ ┣ 📜DBConnection.java
 ┃ ┣ 📜MemberDao.java
 ┃ ┗ 📜MemberDTO.java
 ┣ 📂soket
 ┃ ┣ 📂client
 ┃ ┃ ┣ 📜SocketClient.java
 ┃ ┃ ┗ 📜SocketClientThread.java
 ┃ ┗ 📂server
 ┃ ┃ ┣ 📜Protocol.java
 ┃ ┃ ┣ 📜SocketServer.java
 ┃ ┃ ┗ 📜SocketServerThread.java
 ┗ 📂ui
 ┃ ┣ 📜LoginForm.java
 ┃ ┣ 📜MemberListFrame.java
 ┃ ┣ 📜MemberShipView.java
 ┃ ┣ 📜Sample.java
 ┃ ┗ 📜ZipCodeView.java

이슈관리 & 회고

로그인 관련 이슈

image

  • 설계 방향) 아이디/패스워드/대화명/성명 + 입력 후 등록 누르면 -> 해당 디비에 저장하여 로그인 버튼 눌렀을 때 그 값을 꺼내와서 "로그인이 성공되었습니다." 라고 설계했다.

  • 회원가입 창에서 MemberShipView을 이용하여 값을 받아옴 -> 처음엔 무작정 클래스 생성자 안 this를 통해서 값을 getText() 하려고 했는데, 처음 설계 방향 자체를 잘못 잡았다. -> 그래서 테이블 스키마 자체를 다시 설계하여 디비와 연동했다. 그리고 해당 쿼리문을 다시 짜서 -> select 문으로 nickname을 찾고 -> setString 자체를 username/password로 진행했다. (findNickName 메소드 구현) 해서 회원가입 창에서 값을 읽어들이는 부분을 해결했다. ( findNickName 메소드는 소켓통신에 key값으로 닉네임을 넘기는 디비 메소드)

회원가입 이슈

패스워드 입력시 : 값들이 입력되는데 캡슐화로 ( *** ) 바꾼다.

  • 처음엔 변수를 2개를 써서 -> 스트링으로 읽은 다음 -> replace해서 변환하려고 했다.(**) 하지만 이 부분은 이렇게 하는 것 보단 구글링을 통해 JPasswordField 이용하여 구현완료

아이디 / 패스워드 / 닉네임 디비연동

image

java.sql.SQLSyntaxErrorException: ORA-00942: 테이블 또는 뷰 존재하지 않습니다
  • 수정 했더니 해당 에러가 발생했고, 그렇다면 테이블 또는 뷰를 생성해서 연동시켜야했다. 처음엔 오라클 연동을 한 번 해봐서 자신은 없었지만 구선생을 통해 쿼리문을 짰다.

  • 처음엔 단순히 인스턴스화를 통한 전역변수 이용을 하여 구현 하려고 했다. 처음엔 DB를 설계를 하지 않았는데, 아이디,패스워드, 회원정보를 저장 해야 된다는 필요성을 느껴 toad에서 테이블 등록(member) 후 아이디와 패스워드, 닉네임(회원가입창)에서 받아와서 Dao 클래스에 (Save) 메소드에서 해당 내용을 저장하는 디비를 완성했다. (Save 메소드는 로그인을 하기 위한 회원내용 저장)

소켓통신 이슈

소켓통신 연동 이슈

  • 지금까지 연동하여 로그인을 했을 때 채팅창이 열리는 채팅프로그램을 구현 하고 싶었다.(요구사항)

  • 하지만 지금까지 설계한 부분으로는 클래스 설계를 다시 해야 되는 상황이다. 우선 필자가 생각한 설계 방향은 우선 아이디와 비밀번호를 입력하면, 디비에 넘기는데 여기서 추가로 해야 될 부분은 닉네임을 추출하여 소켓과 연동시키는 설계방향으로 진행했다.

  • 이렇게 구현을 먼저하고 설계를 다시 하니 일을 두 번 하는 번거로움이 발생했다. 이 부분만 줄였어도 더 많은 기능을 구현 했을텐데 안타깝다. 다시 한 번 설계의 중요성을 느꼈고, 앞으론 Class Diagram을 이용해 설계를 먼저 해야겠다.

소켓통신 구현 이슈

  • 우선 싱글스레드가 아닌, 멀티스레드로 구현 했기 떄문에 회원 탈퇴 기능을 추가 했을 때, 2개의 채팅창이 있을 때, 한쪽에서 탈퇴하면 바로 Update 하는 메소드를 설계했다.

  • 처음엔 Client/ClientThread만 수정하고 -> dtm.getValutAt() / dtm.setValueAt 이벤트 처리 메소드 설계 및 디비에서 삭제하는 메소드 설계 -> 이런 논리로 회원탈퇴를 눌렀을 때 해당 로그인한 아이디의 내용을 디비에서 삭제하고, 해당 row을 줄이는그리고 로그인 시 해당 회원정보는 삭제 되었기 때문에 다시 접속해야 되는 방향으로 설계했다. 하지만 시점의 문제가 발생했다.

  • A라는 회원이 먼저 로그인하고 B라는 회원이 로그인 했을 때, 먼저 들어온 A를 회원 탈퇴하면 그 내용을 B에 반영하지 못했다. 해당 문제를 겪게 되면서 클래스 시점에 대한 고찰을 다시 한 번 하게 된 것 같다. 클라이언트가 소켓을 서버에 전송하게 되면 (oos)서버에서 그 내용을 읽고(ois) 다시 전송하게 되는데 이 전송과정에 대한 구현이 빠져서 이슈가 발생한 것이였다.

  • 이 부분을 해결하기 위해서 필자는 LogoutRequest,removeList,sendUserList 3개의 메소드를 구현했다.

LogoutRequest

   public void LogoutRequest(String nickName) {
       try {
           String message = nickName + "님이 퇴장하였습니다.";
           broadCasting(210 + "#" + nickName + "#" + message);
           // 사용자 목록 업데이트
           removeList(nickName);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

// 사용자 목록에서 사용자 제거
   public void removeList(String nickName) {
       for (SocketServerThread sst : ss.globalList) {
           if (sst != null && sst.chatName.equals(nickName)) {
               ss.globalList.remove(sst);
               break;
           }
       }
   }

   
   // 사용자 목록을 클라이언트에게 전송
   //서버에 접속할 때 또는 사용자 목록을 요청할 때 사용
   public void sendUserList(SocketServerThread cthread) throws IOException {
       StringBuilder userListMessage = new StringBuilder("100#"); // 목록 메시지를 만들기 위한 문자열 빌더
       for (SocketServerThread sst : ss.globalList) {
           userListMessage.append(sst.chatName).append("#");
       }
       /**
        * 루프 내에서, 각 클라이언트 스레드 sst의 chatName을 가져와서 userListMessage에 # 문자와 함께 추가한다.
        */
       cthread.send(userListMessage.toString());
       System.out.println("회원탈퇴");
   }
  • 이 부분을 구현하면서 가장 어려웠던 부분은 globallist를 이용해야 된다는 건 인지하고 있었지만, 조건을 어떤식으로 걸어야 될지 한참 고민 한 것 같다. 해당 메소드를 구현하면서 이슈는 해결했고, 이를 기점으로 1차 프로젝트는 마무리했다.

포트연결 및 닉네임 연동 오류

image image

  • 소켓 연동은 성공 했으나 닉네임을 받지 못하는 해당 오류가 발생했다.
java.util.NoSuchElementException
   at java.base/java.util.StringTokenizer.nextToken(StringTokenizer.java:347)
  • server/ serverThead /clientThread 모두 닉네임을 연동 시켜야 된다고 판단했고 그 문제가 되는 클래스 내부 메소드 로그를 찍어서 문제 되는 부분을 확인했다. ->

  • 이 부분에서 처음 생각한 방향은 디비를 사용하지 않고 인스턴스화, 클래스(this)를 통한 방향으로 진행을 설계하여 세션의 개념처럼 nickname을 싱글톤으로 구현했다. 하지만 이 부분에서 필자가 간과한 부분이 있다. 소켓통신 프로그램은 멀티스레드인데 싱글톤으로 따로 만들었다니. 해당 부분을 진행하면서 스레드에 대한 공부를 다시 하게 됐다. 블로그 참고

troubleshooting

  • 해당 오류 관련된 부분은 필자 블로그란에서 진행하고 있다.

chatjava's People

Contributors

ohsaam avatar

Watchers

 avatar

chatjava's Issues

회원가입 시 필드입력

회원가입 시 입력 필드를 다 입력하지 않아도 자동 가입되는 이슈

  • 1. isInputValid, isEmptyOrNull 메소드를 구현해 필드에 값을 입력했는지 check
  • 2. isEmptyOrNull -> str 입력 파라미터 값으로 받고 + isEmptyOrNull 을 사용하여 isInputValid구현 -> 판독하는 역할 -> actionPerformed에서 if문으로 분기하여 사용

삽질 내용 정리

삽질 내용 정리

회원가입 창을 구현 예정.

설계

Confirm

[설계1]

  • 우선 기존에 회원가입 창을 가지고 있던 MemberShipView을 이용하여 값을 받아옴 -> 해결

  • 패스워드 입력시 : 값들이 입력되는데 캡슐화로 ( *** ) 바꾼다.

    • 변수를 2개 써야 하나? -> 스트링으로 읽어서 -> replace 해서 변환한다. --> No
    • JPasswordField 이용하여 구현완료
  • 등록 눌렀을 때 -> 회원가입이 완료 되었습니다 하고 창 닫기 -> 완료

        else if (obj == jbtn_ins)
        {
        	JOptionPane.showMessageDialog(this,"등록이 완료되었습니다.","INFO", JOptionPane.INFORMATION_MESSAGE);
        	dispose();

        }

[설계2]

  1. 아이디/패스워드/대화명/성명 + 입력 후 등록 누르면 -> 해당 디비에 저장하여 로그인 버튼 눌렀을 때 그 값을 꺼내와서 "로그인이 성공되었습니다." 라고 구현
  • 값을 읽어 들여 --> 새로은 VO을 만들어서 ---> VO & 디비를 연동한다. MemberDTO 사용

  • MemberShipView 클래스에서만 사용하면 된다. -> 전역변수로 선언 -> List? or Map? -> 나는 List로 구현하면 될 것 같다.
    구성[DB 고려]

MemberDTO

이걸 기준으로 Sample DataBase 설계

MemberListFrame 클래스를 만듦

여기 까지 VO를 만들고 -> 예제 샘플 값을 입력 완료 했다.
그렇게 되면 여기서 어떻게 해야 될까? -> 보완할 점이 필요하다.

  1. Gender는 남자/여자(스크롤)로 되어 있다. 그 값을 어떻게 가져 올 것인가?

  2. ZipCode & Address에서도 값을 어떻게 가져올 것이가에대한 고민을 해야 된다.

  3. 회원가입창에서 -> 회원정보로 넘어 올 때 어떻게 매핑 하는지가 제일 중요하다.

2023.10.19 정리

  1. 현재까지 디비 연동 완료

  2. 회원정보까지 디비 넘기는 것 구현 완료

  3. 로그아웃 구현

앞으로 해야 될 것.

  1. 로그아웃 구현

  2. 본격적으로 소켓통신 공부 시작


소켓통신 연동

  • 프로토콜을 연동하여 메신져를 만들려고 했다. 하지만 지금 문제는 클래스 설계를 다시 해야된다.
  1. 우선 아이디와 비밀번호를 입력하면, 디비에 넘기는데 여기서 추가로 해야 될 부분은 닉네임을 추출하여 소켓과 연동시켜야한다.

  2. 그리고 디비랑 서버와 소통할 수 있는 DAO를 설계하여 (프로토콜도 설계 예정) 구현하자.

  3. 기존의 메신저 소켓 기능을 수정 할 필요성은 없다. 단, 닉네임을 어떻게 추출해서 디비에 넘길지가 문제다.

설계 흐름

LoginForm은 CONFIRM을 누르면 -> 디비연동(DBConnection)이 됐음(로그로 DB연결 완료)로 sql 연동 -> 회원가입(MembershipView)로 넘어간다.
[등록 눌렀을 경우]

  1. 등록 누르면 디비로 넘어가는데 이 때 쿼리문 실행 (MemberDao-save)에서 해당 부분 진행 -> 리턴 값을 어디에다 줘?[MembershipView - actionPerformed] 에서 이벤트 처리 진행 -> 이 저장한 값을

디비 스키마 부터 수정하자.

  1. MemberDTO 불변객체 Nickname 추가하기 -> 토드 테이블 설계 다시하기 완료[닉네임 추가]
delete from member;


create table member(
  username varchar2(15),
  password varchar2(15),
  nickname varchar2(15)
);

nickname을 추가 했는데 nullpointexception이 나옴 -> 미치고 팔짝 뛰겠음 -> username을 세션값으로 넘겨줬는데 해당 부분을 바꾼다면?

Cannot invoke "String.length()" because "username" is null 이런 에러가 발생함

단위 테스트 했는데 --> 로그인쪽 화면 구현에선 문제가 없음 --> MemberListFrame아니면 MemberDao문제 --> 아니면 로그인 시 세션으로 넘기는 username일지도? 내 추측은 후자다.

해결완료 -> DTO가 문제여서 조건을 걸었던 부분들이 전부 문제가 되었다. 해당 부분 삭제

포트연결 및 닉네임 연동 오류

소켓 연동은 성공 했으나 해당 오류가 발생했다. 필자가 판단하여 봤을 때

닉네임이 넘어오지 않아서

java.util.NoSuchElementException
	at java.base/java.util.StringTokenizer.nextToken(StringTokenizer.java:347)

해당 오류가 발생했다. 그렇다면 server/ serverThead /clientThread 모두 닉네임을 연동 시켜야한다.

  1. SocketClientThread에서 SocketClient의 닉네임을 읽어오지 못하고 있다.

-> 그래서 SocketClient의 this를 통해 ->

	SocketClient sc = null;
	
	public SocketClientThread(SocketClient socketClient) {

		this.sc =socketClient;
	}
    
    

하여 sc.nickname 을 사용했는데 연동이 안 된다.

Issue 관리

Issue1 : 디비쪽 우편번호가 입력이 안된다. -> 완료

  • java.sql.SQLException: service들어가서 해결하면 된다.

Issue2 : 패스워드 캡슐화로 ( *** ) 바꾼다. -> 완료

Issue3 : 데이터 베이스 연동 실패 (java.sql.SQLException:) -> 완료


s===>전체
s===>부산
s===>전남
s===>대구
대구
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
 
	at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
	at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
	at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
	at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:480)
	at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:413)
	at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:508)
	at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:203)
	at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
	at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:510)
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681)
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229)
	at com.util.DBConnectionMgr.getConnection(DBConnectionMgr.java:57)
	at com.chat.ZipCodeView.refreshData(ZipCodeView.java:117)
	at com.chat.ZipCodeView.actionPerformed(ZipCodeView.java:149)
	at java.desktop/javax.swing.JTextField.fireActionPerformed(JTextField.java:525)
	at java.desktop/javax.swing.JTextField.postActionEvent(JTextField.java:740)
	at java.desktop/javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:856)
	at java.desktop/javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1810)
	at java.desktop/javax.swing.JComponent.processKeyBinding(JComponent.java:2947)
	at java.desktop/javax.swing.JComponent.processKeyBindings(JComponent.java:2995)
	at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2909)
	at java.desktop/java.awt.Component.processEvent(Component.java:6403)
	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
	at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1952)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:883)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1150)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1020)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:848)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4882)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: oracle.net.ns.NetException: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
 
	at oracle.net.ns.NSProtocol.connect(NSProtocol.java:361)
	at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:966)
	at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:292)
	... 47 more

2023.10.19일 오류 발생 해결 아직 못함 -> Oracle 다시 깔아야 하는가?

java.sql.SQLException: 부적합한 열 인덱스 + 수정하면 -> 완료

해당 부분 참고

--> ??로 해결 시도 --> 아직도 해결이 안된다. --> 디비 연동은 되었음 --> sql과 DTO가 열 맞는 것으로 예상 --> 나눠져있던 이벤트 처리를 하나로 바꿈 --> 등록 누르면 ---> 해결 완료

  1. 등록을 눌렀을 때 -> 해당 정보가 디비에 저장 되어야 한다 -> MemberListFrame에 MemberShipView의 정보를 받아와 저장해야 된다. --> insert문 수정 --> 날짜 읽어오는 부분 삭제 --> 이 부분 때문에 매핑이 안 됐음 (수정완료)
java.sql.SQLSyntaxErrorException: ORA-00942: 테이블 또는 뷰가 존재하지 않습니다
 

에러 발생 --> 해결방법은?

  • 내 생각은 등록을 눌렀을 때 이 정보를 가지고 -> 클래스 매핑이 안 되서 그럼 -> 그래서 전역변수로 해서 this로 넘겨 봤는데 같이 창은 창이 뜨고 해결이 안된다. --> 방향성이 안 맞음

  • 그렇다면 테이블 또는 뷰를 생성해서 연동시켜야함 --> 테이블 또는 뷰를 MemberListFrame으로 설정함(GUI) --> 지금 DTO로 연동은 되는데 ListFrame에 담기지 않는다.
    MemberShipView 값들을 받아와 MemberListFrame으로 설정하는것이 중요한 포인트

  • 로그인까지 이벤트 처리 완료 --> 하지만 문제는 데이블 또는 뷰가 존재하지 않습니다. 에러만 해결하면 된다. MemberListFrame에서 어떻게 처리하느냐가 관건

  • 쉽지 않구나

애초에 처음에 우편번호 찾기 할 때 에러가 발생함 --> 이 부분을 먼저 처리 후 디비 연동 및 사용 할 것 .

  • 구글링을 해보니 디비 스키마 설계를 할 때 굳이 10자리가 아니라 2자리만 해도 된다. -> 아이디 유효성 검사를 하는데도 아이디/패스워드만 디비에 저장 후 -> 구현하자

그래서 MemberListFrame / 및 MemberDTO / DAO 전부 수정 완료

-> 이제 매핑하는거만 남았다. --> 간단하지만 디비 스키마 만들었고 , 그걸 토대로 데이터 저장 창까지 구현은 다 했다.


다음 단계는 회원가입을 통해 -> 회원정보에 디비 연동하여 구현 하는 것이다. 계속 이 지점에서 머물고 있는 것 같지만, 이전에는 행/정보 입력 칸이 비어 있어서 아예 구현이 안됐다..

그러면 회원가입창인 MemberShipView 보고 / MemberListFrame 둘 사이에 관계를 구현하면 될 것 같다. (쉽게 얘기하면 붙이는 걸 어떤식으로 할꺼냐의 문제다)

  1. 멤버쉽뷰를 -> This를 통해서 Frame에 넘긴다? 구체적으로 회원가입 창 등록을 눌렀을 때 디비 정보(아이디/패스워드)가 MemberListFrame여기로 넘어가야한다.

  2. rs에서 에러가 계속적으로 발생함 "PASSWORD": 부적합한 식별자 -> 에러 해결 --> 테이블 설정들어가서 --> 테이블 업데이트 했음

[ORACLE] 오라클 ORA-00001: 무결성 제약 조건에 위배됩니다 -> 완료

해당 부분 필자가 toad에 테이블 조건을 primary key로 잘 못 줘서 delete 후 -> 다시 테이블 생성함 -> 해결

폰트 이벤트처리

폰트 이벤트처리완료

image

image

글자색을 누르면 해당 메인 채팅창 글자색 변경완료

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.