2013-04-22 4 views
2

여기에 게시 한 것은 이번이 처음이지만이 커뮤니티는 프로그래밍을 시작한 이후로 큰 도움이되었습니다. 기본적으로 행맨 게임을위한 몇 가지 다른 재생 모드가있는 간단한 프로그램을 만들고 있습니다. 이 사이트에 대한 연구를 해본 결과, API를 통해 내가 막혀있는 메소드를 구현하는 방법에 대한 단서를 읽을 수있었습니다. 프로그램의 모든 부분은 잘못된 추측이있을 때마다 GUI에 이미지를 추가해야하는 부분을 제외하고는 훌륭하게 작동합니다. wrongGuess()라는 메서드를 작성했습니다. .jpg를 읽은 다음 JLabel에 할당하지만 GUI에 한 번만 그림을 추가합니다. 나는 스윙과 AWT에 매우 새롭고 조금 실망 스럽다. 나는 여기에있는 누군가가 해결책을 제시 할 수 있기를 바랍니다. 그래서 나는 지식 기반을 조금 더 깊게 할 수 있습니다.잘못된 추측이있을 때마다 내 프로그램에서 .jpg를 GUI에 추가해야합니다.

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 


public class GUI { 

     private static String lettersFileName; 
     private static String playerType; 
     private static char guess; 
     private static String guessString; 
     private static HangmanPlayer aiPlayer; 
     private static hangmanLogic hangmanGame; 
     private final JPanel hangmanPanel = new JPanel(new BorderLayout()); 
     private JPanel graphicsPanel = new JPanel(new GridLayout()); 

     //Constructor 
     GUI(String playerType, String lettersFileName, hangmanLogic hangmanGame){ 
      GUI.playerType = playerType; 
      GUI.lettersFileName = lettersFileName; 
      GUI.hangmanGame = hangmanGame; 
     } 

