Skip to content

[Fix/client/waitingroom-UI] 대기실 오류 및 게임 시작 수정 #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 34 additions & 10 deletions client/src/main/java/org/kunp/Client.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kunp;

import org.kunp.inner.InnerWaitingRoomComponent;
import org.kunp.waiting.WaitingRoomCreationPanel;
import org.kunp.waiting.WaitingRoomListPanel;

Expand All @@ -18,31 +19,54 @@ public class Client {

public Client() {
try {
// 서버와 연결
socket = new Socket(SERVER_HOST, SERVER_PORT);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

// 서버에서 세션 ID 수신
sessionId = in.readLine();
System.out.println("Connected with session ID: " + sessionId);
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "서버 연결 실패: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
return;
}

// 화면 관리 및 상태 초기화
ScreenManager screenManager = new ScreenManager();
ServerCommunicator serverCommunicator = new ServerCommunicator(in, out);
StateManager stateManager = new StateManager(screenManager, serverCommunicator, sessionId);

// 프레임 설정
JFrame frame = new JFrame("Tag Game - 대기실");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 500); // 화면 크기
frame.setLayout(new BorderLayout());
frame.setSize(600, 500); // 화면 크기를 키움

// 대기실 목록 패널
JPanel parentPanel = new JPanel(new BorderLayout());
WaitingRoomListPanel waitingRoomListPanel = new WaitingRoomListPanel(parentPanel, in, out, sessionId);
parentPanel.add(waitingRoomListPanel, BorderLayout.CENTER);
// 화면 등록
registerScreens(sessionId, screenManager, stateManager, serverCommunicator);

// 대기실 생성 패널
WaitingRoomCreationPanel waitingRoomCreationPanel = new WaitingRoomCreationPanel(parentPanel, in, out, sessionId);
parentPanel.add(waitingRoomCreationPanel, BorderLayout.SOUTH);
// 화면 전환
screenManager.showScreen("WaitingRoom");

frame.add(parentPanel, BorderLayout.CENTER);
frame.add(screenManager.getMainPanel(), BorderLayout.CENTER);
frame.setVisible(true);
}
}

/**
* 화면 등록 메서드
* @param screenManager 화면 관리 객체
* @param stateManager 상태 관리 객체
*/
private void registerScreens(String sessionId, ScreenManager screenManager, StateManager stateManager, ServerCommunicator serverCommunicator) {
// 대기실 화면
JPanel waitingRoomPanel = new JPanel(new BorderLayout());
waitingRoomPanel.add(new WaitingRoomListPanel(sessionId, stateManager, serverCommunicator, screenManager, in, out), BorderLayout.CENTER);
waitingRoomPanel.add(new WaitingRoomCreationPanel(stateManager, screenManager, serverCommunicator, in, out), BorderLayout.SOUTH);
screenManager.addScreen("WaitingRoom", waitingRoomPanel);

// Map 화면 (게임 화면)
screenManager.addScreen("Map", new JPanel());
}
}
27 changes: 27 additions & 0 deletions client/src/main/java/org/kunp/ScreenManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.kunp;

import javax.swing.*;
import java.awt.*;

public class ScreenManager {
private final JPanel mainPanel;
private final CardLayout cardLayout;

public ScreenManager() {
this.cardLayout = new CardLayout();
this.mainPanel = new JPanel(cardLayout);
}

public JPanel getMainPanel() {
return mainPanel;
}

public void addScreen(String name, JPanel screen) {
mainPanel.add(screen, name);
}

public void showScreen(String name) {
cardLayout.show(mainPanel, name);
}
}

54 changes: 54 additions & 0 deletions client/src/main/java/org/kunp/ServerCommunicator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.kunp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

public class ServerCommunicator {
private final BufferedReader in;
private final PrintWriter out;
private final List<ServerMessageListener> listeners = new ArrayList<>();

public interface ServerMessageListener {
void onMessageReceived(String message);
}

public ServerCommunicator(BufferedReader in, PrintWriter out) {
this.in = in;
this.out = out;

// 서버 메시지 수신 스레드
new Thread(() -> {
try {
String message;
while ((message = in.readLine()) != null) {
System.out.println(message);
notifyListeners(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}

public void sendRequest(String message) {
out.println(message);
out.flush();
}

public void addMessageListener(ServerMessageListener listener) {
listeners.add(listener);
}

public void removeMessageListener(ServerMessageListener listener) {
listeners.remove(listener);
}

private void notifyListeners(String message) {
for (ServerMessageListener listener : listeners) {
listener.onMessageReceived(message);
}
}
}
41 changes: 41 additions & 0 deletions client/src/main/java/org/kunp/StateManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.kunp;

import javax.swing.*;

public class StateManager {
private final ScreenManager screenManager;
private final ServerCommunicator serverCommunicator;
private final String sessionId;
private String currentScreen; // 현재 화면을 추적하는 필드 추가

public StateManager(ScreenManager screenManager, ServerCommunicator serverCommunicator, String sessionId) {
this.screenManager = screenManager;
this.serverCommunicator = serverCommunicator;
this.sessionId = sessionId;
this.currentScreen = ""; // 초기화
}

public String getSessionId() {
return sessionId;
}

public void switchTo(String screenName) {
currentScreen = screenName; // 현재 화면 업데이트
SwingUtilities.invokeLater(() -> screenManager.showScreen(screenName));
}

public String getCurrentScreen() {
return currentScreen; // 현재 화면 반환
}

public void sendServerRequest(String request, Runnable onSuccess) {
serverCommunicator.sendRequest(request);
SwingUtilities.invokeLater(onSuccess);
}

public void addMessageListener(ServerCommunicator.ServerMessageListener listener) {
serverCommunicator.addMessageListener(listener);
}
}


101 changes: 56 additions & 45 deletions client/src/main/java/org/kunp/inner/InnerWaitingRoomComponent.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
package org.kunp.inner;

import org.kunp.ScreenManager;
import org.kunp.ServerCommunicator;
import org.kunp.StateManager;
import org.kunp.map.Map;
import org.kunp.map.Player;

import javax.swing.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.*;

public class InnerWaitingRoomComponent extends JPanel {

public InnerWaitingRoomComponent(
JPanel parentPanel,
String roomName,
BufferedReader in,
PrintWriter out,
String sessionId) {

public class InnerWaitingRoomComponent extends JPanel {
public InnerWaitingRoomComponent(StateManager stateManager, ServerCommunicator serverCommunicator, ScreenManager screenManager, String roomName, BufferedReader in, PrintWriter out) {
setLayout(new BorderLayout());
setBorder(BorderFactory.createLineBorder(Color.GRAY));
setPreferredSize(new Dimension(350, 200));
Expand All @@ -27,47 +25,60 @@ public InnerWaitingRoomComponent(
add(nameLabel, BorderLayout.NORTH);

Set<String> sessionIds = new HashSet<>();
// 사용자 목록 패널 추가
InnerWaitingRoomListPanel listPanel = new InnerWaitingRoomListPanel(sessionIds);
add(listPanel, BorderLayout.CENTER);

// 컨트롤 패널 추가
InnerWaitingRoomControlPanel controlPanel =
new InnerWaitingRoomControlPanel(parentPanel, roomName, in, out, sessionId);
InnerWaitingRoomControlPanel controlPanel = new InnerWaitingRoomControlPanel(stateManager, screenManager, serverCommunicator, roomName, in, out);
add(controlPanel, BorderLayout.SOUTH);

// 서버 메시지 수신 및 처리 스레드
Thread thread = new Thread(() -> {
try {
String message;
while ((message = in.readLine()) != null) {
System.out.println("Received: " + message);
String[] tokens = message.split("\\|");
// 메시지 리스너 등록
ServerCommunicator.ServerMessageListener listener = message -> {
handleServerMessage( message, sessionIds, listPanel, in, out, stateManager, screenManager);
};

stateManager.addMessageListener(listener);
}

if (tokens.length > 1) {
String type = tokens[0]; // 메시지 타입 (예: 110)
String[] data = tokens[1].split(",");
private void handleServerMessage(String message, Set<String> sessionIds, InnerWaitingRoomListPanel listPanel, BufferedReader in, PrintWriter out, StateManager stateManager, ScreenManager screenManager) {
String[] tokens = message.split("\\|");
System.out.println(message);

SwingUtilities.invokeLater(() -> {
switch (type) {
case "110": // 새 사용자 입장
sessionIds.addAll(List.of(data));
break;
case "111": // 사용자 퇴장
sessionIds.remove(data[0]);
break;
default:
System.out.println("Unhandled message type: " + type);
return;
}
listPanel.updateSessionList(sessionIds); // UI 갱신
if (tokens.length > 1) {
String type = tokens[0];
switch (type) {
case "110" -> {
String[] sessions = message.split("\n");
String lastSessionMessage = sessions[sessions.length - 1];
String[] sessionData = lastSessionMessage.split("\\|");
if (sessionData.length > 1) {
String[] sessionIdsArray = sessionData[1].split(",");
Set<String> newSessionIds = Set.of(sessionIdsArray);
sessionIds.addAll(newSessionIds);
}
}
case "111" -> {
String[] data = tokens[1].split(",");
sessionIds.remove(data[0]);
}
case "113" -> SwingUtilities.invokeLater(() -> {
System.out.println("Game starting...");
try {
String role = tokens[1].equals("0") ? "tagger" : "normal";
Player player = new Player(
Integer.parseInt(tokens[2]), Integer.parseInt(tokens[3]), role, out, stateManager.getSessionId()
);
screenManager.addScreen("Map", new Map(in, out, player, stateManager.getSessionId()));
System.out.println("Map screen added successfully.");
stateManager.sendServerRequest(message, () -> {
stateManager.switchTo("Map");
});
} catch (Exception ex) {
ex.printStackTrace(); // 오류 출력
}
});
}
default -> System.out.println("Unhandled message type: " + type);
}
} catch (IOException e) {
e.printStackTrace();
}
});
thread.start();
SwingUtilities.invokeLater(() -> listPanel.updateSessionList(sessionIds));
}
}
}
}
Loading