public void actionPerformed(ActionEvent e) {
    if (e.getSource() == ld.st) // 0.로딩화면에서 Enter버튼 클릭
    {
      System.out.println("할리갈리 온라인 안쪽으로 접근중...");
      card.show(getContentPane(), "LOG");
    } else if (e.getSource() == login.bt1) // 1.팝업창으로 회원가입창 띄우기
    {
      mID.setBounds(470, 310, 340, 420);
      mID.setVisible(true);
    } else if (e.getSource() == login.bt2) // 2.로그인버튼 누르기
    {
      ld.clip.stop();
      wr.clip.play();
      id = login.tf.getText().trim(); // ID입력안했을때
      if (id.length() < 1) {
        JOptionPane.showMessageDialog(this, "ID를 입력하세요");
        login.tf.requestFocus();
        return;
      }
      String pass = new String(login.pf.getPassword()); // PWD입력안했을때
      if (pass.length() < 1) {
        JOptionPane.showMessageDialog(this, "Password를 입력하세요");
        login.pf.requestFocus();
        return;
      }

      connection(); // 모두 정확히 처리했으면, connection()메소드로 이동!!

      try {
        out.write(
            (Function.LOGIN
                    + "|"
                    + id
                    + "|" // 로그인버튼 눌러서 server에게 요청
                    + pass
                    + "\n")
                .getBytes());
      } catch (Exception ex) {
      }
    } else if (e.getSource() == wr.tf || e.getSource() == wr.b1) // 3.waitroom에서 채팅입력할 때
    {
      String data = wr.tf.getText(); // 입력한 값 가져오기
      if (data.length() < 1) return;
      try {
        out.write((Function.WAITCHAT1 + "|" + data + "\n").getBytes()); // 채팅전송을 server에게 요청
      } catch (Exception ex) {
      }
      wr.tf.setText("");
    } else if (e.getSource() == gw.tf || e.getSource() == gw.b1) // 4.gameWindow에서 채팅입력할 때
    {
      String data = gw.tf.getText(); // 입력한 값 가져오기
      if (data.length() < 1) return;
      try {
        out.write((Function.ROOMCHAT + "|" + data + "\n").getBytes()); // 채팅전송을 server에게
      } catch (Exception ex) {
      }
      gw.tf.setText("");
    } else if (e.getSource() == wr.b2) // 5.방만들기창
    {
      mr.tf.setText(""); // 방만들기 초기화
      mr.pf.setText("");
      mr.rb1.setSelected(true);
      mr.setBounds(500, 300, 260, 290);
      mr.setVisible(true);
    } else if (e.getSource() == wr.b3) // 6.방들어가기 버튼처리 /////////////////////////////////
    {
      wr.clip.stop();
      gw.clip.play();
      System.out.println("방유저리스트수: " + gw.model1.getRowCount());
      for (int i = 0; i < gw.model1.getRowCount(); i++) {
        System.out.println("방유저리스트삭제");
        gw.model1.removeRow(i); // 추가
      }
      // gw.model1.removeRow(0); //추가
      if (rowNum >= 0) {
        try {
          gw.ta.setText("");
          out.write((Function.JOINROOM + "|" + rowNum + "\n").getBytes());
        } catch (Exception e2) {
        }
      }
    } else if (e.getSource() == mr.b1) // 6.방만들기창에서 확인 눌렀을때//////////////////////////////
    {
      wr.clip.stop();
      gw.clip.play();
      gw.clip.loop();

      String subject = mr.tf.getText().trim(); // 방이름 입력 안했을때
      if (subject.length() < 1) {
        JOptionPane.showMessageDialog(this, "방이름을 입력하세요");
        mr.tf.requestFocus();
        return;
      }

      if (mr.rb2.isSelected()) { // 비공개 버튼 눌렀을 때
        String pw = new String(mr.pf.getPassword());
        if (pw.length() < 1) {
          JOptionPane.showMessageDialog(this, "비밀번호를 입력하세요");
          mr.pf.requestFocus();
          return;
        }
      }

      mr.dispose();
      /*System.out.println("방유저리스트수: "+gw.model1.getRowCount());
          for(int i=0;i<gw.model1.getRowCount();i++)
      {
          	  System.out.println("방유저리스트삭제");
       gw.model1.removeRow(i); //추가
      }*/
      try {
        String roomType = ""; // 1.공개or비공개 저장
        if (mr.rb1.isSelected()) {
          roomType = mr.rb1.getText();
        } // 공개
        else if (mr.rb2.isSelected()) {
          roomType = mr.rb2.getText();
        } // 비공개
        String roomName = mr.tf.getText(); // 2.방이름
        String capaNum = mr.box.getSelectedItem().toString(); // 3.최대인원수
        out.write(
            (Function.MAKEROOM + "|" + roomType + "|" + roomName + "|" + capaNum + "\n")
                .getBytes());
        // 공개여부,방이름,최대인원 넘겨줌

      } catch (Exception ex) {
      }

    } else if (e.getSource() == wr.b8) // 도움말 버튼처리
    {
      help.setVisible(true);
      repaint();
    } else if (e.getSource() == wr.b9) // 게임종료 버튼처리
    {
      /*서버로 종료 메시지 전송후 프로그램 종료*/
      try {
        out.write((Function.CLIENTEXIT + "|\n").getBytes());

      } catch (Exception e2) {
      }

      try {
        s.close(); // 소켓해제
      } catch (IOException e1) {
        e1.printStackTrace();
      }
      System.exit(0);
    } else if (e.getSource() == mID.b1) // 가입완료버튼
    {
      String name = mID.tf1.getText().trim();
      String id = mID.tf2.getText().trim();
      String pass1 = new String(mID.pf1.getPassword());
      String pass2 = new String(mID.pf2.getPassword());
      if (name.length() < 1) {
        JOptionPane.showMessageDialog(this, "이름을 입력하세요");
        mID.tf1.requestFocus();
        return;
      } else if (id.length() < 1) {
        JOptionPane.showMessageDialog(this, "ID를 입력하세요");
        mID.tf2.requestFocus();
        return;
      } else if (mID.ck == false) {
        JOptionPane.showMessageDialog(this, "ID 중복체크 하시오");
        mID.tf2.requestFocus();
        return;
      } else if (pass1.length() < 1) {
        JOptionPane.showMessageDialog(this, "비밀번호를 입력하세요");
        mID.pf1.requestFocus();
        return;
      } else if (pass2.length() < 1) {
        JOptionPane.showMessageDialog(this, "비밀번호 확인을 입력하세요");
        mID.pf2.requestFocus();
        return;
      } else if (!(pass1.equals(pass2))) {
        JOptionPane.showMessageDialog(this, "비밀번호가 동일하지 않습니다");
        mID.pf1.requestFocus();
        return;
      }
      try {
        out.write((Function.SUCCESSJOIN + "|" + name + "|" + id + "|" + pass1 + "\n").getBytes());
      } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }
      JOptionPane.showMessageDialog(this, "회원가입완료");
      mID.dispose();
    } else if (e.getSource() == mID.b2) {
      mID.tf1.setText("");
      mID.tf2.setText("");
      mID.pf1.setText("");
      mID.pf2.setText("");
      mID.dispose();
    } else if (e.getSource() == mID.b3) // ID중복체크
    {
      String id = mID.tf2.getText().trim();
      if (id.length() < 1) {
        JOptionPane.showMessageDialog(this, "ID를 입력하세요");
        mID.tf2.requestFocus();
        return;
      }

      if (mID.num == 0) // 한번도 소켓을 연결하지 않았다면
      {
        System.out.println("연결시도");
        connection();
        mID.num++;
      }

      System.out.println("ID중복체크");
      try {
        System.out.println(id);
        out.write((Function.IDCHECK + "|" + id + "\n").getBytes()); // ID중복체크를 server에게 요청
      } catch (Exception ex) {
      }
    } else if (e.getSource() == gw.b4) { // GameWindow에서 준비버튼 눌렀을 때

      gw.clip.stop();
      gw.clip3.play();
      try {
        out.write((Function.ROOMREADY + "|" + "\n").getBytes());
      } catch (IOException e1) {
        e1.printStackTrace();
      }
    } else if (e.getSource() == gw.b5) { // GameWindow에서 시작버튼 눌렀을 때
      try {
        out.write((Function.ROOMSTART + "|" + "\n").getBytes());
        gw.b5.setEnabled(false);
      } catch (IOException e1) {
        e1.printStackTrace();
      }
    } else if (e.getSource() == gw.b6) // GameWindow에서 나가기 눌렀을 때
    {
      gw.clip.stop();
      gw.clip2.play();
      wr.clip.play();
      System.out.println("방나가기 버튼 Click");
      System.out.println("방유저리스트수: " + gw.model1.getRowCount());
      // int tmp=gw.model1.getRowCount();
      /*for(int i=0;i<gw.model1.getRowCount();i++)
      {
      	  gw.model1.removeRow(i); //추가
      }*/
      // gw.model1.
      wr.ta.setText(""); // 수정
      gw.b4.setEnabled(true);
      try {
        out.write((Function.EXITROOM + "|" + "\n").getBytes());
      } catch (Exception ex) {
      }
    } else if (e.getSource() == gw.cardOpen) // 카드뒤집기 눌렀을 때!!!
    {
      gw.clip4.play(); // 카드 넘기는 소리
      gw.cardOpen.setBorderPainted(false);
      gw.cardOpen.setContentAreaFilled(false);
      gw.cardOpen.setEnabled(false);
      try {
        out.write((Function.CARDOPEN + "|" + id + "\n").getBytes());
      } catch (IOException e1) {
        e1.printStackTrace();
      }
    } else if (e.getSource() == gw.bell) // 종치기 버튼
    {
      gw.clip1.play(); // 종치는소리
      try {
        out.write((Function.BELL + "|" + id + "\n").getBytes());
      } catch (IOException e1) {
        e1.printStackTrace();
      }
    }
  }
  @Override
  public void run() { // client와 server간의 통신

    while (true) {
      try {
        String msg = in.readLine();
        System.out.println("Server=>" + msg);
        StringTokenizer st = new StringTokenizer(msg, "|");
        int protocol = Integer.parseInt(st.nextToken());
        switch (protocol) {
          case Function.YOURTURN: // 0.자기차례일 때 카드뒤집기 버튼활성화
            {
              gw.cardOpen.setBorderPainted(false);
              gw.cardOpen.setContentAreaFilled(false);
              gw.cardOpen.setEnabled(true);
            }
            break;
          case Function.DELROW: // 1.게임종료한 client 정보 접속자 List 에서 삭제
            {
              int rowIndex = (Integer.parseInt(st.nextToken())); // rowIndex=delIndex
              System.out.println("삭제 줄: " + rowIndex);
              wr.model2.removeRow(rowIndex); // 접속자리스트에서 삭제
            }
            break;
          case Function.CLIENTEXIT: // 2.waitRoom 채팅방에 00님이 나가셨습니다 전송
            {
              wr.ta.append(st.nextToken() + "\n");
              wr.bar.setValue(wr.bar.getMaximum());
            }
            break;
          case Function.MYLOG: // 1.window타이틀에 사용자이름 업데이트
            {
              String id = st.nextToken();
              setTitle(id);
              card.show(getContentPane(), "WR"); // waitingroom으로 창 전환
            }
            break;

          case Function.LOGIN: // 2.접속자테이블에 사용자 업데이트
            {
              String[] data = {st.nextToken(), st.nextToken()};

              wr.model2.addRow(data);
            }
            break;

          case Function.ROOMUSER: // 2.게임룸 유저테이블에 유저업데이트
            {
              System.out.println("In-ROOMUSER");
              String[] data = {st.nextToken()};
              gw.model1.addRow(data);
            }
            break;
          case Function.OUTUSER:
            {
              int rowIndex = (Integer.parseInt(st.nextToken())); // rowIndex=delIndex
              System.out.println("삭제 줄: " + rowIndex);
              gw.model1.removeRow(rowIndex);
            }

          case Function.WAITCHAT1: // 3.채팅할 때(waitroom)
            {
              wr.ta.append(st.nextToken() + "\n");
              wr.bar.setValue(wr.bar.getMaximum());
            }
            break;

          case Function.ROOMCHAT: // 3.채팅할 때(gameWindow)
            {
              gw.ta.append(st.nextToken() + "\n");
              gw.bar.setValue(gw.bar.getMaximum());
              validate();
            }
            break;

          case Function.NOTOVERLAP: // 4.ID가 중복되지 않을 때
            {
              JOptionPane.showMessageDialog(this, "ID가 중복되지 않습니다");
              mID.ck = true;
              mID.pf1.requestFocus();
            }
            break;

          case Function.OVERLAP: // 4.ID가 중복될 때
            {
              JOptionPane.showMessageDialog(this, "ID가 중복됩니다. 다시 입력하세요.");
              mID.ck = false;
              mID.pf1.requestFocus();
            }
            break;

          case Function.MAKEROOM: // 5.client가 방만들기 확인 버튼을 눌렀을 때(게임창 전환)
            {
              String roomId = st.nextToken(); // 게임룸 만든 사람 	id
              String roomName = st.nextToken(); // 새로 만든 게임룸의 	이름
              String humanNum = st.nextToken(); // 현재인원수	//아직 안쓰임
              String capaNum = st.nextToken(); // 최대인원수	//아직 안쓰임
              setTitle("방장_" + roomId + "    " + "방제_" + roomName);
              gw.b5.setEnabled(false); // 시작버튼 비활성화
              gw.ta.setText("");
              card.show(getContentPane(), "GW"); // 게임창으로 전환
            }
            break;

          case Function.ROOMINFORM: // 5.client가 방만들기 확인 버튼을 눌렀을 때(waitRoom의 리스트에 방 추가)
            {
              String roomType = st.nextToken(); // 공개비공개
              String roomName = st.nextToken(); // 게임룸의 이름
              String nnum = st.nextToken(); // 현재인원
              String num = st.nextToken(); // 최대인원
              String pos = st.nextToken(); // 방상태(게임대기중)
              String[] data = {roomType, roomName, nnum, num, pos};
              wr.model1.addRow(data); // waitRoom의 리스트에 방 추가						
              wr.repaint();
            }
            break;

          case Function.JOINROOM: // 6.방에 들어가기 했을 때(인원 수에따라 입장 가능 여부)
            {
              String result = st.nextToken();
              if (result.equals("TRUE")) {
                String roomMaker = st.nextToken();
                String roomName = st.nextToken();
                setTitle("방장_" + roomMaker + "    " + "방제_" + roomName);
                gw.b5.setEnabled(false); // 시작버튼 비활성화
                gw.tf.setText("");
                card.show(getContentPane(), "GW");
                // 준비버튼 활성화
                gw.b4.setEnabled(true);
                validate();
              } else {
                JOptionPane.showMessageDialog(this, "방이 꽉찼습니다.");
              }
            }
            break;

          case Function.ROOMREADY: // 6.준비버튼 눌렀을 때 버튼 비활성화
            {
              System.out.println("최종적으로 준비전달받음");
              gw.b4.setEnabled(false); // 준비버튼비활성화
            }
            break;

          case Function.ROOMREADYBUTTON: // 7.모두준비했을 때 방장만 시작 활성화
            {
              System.out.println("방장의 권한으로 시작버튼 활성화");
              gw.b5.setEnabled(true); // 준비버튼비활성화
            }
            break;
            //					  case Function.GAMESTART:			//7.모두준비했을 때 방장만 시작 활성화
            //					  {
            //						  System.out.println("방장의 권한으로 시작버튼 활성화");
            //						  gw.cardOpen.setBorderPainted(false);
            //							gw.cardOpen.setContentAreaFilled(false);
            //							gw.cardOpen.setEnabled(false);
            //
            //					  }
            //					  break;
            /*[방인원변경 ] ->*/
          case Function.CHGROOMUSER:
            {
              // 대기실 방 List table 의 특정 Row 의 방인원이 변경됨
              int row = Integer.parseInt(st.nextToken());
              String userNum = st.nextToken();
              wr.model1.setValueAt(userNum, row, 2);
              wr.repaint();
            }
            break;

            /*[유저상태변경] ->*/
          case Function.CHGUSERPOS:
            {
              int row = Integer.parseInt(st.nextToken()); // 방번호
              System.out.println("\\\\\\--->" + row);
              String pos = st.nextToken(); // 현재인원수
              wr.model2.setValueAt(pos, row, 1);
              wr.repaint();
            }
            break;

            /*[방상태변경 ] ->*/
          case Function.CHGROOMSTATE:
            {
              // 대기실 방 List table 의 특정 Row 의 방인원이 변경됨
              int row = Integer.parseInt(st.nextToken()); // 방번호
              String roomState = st.nextToken(); // 방상태
              wr.model1.setValueAt(roomState, row, 4);
              wr.repaint();
            }
            break;

            /*[방나가기] ->*/
          case Function.DELROOM: // 방에 사용자가 없에 방삭제 메시지 받음
            {
              gw.tf.setText("");
              int roomRow = Integer.parseInt(st.nextToken());
              System.out.println(roomRow + "방 삭제");
              wr.model1.removeRow(roomRow);
              wr.repaint();
            }
            break;
          case Function.REPAINT:
            {
              String tmpName = st.nextToken();
              int b = Integer.parseInt(st.nextToken());
              System.out.println("InREPAIT-ID:" + tmpName + "Number:" + b);
              gw.UpdateDraw(tmpName, b);
            }
            break;
          case Function.CARDNUM:
            {
              String tmpName = st.nextToken(); // id
              int b = Integer.parseInt(st.nextToken()); // 카드수
              System.out.println("InCARDNUM-ID:" + tmpName + "Number:" + b);
              gw.UpdateCardNum(tmpName, b);
            }
            break;
          case Function.DEAD:
            {
              gw.ta.append("당신은 죽었습니다.\n");
              gw.bell.setEnabled(false);
              gw.cardOpen.setEnabled(false);
            }
            break;
          case Function.UPDATEDEAD:
            {
              String tmpName = st.nextToken();
              gw.ta.append(tmpName + " 님이 죽었습니다.\n");
              gw.UpdateDead(tmpName);
              validate();
            }
            break;
          case Function.BELLSUCCESS:
            {
              String tmpName = st.nextToken();
              gw.ta.append(tmpName + " 님이 종치기 성공했습니다.\n");
              gw.bell.setEnabled(true);
              gw.CardInit();
            }
            break;

          case Function.BELLFAIL:
            {
              String tmpName = st.nextToken();
              gw.ta.append(tmpName + "님이 종치기 실패하였습니다.\n");
              gw.bell.setEnabled(true);
              validate();
            }
            break;

          case Function.BELL:
            {
              gw.bell.setEnabled(false);
            }
            break;

          case Function.TURNINFO:
            {
              gw.userName[0] = st.nextToken();
              gw.userName[1] = st.nextToken();
              gw.userName[2] = st.nextToken();
              gw.userName[3] = st.nextToken();
            }
            break;
          case Function.EXITFALSE: // 게임시작시 나가기비활성화
            {
              gw.b6.setEnabled(false);
            }
            break;

          case Function.IDLABEL: // 게임시작시 id라벨 입력
            {
              String ID = st.nextToken(); // id
              for (int i = 0; i < 4; i++) {
                if (ID.equals(gw.userName[i])) {
                  gw.laPlayer[i].setText("Player" + (i + 1) + ": " + ID);
                }
              }
            }
            break;
          case Function.GAMEEXIT:
            {
              System.out.println("zzzzz");
              String tmpId = st.nextToken();
              String tmpMsg = st.nextToken();
              gw.ta.append("게임종료=====>" + tmpId + tmpMsg);
              gw.b4.setEnabled(true);
              gw.b6.setEnabled(true);
              gw.CardInit();
            }
            break;
        }
      } catch (Exception ex) {
        validate();
      }
      validate();
    }
  }