我正在寻求解决N-Queens问题,我已经确定了我遇到的问题。有一个JButton被按下,以便在框架中以文本方式告诉用户他们的解决方案是否正确。这个按钮似乎只在皇后没有被放置在电路板上时起作用。问题似乎是我的JLabel" ifNotSafe"的setText()方法。工作不正常。如果我将print语句放在该方法调用下,则会向控制台发送正确的消息,但标签不会更改。这个标签奇怪地只适用于皇后尚未被放置在棋盘上的情况。还有一个带有x值和y值的Boxes对象,以及每个对象的getter方法。
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
/*
* Overall class to make the whole ChessBoard and all the helper methods to
* tell the user whether their solution is correct or not
*/
public class ChessBoardGUI extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
//ImageIcon queenP = new //ImageIcon(getClass().getResource("/images/queen.png"));
//Image img = queenP.getImage();
//Image newImg = img.getScaledInstance(40, 40, java.awt.Image.SCALE_SMOOTH);
ImageIcon queenPic = new ImageIcon(newImg);
private static JButton tip;
private static JButton safe;
private static JLabel ifNotSafe;
private JButton[][] chessBoxes = new JButton[8][8];
public static JPanel chessBoard;
public static ArrayList<Boxes> queensOnBoard = new ArrayList<Boxes>();
/*
* Makes the whole frame for the ChessBoard
*/
public ChessBoardGUI() {
createBoard();
createOtherThings();
setSize(500, 500);
}
/*
* Creates the Tip and Safe buttons And Label to display when the solution
* is incorrect
*/
public void createOtherThings() {
safe = new JButton("Safe?");
tip = new JButton("Tip");
ifNotSafe = new JLabel("Status of Board is displayed here...");
ButtonListen1 safeListener = new ButtonListen1();
ButtonListen2 tipListener = new ButtonListen2();
safe.addActionListener(safeListener);
tip.addActionListener(tipListener);
}
/*
* ActionListener for the safe button
*/
class ButtonListen1 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// Tells user which queens are not safe
if (checkSolution(queensOnBoard) == true) {
//****THIS IS WHERE THE PROBLEM IS *******
ifNotSafe.setText("This Solution is correct so far");
System.out.println("Solution is correct");
} else{
ifNotSafe.setText("This Solution is incorrect so far");
// *********Also highlight the queens that are not safe******
System.out.println("Solution is incorrect");
}
}
}
/*
* ActionListener for the tip button
*/
class ButtonListen2 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// ********Tells the user other places to put queens********
}
}
/*
* Creates the overall ChessBoard
*/
public void createBoard() {
GridLayout gridLayout = new GridLayout();
gridLayout.setRows(8);
gridLayout.setColumns(8);
chessBoard = new JPanel(gridLayout);
chessBoard.setSize(400, 400);
chessBoard.setBorder(new LineBorder(Color.BLACK));
chessBoard.setVisible(true);
/*
* Loops through to add each chessBox to the chessBoard
*/
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
chessBoxes[x][y] = new JButton();
chessBoxes[x][y].setBorderPainted(false);
/*
* Assigns a color to every other box
*/
if ((x + y) % 2 == 0) {
chessBoxes[x][y].setBackground(Color.BLACK);
} else {
chessBoxes[x][y].setBackground(Color.WHITE);
}
chessBoxes[x][y].setOpaque(true);
chessBoard.add(chessBoxes[x][y]);
// Adds the ActionListener to each chessBox
BoxListener boxListen = new BoxListener();
chessBoxes[x][y].addActionListener(boxListen);
}
}
}
/*
* Action Listener for if the individual boxes on the ChessBoard are clicked
*/
class BoxListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JButton button = ((JButton) e.getSource());
// Runs through a loop to find the X and Y coordinate of the
// JButton(Box) that was clicked
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
if (chessBoxes[x][y] == button) {
/*
* If there is No Queen at that JButton
*/
if ((isOnBoard(queensOnBoard, x, y) == false)) {
// Makes sure the user can not place more than
// 8 Queens on the board
if (queensOnBoard.size() < 8) {
// Sets Picture of Queen on box
//button.setIcon(queenPic);
button.setText("Occupied");
// Adds box to the ArrayList of occupied boxes
queensOnBoard.add(new Boxes(x, y));
}
}
/*
* If there is a Queen at that JButton
*/
else {
removeQueen(queensOnBoard, x, y);
//button.setIcon(null);
button.setText("");
}
}
}
}
}
}
/*
* Checks if a certain Box has a Queen in it or not
*
* @param a Is the ArrayList of the Boxes currently occupied by Queens
*
* @param x Is the X coordinate of the Box that was clicked
*
* @param y Is the Y coordinate of the Box that was clicked
*/
public boolean isOnBoard(ArrayList<Boxes> a, int x, int y) {
for (int i = 0; i < a.size(); i++) {
if (((a.get(i)).getX() == x) && ((a.get(i)).getY() == y)) {
return true;
}
}
return false;
}
/*
* Removes a Queen from the GUI at the specified Box (JButton)
*
* @param a Is the ArrayList of the Boxes currently occupied by Queens
*
* @param x Is the X coordinate of the Box that was clicked
*
* @param y Is the Y coordinate of the Box that was clicked
*/
public void removeQueen(ArrayList<Boxes> a, int x, int y) {
/*
* Removes the box from the overall ArrayList of Boxes Occupied by
* queens according to the x and y location
*/
for (int i = 0; i < a.size(); i++) {
if (((a.get(i)).getX() == x) && ((a.get(i)).getY() == y)) {
queensOnBoard.remove(i);
}
}
}
/*
* Return to the user which queens need to be highlighted
*
* @param queensOnBoard Is the ArrayList of Boxes that are occupied by
* Queens currently on the ChessBoard
*/
public void conflictingQueens(ArrayList<Boxes> queensOnBoard) {
// *******Call the highlightBoxes method using the ArrayList
// Of Boxes you get from this method
}
/*
* Checks to see if solution is correct thusfar
*
* @param queensOnBoard Is the ArrayList of Boxes that are occupied by
* Queens currently on the ChessBoard
*/
public boolean checkSolution(ArrayList<Boxes> queensOnBoard) {
int size = queensOnBoard.size();
if (size < 1) {
return true;
}
if (size == 1) {
return true;
}
for (int x = 0; x < size - 1; x++) {
for (int y = 1; y < size; y++) {
// Checks if Queen is safe from horizontal attacks
if (queensOnBoard.get(x).getX() == queensOnBoard.get(y).getX()) {
return false;
// Checks if Queen is safe from vertical attacks
} else if (queensOnBoard.get(x).getY() == queensOnBoard.get(y).getY()) {
return false;
// Checks if Queen is safe from diagonal attacks
// Uses diagonalAttack(queensOnBoard) as a helper method
} // else if(){
// return false;
// }
}
}
return true;
}
/*
* Checks to see if the queen is safe from diagonal attacks
*
*
*/
// public boolean diagonalAttack(ArrayList<Boxes> queensOnBoard){
//********
// }
/*
* Highlights boxes that are conflicting with one another
*
* @param highlight Is the ArrayList of Boxes that are occupied by Queens
* currently on the ChessBoard
*/
public void highlightBoxes(ArrayList<Boxes> highlight) {
int size1 = highlight.size();
int size2 = queensOnBoard.size();
// When there aren't any queens at risk, this block
// changes the background colors of the boxes back to
// Their respective color
if ((size1 == 0) && size1 == 1) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
chessBoxes[x][y] = new JButton();
chessBoxes[x][y].setBorderPainted(false);
/*
* Assigns a color to every other box
*/
if ((x + y) % 2 == 0) {
chessBoxes[x][y].setBackground(Color.BLACK);
} else {
chessBoxes[x][y].setBackground(Color.WHITE);
}
}
}
}
// Runs through both the highlight and queensOnBoard ArrayLists and
// changes the background for the Queens at risk
for (int b = 0; b < size2; b++) {
for (int a = 0; a < size1; a++) {
if ((highlight.get(a).getX() == queensOnBoard.get(b).getX())
&& (highlight.get(a).getY() == queensOnBoard.get(b).getY())) {
int x = queensOnBoard.get(b).getX();
int y = queensOnBoard.get(b).getY();
chessBoxes[x][y].setBackground(Color.RED);
}
}
}
}
/*
* Main method to run the program
*
* @param args Is the String of args given to the console to run the
* operations of the program
*/
public static void main(String[] args) {
JFrame frame = new ChessBoardGUI();
frame.add(chessBoard);
chessBoard.setLocation(50, 50);
JPanel panel1 = new JPanel();
panel1.add(ifNotSafe);
panel1.add(safe);
panel1.add(tip);
frame.add(panel1);
frame.setTitle("ChessBoard");
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
答案 0 :(得分:2)
您可能遇到布局问题,因为JLabel没有很好地显示,因为保存它的JPanel已经错误地添加到GUI。理解JFrame的contentPane默认使用BorderLayout,因此在向其添加组件时,应指定组件应放置的BorderLayout位置。网格将放置BorderLayout.CENTER,panel1应放置BorderLayout.PAGE_START。此外,应设置网格的首选大小,并且在添加所有组件之后,您应该在JFrame 上调用pack()
,但之前使其可见或设置其位置。
其他小琐事:
测试代码如下。请注意,我没有您的女王图像,所以我创建了一个您不需要的方法,private Icon createQueenIcon()
。这样您的代码就可以在我的系统上运行。为了使代码运行和编译,我创建并包含了必要的Boxes类。将来,请确保包含我们编译和运行代码所需的所有内容!
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.*;
public class ChessBoardGUI extends JFrame {
private static final long serialVersionUID = 1L;
// !! code changes below only to allow me to run your code without
// your images. !!
// ImageIcon queenP = new ImageIcon(getClass().getResource("/images/queen.png"));
// Image img = queenP.getImage();
// Image newImg = img.getScaledInstance(40, 40,
// java.awt.Image.SCALE_SMOOTH);
private ImageIcon queenPic = createQueenIcon(); //!! delete this
// all fields should be private and non-static
private JButton tip;
private JButton safe;
private JLabel ifNotSafe;
private JButton[][] chessBoxes = new JButton[8][8];
private JPanel chessBoard;
private ArrayList<Boxes> queensOnBoard = new ArrayList<Boxes>();
public ChessBoardGUI() {
createBoard();
add(chessBoard, BorderLayout.CENTER); // Do this here
// !! createOtherThings(); // get rid of -- put in constructor
safe = new JButton("Safe?");
tip = new JButton("Tip");
ifNotSafe = new JLabel("Status of Board is displayed here...");
ButtonListen1 safeListener = new ButtonListen1();
ButtonListen2 tipListener = new ButtonListen2();
safe.addActionListener(safeListener);
tip.addActionListener(tipListener);
// !! add the panel1 here!
JPanel panel1 = new JPanel();
panel1.add(ifNotSafe);
panel1.add(safe);
panel1.add(tip);
add(panel1, BorderLayout.PAGE_START); // using BorderLayout constants
// !! setSize(500, 500);
}
// !! so I can use images without having an image
// !! you won't need this
private Icon createQueenIcon() {
int w = 40;
BufferedImage img2 = new BufferedImage(w, w, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img2.createGraphics();
g2.setColor(new Color(183, 65, 14));
g2.fillRect(0, 0, w, w);
g2.setColor(new Color(255, 215, 0));
Font font = new Font(Font.SANS_SERIF, Font.BOLD, 30);
g2.setFont(font);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
FontMetrics fontMetrics = g2.getFontMetrics();
int textX = (w - fontMetrics.charWidth('Q')) / 2;
int textY = (w - fontMetrics.getHeight()) / 2 + fontMetrics.getAscent();
g2.drawString("Q", textX, textY);
g2.dispose();
return new ImageIcon(img2);
}
class ButtonListen1 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (checkSolution(queensOnBoard) == true) {
// ****THIS IS WHERE THE PROBLEM IS ******* !!
ifNotSafe.setText("This Solution is correct so far");
System.out.println("Solution is correct");
} else {
ifNotSafe.setText("This Solution is incorrect so far");
// *********Also highlight the queens that are not safe******
System.out.println("Solution is incorrect");
}
}
}
/*
* ActionListener for the tip button
*/
class ButtonListen2 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
}
}
/*
* Creates the overall ChessBoard
*/
public void createBoard() {
GridLayout gridLayout = new GridLayout();
gridLayout.setRows(8);
gridLayout.setColumns(8);
chessBoard = new JPanel(gridLayout);
chessBoard.setPreferredSize(new Dimension(640, 640));
chessBoard.setBorder(new LineBorder(Color.BLACK));
chessBoard.setVisible(true);
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
chessBoxes[x][y] = new JButton();
chessBoxes[x][y].setBorderPainted(false);
if ((x + y) % 2 == 0) {
chessBoxes[x][y].setBackground(Color.BLACK);
} else {
chessBoxes[x][y].setBackground(Color.WHITE);
}
chessBoxes[x][y].setOpaque(true);
chessBoard.add(chessBoxes[x][y]);
BoxListener boxListen = new BoxListener();
chessBoxes[x][y].addActionListener(boxListen);
}
}
}
class BoxListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JButton button = ((JButton) e.getSource());
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
if (chessBoxes[x][y] == button) {
if ((isOnBoard(queensOnBoard, x, y) == false)) {
if (queensOnBoard.size() < 8) {
button.setIcon(queenPic);
queensOnBoard.add(new Boxes(x, y));
}
}
/*
* If there is a Queen at that JButton
*/
else {
removeQueen(queensOnBoard, x, y);
button.setIcon(null);
}
}
}
}
}
}
/*
* Checks if a certain Box has a Queen in it or not
*
* @param a Is the ArrayList of the Boxes currently occupied by Queens
*
* @param x Is the X coordinate of the Box that was clicked
*
* @param y Is the Y coordinate of the Box that was clicked
*/
public boolean isOnBoard(ArrayList<Boxes> a, int x, int y) {
for (int i = 0; i < a.size(); i++) {
if (((a.get(i)).getX() == x) && ((a.get(i)).getY() == y)) {
return true;
}
}
return false;
}
/*
* Removes a Queen from the GUI at the specified Box (JButton)
*
* @param a Is the ArrayList of the Boxes currently occupied by Queens
*
* @param x Is the X coordinate of the Box that was clicked
*
* @param y Is the Y coordinate of the Box that was clicked
*/
public void removeQueen(ArrayList<Boxes> a, int x, int y) {
/*
* Removes the box from the overall ArrayList of Boxes Occupied by
* queens according to the x and y location
*/
for (int i = 0; i < a.size(); i++) {
if (((a.get(i)).getX() == x) && ((a.get(i)).getY() == y)) {
queensOnBoard.remove(i);
}
}
}
/*
* Return to the user which queens need to be highlighted
*
* @param queensOnBoard Is the ArrayList of Boxes that are occupied by
* Queens currently on the ChessBoard
*/
public void conflictingQueens(ArrayList<Boxes> queensOnBoard2) {
}
/*
* Checks to see if solution is correct thusfar
*
* @param queensOnBoard Is the ArrayList of Boxes that are occupied by
* Queens currently on the ChessBoard
*/
public boolean checkSolution(ArrayList<Boxes> queensOnBoard2) {
int size = queensOnBoard2.size();
if (size < 1) {
return true;
}
if (size == 1) {
return true;
}
for (int x = 0; x < size - 1; x++) {
for (int y = 1; y < size; y++) {
if (queensOnBoard2.get(x).getX() == queensOnBoard2.get(y).getX()) {
return false;
} else if (queensOnBoard2.get(x).getY() == queensOnBoard2.get(y).getY()) {
return false;
}
}
}
return true;
}
/*
* Checks to see if the queen is safe from diagonal attacks
*/
/*
* Highlights boxes that are conflicting with one another
*
* @param highlight Is the ArrayList of Boxes that are occupied by Queens
* currently on the ChessBoard
*/
public void highlightBoxes(ArrayList<Boxes> highlight) {
int size1 = highlight.size();
int size2 = queensOnBoard.size();
if ((size1 == 0) && size1 == 1) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
chessBoxes[x][y] = new JButton();
chessBoxes[x][y].setBorderPainted(false);
/*
* Assigns a color to every other box
*/
if ((x + y) % 2 == 0) {
chessBoxes[x][y].setBackground(Color.BLACK);
} else {
chessBoxes[x][y].setBackground(Color.WHITE);
}
}
}
}
for (int b = 0; b < size2; b++) {
for (int a = 0; a < size1; a++) {
if ((highlight.get(a).getX() == queensOnBoard.get(b).getX())
&& (highlight.get(a).getY() == queensOnBoard.get(b).getY())) {
int x = queensOnBoard.get(b).getX();
int y = queensOnBoard.get(b).getY();
chessBoxes[x][y].setBackground(Color.RED);
}
}
}
}
public static void main(String[] args) {
// !! create the GUI in a Swing thread-safe manner
SwingUtilities.invokeLater(() -> createGui());
}
public static void createGui() {
JFrame frame = new ChessBoardGUI();
// !! frame.add(chessBoard); // not here
// !! chessBoard.setLocation(50, 50);
// !! this does not belong within main
// !! JPanel panel1 = new JPanel();
// panel1.add(ifNotSafe);
// panel1.add(safe);
// panel1.add(tip);
// frame.add(panel1);
frame.setTitle("ChessBoard");
frame.pack(); // !! call this to have your GUI size itself
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private static class Boxes {
private int x;
private int y;
public Boxes(int x, int y) {
this.x = x;
this.y = y;
}
public int getY() {
return x;
}
public int getX() {
return y;
}
}
}