【问题标题】:How would I properly implement a JScrollPane GUI into my Java game?如何在我的 Java 游戏中正确实现 JScrollPane GUI?
【发布时间】:2019-11-20 15:07:40
【问题描述】:

几天来,我一直在尝试将这个“基本”GUI 应用到我的井字游戏中。这段代码的大纲要求我在 JScrollPane GUI 内设置一个包含 JTextArea 的基本 JFrame。所有这些都在 TicTacToeFrame 类中,该类扩展了 TicTacToe 类(包含棋盘的所有方法/构造函数,包括将棋盘打印到控制台的方法)。 TicTacToeFrame 需要重写 print() 方法,因此作为字符串的板将打印到 GUI 而不是控制台。 注意,我必须保留:

public class TicTacToeFrame extends TicTacToe

它们不允许我们像这样从 JFrame 扩展:

public class TicTacToeFrame extends JFrame

我所拥有的如下所示:

井字游戏(作品)

import java.util.*;

/**
 * A class modelling a tic-tac-toe (noughts and crosses, Xs and Os) game.
 * 
 * @author Supasta
 * @version November 20, 2019
 */

public class TicTacToe
{
   public static final String PLAYER_X = "X"; // player using "X"
   public static final String PLAYER_O = "O"; // player using "O"
   public static final String EMPTY = " ";  // empty cell
   public static final String TIE = "T"; // game ended in a tie

   private String player;   // current player (PLAYER_X or PLAYER_O)

   private String winner;   // winner: PLAYER_X, PLAYER_O, TIE, EMPTY = in progress

   private int numFreeSquares; // number of squares still free

   private String board[][]; // 3x3 array representing the board

   private TicTacToeFrame gui;
   /** 
    * Constructs a new Tic-Tac-Toe board.
    */
   public TicTacToe()
   {
      board = new String[3][3];
   }

   /**
    * Sets everything up for a new game.  Marks all squares in the Tic Tac Toe board as empty,
    * and indicates no winner yet, 9 free squares and the current player is player X.
    */
   private void clearBoard()
   {
      for (int i = 0; i < 3; i++) {
         for (int j = 0; j < 3; j++) {
            board[i][j] = EMPTY;
         }
      }
      winner = EMPTY;
      numFreeSquares = 9;
      player = PLAYER_X;     // Player X always has the first turn.
   }


   /**
    * Plays one game of Tic Tac Toe.
    */

   public void playGame()
   {
      int row, col;
      Scanner sc;

      clearBoard(); // clear the board

      gui = new TicTacToeFrame();

      // print starting board
      gui.print();

      // loop until the game ends
      while (winner==EMPTY) { // game still in progress

         // get input (row and column)
         while (true) { // repeat until valid input
            System.out.print("Enter row and column of chosen square (0, 1, 2 for each): ");
            sc = new Scanner(System.in);
            row = sc.nextInt();
            col = sc.nextInt();
            if (row>=0 && row<=2 && col>=0 && col<=2 && board[row][col]==EMPTY) break;
            System.out.println("Invalid selection, try again.");
         }

         board[row][col] = player;        // fill in the square with player
         numFreeSquares--;            // decrement number of free squares

         // see if the game is over
         if (haveWinner(row,col)) 
            winner = player; // must be the player who just went
         else if (numFreeSquares==0) 
            winner = TIE; // board is full so it's a tie

         // print current board
         print();

         // change to other player (this won't do anything if game has ended)
         if (player==PLAYER_X) 
            player=PLAYER_O;
         else 
            player=PLAYER_X;
      }

   } 


   /**
    * Returns true if filling the given square gives us a winner, and false
    * otherwise.
    *
    * @param int row of square just set
    * @param int col of square just set
    * 
    * @return true if we have a winner, false otherwise
    */
   private boolean haveWinner(int row, int col) 
   {
       // unless at least 5 squares have been filled, we don't need to go any further
       // (the earliest we can have a winner is after player X's 3rd move).

       if (numFreeSquares>4) return false;

       // Note: We don't need to check all rows, columns, and diagonals, only those
       // that contain the latest filled square.  We know that we have a winner 
       // if all 3 squares are the same, as they can't all be blank (as the latest
       // filled square is one of them).

       // check row "row"
       if ( board[row][0].equals(board[row][1]) &&
            board[row][0].equals(board[row][2]) ) return true;

       // check column "col"
       if ( board[0][col].equals(board[1][col]) &&
            board[0][col].equals(board[2][col]) ) return true;

       // if row=col check one diagonal
       if (row==col)
          if ( board[0][0].equals(board[1][1]) &&
               board[0][0].equals(board[2][2]) ) return true;

       // if row=2-col check other diagonal
       if (row==2-col)
          if ( board[0][2].equals(board[1][1]) &&
               board[0][2].equals(board[2][0]) ) return true;

       // no winner yet
       return false;
   }


   /**
    * Prints the board to standard out using toString().
    */
    public void print() 
    {
        System.out.println(toString());
    }


   /**
    * Returns a string representing the current state of the game.  This should look like
    * a regular tic tac toe board, and be followed by a message if the game is over that says
    * who won (or indicates a tie).
    *
    * @return String representing the tic tac toe game state
    */
    public String toString() 
    {
        String currentState = "";
        String progress = "";

        for(int i=0 ; i < 3; ++i){
            currentState += board[i][0] + " | " + board[i][1] + " | " + board[i][2] + "\n";

            if(i == 2){
                break;
            }

            currentState += "------------\n";
        }

        /* Prints the winner, only if there is a winner */
        if(winner != EMPTY){
            if(this.winner == TIE){
                progress = ("The games ends in a tie!");
            }
            else{
                progress = ("Game over, " + player + " wins!");
            }
        }
        else{
            progress = "Game in progress";
        }
        return currentState + "\n" + progress + "\n";
    }

}

TicTacToeFrame 类(已损坏)

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

/**
 * A class modelling a tic-tac-toe (noughts and crosses, Xs and Os) game in a very
 * simple GUI window.
 * 
 * @author Supasta
 * @version November 20, 2019
 */

public class TicTacToeFrame extends TicTacToe 
{ 
   private JTextArea status; // text area to print game status
   private JFrame frame;
   private JScrollPane sta;

   /** 
    * Constructs a new Tic-Tac-Toe board and sets up the basic
    * JFrame containing a JTextArea in a JScrollPane GUI.
    */
   public TicTacToeFrame()
   { 
       super();
       final JFrame frame = new JFrame("Tic Tac Toe");

       frame.setSize(500,500);

       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       status = new JTextArea(super.toString());
       JScrollPane sta = new JScrollPane();

       sta.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);  
       sta.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

       frame.getContentPane().add(sta);
       frame.setVisible(true);
   }

   /**
    * Prints the board to the GUI using toString().
    */
    public void print() 
    {  
        status.replaceSelection(toString());
    }

}

我应该在我的井字游戏框架中进行哪些更改?现在 GUI 甚至都不会出现。在测试期间,如果我让它出现,它不会打印任何文本。

【问题讨论】:

  • 对于初学者,您将 JScrollPane 添加到 JFrame,但您没有向 JScrollPane 添加任何内容。你需要做 JScrollPane sta = new JScrollPane(status);
  • 我最初确实有这个,但它仍然没有向 GUI 输出任何内容。经过各种尝试使其正常工作后,我必须对其进行更改。你还有什么其他可能有问题的地方吗?
  • 尝试在 frame.setVisible(true) 之前添加 frame.pack();如果这不起作用,请查看布局约束

标签: java oop user-interface


【解决方案1】:

我认为这里真正的问题是您是 swing GUI 的新手。您正在尝试将框架应用到现有代码并希望看到它 - 但必须明确添加所有内容。

import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class Test {
    /**
     * Do this for thread safety
     * @param args
     */
    public static void main (String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createGUI();
            }
        });
    }

    /**
     * create the JFrame
     */
    private static void createGUI() {
        JFrame jf = new JFrame();

        addComponents(jf.getContentPane());

        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
    }

    /**
     * add the components
     * ALL YOUR NEW TIC TAC TOE RELATED JPANELS, JTEXTFIELDS, ETC. WILL GO HERE!
     * @param pane
     */
    private static void addComponents(Container pane) {
        pane.setLayout(new FlowLayout());

        JTextArea jta = new JTextArea("some text");
        JScrollPane jsp = new JScrollPane(jta);
        jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        pane.add(jsp);
    }
}

为了帮助您入门,这里有一个非常基本的程序,它将向您展示我是如何添加可滚动的 JTextArea 的。我会从头开始,并从井字游戏中逐步添加您的功能。一次添加一项。

如何让 X 显得更大?我要在哪里?什么时候需要?

这些都是我希望您有的问题 - 我建议您对 JPanel 的不同布局管理器进行一些研究。毫无疑问,你会发现,作为初学者,让挥杆做你想做的事情是很复杂的。

【讨论】:

  • 非常感谢您的帮助,我现在确实设法让它工作了,把它布置出来真的让一步一步地完成它变得更容易了。我真的很感激!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
相关资源
最近更新 更多