    /** 
    * Private listener subclass that allows a user to initiate a guess 
    * The action is specific to the type of player (i.e. systematic AI, 
    * random AI, or a human player) 
    */ 
    public void drawGUI() { 
     //Constructs AI player if applicable 

     if (playerType.equals("s")) 

     { 

      aiPlayer = new SystematicPlayer(lettersFileName); 

     } 

     else if (playerType.equals("r")) 

     { 

      aiPlayer = new RandomPlayer(lettersFileName); 

     } 


     //Constructs a hangmanFrame 
     HangmanFrame hangmanFrame = new HangmanFrame(500, 500); 

     //Main section 
     final JPanel mainPanel = new JPanel(new GridLayout(1, 2)); 

     //Title section 
     final JPanel titlePanel = new JPanel(); 
     titlePanel.setBackground(new Color(40, 40, 40)); 
     final JLabel title = new JLabel("Let's Hang Out..."); 
     title.setFont(new Font("Helvetica", Font.BOLD, 18)); 
     title.setHorizontalAlignment(JLabel.CENTER); 
     title.setForeground(Color.WHITE); 
     titlePanel.add(title); 

     //Left border section 
     final JPanel leftBorderPanel = new JPanel(); 
     leftBorderPanel.setBackground(new Color(40, 40, 40)); 

     //Right border section 
     final JPanel rightBorderPanel = new JPanel(); 
     rightBorderPanel.setBackground(new Color(40, 40, 40)); 

     //Hangman section (left sub-section) 
     //final JPanel hangmanPanel = new JPanel(new BorderLayout()); 
     hangmanPanel.setBackground(new Color(120, 120, 120)); 
     final JLabel hangmanTopCommentLabel = new JLabel("To Start Playing"); 
     hangmanTopCommentLabel.setFont(new Font("Helvetica", Font.BOLD, 16)); 
     hangmanTopCommentLabel.setHorizontalAlignment(JLabel.CENTER); 
     hangmanTopCommentLabel.setForeground(Color.WHITE); 
     hangmanPanel.add(hangmanTopCommentLabel, BorderLayout.NORTH); 


     hangmanPanel.add(graphicsPanel); 





     //Set images up for display 
     final JLabel image = new JLabel(); 
     hangmanPanel.add(image, BorderLayout.CENTER); 


     final JLabel hangmanBottomCommentLabel = new JLabel(); 
     hangmanBottomCommentLabel.setFont(new Font("Helvetica", Font.BOLD, 16)); 
     hangmanBottomCommentLabel.setHorizontalAlignment(JLabel.CENTER); 
     hangmanBottomCommentLabel.setForeground(Color.WHITE); 
     hangmanPanel.add(hangmanBottomCommentLabel, BorderLayout.SOUTH); 

     //Right sub-section 
     final JPanel rightSubPanel = new JPanel(new GridLayout(3,1)); 

     //Revealed phrase section 
     final JPanel phrasePanel = new JPanel(new BorderLayout()); 
     phrasePanel.setBackground(new Color(230, 230, 230)); 
     phrasePanel.setBorder(BorderFactory.createLineBorder(Color.black)); 
     final JLabel phraseTitleLabel = new JLabel("Revealed Phrase"); 
     phraseTitleLabel.setFont(new Font("Helvetica", Font.BOLD, 16)); 
     phraseTitleLabel.setHorizontalAlignment(JLabel.CENTER); 
     phrasePanel.add(phraseTitleLabel, BorderLayout.NORTH); 
     final JLabel phraseLabel = new JLabel(hangmanGame.getRevealedKeyPhrase()); 
     phraseLabel.setFont(new Font("Helvetica", Font.BOLD, 20)); 
     phraseLabel.setHorizontalAlignment(JLabel.CENTER); 
     phraseLabel.setForeground(new Color(196, 0, 0)); 
     phrasePanel.add(phraseLabel, BorderLayout.CENTER); 

     //Already guessed letters section 
     final JPanel alreadyGuessedPanel = new JPanel(new BorderLayout()); 
     alreadyGuessedPanel.setBackground(new Color(230, 230, 230)); 
     alreadyGuessedPanel.setBorder(
      BorderFactory.createLineBorder(Color.black)); 
     final JLabel alreadyGuessedTitleLabel = new JLabel(
      "Already Guessed Letters"); 
     alreadyGuessedTitleLabel.setFont(new Font("Helvetica", Font.BOLD, 16)); 
     alreadyGuessedTitleLabel.setHorizontalAlignment(JLabel.CENTER); 
     alreadyGuessedPanel.add(alreadyGuessedTitleLabel, BorderLayout.NORTH); 
     final JTextArea alreadyGuessedLabel = new JTextArea(""); 
     alreadyGuessedLabel.setFont(new Font("Helvetica", Font.BOLD, 22)); 
     alreadyGuessedLabel.setBackground(new Color(230, 230, 230)); 
     alreadyGuessedLabel.setLineWrap(true); 
     alreadyGuessedLabel.setEditable(false); 
     alreadyGuessedPanel.add(alreadyGuessedLabel, BorderLayout.CENTER); 

     //Guesses remaining section 
     final JPanel guessesRemaining = new JPanel(new BorderLayout()); 
     guessesRemaining.setBackground(new Color(230, 230, 230)); 
     guessesRemaining.setBorder(BorderFactory.createLineBorder(Color.black)); 
     final JLabel guessesRemainingTitleLabel = new JLabel("Guesses Remaining"); 
     guessesRemainingTitleLabel.setFont(new Font("Helvetica", Font.BOLD, 16)); 
     guessesRemainingTitleLabel.setHorizontalAlignment(JLabel.CENTER); 
     guessesRemaining.add(guessesRemainingTitleLabel, BorderLayout.NORTH); 
     final JLabel guessesRemainingLabel = new JLabel(Integer.toString(
      hangmanGame.getnumberOfGuessesRemaining())); 
     guessesRemainingLabel.setFont(new Font("Helvetica", Font.BOLD, 60)); 
     guessesRemainingLabel.setHorizontalAlignment(JLabel.CENTER); 
     guessesRemaining.add(guessesRemainingLabel, BorderLayout.CENTER); 

     //Guess input section 
     final JPanel guessInputPanel = new JPanel(new FlowLayout());  
     guessInputPanel.setBackground(new Color(40, 40, 40)); 
     JButton guessButton = new JButton("Guess!"); 
     guessButton.setBackground(new Color(230, 230, 230)); 
     guessButton.setBorderPainted(false); 
     guessButton.setForeground(new Color(196, 0, 0)); 
     final JLabel playerTypeLabel = new JLabel(); 
     playerTypeLabel.setFont(new Font("Helvetica", Font.BOLD, 14)); 
     playerTypeLabel.setHorizontalAlignment(JLabel.LEFT); 
     playerTypeLabel.setForeground(Color.WHITE); 
     final JTextField guessField = new JTextField(10); 
     guessInputPanel.add(playerTypeLabel); 

     //Nests panels 
     mainPanel.add(hangmanPanel); 
     rightSubPanel.add(phrasePanel); 
     rightSubPanel.add(alreadyGuessedPanel); 
     rightSubPanel.add(guessesRemaining); 
     mainPanel.add(rightSubPanel); 

     //Modifies specific components to fit the player type 
     if (playerType.equalsIgnoreCase("s")) 
     { 
     playerTypeLabel.setText(("Systematic AI Player")); 
     hangmanBottomCommentLabel.setText(("Press Guess")); 
     guessInputPanel.add(guessButton); 
     } 
     else if (playerType.equalsIgnoreCase("r")) 
     { 
     playerTypeLabel.setText(("Random AI Player")); 
     hangmanBottomCommentLabel.setText(("Press Guess")); 
     guessInputPanel.add(guessButton); 
     } 
     else if (playerType.equalsIgnoreCase("h")) 
     { 
     playerTypeLabel.setText(("Human Player")); 
     hangmanBottomCommentLabel.setText(("Enter A Guess")); 
     guessInputPanel.add(guessField); 
     guessInputPanel.add(guessButton); 

     /** 
      * Private listener subclass that selects all text 
      * in the guessField when it receives a mouse click 
      * 
      */ 
     class GuessFieldMouseListener implements MouseListener 
     { 
      public void mousePressed(MouseEvent event) 
      { 
       //Selects all text 
       guessField.requestFocus(); 
       guessField.selectAll(); 

      } 
      @Override 
      public void mouseClicked(MouseEvent event) 
      { 
       // TODO Auto-generated method stub 
      } 
      @Override 
      public void mouseEntered(MouseEvent event) 
      { 
       // TODO Auto-generated method stub 
      } 
      @Override 
      public void mouseExited(MouseEvent event) 
      { 
       // TODO Auto-generated method stub 
      } 
      @Override 
      public void mouseReleased(MouseEvent event) 
      { 
       // TODO Auto-generated method stub 
      } 
     } 

     //Adds guessFieldListener to guessField 
     MouseListener guessFieldListener = new GuessFieldMouseListener(); 
     guessField.addMouseListener(guessFieldListener); 
     } 

     /** 
     * Private listener subclass that allows a user to initiate a guess 
     * The action is specific to the type of player (i.e. systematic AI, 
     * random AI, or a human player) 
     */ 
     class GuessActionListener implements ActionListener 
     { 
     public void actionPerformed(ActionEvent event) 
     { 
      /* 
      * Accepts a guess from a given player type and assigns guessString 
      * (s - AI systematic, r - AI random, or h - human) 
      * and determines if the guess is part of the key phrase 
      */ 
       if (playerType.equals("s")) 
       { 
        guess = aiPlayer.makeGuess(); 

        guessString = Character.toString(guess).toUpperCase(); 
       } 
       else if (playerType.equals("r")) 
       { 
        guess = aiPlayer.makeGuess(); 

        guessString = Character.toString(guess).toUpperCase(); 
       } 
       else if (playerType.equals("h")) 
       { 
        guess = guessField.getText().charAt(0); 

        guessString = Character.toString(guess).toUpperCase(); 
       } 
       //Determines if the game is already over 
       if (!hangmanGame.isGameOver()) 
       { 
        try 
        { 
        //Determines if the guess is part of the key phrase 
        if (hangmanGame.guessCharacter(guess)) 
        { 
         //Determines if the current guess ended the game 
         if (hangmanGame.isGameOver()) 
         { 
          if (hangmanGame.getKeyPhrase().equals(
           hangmanGame.getRevealedKeyPhrase())) 
          { 
           //Updates comment labels 
           hangmanTopCommentLabel.setText("You Win!!!"); 
           hangmanBottomCommentLabel.setText("Game Over!"); 
          } 
          else 
          { 
           //Updates comment labels 
           hangmanTopCommentLabel.setText("You Lose!!!"); 
           hangmanBottomCommentLabel.setText("Game Over!"); 
          } 
         } 
         else 
         { 
          //Updates comment labels 
          hangmanTopCommentLabel.setText("Current Guess: " + 
           guessString); 
          hangmanBottomCommentLabel.setText("CORRECT!"); 

          //image.setIcon(new ImageIcon("madBro.jpg")); 



         } 
        } 
        else 
        { 
         if (hangmanGame.isGameOver()) 
         { 
          //Updates comment labels 
          if (hangmanGame.getKeyPhrase().equals(
           hangmanGame.getRevealedKeyPhrase())) 
          { 
           hangmanTopCommentLabel.setText("You Win!!!"); 
           hangmanBottomCommentLabel.setText("Game Over!"); 
          } 
          else 
          { 
           hangmanTopCommentLabel.setText("You Lose!!!"); 
           hangmanBottomCommentLabel.setText("Game Over!"); 
          } 
         } 
         else 
         { 
          //Updates comment labels 
          hangmanTopCommentLabel.setText("Current Guess: " + 
           guessString); 
          hangmanBottomCommentLabel.setText("WRONG!"); 




          //image.setIcon(new ImageIcon("realMad.jpg")); 
          wrongGuess();  


         } 
        } 

        //Updates guessesReaminingLabel and phraseLabel 
        guessesRemainingLabel.setText(
          Integer.toString(
           hangmanGame 
           .getnumberOfGuessesRemaining())); 
        phraseLabel.setText(
          hangmanGame.getRevealedKeyPhrase()); 

        /* 
         * Allows the alreadyGuessedLabel to be updated 
         * with a comma delimited list of the already 
         * guessed characters 
         */ 
        if (alreadyGuessedLabel.getText().equals("")) 
        { 
         alreadyGuessedLabel.setText(
           alreadyGuessedLabel.getText() + " " + 
            guessString); 
        } 
        else 
        { 
         alreadyGuessedLabel.setText(
           alreadyGuessedLabel.getText() + 
           ", " + guessString); 
        } 
        } 
        catch (InvalidInputException e) 
        { 
        //Updates comment labels 
        hangmanTopCommentLabel.setText("Current Guess: " + 
          guessString); 
        hangmanBottomCommentLabel.setText("Invalid Input!"); 

        } 
        catch (AlreadyGuessedException e){ 
        //Updates comment labels 
        hangmanTopCommentLabel.setText("Current Guess: " + 
          guessString); 
        hangmanBottomCommentLabel.setText("Already Guessed!"); 
        } 
       } 
       else 
       { 
        //Updates comment labels 
        hangmanTopCommentLabel.setText("The Game is Over!"); 
        hangmanBottomCommentLabel.setText("Give It Up!"); 
       } 
     } 
     } 

     //Adds guessListener to guessButton 
     ActionListener guessListener = new GuessActionListener(); 
     guessButton.addActionListener(guessListener); 

     //Adds components to the frame 
     hangmanFrame.add(titlePanel, BorderLayout.NORTH); 
     hangmanFrame.add(leftBorderPanel, BorderLayout.WEST); 
     hangmanFrame.add(mainPanel, BorderLayout.CENTER); 
     hangmanFrame.add(rightBorderPanel, BorderLayout.EAST); 
     hangmanFrame.add(guessInputPanel, BorderLayout.SOUTH); 

     //Makes the hangman GUI visible 
     hangmanFrame.setVisible(true); 
    } 

