我正在用一个棋盘做一个战舰游戏。下图显示了board gui的外观。我当前的代码设置了一个没有“菜单层”的板(我试着用intellij中的SwingGUI设计器来做这个,得到了下面的表单(见图),但是找不到在面板中插入这些按钮的方法。目前,我有以下代码。
package BattleshipGUI;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BoardFrame extends JFrame {
//variables
Ships ship = new Ships();
static final Color colorHit = Color.red;
static final Color colorNormal = Color.gray;
static final Color colorWater = Color.blue;
static final Color colorCarrier = Color.yellow;
static final Color colorBattleship = Color.BLACK;
static final Color colorSubmarine = Color.magenta;
static final Color colorDestroyer = Color.white;
int[][] map;
private Container contents;
int cols;
int rows;
boolean equalPoints;
Player p1 = new Player();
Player p2 = new Player();
private JPanel mainPanel; // I tried using the GUI swing designer, but I cant manage to create
//a menu-layer on top of the buttons
private JButton buttonHighScores;
private JButton quitGame;
private JLabel player1Points;
private JLabel player2Points;
private JLabel playerTurn;
JButton[][] tiles = new JButton[100][100]; // I create 100*100 buttons, but only assign the right
// number to them
public void setMap(int[][] map) {
this.map = map;
}
public void SetFrame(int r, int c) {
this.rows = r;
this.cols = c;
}
public BoardFrame(int r, int c) {
super("Battleship");
setSize(400,450); // I create a frame
this.setLayout(new GridLayout(r, c)); // I set the layout depending on the number of rows and
//columns
AttackHandler attackHandler = new AttackHandler(); // action event class
p1.turn = true; // player 1's turn is true, he commences
p2.turn= false; //player 2's turn is false
for (int i =0; i<r; i++) {
for (int j =0; j <c; j++) {
tiles[i][j] = new JButton(); // this is where all the buttons are declared
tiles[i][j].setBackground(colorNormal);
add(tiles[i][j]);
tiles[i][j].addActionListener(attackHandler);
}
}
setResizable(true);
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(this.DISPOSE_ON_CLOSE);
setSize(400,450); //the size of my frame
}
public class AttackHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (source == tiles[i][j]) {
isHit(i, j);
return;
}
}
}
}
}
public void isHit(int row, int col) {
// the map consists of an 2D array
//where 0's represent the water, 1's represent the tiles that are
//already hit, and the other represent the ships
if (AllHit()) {
JOptionPane.showMessageDialog(null, "All Ships Destructed!");
setWinner();
String winner =DecideWinner();
JOptionPane.showMessageDialog(null, winner+" has won!", "Winner",
JOptionPane.PLAIN_MESSAGE);
int again = JOptionPane.showConfirmDialog(null, "Play Again", "Play
Again",JOptionPane.YES_NO_OPTION);
if (again==0){
Main.main(null);
}
dispose();
}
else if (map[row][col] == 5) {
AddPoint(p1.turn, 5); // this should add points to the player that
//has the turn
tiles[row][col].setBackground(colorCarrier);
map[row][col] = 1;
} else if (map[row][col] == 4) {
AddPoint(p1.turn, 4);
tiles[row][col].setBackground(colorBattleship);
map[row][col] = 1;
} else if (map[row][col] == 3) {
AddPoint(p1.turn, 3);
tiles[row][col].setBackground(colorSubmarine);
map[row][col] = 1;
} else if (map[row][col] == 2) {
AddPoint(p1.turn, 2);
tiles[row][col].setBackground(colorDestroyer);
map[row][col] = 1;
} else if (map[row][col] == 1) {
System.out.println("Already Hit!");
} else if (map[row][col] == 0 || map[row][col] == 9) {
tiles[row][col].setBackground(colorWater);
map[row][col] = 1;
}
p1.changeTurn(p1.turn); // every click, the turn of each player should
//switch from true to false, p1 starts with value
//true, and p2 with false
p2.changeTurn(p2.turn);
System.out.println("Points Player 1: "+p1.points);
System.out.println("Points Player 2: "+p2.points);
}
public boolean AllHit() { // if all ships are hit, a message pops up
boolean allHit = true;
for (int i = 0; i<rows;i++) {
for (int j = 0; j < cols; j++) {
if (map[i][j] != 1 && map[i][j] != 0) {
allHit = false;
break;
}
}
}
return allHit;
}
public void AddRandomShips(int rows, int cols) {
int[][] map = ship.setRandomShips(rows, cols);
setMap(map);
}
public void AddShipsNotRandom(int size, int[][] coordinates){
int[][] map = ship.PlaceShips(size, coordinates);
setMap(map);
}
public void ScoreMethod(boolean scoreMethod){
if(scoreMethod){
equalPoints = true;
}
else if(!scoreMethod){ // the second method adjusts the score
//for the second player because the first player
//is more likely to hit a ship
equalPoints = false;
}
}
public void AddPoint(boolean turn,int amount){
if (turn){
p1.points = p1.points+ amount;
}
else p2.points = p2.points+amount;
}
public void setWinner(){
if(p1.points>p2.points){
p1.setWon();
}
else p2.setWon();
}
public String DecideWinner(){
if (p1.won == true){
return "Player 1";
}
else return "Player 2";
}
}
gui应该是这样的:
这是我的代码生成的:
这是我使用intellij的swing设计器设计的for(带有“按钮”的面板应该充满 JButton
我在代码中创建的):
更新:
多亏了克罗坎普先生,我才添加了一个菜单覆盖图。代码如下所示:
package BattleshipGUI;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import java.awt.Dimension;
public class BoardFrame extends JFrame {
//variables
Ships ship = new Ships();
static final Color colorNormal = Color.gray;
static final Color colorWater = Color.blue;
static final Color colorCarrier = Color.yellow;
static final Color colorBattleship = Color.BLACK;
static final Color colorSubmarine = Color.magenta;
static final Color colorDestroyer = Color.white;
int[][] map;
int cols;
int rows;
boolean equalPoints;
Player p1 = new Player();
Player p2 = new Player();
JButton[][] tiles = new JButton[100][100];
public void setMap(int[][] map) {
this.map = map;
}
public void SetFrame(int r, int c) {
this.rows = r;
this.cols = c;
}
JButton highScoresButton = new JButton("High Scores");
JLabel player1ScoreTitleLabel = new JLabel(String.valueOf(p1.points));
JLabel turnTitleLabel = new JLabel(Turn());
JLabel player2ScoreTitleLabel = new JLabel(String.valueOf(p1.points));
JButton quitGameButton = new JButton("Quite Game");
JFrame frame = new JFrame("Battleship");
public BoardFrame(int r, int c) {
super("Battleship");
AttackHandler attackHandler = new AttackHandler(); // action event class
p1.turn = true; // player 1's turn is true, he commences
p2.turn= false; //player 2's turn is false
JFrame frame = new JFrame("Battleship");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// panel 1 (yellow border)
JPanel panel1 = new JPanel(new GridBagLayout());
JButton highScoresButton = new JButton("High Scores");
JLabel player1ScoreTitleLabel = new JLabel(String.valueOf(p1.points));
JLabel turnTitleLabel = new JLabel(Turn());
JLabel player2ScoreTitleLabel = new JLabel(String.valueOf(p1.points));
JButton quitGameButton = new JButton("Quite Game");
GridBagConstraints s = new GridBagConstraints();
s.weightx = 1;
s.gridx = 0;
s.gridy = 0;
panel1.add(highScoresButton, s);
s.weightx = 1;
s.gridx = 1;
s.gridy = 0;
panel1.add(player1ScoreTitleLabel, s);
s.weightx = 1;
s.gridx = 2;
s.gridy = 0;
panel1.add(turnTitleLabel);
s.weightx = 1;
s.gridx = 3;
s.gridy = 0;
panel1.add(player2ScoreTitleLabel, s);
s.weightx = 1;
s.gridx = 4;
s.gridy = 0;
panel1.add(quitGameButton, s);
// panel 2 (red border)
JPanel panel2 = new JPanel();
GridLayout layout = new GridLayout(r, c);
layout.setHgap(0);
layout.setVgap(0);
panel2.setLayout(layout);
panel2.setBorder(new LineBorder(Color.blue, 4));
for (int i =0; i<r; i++) {
for (int j =0; j < c; j++) {
tiles[i][j] = new JButton(){
@Override
public Dimension getPreferredSize() {
return new Dimension(100,100);
}
};
tiles[i][j].setBackground(colorNormal);
panel2.add(tiles[i][j]);
tiles[i][j].addActionListener(attackHandler);
}
}
frame.add(panel1, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public class AttackHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (source == tiles[i][j]) {
isHit(i, j);
return;
}
}
}
}
}
public void isHit(int row, int col) {
if (AllHit()) {
JOptionPane.showMessageDialog(null, "All Ships Destructed!");
setWinner();
String winner =DecideWinner();
if(p1.won){
p1.checkHighScore();
}
else if (p2.won){
p2.checkHighScore();
}
JOptionPane.showMessageDialog(null, winner, "Winner",
JOptionPane.PLAIN_MESSAGE);
int again = JOptionPane.showConfirmDialog(null, "Play Again", "Play
Again",JOptionPane.YES_NO_OPTION);
if (again==0){
Main.main(null);
}
frame.dispose();
}
else if (map[row][col] == 5) {
AddPoint(p1.turn, 5);
tiles[row][col].setBackground(colorCarrier);
map[row][col] = 1;
} else if (map[row][col] == 4) {
AddPoint(p1.turn, 4);
tiles[row][col].setBackground(colorBattleship);
map[row][col] = 1;
} else if (map[row][col] == 3) {
AddPoint(p1.turn, 3);
tiles[row][col].setBackground(colorSubmarine);
map[row][col] = 1;
} else if (map[row][col] == 2) {
AddPoint(p1.turn, 2);
tiles[row][col].setBackground(colorDestroyer);
map[row][col] = 1;
} else if (map[row][col] == 1) {
System.out.println("Already Hit!");
} else if (map[row][col] == 0 || map[row][col] == 9) {
tiles[row][col].setBackground(colorWater);
map[row][col] = 1;
}
p1.changeTurn(p1.turn);
p2.changeTurn(p2.turn);
// I cannot find a way to change the labels....
player1ScoreTitleLabel.setText(String.valueOf(p1.points));
player2ScoreTitleLabel.setText(String.valueOf(p2.points));
turnTitleLabel.setText(Turn());
System.out.println("Points Player 1: "+p1.points);
System.out.println("Points Player 2: "+p2.points);
}
public boolean AllHit() {
boolean allHit = true;
for (int i = 0; i<rows;i++) {
for (int j = 0; j < cols; j++) {
if (map[i][j] != 1 && map[i][j] != 0) {
allHit = false;
break;
}
}
}
return allHit;
}
public void AddRandomShips(int rows, int cols) {
int[][] map = ship.setRandomShips(rows, cols);
setMap(map);
}
public void AddShipsNotRandom(int size, int[][] coordinates){
int[][] map = ship.PlaceShips(size, coordinates);
setMap(map);
}
public void ScoreMethod(boolean scoreMethod){
if(scoreMethod){
equalPoints = true;
}
else {
equalPoints = false;
}
}
public void AddPoint(boolean turn,int amount){
if (turn){
p1.points = p1.points+ amount;
}
else p2.points = p2.points+amount;
}
public void setWinner(){
if(p1.points>p2.points){
p1.setWon();
}
else if (p2.points>p1.points){
p2.setWon();
}
}
public String DecideWinner(){
if (p1.won){
return "Player 1 won the game!";
}
else if (p2.won){
return "Player 2 won the game!";
}
else return "It's a tie!";
}
public String Turn(){
if (p1.turn){
return "Player 1";
}else return "Player 2";
}
这将生成以下gui:
但是,我仍在努力寻找更改分数jlabels文本值的方法,以下代码对我不起作用:
player1ScoreTitleLabel.setText(String.valueOf(p1.points));
player2ScoreTitleLabel.setText(String.valueOf(p2.points));
turnTitleLabel.setText(Turn())
1条答案
按热度按时间pxiryf3j1#
在我的评论中添加了一个小示例,帮助您在构建ui时尽可能多地结合swing最佳实践,而无需ide的负担:
我选择使用
JLabel
因为这更有意义黄色边框表示
panel1
它利用了gridbaglayout。红色面板代表
panel2
它利用了网格布局。最后是2
JPanel
添加到JFrame
默认情况下使用borderlayout。testapp.java文件: