diff --git a/client/src/main/java/org/kunp/Client.java b/client/src/main/java/org/kunp/Client.java index c145555..808951b 100644 --- a/client/src/main/java/org/kunp/Client.java +++ b/client/src/main/java/org/kunp/Client.java @@ -1,5 +1,6 @@ package org.kunp; +import org.kunp.inner.InnerWaitingRoomComponent; import org.kunp.waiting.WaitingRoomCreationPanel; import org.kunp.waiting.WaitingRoomListPanel; @@ -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()); + } +} diff --git a/client/src/main/java/org/kunp/ScreenManager.java b/client/src/main/java/org/kunp/ScreenManager.java new file mode 100644 index 0000000..b2758f4 --- /dev/null +++ b/client/src/main/java/org/kunp/ScreenManager.java @@ -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); + } +} + diff --git a/client/src/main/java/org/kunp/ServerCommunicator.java b/client/src/main/java/org/kunp/ServerCommunicator.java new file mode 100644 index 0000000..cc77dac --- /dev/null +++ b/client/src/main/java/org/kunp/ServerCommunicator.java @@ -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 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); + } + } +} diff --git a/client/src/main/java/org/kunp/StateManager.java b/client/src/main/java/org/kunp/StateManager.java new file mode 100644 index 0000000..12aaa19 --- /dev/null +++ b/client/src/main/java/org/kunp/StateManager.java @@ -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); + } +} + + diff --git a/client/src/main/java/org/kunp/inner/InnerWaitingRoomComponent.java b/client/src/main/java/org/kunp/inner/InnerWaitingRoomComponent.java index 633b61f..5c63602 100644 --- a/client/src/main/java/org/kunp/inner/InnerWaitingRoomComponent.java +++ b/client/src/main/java/org/kunp/inner/InnerWaitingRoomComponent.java @@ -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)); @@ -27,47 +25,60 @@ public InnerWaitingRoomComponent( add(nameLabel, BorderLayout.NORTH); Set 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 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 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)); + } } -} +} \ No newline at end of file diff --git a/client/src/main/java/org/kunp/inner/InnerWaitingRoomControlPanel.java b/client/src/main/java/org/kunp/inner/InnerWaitingRoomControlPanel.java index 19b5b59..ec25922 100644 --- a/client/src/main/java/org/kunp/inner/InnerWaitingRoomControlPanel.java +++ b/client/src/main/java/org/kunp/inner/InnerWaitingRoomControlPanel.java @@ -1,18 +1,19 @@ 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 org.kunp.waiting.WaitingRoomCreationPanel; -import org.kunp.waiting.WaitingRoomListPanel; import javax.swing.*; import java.awt.*; import java.io.BufferedReader; -import java.io.IOException; import java.io.PrintWriter; public class InnerWaitingRoomControlPanel extends JPanel { - public InnerWaitingRoomControlPanel(JPanel parentPanel, String roomName, BufferedReader in, PrintWriter out, String sessionId) { + + public InnerWaitingRoomControlPanel(StateManager stateManager, ScreenManager screenManager,ServerCommunicator serverCommunicator, String roomName, BufferedReader in, PrintWriter out) { setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5)); setPreferredSize(new Dimension(350, 50)); @@ -26,56 +27,18 @@ public InnerWaitingRoomControlPanel(JPanel parentPanel, String roomName, Buffere exitButton.setPreferredSize(new Dimension(100, 30)); add(exitButton); + // 게임 시작 버튼 startGameButton.addActionListener(e -> { - new Thread(() -> { - try { - String message = String.format("105|%s|%s|%d|%d|1", sessionId, roomName, 0, 0); - out.println(message); - out.flush(); - String response = in.readLine(); - System.out.println(response); - - String[] tokens = response.split("\\|"); - String role; - if(Integer.parseInt(tokens[2]) == 0){ - role = "tagger"; - }else{ - role = "normal"; - } - Player player = new Player(Integer.parseInt(tokens[3]), Integer.parseInt(tokens[4]), role, out, sessionId); - SwingUtilities.invokeLater(() -> { - parentPanel.removeAll(); - parentPanel.add(new Map(in, out, player, sessionId)); - parentPanel.revalidate(); - parentPanel.repaint(); - }); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - }).start(); + String message = String.format("105|%s|%s|%d|%d|1", stateManager.getSessionId(), roomName, 0, 0); + serverCommunicator.sendRequest(message); }); + // 나가기 버튼 exitButton.addActionListener(e -> { - new Thread(()->{ - String message = String.format("103|%s|%s|%d|%d|1", sessionId, roomName, 0, 0); - out.println(message); - out.flush(); - - SwingUtilities.invokeLater(() -> { - parentPanel.removeAll(); // 기존 컴포넌트 제거 - - // 패널 레이아웃 명확히 설정 (BorderLayout으로 유지) - parentPanel.setLayout(new BorderLayout()); - - // 대기실 목록 및 생성 패널 추가 - parentPanel.add(new WaitingRoomListPanel(parentPanel, in, out, sessionId), BorderLayout.CENTER); - parentPanel.add(new WaitingRoomCreationPanel(parentPanel, in, out, sessionId), BorderLayout.SOUTH); - - // UI 갱신 - parentPanel.revalidate(); - parentPanel.repaint(); - }); - }).start(); + String message = String.format("103|%s|%s|%d|%d|1", stateManager.getSessionId(), roomName, 0, 0); + stateManager.sendServerRequest(message, () -> { + stateManager.switchTo("WaitingRoom"); + }); }); } -} \ No newline at end of file +} diff --git a/client/src/main/java/org/kunp/inner/InnerWaitingRoomListPanel.java b/client/src/main/java/org/kunp/inner/InnerWaitingRoomListPanel.java index f69065b..09af267 100644 --- a/client/src/main/java/org/kunp/inner/InnerWaitingRoomListPanel.java +++ b/client/src/main/java/org/kunp/inner/InnerWaitingRoomListPanel.java @@ -5,7 +5,7 @@ import java.util.Set; public class InnerWaitingRoomListPanel extends JPanel { - private JPanel gridPanel; + private final JPanel gridPanel; public InnerWaitingRoomListPanel(Set sessionIds) { setLayout(new BorderLayout()); @@ -20,27 +20,22 @@ public InnerWaitingRoomListPanel(Set sessionIds) { } public void updateSessionList(Set sessionIds) { - gridPanel.removeAll(); // 기존 컴포넌트 제거 - - // 짝수 인원만 추가 - if (sessionIds.size() % 2 != 0) { - sessionIds.add("대기 중"); // 임시로 빈 자리 추가 - } + gridPanel.removeAll(); for (String id : sessionIds) { JPanel userPanel = new JPanel(); userPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); - userPanel.setLayout(new GridBagLayout()); // 중앙 정렬을 위해 GridBagLayout 사용 + userPanel.setLayout(new GridBagLayout()); JLabel label = new JLabel(id); - label.setFont(new Font("Arial", Font.BOLD, 16)); // 글꼴 설정 (크기 및 스타일) - label.setHorizontalAlignment(SwingConstants.CENTER); // 중앙 정렬 + label.setFont(new Font("Arial", Font.BOLD, 16)); + label.setHorizontalAlignment(SwingConstants.CENTER); - userPanel.add(label); // 패널에 라벨 추가 + userPanel.add(label); gridPanel.add(userPanel); } gridPanel.revalidate(); gridPanel.repaint(); } -} \ No newline at end of file +} diff --git a/client/src/main/java/org/kunp/waiting/WaitingRoomComponent.java b/client/src/main/java/org/kunp/waiting/WaitingRoomComponent.java index cfdee04..063c5da 100644 --- a/client/src/main/java/org/kunp/waiting/WaitingRoomComponent.java +++ b/client/src/main/java/org/kunp/waiting/WaitingRoomComponent.java @@ -1,17 +1,18 @@ package org.kunp.waiting; +import org.kunp.ScreenManager; +import org.kunp.ServerCommunicator; +import org.kunp.StateManager; import org.kunp.inner.InnerWaitingRoomComponent; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.PrintWriter; -// 대기실 컴포넌트 + public class WaitingRoomComponent extends JPanel { - public WaitingRoomComponent(BufferedReader in, PrintWriter out, String sessionId, String roomName, JPanel parentPanel) { + public WaitingRoomComponent(String sessionId, String roomName, StateManager stateManager, ScreenManager screenManager, ServerCommunicator serverCommunicator, BufferedReader in, PrintWriter out) { setLayout(new BorderLayout()); setBorder(BorderFactory.createLineBorder(Color.GRAY)); setPreferredSize(new Dimension(350, 70)); @@ -20,7 +21,6 @@ public WaitingRoomComponent(BufferedReader in, PrintWriter out, String sessionId nameLabel.setHorizontalAlignment(SwingConstants.LEFT); add(nameLabel, BorderLayout.CENTER); - // 입장 버튼을 오른쪽 아래에 작게 배치 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5)); JButton enterButton = new JButton("입장"); enterButton.setFocusPainted(false); @@ -29,19 +29,13 @@ public WaitingRoomComponent(BufferedReader in, PrintWriter out, String sessionId add(buttonPanel, BorderLayout.SOUTH); - enterButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String message = String.format("101|%s|%s|%d|%d|1", sessionId, roomName, 0, 0); - out.println(message); - out.flush(); - - // GameRoomComponent로 전환 - parentPanel.removeAll(); - parentPanel.add(new InnerWaitingRoomComponent(parentPanel, roomName, in, out, sessionId)); - parentPanel.revalidate(); - parentPanel.repaint(); - } + enterButton.addActionListener(e -> { + String message = String.format("101|%s|%s|%d|%d|1", sessionId, roomName, 0, 0); + // InnerWaitingRoom 화면 (추가된 컴포넌트) + screenManager.addScreen("InnerWaitingRoom", new InnerWaitingRoomComponent(stateManager, serverCommunicator, screenManager, roomName, in, out)); + stateManager.sendServerRequest(message, () -> { + stateManager.switchTo("InnerWaitingRoom"); + }); }); } } \ No newline at end of file diff --git a/client/src/main/java/org/kunp/waiting/WaitingRoomCreationPanel.java b/client/src/main/java/org/kunp/waiting/WaitingRoomCreationPanel.java index 73e1928..5797cb2 100644 --- a/client/src/main/java/org/kunp/waiting/WaitingRoomCreationPanel.java +++ b/client/src/main/java/org/kunp/waiting/WaitingRoomCreationPanel.java @@ -1,64 +1,57 @@ package org.kunp.waiting; +import org.kunp.ScreenManager; +import org.kunp.ServerCommunicator; +import org.kunp.StateManager; import org.kunp.inner.InnerWaitingRoomComponent; - import javax.swing.*; import java.awt.*; -import java.io.*; -import java.util.Set; +import java.io.BufferedReader; +import java.io.PrintWriter; -// 대기실 생성 패널 public class WaitingRoomCreationPanel extends JPanel { - private JTextField roomNameField; - private JTextField timeLimitField; - private JTextField playerLimitField; - - public WaitingRoomCreationPanel(JPanel parentPanel, BufferedReader in, PrintWriter out, String sessionId) { + private final JTextField roomNameField; + private final JTextField timeLimitField; + private final JTextField playerLimitField; + public WaitingRoomCreationPanel(StateManager stateManager, ScreenManager screenManager, ServerCommunicator serverCommunicator, BufferedReader in, PrintWriter out) { setLayout(new BorderLayout()); setPreferredSize(new Dimension(350, 150)); - // 대기실 생성 버튼 JButton createRoomButton = new JButton("대기실 생성"); createRoomButton.setFocusPainted(false); createRoomButton.setPreferredSize(new Dimension(100, 50)); - // GridBagLayout을 사용하여 입력 필드 패널 구성 JPanel inputPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.insets = new Insets(5, 5, 5, 5); // 컴포넌트 간격 설정 + gbc.insets = new Insets(5, 5, 5, 5); - // 대기실 생성을 위한 입력 필드 설정 roomNameField = new JTextField(15); timeLimitField = new JTextField(15); playerLimitField = new JTextField(15); - // 대기실 생성 버튼 위치 조정 gbc.gridx = 0; gbc.gridy = 0; - gbc.gridheight = 3; // 버튼을 입력 필드와 같은 높이로 설정 - gbc.insets = new Insets(0, 0, 0, 15); // 오른쪽 간격을 줘서 버튼과 입력 필드 간격 조정 + gbc.gridheight = 3; + gbc.insets = new Insets(0, 0, 0, 15); inputPanel.add(createRoomButton, gbc); - gbc.gridheight = 1; // 다른 컴포넌트는 기본 높이로 설정 - gbc.insets = new Insets(5, 5, 5, 5); // 기본 간격으로 복원 + gbc.gridheight = 1; + gbc.insets = new Insets(5, 5, 5, 5); - // 대기실 이름 gbc.gridx = 1; gbc.gridy = 0; inputPanel.add(new JLabel("대기실 이름"), gbc); gbc.gridx = 2; inputPanel.add(roomNameField, gbc); - // 제한 시간 gbc.gridx = 1; gbc.gridy = 1; inputPanel.add(new JLabel("제한 시간"), gbc); gbc.gridx = 2; inputPanel.add(timeLimitField, gbc); - // 제한 인원 gbc.gridx = 1; gbc.gridy = 2; inputPanel.add(new JLabel("제한 인원"), gbc); @@ -67,7 +60,6 @@ public WaitingRoomCreationPanel(JPanel parentPanel, BufferedReader in, PrintWrit add(inputPanel, BorderLayout.CENTER); - // 대기실 생성 버튼 동작 createRoomButton.addActionListener(e -> { String roomName = roomNameField.getText().trim(); String timeLimitText = timeLimitField.getText().trim(); @@ -78,29 +70,17 @@ public WaitingRoomCreationPanel(JPanel parentPanel, BufferedReader in, PrintWrit int timeLimit = Integer.parseInt(timeLimitText); int playerLimit = Integer.parseInt(playerLimitText); - if (timeLimit <= 0) { - JOptionPane.showMessageDialog(this, "제한 시간은 1 이상의 분 단위 정수여야 합니다.", "입력 오류", JOptionPane.WARNING_MESSAGE); - } else if (playerLimit < 2 || playerLimit > 8 || playerLimit % 2 != 0) { - JOptionPane.showMessageDialog(this, "제한 인원은 2명 이상 8명 이하의 짝수여야 합니다.", "입력 오류", JOptionPane.WARNING_MESSAGE); - } else if (roomName.contains(",")) { - JOptionPane.showMessageDialog(this, "대기실 이름에 , 은 포함될 수 없습니다.", "입력 오류", JOptionPane.WARNING_MESSAGE); + if (timeLimit <= 0 || playerLimit < 2 || playerLimit > 8 || playerLimit % 2 != 0 || roomName.contains(",")) { + JOptionPane.showMessageDialog(this, "입력 오류: 제한 시간과 인원을 확인하세요.", "입력 오류", JOptionPane.WARNING_MESSAGE); } else { - // 서버 응답을 기다리기 위한 스레드 - new Thread(() -> { - String message = String.format("102|%s|%s|%d|%d|1", sessionId, roomName, timeLimit, playerLimit); - out.println(message); - out.flush(); - - String message2 = String.format("101|%s|%s|%d|%d|1", sessionId, roomName, 0, 0); - out.println(message2); - out.flush(); - - // GameRoomComponent로 전환 - parentPanel.removeAll(); - parentPanel.add(new InnerWaitingRoomComponent(parentPanel, roomName, in, out, sessionId)); - parentPanel.revalidate(); - parentPanel.repaint(); - }).start(); // 스레드 시작 + String message = String.format("102|%s|%s|%d|%d|1", stateManager.getSessionId(), roomName, timeLimit, playerLimit); + stateManager.sendServerRequest(message, () -> {}); + + message = String.format("101|%s|%s|%d|%d|1", stateManager.getSessionId(), roomName, timeLimit, playerLimit); + screenManager.addScreen("InnerWaitingRoom", new InnerWaitingRoomComponent(stateManager, serverCommunicator, screenManager, roomName, in ,out)); + stateManager.sendServerRequest(message, () -> { + stateManager.switchTo("InnerWaitingRoom"); + }); } } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(this, "제한 시간과 제한 인원은 숫자여야 합니다.", "입력 오류", JOptionPane.WARNING_MESSAGE); @@ -111,3 +91,4 @@ public WaitingRoomCreationPanel(JPanel parentPanel, BufferedReader in, PrintWrit }); } } + diff --git a/client/src/main/java/org/kunp/waiting/WaitingRoomListPanel.java b/client/src/main/java/org/kunp/waiting/WaitingRoomListPanel.java index 61b7b78..7607615 100644 --- a/client/src/main/java/org/kunp/waiting/WaitingRoomListPanel.java +++ b/client/src/main/java/org/kunp/waiting/WaitingRoomListPanel.java @@ -1,85 +1,62 @@ package org.kunp.waiting; +import org.kunp.ScreenManager; +import org.kunp.ServerCommunicator; +import org.kunp.StateManager; import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; import java.io.BufferedReader; -import java.io.IOException; import java.io.PrintWriter; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -// 대기실 목록 리스트 패널 public class WaitingRoomListPanel extends JPanel { - public WaitingRoomListPanel( - JPanel parentPanel, BufferedReader in, PrintWriter out, String sessionId) { - + ServerCommunicator serverCommunicator; + public WaitingRoomListPanel(String sessionId, StateManager stateManager, ServerCommunicator serverCommunicator, ScreenManager screenManager, BufferedReader in, PrintWriter out) { + this.serverCommunicator = serverCommunicator; setLayout(new BorderLayout()); setBorder(new TitledBorder("대기실 목록")); - // 대기실 목록은 스크롤이 가능한 리스트 JPanel roomListPanel = new JPanel(); roomListPanel.setLayout(new BoxLayout(roomListPanel, BoxLayout.Y_AXIS)); JScrollPane scrollPane = new JScrollPane(roomListPanel); scrollPane.setPreferredSize(new Dimension(400, 250)); - - // 마우스 휠 스크롤시 속도 설정 scrollPane.getVerticalScrollBar().setUnitIncrement(16); List rooms = new ArrayList<>(); - JButton refreshButton = new JButton("새로고침"); refreshButton.setFocusPainted(false); refreshButton.setPreferredSize(new Dimension(100, 50)); add(refreshButton, BorderLayout.NORTH); add(scrollPane, BorderLayout.CENTER); - refreshButton.addActionListener(e -> { - new Thread(() -> { - try { - String message = String.format("100|%s|%s|%d|%d|1", sessionId, null, 0, 0); - out.println(message); - out.flush(); - String response = in.readLine(); - String[] tokens = response.split("\\|"); - - SwingUtilities.invokeLater(() -> { - try { - System.out.println("Running on EDT: " + SwingUtilities.isEventDispatchThread()); - - // Rooms 업데이트 - rooms.clear(); - if(tokens.length > 1) { - Arrays.stream(tokens[1].split(",")) - .map(el -> new WaitingRoomComponent(in, out, sessionId, el, parentPanel)) - .forEach(rooms::add); - } - // RoomListPanel 업데이트 - roomListPanel.removeAll(); - rooms.forEach(roomListPanel::add); - - // 디버깅 로그 - System.out.println("Number of rooms: " + rooms.size()); - System.out.println("Room list panel component count: " + roomListPanel.getComponentCount()); - - // 갱신 - roomListPanel.revalidate(); - roomListPanel.repaint(); - - // 상위 패널 갱신 - parentPanel.revalidate(); - parentPanel.repaint(); - } catch (Exception exx) { - exx.printStackTrace(); - } - }); + serverCommunicator.addMessageListener(message -> { + String[] roomData = message.split("\\|"); + SwingUtilities.invokeLater(() -> { + if(roomData[0].equals("112")) { + rooms.clear(); + roomListPanel.removeAll(); + if (roomData.length > 1) { + Arrays.stream(roomData[1].split(",")) + .map(el -> new WaitingRoomComponent(sessionId, el, stateManager, screenManager, serverCommunicator, in, out)) + .forEach(rooms::add); + } + rooms.forEach(roomListPanel::add); + roomListPanel.revalidate(); + roomListPanel.repaint(); + } + }); + }); - } catch (IOException ex) { - ex.printStackTrace(); // 예외 로그 - } // 스레드 시작 - }).start(); + refreshButton.addActionListener(e -> { + // 방 목록 요청 + String requestMessage = String.format("100|%s|%s|%d|%d|1", sessionId, null, 0, 0); // 요청 메시지 형식 + serverCommunicator.sendRequest(requestMessage); }); } } +