    /** 
    * Adds new graphic representation for each wrong guess made 
    */ 
    private void wrongGuess() 
    { 
     ImageIcon broMad = createImageIcon("madBro.jpg"); 
     JLabel wrong = new JLabel(broMad); 
     graphicsPanel.add(wrong); 
    } 
    /** 
    * Method for creating an image icon, found in Oracle.com's knowledge base 
    * @param path location of desired image file 
    * @return Icon, or null if path not found 
    */ 
    private ImageIcon createImageIcon(String path) 
    { 
     java.net.URL imgURL = getClass().getResource(path); 
     if (imgURL != null) { 
      return new ImageIcon(imgURL); 
     } else { 
      JOptionPane.showMessageDialog(null, 
        "Couldn't find file: " + path); 
      return null; 
     } 
    } 
} 

답변

3

몇 가지 조언과 질문 :

  • 가장 먼저, 당신은 당신의 변수에 모든 정적 수정을 제거하는 것이 좋습니다. Swing GUI는 잘 동작하는 객체 지향 코드를 사용해야하며, 몇 가지 예외를 제외하고는 정적 변수를위한 장소가 거의 없다.
  • 이미지 JLabel에서 setIcon(...)으로 전화하는 것을 고려하고 있지만 댓글을 달았습니다. 왜? 이 방법은 JLabel에 의해 디 스플레이 된 이미지를 스왑하려는 경우에 사용하는 올바른 방법입니다.
  • 프로그램에 새로운 기능을 추가하려고 할 때, 더 복잡한 프로그램에 추가하기 전에 먼저 격리시키는 것이 가장 좋습니다. 더 간단한 GUI를 만드십시오. 하나의 이미지를 ImageIcon으로 읽어 들이고이 간단한 프로그램에서 JButton 푸시로 이미지를 바꿀 수 있는지 확인하십시오. 작동 시키면이 기능을 더 큰 프로그램으로 가져 오는 것이 매우 간단해야합니다.
  • 이미지가 크지 않다면 시작할 때 이미지를 프로그램에 모두 읽어 넣고 원하는 경우 스왑 할 수있는 ImageIcon에 넣을 수 있습니다.
