我在网上观看了Tic Tac Toe游戏。游戏运作完美。我需要以这种方式提供 JMenuBar 来即兴创作
JMenuBar > 文件> 新&& 退出
这是完整的代码:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class TicTacToeNewExit implements Runnable, ActionListener{
private String ip = "localhost";
private int port = 22222;
private Scanner scanner = new Scanner(System.in);
private JFrame frame;
private Painter painter;
private Thread thread;
private int WIDTH = 506;
private int HEIGHT = 547;
private JMenuBar jMenuBar;
private JMenu menu;
private JMenuItem newMenuItem, exitMenuItem;
private Socket socket;
private ServerSocket serverSocket;
private DataOutputStream dos;
private DataInputStream dis;
private boolean won = false;
private boolean enemyWon = false;
private boolean tie = false;
private boolean accepted = false;
private boolean circle = true;
private boolean unableToCommunicateWithOpponent = false;
private boolean yourTurn = false;
private BufferedImage board;
private BufferedImage redX;
private BufferedImage redCircle;
private BufferedImage blueX;
private BufferedImage blueCircle;
private String[] spaces = new String[9];
private int lengthOfSpace = 160;
private int errors = 0;
private int firstSpot = -1;
private int secondSpot = -1;
private String wonString = "You Won";
private String enemyWonString = "Opponent Won";
private String unableToCommunicateWithOpponentString = "Cannot connect to opponent";
private String tieString = "It's a tie";
private String waitingString = "Waiting for another player.";
private Font font = new Font("Verdana", Font.BOLD, 30);
private Font smallerFont = new Font("Verdana", Font.BOLD, 20);
private Font largerFont = new Font("Verdana", Font.BOLD, 40);
private int[][] wins = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
public TicTacToeNewExit(){
System.out.println("Enter IP: ");
ip = scanner.nextLine();
System.out.println("Enter port: ");
port = scanner.nextInt();
if(port<1025 || port>65523){
System.out.println("Port Range Problem. Re-enter: ");
port = scanner.nextInt();
}
loadImages();
painter = new Painter();
if(!connect()) initializeServer();
jMenuBar = new JMenuBar();
menu = new JMenu("File");
newMenuItem = new JMenuItem("New");
newMenuItem.setMnemonic(KeyEvent.VK_N);
newMenuItem.setActionCommand("New");
newMenuItem.addActionListener(this);
exitMenuItem = new JMenuItem("Exit");
exitMenuItem.setActionCommand("Exit");
exitMenuItem.addActionListener(this);
menu.add(newMenuItem);
menu.add(exitMenuItem);
jMenuBar.add(menu);
frame = new JFrame();
frame.setTitle("TicTacToePractice");
frame.setContentPane(painter);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(jMenuBar);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
thread = new Thread(this, "TicTacToe1");
thread.start();
}
private void render(Graphics g){
g.drawImage(board, 0, 0, null);
if(unableToCommunicateWithOpponent){
g.setColor(Color.ORANGE);
g.setFont(smallerFont);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
int stringWidth = g2.getFontMetrics().stringWidth(unableToCommunicateWithOpponentString);
g.drawString(unableToCommunicateWithOpponentString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
return;
}
if(accepted){
for (int i = 0; i < spaces.length; i++) {
if (spaces[i] != null) {
int x = (i % 3) * lengthOfSpace + 10 * (i % 3);
int y = (int) (i / 3) * lengthOfSpace + 10 * (int) (i / 3);
if (spaces[i].equals("X")) {
if (circle) {
g.drawImage(redX, x, y, null);
} else {
g.drawImage(blueX, x, y, null);
}
} else if (spaces[i].equals("O")) {
if (circle) {
g.drawImage(blueCircle, x, y, null);
} else {
g.drawImage(redCircle, x, y, null);
}
}
}
}
if (won || enemyWon) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(10));
g.setColor(Color.BLACK);
g.drawLine(firstSpot % 3 * lengthOfSpace + 10 * firstSpot % 3 + lengthOfSpace / 2,
(int) (firstSpot / 3) * lengthOfSpace + 10 * (int) (firstSpot / 3) + lengthOfSpace / 2,
secondSpot % 3 * lengthOfSpace + 10 * secondSpot % 3 + lengthOfSpace / 2,
(int) (secondSpot / 3) * lengthOfSpace + 10 * (int) (secondSpot / 3) + lengthOfSpace / 2); //(x1,y1) && (x2,y2)
g.setColor(Color.GREEN);
g.setFont(largerFont);
if (won) {
int stringWidth = g2.getFontMetrics().stringWidth(wonString);
g.drawString(wonString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
} else if (enemyWon) {
int stringWidth = g2.getFontMetrics().stringWidth(enemyWonString);
g.drawString(enemyWonString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
}
}
if (tie) {
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.BLACK);
g.setFont(largerFont);
int stringWidth = g2.getFontMetrics().stringWidth(tieString);
g.drawString(tieString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
}
}else{
g.setColor(Color.YELLOW);
g.setFont(font);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
int stringWidth = g2.getFontMetrics().stringWidth(waitingString);
g.drawString(waitingString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
return;
}
}
private void loadImages() {
try{
board = ImageIO.read(getClass().getResourceAsStream("/board.png"));
redX = ImageIO.read(getClass().getResourceAsStream("/redX.png"));
redCircle = ImageIO.read(getClass().getResourceAsStream("/redCircle.png"));
blueX = ImageIO.read(getClass().getResourceAsStream("/blueX.png"));
blueCircle = ImageIO.read(getClass().getResourceAsStream("/blueCircle.png"));
}catch(IOException e){
e.printStackTrace();
}
}
private boolean connect() {
try{
socket = new Socket(ip, port);
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
accepted = true;
}catch(IOException e){
System.out.println("Unable to connect to the server. So starting a server on own....Server Started");
return false;
}
System.out.println("Client Connected to Server....");
return true;
}
private void initializeServer() {
try{
serverSocket = new ServerSocket(port);
}catch(Exception e){
e.printStackTrace();
}
yourTurn = true;
circle = false;
}
@Override
public void run() {
while(true){
tick();
painter.repaint();
if(!circle && !accepted){
listenToServerRequest();
}
}
}
private void listenToServerRequest() {
Socket socket = null;
try{
socket = serverSocket.accept();
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
accepted = true;
System.out.println("Client has requested to join. We will accept");
}catch(IOException e){
e.printStackTrace();
}
}
private void tick() {
if(errors >= 10) System.out.println("Too many errors. Take a step down and get a life");
if(!yourTurn && !unableToCommunicateWithOpponent){
try{
int position = dis.readInt();
if(circle){
spaces[position] = "X";
}
else{
spaces[position] = "O";
}
checkForEnemyWin();
checkForTie();
yourTurn = true;
}catch(IOException e){
e.printStackTrace();
errors++;
}
}
}
private void checkForWin(){
for(int i = 0; i < wins.length; i++){
if(circle){
if(spaces[wins[i][0]]=="O" && spaces[wins[i][1]]=="O" && spaces[wins[i][2]]=="O"){
firstSpot = wins[i][0];
secondSpot = wins[i][2];
won = true;
}
}else{
if(spaces[wins[i][0]]=="X" && spaces[wins[i][1]]=="X" && spaces[wins[i][2]]=="X"){
firstSpot = wins[i][0];
secondSpot = wins[i][2];
won = true;
}
}
}
}
private void checkForEnemyWin(){
for (int i = 0; i < wins.length; i++) {
if (circle) {
if (spaces[wins[i][0]] == "X" && spaces[wins[i][1]] == "X" && spaces[wins[i][2]] == "X") {
firstSpot = wins[i][0];
secondSpot = wins[i][2];
enemyWon = true;
}
} else {
if (spaces[wins[i][0]] == "O" && spaces[wins[i][1]] == "O" && spaces[wins[i][2]] == "O") {
firstSpot = wins[i][0];
secondSpot = wins[i][2];
enemyWon = true;
}
}
}
}
private void checkForTie(){
for(int i = 0; i < spaces.length; i++){
if(spaces[i] == null){
return;
}
}
tie = true;
}
@SuppressWarnings("unused")
public static void main(String[] args) {
TicTacToeNewExit ticTacToe = new TicTacToeNewExit();
}
private class Painter extends JPanel implements MouseListener{
private static final long serialVersionUID = 1L;
public Painter(){
setFocusable(true);
requestFocus();
setBackground(Color.WHITE);
addMouseListener(this);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
render(g);
}
@Override
public void mouseClicked(MouseEvent e) {
if(accepted){
if(yourTurn && !unableToCommunicateWithOpponent && !won && !enemyWon){
int x = e.getX()/lengthOfSpace;
int y = e.getY()/lengthOfSpace;
y *= 3;
int position = x+y;
if(spaces[position] == null){
if(!circle) spaces[position] = "X";
else spaces[position] = "O";
yourTurn = false;
repaint();
Toolkit.getDefaultToolkit().sync();
try{
dos.writeInt(position);
dos.flush();
}catch(IOException e1){
errors++;
e1.printStackTrace();
}
System.out.println("Data was sent");
checkForWin();
checkForTie();
}
}
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
@Override
public void actionPerformed(ActionEvent a) {
if(a.getSource() == this.newMenuItem){
this.frame.setContentPane(painter);
errors = 0;
//new TicTacToeNewExit();
}
if(a.getSource() == this.exitMenuItem){
System.exit(0);
}
}
}
ActionPerformed位于代码的最底层。
我无法使用new重新绘制()整个服务器端和客户端游戏。相反,GUI关闭并再次询问localhost和端口号。我该怎样进行以下方式: