diff --git a/src/main/java/gotcha/Main.java b/src/main/java/gotcha/Main.java index fcf1c03..5232215 100644 --- a/src/main/java/gotcha/Main.java +++ b/src/main/java/gotcha/Main.java @@ -68,8 +68,17 @@ public static void main(String[] args) { public static void setScreen(JPanel panel) { frame.setContentPane(panel); frame.pack(); // 새 패널 내용에 맞게 크기 자동 조정 + + // ★ 소모임 생성/수정 화면이면 가로/세로 크기 제한 + if (panel instanceof gotcha.ui.GroupFormScreen) { + frame.setSize(900, 1000); // 소모임 생성/수정 화면 + } else { + frame.setSize(1200, frame.getHeight()); // 그 외 화면 + } frame.setLocationRelativeTo(null); // 항상 중앙에 위치 frame.revalidate(); frame.repaint(); + frame.setResizable(false); } + } diff --git a/src/main/java/gotcha/ui/board/BoardDetailScreen.java b/src/main/java/gotcha/ui/board/BoardDetailScreen.java index 0fda949..caabd53 100644 --- a/src/main/java/gotcha/ui/board/BoardDetailScreen.java +++ b/src/main/java/gotcha/ui/board/BoardDetailScreen.java @@ -13,273 +13,273 @@ import java.util.stream.Collectors; public class BoardDetailScreen extends JPanel { - private final CommentService commentService = new CommentService(); - private final int boardId; - private final int userId = Session.loggedInUserId; - private final JPanel commentListPanel = new JPanel(); - - public BoardDetailScreen(int boardId) { - this.boardId = boardId; - - setLayout(new BorderLayout(15, 15)); - setBorder(BorderFactory.createEmptyBorder(20, 30, 20, 30)); - FontLoader.applyGlobalFont(14f); - - BoardService boardService = new BoardService(); - Map post = boardService.getPostById(boardId); - - JPanel headerPanel = new JPanel(); - headerPanel.setLayout(new BorderLayout()); - - JButton backButton = new JButton("← 뒤로가기"); - backButton.setFont(FontLoader.loadCustomFont(14f)); - backButton.addActionListener(e -> { - int classId = (int) post.get("class_id"); - Main.setScreen(new ClassBoardScreen(classId)); - }); - headerPanel.add(backButton, BorderLayout.EAST); - - JLabel titleLabel = new JLabel("제목: " + post.get("title"), SwingConstants.CENTER); - titleLabel.setFont(FontLoader.loadCustomFont(18f)); - headerPanel.add(titleLabel, BorderLayout.CENTER); - - JTextArea infoArea = new JTextArea( - "작성자: " + post.get("writer") + "\n작성일: " + post.get("created_at") - ); - infoArea.setEditable(false); - infoArea.setFont(FontLoader.loadCustomFont(14f)); - infoArea.setOpaque(false); - infoArea.setFocusable(false); - infoArea.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); - headerPanel.add(infoArea, BorderLayout.SOUTH); - - add(headerPanel, BorderLayout.NORTH); - - JTextArea contextArea = new JTextArea(post.get("context").toString()); - contextArea.setLineWrap(true); - contextArea.setWrapStyleWord(true); - contextArea.setEditable(false); - contextArea.setFont(FontLoader.loadCustomFont(14f)); - JScrollPane contentScroll = new JScrollPane(contextArea); - contentScroll.setPreferredSize(new Dimension(500, 250)); - add(contentScroll, BorderLayout.CENTER); - - JPanel bottomPanel = new JPanel(new BorderLayout(10, 10)); - commentListPanel.setLayout(new BoxLayout(commentListPanel, BoxLayout.Y_AXIS)); - JScrollPane commentScroll = new JScrollPane(commentListPanel); - commentScroll.setBorder(BorderFactory.createTitledBorder("댓글 목록")); - commentScroll.setPreferredSize(new Dimension(500, 250)); - bottomPanel.add(commentScroll, BorderLayout.CENTER); - - JPanel inputPanel = new JPanel(new BorderLayout(5, 5)); - JTextArea commentInput = new JTextArea(3, 50); - commentInput.setLineWrap(true); - commentInput.setWrapStyleWord(true); - JScrollPane inputScroll = new JScrollPane(commentInput); - - JButton submitButton = new JButton("댓글 등록"); - submitButton.addActionListener(e -> { - String content = commentInput.getText().trim(); - if (!content.isEmpty()) { - boolean success = commentService.addComment(boardId, userId, content); - if (success) { - commentInput.setText(""); - refreshComments(); - } else { - JOptionPane.showMessageDialog(this, "댓글 등록에 실패했습니다."); - } - } else { - JOptionPane.showMessageDialog(this, "댓글을 입력하세요."); - } - }); - - inputPanel.add(inputScroll, BorderLayout.CENTER); - inputPanel.add(submitButton, BorderLayout.EAST); - bottomPanel.add(inputPanel, BorderLayout.SOUTH); - - add(bottomPanel, BorderLayout.SOUTH); - refreshComments(); - } - - private JPanel createReplyInputPanel(int parentId) { - JPanel replyInputPanel = new JPanel(new BorderLayout()); - JTextArea replyInput = new JTextArea(2, 30); - JButton replySubmit = new JButton("등록"); - - replyInput.setLineWrap(true); - replyInput.setWrapStyleWord(true); - - replyInputPanel.add(new JScrollPane(replyInput), BorderLayout.CENTER); - replyInputPanel.add(replySubmit, BorderLayout.EAST); - replyInputPanel.setVisible(false); - - replySubmit.addActionListener(e -> { - String content = replyInput.getText().trim(); - if (!content.isEmpty()) { - boolean success = commentService.addReply(boardId, userId, content, parentId); - if (success) { - replyInput.setText(""); - replyInputPanel.setVisible(false); - refreshComments(); - } else { - JOptionPane.showMessageDialog(this, "대댓글 등록 실패"); - } - } else { - JOptionPane.showMessageDialog(this, "내용을 입력하세요."); - } - }); - - return replyInputPanel; - } - - private void refreshComments() { - commentListPanel.removeAll(); - - List> comments = commentService.getCommentsByBoardId(boardId); - - comments.sort((a, b) -> { - Object pa = a.get("parent_id"); - Object pb = b.get("parent_id"); - - int pidA = pa == null ? 0 : ((Number) pa).intValue(); - int pidB = pb == null ? 0 : ((Number) pb).intValue(); - - if (pidA != pidB) return Integer.compare(pidA, pidB); - return Integer.compare((int) a.get("comment_id"), (int) b.get("comment_id")); - }); - - List> parentComments = comments.stream() - .filter(c -> c.get("parent_id") == null) - .collect(Collectors.toList()); - - for (Map parent : parentComments) { - JPanel parentPanel = buildCommentWithReplies(parent, comments, 0); - commentListPanel.add(parentPanel); - } - - commentListPanel.revalidate(); - commentListPanel.repaint(); - } - - private JPanel buildCommentWithReplies(Map comment, List> allComments, int depth) { - int commentId = (int) comment.get("comment_id"); - - JPanel block = new JPanel(); - block.setLayout(new BoxLayout(block, BoxLayout.Y_AXIS)); - block.setAlignmentX(Component.LEFT_ALIGNMENT); - - // ㄴ + 댓글 + 답글 버튼 패널 - JPanel commentRow = new JPanel(); - commentRow.setLayout(new BoxLayout(commentRow, BoxLayout.X_AXIS)); - commentRow.setAlignmentX(Component.LEFT_ALIGNMENT); - - JLabel arrowLabel = new JLabel(depth > 0 ? "↳ " : " "); - arrowLabel.setFont(FontLoader.loadCustomFont(16f)); - arrowLabel.setPreferredSize(new Dimension(20, 20)); - commentRow.add(arrowLabel); - - JPanel commentPanel = buildCommentPanel(comment); - commentRow.add(commentPanel); - - JButton replyBtn = new JButton("답글"); - commentRow.add(Box.createRigidArea(new Dimension(10, 0))); - commentRow.add(replyBtn); - - // 들여쓰기 wrapper - JPanel indentWrapper = new JPanel(); - indentWrapper.setLayout(new BoxLayout(indentWrapper, BoxLayout.Y_AXIS)); - indentWrapper.setBorder(BorderFactory.createEmptyBorder(0, 20 * depth, 10, 0)); - indentWrapper.setAlignmentX(Component.LEFT_ALIGNMENT); - indentWrapper.add(commentRow); - - block.add(indentWrapper); - - // 대댓글 입력창은 block 바깥에 depth+1로 추가되어야 함 - JPanel replyInputPanel = createReplyInputPanel(commentId); - replyInputPanel.setVisible(false); - - JPanel replyInputWrapper = new JPanel(); - replyInputWrapper.setLayout(new BoxLayout(replyInputWrapper, BoxLayout.Y_AXIS)); - replyInputWrapper.setBorder(BorderFactory.createEmptyBorder(0, 20 * (depth + 1), 10, 0)); - replyInputWrapper.setAlignmentX(Component.LEFT_ALIGNMENT); - replyInputWrapper.add(replyInputPanel); - - block.add(replyInputWrapper); - - replyBtn.addActionListener(e -> { - replyInputPanel.setVisible(!replyInputPanel.isVisible()); - replyInputPanel.revalidate(); - replyInputPanel.repaint(); - }); - - // 대댓글 추가 - List> replies = allComments.stream() - .filter(c -> { - Object parent = c.get("parent_id"); - return parent != null && ((Number) parent).intValue() == commentId; - }) - .collect(Collectors.toList()); - - for (Map reply : replies) { - JPanel replyBlock = buildCommentWithReplies(reply, allComments, depth + 1); - block.add(replyBlock); - } - - return block; - } - - private JPanel buildCommentPanel(Map comment) { - int commentId = (int) comment.get("comment_id"); - Number writerNum = (Number) comment.get("user_id"); - int writerId = (writerNum != null) ? writerNum.intValue() : -1; - String writer = (String) comment.get("nickname"); - String createdAt = comment.get("created_at").toString(); - String content = (String) comment.get("content"); - - JPanel commentPanel = new JPanel(); - commentPanel.setLayout(new BoxLayout(commentPanel, BoxLayout.Y_AXIS)); - commentPanel.setAlignmentX(Component.LEFT_ALIGNMENT); - - JTextArea commentArea = new JTextArea(writer + " | " + createdAt + "\n" + content); - commentArea.setEditable(false); - commentArea.setBackground(new Color(245, 245, 245)); - commentArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - commentPanel.add(commentArea); - - if (writerId == userId) { - JButton editBtn = new JButton("수정"); - JButton deleteBtn = new JButton("삭제"); - - editBtn.addActionListener(e -> { - String newContent = JOptionPane.showInputDialog(this, "댓글 수정", content); - if (newContent != null && !newContent.trim().isEmpty()) { - if (commentService.updateComment(commentId, newContent.trim())) { - refreshComments(); - } else { - JOptionPane.showMessageDialog(this, "댓글 수정 실패"); - } - } - }); - - deleteBtn.addActionListener(e -> { - int confirm = JOptionPane.showConfirmDialog(this, "정말 삭제하시겠습니까?", "삭제 확인", JOptionPane.YES_NO_OPTION); - if (confirm == JOptionPane.YES_OPTION) { - if (commentService.deleteComment(commentId)) { - refreshComments(); - } else { - JOptionPane.showMessageDialog(this, "댓글 삭제 실패"); - } - } - }); - - JPanel actionPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); - actionPanel.add(editBtn); - actionPanel.add(deleteBtn); - commentPanel.add(actionPanel); - } - - return commentPanel; - } +private final CommentService commentService = new CommentService(); +private final int boardId; +private final int userId = Session.loggedInUserId; +private final JPanel commentListPanel = new JPanel(); + +public BoardDetailScreen(int boardId) { +this.boardId = boardId; + +setLayout(new BorderLayout(15, 15)); +setBorder(BorderFactory.createEmptyBorder(20, 30, 20, 30)); +FontLoader.applyGlobalFont(14f); + +BoardService boardService = new BoardService(); +Map post = boardService.getPostById(boardId); + +JPanel headerPanel = new JPanel(); +headerPanel.setLayout(new BorderLayout()); + +JButton backButton = new JButton("← 뒤로가기"); +backButton.setFont(FontLoader.loadCustomFont(14f)); +backButton.addActionListener(e -> { +int classId = (int) post.get("class_id"); +Main.setScreen(new ClassBoardScreen(classId)); +}); +headerPanel.add(backButton, BorderLayout.EAST); + +JLabel titleLabel = new JLabel("제목: " + post.get("title"), SwingConstants.CENTER); +titleLabel.setFont(FontLoader.loadCustomFont(18f)); +headerPanel.add(titleLabel, BorderLayout.CENTER); + +JTextArea infoArea = new JTextArea( +"작성자: " + post.get("writer") + "\n작성일: " + post.get("created_at") +); +infoArea.setEditable(false); +infoArea.setFont(FontLoader.loadCustomFont(14f)); +infoArea.setOpaque(false); +infoArea.setFocusable(false); +infoArea.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); +headerPanel.add(infoArea, BorderLayout.SOUTH); + +add(headerPanel, BorderLayout.NORTH); + +JTextArea contextArea = new JTextArea(post.get("context").toString()); +contextArea.setLineWrap(true); +contextArea.setWrapStyleWord(true); +contextArea.setEditable(false); +contextArea.setFont(FontLoader.loadCustomFont(14f)); +JScrollPane contentScroll = new JScrollPane(contextArea); +contentScroll.setPreferredSize(new Dimension(500, 250)); +add(contentScroll, BorderLayout.CENTER); + +JPanel bottomPanel = new JPanel(new BorderLayout(10, 10)); +commentListPanel.setLayout(new BoxLayout(commentListPanel, BoxLayout.Y_AXIS)); +JScrollPane commentScroll = new JScrollPane(commentListPanel); +commentScroll.setBorder(BorderFactory.createTitledBorder("댓글 목록")); +commentScroll.setPreferredSize(new Dimension(500, 250)); +bottomPanel.add(commentScroll, BorderLayout.CENTER); + +JPanel inputPanel = new JPanel(new BorderLayout(5, 5)); +JTextArea commentInput = new JTextArea(3, 50); +commentInput.setLineWrap(true); +commentInput.setWrapStyleWord(true); +JScrollPane inputScroll = new JScrollPane(commentInput); + +JButton submitButton = new JButton("댓글 등록"); +submitButton.addActionListener(e -> { +String content = commentInput.getText().trim(); +if (!content.isEmpty()) { +boolean success = commentService.addComment(boardId, userId, content); +if (success) { +commentInput.setText(""); +refreshComments(); +} else { +JOptionPane.showMessageDialog(this, "댓글 등록에 실패했습니다."); +} +} else { +JOptionPane.showMessageDialog(this, "댓글을 입력하세요."); +} +}); + +inputPanel.add(inputScroll, BorderLayout.CENTER); +inputPanel.add(submitButton, BorderLayout.EAST); +bottomPanel.add(inputPanel, BorderLayout.SOUTH); + +add(bottomPanel, BorderLayout.SOUTH); +refreshComments(); +} + +private JPanel createReplyInputPanel(int parentId) { +JPanel replyInputPanel = new JPanel(new BorderLayout()); +JTextArea replyInput = new JTextArea(2, 30); +JButton replySubmit = new JButton("등록"); + +replyInput.setLineWrap(true); +replyInput.setWrapStyleWord(true); + +replyInputPanel.add(new JScrollPane(replyInput), BorderLayout.CENTER); +replyInputPanel.add(replySubmit, BorderLayout.EAST); +replyInputPanel.setVisible(false); + +replySubmit.addActionListener(e -> { +String content = replyInput.getText().trim(); +if (!content.isEmpty()) { +boolean success = commentService.addReply(boardId, userId, content, parentId); +if (success) { +replyInput.setText(""); +replyInputPanel.setVisible(false); +refreshComments(); +} else { +JOptionPane.showMessageDialog(this, "대댓글 등록 실패"); +} +} else { +JOptionPane.showMessageDialog(this, "내용을 입력하세요."); +} +}); + +return replyInputPanel; +} + +private void refreshComments() { +commentListPanel.removeAll(); + +List> comments = commentService.getCommentsByBoardId(boardId); + +comments.sort((a, b) -> { +Object pa = a.get("parent_id"); +Object pb = b.get("parent_id"); + +int pidA = pa == null ? 0 : ((Number) pa).intValue(); +int pidB = pb == null ? 0 : ((Number) pb).intValue(); + +if (pidA != pidB) return Integer.compare(pidA, pidB); +return Integer.compare((int) a.get("comment_id"), (int) b.get("comment_id")); +}); + +List> parentComments = comments.stream() +.filter(c -> c.get("parent_id") == null) +.collect(Collectors.toList()); +for (Map parent : parentComments) { +JPanel parentPanel = buildCommentWithReplies(parent, comments, 0); +commentListPanel.add(parentPanel); } + +commentListPanel.revalidate(); +commentListPanel.repaint(); +} + +private JPanel buildCommentWithReplies(Map comment, List> allComments, int depth) { +int commentId = (int) comment.get("comment_id"); + +JPanel block = new JPanel(); +block.setLayout(new BoxLayout(block, BoxLayout.Y_AXIS)); +block.setAlignmentX(Component.LEFT_ALIGNMENT); + +// ㄴ + 댓글 + 답글 버튼 패널 +JPanel commentRow = new JPanel(); +commentRow.setLayout(new BoxLayout(commentRow, BoxLayout.X_AXIS)); +commentRow.setAlignmentX(Component.LEFT_ALIGNMENT); + +JLabel arrowLabel = new JLabel(depth > 0 ? "↳ " : " "); +arrowLabel.setFont(FontLoader.loadCustomFont(16f)); +arrowLabel.setPreferredSize(new Dimension(20, 20)); +commentRow.add(arrowLabel); + +JPanel commentPanel = buildCommentPanel(comment); +commentRow.add(commentPanel); + +JButton replyBtn = new JButton("답글"); +commentRow.add(Box.createRigidArea(new Dimension(10, 0))); +commentRow.add(replyBtn); + +// 들여쓰기 wrapper +JPanel indentWrapper = new JPanel(); +indentWrapper.setLayout(new BoxLayout(indentWrapper, BoxLayout.Y_AXIS)); +indentWrapper.setBorder(BorderFactory.createEmptyBorder(0, 20 * depth, 10, 0)); +indentWrapper.setAlignmentX(Component.LEFT_ALIGNMENT); +indentWrapper.add(commentRow); + +block.add(indentWrapper); + +// 대댓글 입력창은 block 바깥에 depth+1로 추가되어야 함 +JPanel replyInputPanel = createReplyInputPanel(commentId); +replyInputPanel.setVisible(false); + +JPanel replyInputWrapper = new JPanel(); +replyInputWrapper.setLayout(new BoxLayout(replyInputWrapper, BoxLayout.Y_AXIS)); +replyInputWrapper.setBorder(BorderFactory.createEmptyBorder(0, 20 * (depth + 1), 10, 0)); +replyInputWrapper.setAlignmentX(Component.LEFT_ALIGNMENT); +replyInputWrapper.add(replyInputPanel); + +block.add(replyInputWrapper); + +replyBtn.addActionListener(e -> { +replyInputPanel.setVisible(!replyInputPanel.isVisible()); +replyInputPanel.revalidate(); +replyInputPanel.repaint(); +}); + +// 대댓글 추가 +List> replies = allComments.stream() +.filter(c -> { +Object parent = c.get("parent_id"); +return parent != null && ((Number) parent).intValue() == commentId; +}) +.collect(Collectors.toList()); + +for (Map reply : replies) { +JPanel replyBlock = buildCommentWithReplies(reply, allComments, depth + 1); +block.add(replyBlock); +} + +return block; +} + +private JPanel buildCommentPanel(Map comment) { +int commentId = (int) comment.get("comment_id"); +Number writerNum = (Number) comment.get("user_id"); +int writerId = (writerNum != null) ? writerNum.intValue() : -1; +String writer = (String) comment.get("nickname"); +String createdAt = comment.get("created_at").toString(); +String content = (String) comment.get("content"); + +JPanel commentPanel = new JPanel(); +commentPanel.setLayout(new BoxLayout(commentPanel, BoxLayout.Y_AXIS)); +commentPanel.setAlignmentX(Component.LEFT_ALIGNMENT); + +JTextArea commentArea = new JTextArea(writer + " | " + createdAt + "\n" + content); +commentArea.setEditable(false); +commentArea.setBackground(new Color(245, 245, 245)); +commentArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + +commentPanel.add(commentArea); + +if (writerId == userId) { +JButton editBtn = new JButton("수정"); +JButton deleteBtn = new JButton("삭제"); + +editBtn.addActionListener(e -> { +String newContent = JOptionPane.showInputDialog(this, "댓글 수정", content); +if (newContent != null && !newContent.trim().isEmpty()) { +if (commentService.updateComment(commentId, newContent.trim())) { +refreshComments(); +} else { +JOptionPane.showMessageDialog(this, "댓글 수정 실패"); +} +} +}); + +deleteBtn.addActionListener(e -> { +int confirm = JOptionPane.showConfirmDialog(this, "정말 삭제하시겠습니까?", "삭제 확인", JOptionPane.YES_NO_OPTION); +if (confirm == JOptionPane.YES_OPTION) { +if (commentService.deleteComment(commentId)) { +refreshComments(); +} else { +JOptionPane.showMessageDialog(this, "댓글 삭제 실패"); +} +} +}); + +JPanel actionPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); +actionPanel.add(editBtn); +actionPanel.add(deleteBtn); +commentPanel.add(actionPanel); +} + +return commentPanel; +} + +} \ No newline at end of file diff --git a/src/main/java/gotcha/ui/board/BoardScreen.java b/src/main/java/gotcha/ui/board/BoardScreen.java index 4cc5dfb..1c92544 100644 --- a/src/main/java/gotcha/ui/board/BoardScreen.java +++ b/src/main/java/gotcha/ui/board/BoardScreen.java @@ -22,24 +22,16 @@ public BoardScreen() { int userId = Session.loggedInUserId; - // 상단 패널 구성 - JPanel topPanel = new JPanel(new BorderLayout()); - - JButton backButton = new JButton("← 뒤로가기"); - backButton.setFont(FontLoader.loadCustomFont(14f)); - backButton.addActionListener(e -> { - // 이전 화면으로 전환 (예: 홈 화면) - Main.setScreen(new gotcha.ui.home.HomeScreen()); - }); - topPanel.add(backButton, BorderLayout.WEST); - + // 상단 패널 (제목만 중앙) JLabel titleLabel = new JLabel("참여 중인 소모임"); titleLabel.setFont(FontLoader.loadCustomFont(20f)); titleLabel.setHorizontalAlignment(SwingConstants.CENTER); - topPanel.add(titleLabel, BorderLayout.CENTER); + JPanel topPanel = new JPanel(new BorderLayout()); + topPanel.add(titleLabel, BorderLayout.CENTER); add(topPanel, BorderLayout.NORTH); + // 표 생성 tableModel = new DefaultTableModel(new String[]{ "소모임 ID", "소모임 이름", "요일", "시작 시간", "진행 시간(분)" }, 0) { @@ -50,6 +42,17 @@ public boolean isCellEditable(int row, int column) { }; classTable = new JTable(tableModel); + classTable.setRowHeight(32); + + // 컬럼 폭 지정 + classTable.getColumnModel().getColumn(0).setMinWidth(0); + classTable.getColumnModel().getColumn(0).setMaxWidth(0); + classTable.getColumnModel().getColumn(0).setWidth(0); // 소모임 ID 숨김 + classTable.getColumnModel().getColumn(1).setPreferredWidth(300); // 소모임 이름 + classTable.getColumnModel().getColumn(2).setPreferredWidth(100); // 요일 + classTable.getColumnModel().getColumn(3).setPreferredWidth(150); // 시작 시간 + classTable.getColumnModel().getColumn(4).setPreferredWidth(100); // 진행 시간 + JScrollPane scrollPane = new JScrollPane(classTable); add(scrollPane, BorderLayout.CENTER); @@ -66,7 +69,18 @@ public void mouseClicked(java.awt.event.MouseEvent e) { } }); + // 우측 하단 버튼 패널 + JButton backButton = new JButton("← 뒤로가기"); + backButton.setFont(FontLoader.loadCustomFont(14f)); + backButton.addActionListener(e -> Main.setScreen(new gotcha.ui.home.HomeScreen())); + + JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonPanel.add(backButton); + add(buttonPanel, BorderLayout.SOUTH); + loadParticipatedClasses(userId); + + } private void loadParticipatedClasses(int userId) { @@ -83,12 +97,9 @@ private void loadParticipatedClasses(int userId) { row.get("duration") != null ? row.get("duration").toString() : "-" }); } - } private void openClassBoardWindow(int classId) { Main.setScreen(new ClassBoardScreen(classId)); } - } - diff --git a/src/main/java/gotcha/ui/board/ClassBoardScreen.java b/src/main/java/gotcha/ui/board/ClassBoardScreen.java index 7dbe09c..9982148 100644 --- a/src/main/java/gotcha/ui/board/ClassBoardScreen.java +++ b/src/main/java/gotcha/ui/board/ClassBoardScreen.java @@ -32,13 +32,8 @@ public ClassBoardScreen(int classId) { String classTitle = boardService.getClassTitleById(classId); - // 상단 - JButton backButton = new JButton("← 뒤로가기"); - backButton.setFont(FontLoader.loadCustomFont(14f)); - backButton.addActionListener(e -> Main.setScreen(new BoardScreen())); - + // 상단 (뒤로가기 버튼 제거) JPanel topPanel = new JPanel(new BorderLayout()); - topPanel.add(backButton, BorderLayout.WEST); JLabel titleLabel = new JLabel("📋 " + classTitle + " 게시판"); titleLabel.setFont(FontLoader.loadCustomFont(22f)); @@ -48,13 +43,8 @@ public ClassBoardScreen(int classId) { JPanel rightButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0)); JButton refreshButton = new JButton("새로고침"); refreshButton.setFont(FontLoader.loadCustomFont(14f)); - - refreshButton.addActionListener(e -> { - loadAllPosts(); // 게시글 다시 불러오기 - }); - + refreshButton.addActionListener(e -> loadAllPosts()); rightButtonPanel.add(refreshButton); - topPanel.add(rightButtonPanel, BorderLayout.EAST); JButton writeButton = new JButton("게시글 작성"); writeButton.setFont(FontLoader.loadCustomFont(14f)); @@ -82,6 +72,7 @@ public boolean isCellEditable(int row, int column) { } }; postTable = new JTable(tableModel); + postTable.setRowHeight(32); postTable.getColumnModel().getColumn(0).setMinWidth(0); postTable.getColumnModel().getColumn(0).setMaxWidth(0); postTable.getColumnModel().getColumn(0).setWidth(0); @@ -128,6 +119,16 @@ public void mouseClicked(java.awt.event.MouseEvent e) { } }); + // --- 우측 하단 뒤로가기 버튼 패널 추가 --- + JButton backButton = new JButton("← 뒤로가기"); + backButton.setFont(FontLoader.loadCustomFont(14f)); + backButton.addActionListener(e -> Main.setScreen(new BoardScreen())); + + JPanel bottomButtonPanel = new JPanel(new BorderLayout()); + bottomButtonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + bottomButtonPanel.add(backButton, BorderLayout.LINE_END); + add(bottomButtonPanel, BorderLayout.PAGE_END); + loadAllPosts(); // 전체 불러오고 첫 페이지 로드 } diff --git a/src/main/java/gotcha/ui/home/HomeScreen.java b/src/main/java/gotcha/ui/home/HomeScreen.java index cdd16d8..1c06aff 100644 --- a/src/main/java/gotcha/ui/home/HomeScreen.java +++ b/src/main/java/gotcha/ui/home/HomeScreen.java @@ -52,7 +52,7 @@ public HomeScreen() { searchCategoryPanel.add(searchPanel, BorderLayout.WEST); searchCategoryPanel.add(categoryPanel, BorderLayout.EAST); - // 하단 버튼 왼쪽 (create, manage, board, region/gender) + // 하단 버튼 왼쪽 (create, manage, board, region/gender) JPanel leftButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10)); JButton createBtn = new JButton("소모임 생성"); JButton manageBtn = new JButton("소모임 관리"); @@ -90,25 +90,36 @@ public boolean isCellEditable(int row, int column) { } }; groupTable.setRowHeight(32); - + JLabel hintLabel = new JLabel("※ 소모임을 더블클릭하면 상세조회할 수 있습니다."); hintLabel.setForeground(Color.GRAY); hintLabel.setFont(hintLabel.getFont().deriveFont(Font.ITALIC, 12f)); centerPanel.add(hintLabel); - JScrollPane tableScroll = new JScrollPane(groupTable); + // --- 소모임 목록: 스크롤, 6행 보이게 --- + int groupHeaderHeight = groupTable.getTableHeader().getPreferredSize().height; + Dimension groupTableSize = new Dimension(780, 5 * 32 + groupHeaderHeight); + groupTable.setPreferredScrollableViewportSize(groupTableSize); - centerPanel.add(Box.createVerticalStrut(20)); + JScrollPane tableScroll = new JScrollPane(groupTable); tableScroll.setBorder(BorderFactory.createTitledBorder("소모임 목록")); - tableScroll.setPreferredSize(new Dimension(780, 200)); + centerPanel.add(Box.createVerticalStrut(20)); centerPanel.add(tableScroll); centerPanel.add(Box.createVerticalStrut(20)); - JScrollPane top5Scroll = new JScrollPane(top5Table); - top5Scroll.setBorder(BorderFactory.createTitledBorder("\nTop 5 활발한 소모임")); - top5Scroll.setPreferredSize(new Dimension(780, 200)); - centerPanel.add(top5Scroll); + // --- Top 5 활발한 소모임: 스크롤 없이 5행만 보이게 --- + top5Table.setRowHeight(32); + int top5HeaderHeight = top5Table.getTableHeader().getPreferredSize().height; + Dimension top5TableSize = new Dimension(780, 5 * 32 + top5HeaderHeight); + top5Table.setPreferredScrollableViewportSize(top5TableSize); + top5Table.setPreferredSize(top5TableSize); + + JPanel top5Panel = new JPanel(new BorderLayout()); + top5Panel.setBorder(BorderFactory.createTitledBorder("Top 5 활발한 소모임")); + top5Panel.add(top5Table.getTableHeader(), BorderLayout.NORTH); + top5Panel.add(top5Table, BorderLayout.CENTER); + centerPanel.add(top5Panel); JPanel mainPanel = new JPanel(new BorderLayout()); mainPanel.add(topPanel, BorderLayout.NORTH); @@ -149,38 +160,8 @@ public void mouseClicked(MouseEvent e) { } }); - refreshTables(); - /* - groupTable.addMouseListener(new java.awt.event.MouseAdapter() { - @Override - public void mouseClicked(java.awt.event.MouseEvent evt) { - int row = groupTable.rowAtPoint(evt.getPoint()); - if (row >= 0 && evt.getClickCount() == 2) { - String title = (String) groupTable.getValueAt(row, 1); - int confirm = JOptionPane.showConfirmDialog( - HomeScreen.this, - "'" + title + "' 소모임을 스크랩하시겠습니까?", - "스크랩 확인", - JOptionPane.YES_NO_OPTION - ); - - if (confirm == JOptionPane.YES_OPTION) { - int classId = Integer.parseInt((String) groupTable.getValueAt(row, 0)); - boolean success = scrapService.addScrap(Session.loggedInUserId, classId); - if (success) { - JOptionPane.showMessageDialog(HomeScreen.this, "스크랩이 완료되었습니다."); - } else { - JOptionPane.showMessageDialog(HomeScreen.this, "이미 스크랩했거나 실패했습니다."); - } - } - } - } - }); - */ - } - private void refreshTables() { DefaultTableModel mainModel = new DefaultTableModel() { @Override @@ -201,9 +182,6 @@ public boolean isCellEditable(int row, int column) { top5Model.setColumnIdentifiers(new String[]{"순위", "소모임 이름", "출석률", "모임 설명"}); service.loadGroupAttendance(top5Model, searchField.getText(), (String) categoryToggle.getSelectedItem()); - // groupTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - // top5Table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); - groupTable.setModel(mainModel); groupTable.setRowHeight(32); groupTable.getColumnModel().getColumn(1).setPreferredWidth(150); @@ -212,10 +190,11 @@ public boolean isCellEditable(int row, int column) { groupTable.getColumnModel().getColumn(4).setPreferredWidth(60); top5Table.setModel(top5Model); - groupTable.setRowHeight(32); + top5Table.setRowHeight(32); top5Table.getColumnModel().getColumn(0).setPreferredWidth(40); top5Table.getColumnModel().getColumn(1).setPreferredWidth(150); top5Table.getColumnModel().getColumn(2).setPreferredWidth(80); top5Table.getColumnModel().getColumn(3).setPreferredWidth(400); + } -} \ No newline at end of file +} diff --git a/src/main/java/gotcha/ui/manage/MyGroupDetailScreen.java b/src/main/java/gotcha/ui/manage/MyGroupDetailScreen.java index 52474c7..75a8f33 100644 --- a/src/main/java/gotcha/ui/manage/MyGroupDetailScreen.java +++ b/src/main/java/gotcha/ui/manage/MyGroupDetailScreen.java @@ -127,6 +127,7 @@ private JPanel createMemberAttendancePanel(int classId) { public boolean isCellEditable(int row, int col) { return false; } }; memberTable = new JTable(model); + memberTable.setRowHeight(32); // 참여자 데이터 불러오기 List> members = new UserDAO().getParticipantsByClassId(classId); diff --git a/src/main/java/gotcha/ui/mypage/ChangePasswordDialog.java b/src/main/java/gotcha/ui/mypage/ChangePasswordDialog.java index a3b2636..5731596 100644 --- a/src/main/java/gotcha/ui/mypage/ChangePasswordDialog.java +++ b/src/main/java/gotcha/ui/mypage/ChangePasswordDialog.java @@ -51,5 +51,6 @@ public ChangePasswordDialog(int userId) { cancelBtn.addActionListener(e -> dispose()); setLocationRelativeTo(null); + pack(); } } diff --git a/src/main/java/gotcha/ui/mypage/DeleteAccountDialog.java b/src/main/java/gotcha/ui/mypage/DeleteAccountDialog.java index eab3469..7d9e8d9 100644 --- a/src/main/java/gotcha/ui/mypage/DeleteAccountDialog.java +++ b/src/main/java/gotcha/ui/mypage/DeleteAccountDialog.java @@ -60,5 +60,6 @@ public DeleteAccountDialog(int userId) { cancelBtn.addActionListener(e -> dispose()); setLocationRelativeTo(null); // 화면 중앙 + pack(); } } diff --git a/src/main/java/gotcha/ui/mypage/EditUserInfoDialog.java b/src/main/java/gotcha/ui/mypage/EditUserInfoDialog.java index 55c2451..8b5178b 100644 --- a/src/main/java/gotcha/ui/mypage/EditUserInfoDialog.java +++ b/src/main/java/gotcha/ui/mypage/EditUserInfoDialog.java @@ -52,5 +52,6 @@ public EditUserInfoDialog(int userId) { cancelBtn.addActionListener(e -> dispose()); setLocationRelativeTo(null); + pack(); } } diff --git a/src/main/java/gotcha/ui/mypage/MyPageScreen.java b/src/main/java/gotcha/ui/mypage/MyPageScreen.java index bf92c13..552f27b 100644 --- a/src/main/java/gotcha/ui/mypage/MyPageScreen.java +++ b/src/main/java/gotcha/ui/mypage/MyPageScreen.java @@ -182,7 +182,7 @@ public MyPageScreen(int userId) { deleteAccountBtn.addActionListener(e -> new DeleteAccountDialog(userId).setVisible(true)); backBtn.addActionListener(e -> gotcha.Main.setScreen(new HomeScreen())); - setPreferredSize(new Dimension(850, 700)); + setPreferredSize(new Dimension(1100, 700)); } diff --git a/src/main/java/gotcha/ui/review/HostReviewScreen.java b/src/main/java/gotcha/ui/review/HostReviewScreen.java index e373d23..468c465 100644 --- a/src/main/java/gotcha/ui/review/HostReviewScreen.java +++ b/src/main/java/gotcha/ui/review/HostReviewScreen.java @@ -5,13 +5,15 @@ import javax.swing.*; import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumnModel; + import java.awt.*; import java.util.List; public class HostReviewScreen extends JDialog { public HostReviewScreen(JFrame parent, int classId) { super(parent, "주최자 리뷰 조회", true); - setSize(600, 400); setLocationRelativeTo(parent); ReviewDAO dao = new ReviewDAO(); @@ -28,6 +30,12 @@ public HostReviewScreen(JFrame parent, int classId) { } JTable table = new JTable(model); + table.getColumnModel().getColumn(0).setPreferredWidth(150); // "닉네임" 컬럼 + table.getColumnModel().getColumn(1).setPreferredWidth(70); // "별점" 컬럼 + table.getColumnModel().getColumn(2).setPreferredWidth(450); // "리뷰 내용" 컬럼 + + table.setRowHeight(32); + JScrollPane scroll = new JScrollPane(table); add(scroll, BorderLayout.CENTER); @@ -36,6 +44,17 @@ public HostReviewScreen(JFrame parent, int classId) { JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); btnPanel.add(closeBtn); add(btnPanel, BorderLayout.SOUTH); + + + setSize(700,400); + setResizable(false); + setLocationRelativeTo(parent); + + } + + + } + diff --git a/src/main/java/gotcha/ui/review/UserReviewScreen.java b/src/main/java/gotcha/ui/review/UserReviewScreen.java index 3e5c644..9fefa8a 100644 --- a/src/main/java/gotcha/ui/review/UserReviewScreen.java +++ b/src/main/java/gotcha/ui/review/UserReviewScreen.java @@ -11,7 +11,6 @@ public class UserReviewScreen extends JDialog { public UserReviewScreen(JFrame parent, int userId) { super(parent, "나에 대한 리뷰 보기", true); - setSize(500, 400); setLocationRelativeTo(parent); UserReviewService service = new UserReviewService(); @@ -26,6 +25,9 @@ public UserReviewScreen(JFrame parent, int userId) { model.addRow(new Object[]{r.getClassTitle(), r.getComment()}); } JTable table = new JTable(model); + table.setRowHeight(32); + table.getColumnModel().getColumn(0).setPreferredWidth(300); + table.getColumnModel().getColumn(1).setPreferredWidth(450); JScrollPane scroll = new JScrollPane(table); add(scroll, BorderLayout.CENTER); @@ -36,5 +38,9 @@ public UserReviewScreen(JFrame parent, int userId) { btnPanel.add(closeBtn); add(btnPanel, BorderLayout.SOUTH); + pack(); + setSize(900, 400); + setResizable(false); + setLocationRelativeTo(parent); } }