MVC architecture user interface implemented with swing
This commit is contained in:
parent
e7e8979128
commit
71c43b35c3
3 changed files with 300 additions and 6 deletions
86
app/src/main/java/gui/SudokuController.java
Normal file
86
app/src/main/java/gui/SudokuController.java
Normal file
|
@ -0,0 +1,86 @@
|
|||
package gui;
|
||||
|
||||
import sudoku.SudokuSolver;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* SolverController is a controller for the SudokuSolver interface
|
||||
*/
|
||||
public class SudokuController {
|
||||
SudokuSolver model;
|
||||
SudokuView view;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param model SudokuSolver model
|
||||
* @param view SudokuView view
|
||||
*/
|
||||
public SudokuController(SudokuSolver model, SudokuView view) {
|
||||
this.model = model;
|
||||
this.view = view;
|
||||
|
||||
// Add action listeners to the buttons
|
||||
view.addSolveButtonListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Solve the board
|
||||
model.solve();
|
||||
|
||||
// Update the view
|
||||
view.updateView(model.getBoard());
|
||||
}
|
||||
});
|
||||
|
||||
view.addResetButtonListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Clear the board
|
||||
model.clear();
|
||||
|
||||
// Update the view
|
||||
view.updateView(model.getBoard());
|
||||
}
|
||||
});
|
||||
|
||||
view.addRandomButtonListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Randomize the board
|
||||
model.randomizeBoard();
|
||||
|
||||
// Update the view
|
||||
view.updateView(model.getBoard());
|
||||
}
|
||||
});
|
||||
|
||||
view.addCellClickListener(new CellActionListener());
|
||||
}
|
||||
|
||||
/** Start the GUI */
|
||||
public void start() {
|
||||
view.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* CellActionListener is an ActionListener for the Sudoku grid cells
|
||||
*/
|
||||
private class CellActionListener implements ActionListener {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// Get the row and column from the clicked cell
|
||||
int row = view.getSelectedRow();
|
||||
int col = view.getSelectedColumn();
|
||||
|
||||
String inputText = view.getCellValue(row, col);
|
||||
int value = Integer.parseInt(inputText);
|
||||
// Check if the input is legal and update the model and view
|
||||
if (model.isLegal(row, col, value)) {
|
||||
model.set(row, col, value);
|
||||
view.updateView(model.getBoard());
|
||||
} else {
|
||||
view.showErrorMessage("Invalid input. Try again.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
186
app/src/main/java/gui/SudokuView.java
Normal file
186
app/src/main/java/gui/SudokuView.java
Normal file
|
@ -0,0 +1,186 @@
|
|||
package gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* SolverView is a GUI for the SudokuSolver interface
|
||||
*/
|
||||
public class SudokuView extends JFrame {
|
||||
/** The grid of text fields */
|
||||
private JTextField[][] grid;
|
||||
|
||||
/** Button for solve */
|
||||
private JButton solveButton;
|
||||
/** Button for reset */
|
||||
private JButton resetButton;
|
||||
/** Button for random */
|
||||
private JButton randomButton;
|
||||
|
||||
/** Constructor */
|
||||
public SudokuView() {
|
||||
setTitle("Sudoku Solver");
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
initializeGrid();
|
||||
initializeButtons();
|
||||
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
}
|
||||
|
||||
/** Initialize the grid, called by the constructor */
|
||||
private void initializeGrid() {
|
||||
grid = new JTextField[9][9];
|
||||
JPanel gridPanel = new JPanel(new GridLayout(9, 9));
|
||||
|
||||
for (int row = 0; row < 9; row++) {
|
||||
for (int col = 0; col < 9; col++) {
|
||||
grid[row][col] = new JTextField(2);
|
||||
grid[row][col].setHorizontalAlignment(JTextField.CENTER);
|
||||
gridPanel.add(grid[row][col]);
|
||||
}
|
||||
}
|
||||
|
||||
add(gridPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/** Initialize the buttons, called by the constructor */
|
||||
private void initializeButtons() {
|
||||
solveButton = new JButton("Solve");
|
||||
resetButton = new JButton("Reset");
|
||||
randomButton = new JButton("Randomize");
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.add(solveButton);
|
||||
buttonPanel.add(resetButton);
|
||||
buttonPanel.add(randomButton);
|
||||
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the view with a new grid
|
||||
*
|
||||
* @param newGrid the new grid to display
|
||||
*/
|
||||
public void updateView(int[][] newGrid) {
|
||||
for (int row = 0; row < 9; row++) {
|
||||
for (int col = 0; col < 9; col++) {
|
||||
if (newGrid[row][col] != 0) {
|
||||
grid[row][col].setText(String.valueOf(newGrid[row][col]));
|
||||
} else {
|
||||
grid[row][col].setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to add ActionListener to solve button
|
||||
*
|
||||
* @param listener the ActionListener to add
|
||||
*/
|
||||
public void addSolveButtonListener(ActionListener listener) {
|
||||
solveButton.addActionListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to add ActionListener to reset button
|
||||
*
|
||||
* @param listener the ActionListener to add
|
||||
*/
|
||||
public void addResetButtonListener(ActionListener listener) {
|
||||
resetButton.addActionListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to add ActionListener to randomize button
|
||||
*
|
||||
* @param listener the ActionListener to add
|
||||
*/
|
||||
public void addRandomButtonListener(ActionListener listener) {
|
||||
randomButton.addActionListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to add ActionListener to individual cells in the grid
|
||||
* <p>
|
||||
* Assumes that the ActionListener will be the same for all cells
|
||||
* and that the listener will be capable of determining which cell
|
||||
* was clicked
|
||||
*
|
||||
* @param listener the ActionListener to add
|
||||
*/
|
||||
public void addCellClickListener(ActionListener listener) {
|
||||
for (int row = 0; row < 9; row++) {
|
||||
for (int col = 0; col < 9; col++) {
|
||||
grid[row][col].addActionListener(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method to retrieve the values from the text fields
|
||||
*
|
||||
* @param row the row of the cell
|
||||
* @param col the column of the cell
|
||||
* @return the value of the cell
|
||||
*/
|
||||
public String getCellValue(int row, int col) {
|
||||
return grid[row][col].getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the selected row (example implementation)
|
||||
*
|
||||
* @return the selected row, or -1 if no cell is selected
|
||||
*/
|
||||
public int getSelectedRow() {
|
||||
for (int row = 0; row < 9; row++) {
|
||||
for (int col = 0; col < 9; col++) {
|
||||
if (grid[row][col].isFocusOwner()) {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1; // Return -1 if no cell is selected
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the selected column (example implementation)
|
||||
*
|
||||
* @return the selected row, or -1 if no cell is selected
|
||||
*/
|
||||
public int getSelectedColumn() {
|
||||
for (int row = 0; row < 9; row++) {
|
||||
for (int col = 0; col < 9; col++) {
|
||||
if (grid[row][col].isFocusOwner()) {
|
||||
return col;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1; // Return -1 if no cell is selected
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods to show dialogs
|
||||
*
|
||||
* @param message the message to display
|
||||
* @return the user input
|
||||
*/
|
||||
public String showInputDialog(String message) {
|
||||
return JOptionPane.showInputDialog(this, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to show error messages
|
||||
*
|
||||
* @param message the message to display
|
||||
*/
|
||||
public void showErrorMessage(String message) {
|
||||
JOptionPane.showMessageDialog(this, message);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,34 @@
|
|||
package sudoku;
|
||||
|
||||
import gui.SudokuController;
|
||||
import gui.SudokuView;
|
||||
|
||||
/** SolverMain is the main class for the Sudoku Solver */
|
||||
public class SolverMain {
|
||||
|
||||
private Solver model;
|
||||
private SudokuView view;
|
||||
private SudokuController controller;
|
||||
|
||||
/** Constructor */
|
||||
SolverMain() {
|
||||
model = new Solver();
|
||||
view = new SudokuView();
|
||||
controller = new SudokuController(model, view);
|
||||
}
|
||||
|
||||
/** Start the GUI */
|
||||
void start() {
|
||||
controller.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method
|
||||
*
|
||||
* @param args command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Solver s = new Solver();
|
||||
System.out.println(s.toString());
|
||||
s.randomizeBoard();
|
||||
System.out.println(s.toString());
|
||||
s.solve();
|
||||
System.out.println(s.toString());
|
||||
SolverMain main = new SolverMain();
|
||||
main.start();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue