[英]How would I properly implement a JScrollPane GUI into my Java game?
幾天來,我一直在嘗試將這個“基本”GUI 應用到我的井字游戲中。 這段代碼的大綱要求我在 JScrollPane GUI 內設置一個基本的 JFrame,其中包含一個 JTextArea。 所有這些都在 class TicTacToeFrame 中,它擴展了 class TicTacToe(包含板的所有方法/構造函數,包括將板打印到控制台的方法)。 TicTacToeFrame 需要重寫 print() 方法,因此作為字符串的板將打印到 GUI 而不是控制台。 注意,我需要保留:
public class TicTacToeFrame extends TicTacToe
他們不允許我們從 JFrame 擴展,例如:
public class TicTacToeFrame extends JFrame
我所擁有的如下所示:
井字游戲 class(工程)
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 class(壞掉)
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 甚至都不會出現。在測試期間,如果我讓它出現,它不會打印任何文本。
我認為這里真正的問題是您是 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 的不同布局管理器進行一些研究。 毫無疑問,你會發現,讓 swing 做你想做的事,作為一個初學者是很復雜的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.