+1

먼저 정적 변수에 포인터를 보내 주셔서 감사합니다. 나는 새로운 자바이고, 나는 나쁜 습관을 찾아 냈다. 정적 변수 중 하나입니다. 나는 그 당시 setIcon을 실험하고 있었지만, 내가해야 할 일이 가능하지 않다고 생각합니다. 플레이어가 잘못 생각할 때마다 동일한 이미지를 GUI에 추가해야합니다. 따라서 나쁜 추측이 2 건 있으면 GUI에 두 개의 이미지가 필요합니다. 세 가지 나쁜 추측 = 세 이미지, 등등. 새로운 기능을 실험하는 데 도움이되는 또 다른 지침이있을 수 있습니다. –

1

나는 순간에 PC에서 아니에요 그래서 코드를 실행할 수 없습니다, 그러나 저 기본적으로

에서이

hangmanPanel.add(graphicsPanel); 

    //Set images up for display 
    final JLabel image = new JLabel(); 
    hangmanPanel.add(image, BorderLayout.CENTER); 

나올 때, 당신은에 graphicsPanel 추가 hangmanPanel은 기본적으로 CENTER 위치에, 다음 효과에 graphicsPanel

+0

내가 발견 한 것은 기본적으로 이미지가 원하는대로 추가된다는 것입니다. 문제는 그들이 서로의 위에 쌓여 있다는 것입니다. 그래서 그것들을 볼 수있는 유일한 방법은 추가되는 GUI 윈도우의 크기를 변경하여 다른 좌표로 초기화하는 것입니다. 이 시점에서 문제는 이미지를 추가하는 방식을 적절히 제어하여 이미지를 올바르게 표시하는 것입니다. 즉 서로의 상부에 적층되지 않는다. 의견을 보내 주셔서 감사합니다. –

0

시도의 호출 다시 그리기를() 제거의 image 라벨을 오버라이드 (override) 모든 변경이 이루어진 후 전체 JFrame.

+1

나를 도우 려던 모든 사람들에게 약간의 피드백 만 있습니다. GridLayout이있는 패널에 그림을 추가하여이 문제를 해결할 수있었습니다. 나는 그들의 통찰력과 시간에 대해 모두에게 감사하고 싶다. 평화. –

1

a 행맨 게임.

Hangman의 경우 일반적으로 모든 그래픽 요소를 하나의 단일 이미지로 그려서 단일 (단일) 레이블로 표시 할 수 있습니다.