你能在jpanel中添加jbuttons吗

wfauudbj  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(546)

我正在用一个棋盘做一个战舰游戏。下图显示了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())
pxiryf3j

pxiryf3j1#

在我的评论中添加了一个小示例,帮助您在构建ui时尽可能多地结合swing最佳实践,而无需ide的负担:
我选择使用 JLabel 因为这更有意义
黄色边框表示 panel1 它利用了gridbaglayout。
红色面板代表 panel2 它利用了网格布局。
最后是2 JPanel 添加到 JFrame 默认情况下使用borderlayout。

testapp.java文件:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
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.SwingUtilities;
import javax.swing.border.LineBorder;

public class TestApp {

    public TestApp() {
        createAndShowGui();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TestApp::new);
    }

    private void createAndShowGui() {
        JFrame frame = new JFrame("TestApp");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // panel 1 (yellow border)
        JPanel panel1 = new JPanel(new GridBagLayout());
        JButton highScoresButton = new JButton("High Scores");
        JLabel player1ScoreLabel = new JLabel("<html>Player 1 Score:<br><h2>950</h2>");
        JLabel turnLabel = new JLabel("<html>Turn:<br><h1>Player 1</h1>");
        JLabel player2ScoreLabel = new JLabel("<html>Player 2 Score:<br><h2>925</h2>");
        JButton quitGameButton = new JButton("Quit Game");
        GridBagConstraints c = new GridBagConstraints();
        c.weightx = 1;
        c.gridx = 0;
        c.gridy = 0;
        panel1.add(highScoresButton, c);
        c.weightx = 1;
        c.gridx = 1;
        c.gridy = 0;
        panel1.add(player1ScoreLabel, c);
        c.weightx = 1;
        c.gridx = 2;
        c.gridy = 0;
        panel1.add(turnLabel);
        c.weightx = 1;
        c.gridx = 3;
        c.gridy = 0;
        panel1.add(player2ScoreLabel, c);
        c.weightx = 1;
        c.gridx = 4;
        c.gridy = 0;
        panel1.add(quitGameButton, c);
        panel1.setBorder(new LineBorder(Color.YELLOW, 4)); // just for visual purposes of the answer

        // panel 2 (red border)
        JPanel panel2 = new JPanel();
        GridLayout layout = new GridLayout(8, 8);
        layout.setHgap(5);
        layout.setVgap(5);
        panel2.setLayout(layout);
        panel2.setBorder(new LineBorder(Color.RED, 4)); // just for visual purposes of the answer

        for (int i = 0; i < 64; i++) {
            JLabel label = new JLabel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(100, 100);
                }
            };
            label.setOpaque(true);
            label.setBackground(Color.DARK_GRAY);
            panel2.add(label);
        }

        frame.add(panel1, BorderLayout.NORTH);
        frame.add(panel2, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
}

相关问题