2

这是我第一次在这里发帖,但是自从我开始编程以来,这个社区对我的帮助很大。基本上,我正在开发一个简单的程序,该程序有几种不同的游戏模式用于刽子手游戏。我在这个网站上做了一些研究,并通读了 API 以获得一些关于如何实现我坚持的方法的线索。程序中的所有内容都运行良好,除了每次做出错误猜测时我需要将图像添加到 GUI 的部分。我写了一个名为 wrongGuess(); 的方法。读取 .jpg 并将其分配给 JLabel,但它只会将图片添加到 GUI 一次。我对摇摆和 AWT 非常陌生,发现它们有点令人沮丧。我希望这里有人可以提供一个解决方案,这样我就可以加深我的知识基础。

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;
        }
    }
}
4

4 回答 4

3

一些建议和问题:

  • 首先,您将希望摆脱变量上的所有静态修饰符。您的 Swing GUI 应该使用行为良好的面向对象代码,除了少数例外,静态变量几乎没有位置。
  • 您似乎正在考虑调用setIcon(...)您的图像 JLabel,但已将其注释掉。为什么?当您希望交换由 JLabel 显示的图像时,这是使用的正确方法。
  • 在尝试向程序添加一些新的复杂功能时,我发现通常最好先尝试使其独立工作,然后再尝试将其添加到更大更复杂的程序中。考虑创建一个简单的 GUI,将几个图像读入 ImageIcons,看看您是否可以在这个更简单的程序中交换 JButton push 上的图像。如果你让它工作,那么将这个功能引入更大的程序应该是相当简单的。
  • 请注意,如果您的图像不是那么大,您可以在启动时将它们全部读入程序并将它们放入 ImageIcons 中,以便在需要时进行交换。
于 2013-04-22T21:57:16.127 回答
1

..一个刽子手游戏。

对于 Hangman,您通常会将所有图形元素绘制到一个图像中,然后您可能会在(单个)标签中显示该图像。

于 2013-04-23T02:40:06.617 回答
1

我现在不在 PC 上,所以我无法运行代码,但是这个

  hangmanPanel.add(graphicsPanel);

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

向我扑来

基本上,您将默认情况下添加graphicsPanel到该位置,然后用标签覆盖它,有效地删除hangmanPanelCENTERimagegraphicsPanel

于 2013-04-22T22:01:04.590 回答
0

完成所有更改后,尝试在整个 JFrame 上调用 repaint()。

于 2013-04-22T22:02:51.017 回答