在SudokuSolver程序中实现ActionListener时遇到一些问题



`

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class UI {
SudokuBoard board;
JTextField[][] grid;
JFrame frame;
public UI(SudokuBoard board) {
this.board = board;
this.grid = new JTextField[9][9];
SwingUtilities.invokeLater(() -> createWindow("SudokuGame", 1000, 1000));
}
private void createWindow(String title, int width, int height) {
// creating main window
this.frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = frame.getContentPane();
frame.setPreferredSize(new Dimension(width, height));
// creating buttons
JPanel buttonPanel = new JPanel();
JButton solve = new JButton("Solve");
JButton clear = new JButton("Clear");
buttonPanel.add(solve);
buttonPanel.add(clear);
pane.add(buttonPanel, BorderLayout.SOUTH);
solve.addActionListener(e -> {
if (board.solve()) {
updateBoard();
} else {
JOptionPane.showMessageDialog(frame, "Unsolvable Board");
}
});
clear.addActionListener(e -> {
board.clear();
updateBoard();
});
// creating game grid
JPanel topPanel = new JPanel(new GridLayout(9, 9));
topPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
Font font = new Font("Monospaced", Font.BOLD, 80);
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
JTextField temp = new JTextField(1);
temp.setBorder(BorderFactory.createLineBorder(Color.black, 3));
temp.setPreferredSize(new Dimension(100, 100));
temp.setHorizontalAlignment(JTextField.CENTER);
temp.setFont(font);
temp.addActionListener(new SetAction(row, col, temp, board));
if (((col < 3 || col > 5) && (row < 3 || row > 5)) || col > 2 && col < 6 && row > 2 && row < 6) {
temp.setBackground(new Color(91, 166, 209));
} else {
temp.setBackground(new Color(181, 197, 209));
}
grid[row][col] = temp;
topPanel.add(temp);
}
}
pane.add(topPanel);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
updateBoard();
}
private void updateBoard() {
int[][] temp = board.getMatrix();
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (temp[row][col] == 0) {
grid[row][col].setText("");
} else {
grid[row][col].setText(Integer.toString(temp[row][col]));
}
}
}
}
class SetAction implements ActionListener {
private int row, col;
private SudokuBoard board;
private JTextField text;
public SetAction(int r, int c, JTextField text, SudokuBoard board) {
row = r;
col = c;
this.text = text;
this.board = board;
}
@Override
public void actionPerformed(ActionEvent e) {
String inp = text.getText();
board.set(row, col, Integer.parseInt(inp));     
}
}
}

`

`

public class SudokuBoard implements SudokuSolver {
int[][] board;
public SudokuBoard() {
int[][] temp = {
{ 7, 0, 2, 0, 5, 0, 6, 0, 0 },
{ 0, 0, 0, 0, 0, 3, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 9, 5, 0, 0 },
{ 8, 0, 0, 0, 0, 0, 0, 9, 0 },
{ 0, 4, 3, 0, 0, 0, 7, 5, 0 },
{ 0, 9, 0, 0, 0, 0, 0, 0, 8 },
{ 0, 0, 9, 7, 0, 0, 0, 0, 5 },
{ 0, 0, 0, 2, 0, 0, 0, 0, 0 },
{ 0, 0, 7, 0, 4, 0, 2, 0, 3 } };
board = temp;
}
@Override
public void set(int row, int col, int digit) {
if (row >= 0 && row < 9 && col >= 0 && col < 9) {
board[row][col] = digit;
} else {
throw new IllegalArgumentException();
}
}
@Override
public void remove(int row, int col) {
if (row > 9 || col > 9 || row < 0 || col < 0) {
throw new IllegalArgumentException();
}
board[row][col] = 0;
}
@Override
public void clear() {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j] = 0;
}
}
}
@Override
public void setMatrix(int[][] matrix) {
if (matrix.length != 9 || matrix[0].length != 9) {
throw new IllegalArgumentException();
} else {
board = matrix;
}
}
@Override
public int[][] getMatrix() {
return board;
}
/**
* Method for printing the board
*/
public void printBoard() {
for (int row = 0; row < 9; row++) {
if (row % 3 == 0 && row != 0) {
System.out.println("---------------------");
}
for (int column = 0; column < 9; column++) {
if (column % 3 == 0 && column != 0) {
System.out.print("|");
System.out.print(" ");
}
System.out.print(board[row][column]);
System.out.print(" ");
}
System.out.println();
}
}
@Override
public boolean legal(int digit, int row, int col) {
for (int i = 0; i < board[row].length; i++) { // check if the number is in the row
if (board[row][i] == digit) {
return false;
}
}
for (int i = 0; i < board.length; i++) {// check if the number is in the column
if (board[i][col] == digit) {
return false;
}
}
// For checking if the number is in the box
int boxRow = row - row % 3;
int boxCol = col - col % 3;
for (int i = boxRow; i < boxRow + 3; i++) {
for (int j = boxCol; j < boxCol + 3; j++) {
if (board[i][j] == digit) {
return false;
}
}
}
return true;
}
@Override
public boolean solve() {
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
if (board[row][col] == 0) { // check for "empty" spots
for (int numberToTry = 1; numberToTry <= 9; numberToTry++) {
if (legal(numberToTry, row, col)) {
set(row, col, numberToTry);
if (solve()) { // recursive call of the solve method
return true;
} else {
set(row, col, 0);
}
}
}
return false;
}
}
}
return true;
}
}

`

嗨,这是我在学校做的一个项目,我还远远没有完成。然而,目前我的求解器似乎可以正常工作,尽管我无法让UI工作。它可以显示我在构造函数中的示例数独,也可以求解它,但我不能通过从ui中读取输入来更改棋盘。

当我在UI中更改某些内容并按下求解按钮时,它只会将所有内容更改回我开始使用的样本板的求解方式。有什么建议吗?我的猜测是,要么SetAction的实现是错误的,要么我尝试读取JTextFields的方式是错误的?

我用";"印刷板";功能,它似乎在那里工作。

编辑:界面数独解算器来自任务,它只包含我们在解决方案中必须有的方法

如果您记得在更改单元格值后按Enter键,那么您的程序确实可以工作。

问题就在这里:

temp.addActionListener(new SetAction(row, col, temp, board));

那条线是正确的,但还不够。当用户在JTextField中按Enter键时,会调用JTextField的ActionListener。如果用户从未按Enter键,则永远不会调用ActionListener。

您可以使用InputVerifier:强制调用它

SetAction setAction = new SetAction(row, col, temp, board);
temp.addActionListener(setAction);
temp.setInputVerifier(new InputVerifier() {
@Override
public boolean verify(JComponent component) {
setAction.actionPerformed(null);
return true;
}
});

最新更新