package gui;
import javax.swing.ComponentInputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JFileChooser;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.Component;
import java.awt.Container;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.io.FileNotFoundException;
import java.io.IOException;
import sudoku.NotSolvableException;
import sudoku.HelpingState;
public class SudokuGUI extends JFrame {
private static final String LOOK_AND_FEEL_ERROR_MESSAGE =
"Could not initiate look and feel. Will now "
+ "use default look and feel.";
private static final String INVALID_FILE_MESSAGE = "Could not read file.";
private static final String LOAD_DIALOG_CAPTION = "Load sudoku";
private static final String NO_MORE_SOLVABLE_MESSAGE = "Sudoku no more solvable. "
+ "Use undo or unset to correct the mistakes.";
private static final String ERROR_CAPTION = "Error";
private static final String SOLVED_MESSAGE = "Congratulations! The sudoku is solved.";
private static final String SOLVED_CAPTION = "Sudoku solved";
private static final String ALREADY_SOLVED_MESSAGE = "The sudoku is already solved.";
private static final String ALREADY_SOLVED_CAPTION = "Sudoku already solved";
private static final String CLOSE_BUTTON_CAPTION = "Close";
private static final String LOAD_BUTTON_CAPTION = "Load";
private static final String UNDO_BUTTON_CAPTION = "Undo";
private static final String FILE_NOT_FOUND_MESSAGE =
"File %s does not exist.";
private static final String HELP_BUTTON_CAPTION =
"Help";
private HelpingState s;
private SudokuBoard board;
public static void main(String[] args) {
new SudokuGUI();
}
public void showMessage(String title, String msg) {
showMessage(title, msg, JOptionPane.PLAIN_MESSAGE);
}
public void showMessage(String title, String msg, int type) {
JOptionPane.showMessageDialog(this, msg, title, type);
}
public SudokuGUI() {
s = new HelpingState();
this.setTitle("Sudoku");
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
System.out.println(info);
}
addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent e) {
JFrame frame = (JFrame) e.getSource();
if (frame.getWidth() < 280) {
frame.setSize(280, frame.getHeight());
}
if (frame.getHeight() < 320) {
frame.setSize(frame.getWidth(), 320);
}
}
public void componentMoved(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
public void componentShown(ComponentEvent e) {}
});
setMinimumSize(new Dimension(160, 180));
Container cp = getContentPane();
setLayout(new BorderLayout(20, 20));
board = new SudokuBoard();
board.state = s;
JPanel panel = new JPanel();
JPanel buttonPanel = new JPanel();
cp.add(board, BorderLayout.CENTER);
cp.add(panel, BorderLayout.SOUTH);
Button help = new Button(HELP_BUTTON_CAPTION);
Button undo = new Button(UNDO_BUTTON_CAPTION);
Button load = new Button(LOAD_BUTTON_CAPTION);
Button close = new Button(CLOSE_BUTTON_CAPTION);
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
panel.add(buttonPanel);
buttonPanel.setLayout(new GridLayout(1, 4, 20, 20));
buttonPanel.add(help);
buttonPanel.add(undo);
buttonPanel.add(load);
buttonPanel.add(close);
help.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
if (s.isSolution()) {
showMessage(ALREADY_SOLVED_CAPTION,
ALREADY_SOLVED_MESSAGE);
board.repaint();
return;
}
s.getHelp();
if (s.isSolution()) {
showMessage(SOLVED_CAPTION,
SOLVED_MESSAGE);
}
} catch (NotSolvableException ex) {
showMessage(ERROR_CAPTION, NO_MORE_SOLVABLE_MESSAGE,
JOptionPane.ERROR_MESSAGE);
}
board.repaint();
}
});
undo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
s.undo();
board.repaint();
}
});
load.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle(LOAD_DIALOG_CAPTION);
if (fileChooser.showOpenDialog(null) ==
JFileChooser.APPROVE_OPTION) {
try {
s.loadFromFile(fileChooser.getSelectedFile().
getAbsolutePath());
board.repaint();
} catch (FileNotFoundException ex) {
showMessage(ERROR_CAPTION,
String.format(FILE_NOT_FOUND_MESSAGE,
fileChooser.getSelectedFile().getPath()),
JOptionPane.ERROR_MESSAGE);
} catch (IOException ex) {
showMessage(ERROR_CAPTION,
INVALID_FILE_MESSAGE,
JOptionPane.ERROR_MESSAGE);
} catch (NotSolvableException ex) {
showMessage(ERROR_CAPTION,
"Input file is contradictory or invalid.",
JOptionPane.ERROR_MESSAGE);
}
}
}
});
close.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
);
setSize(500, 600);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}