In a previous question I asked how I could implement processor-intensive work, which was called by a Swing component, without the GUI locking up. I was then pointed to the SwingWorker class. I implemented this and it works! But...
I am writing a program that solves sudoku puzzles. It has a Swing GUI with a "solve" button. I have written an actionListener class with an actionPerformed method that is invoked when the user presses this button. It is the following:
public void actionPerformed(ActionEvent event) { try { worker = new SudokuSolveWorker(); worker.addPropertyChangeListener(this); worker.execute(); SolveFrame sf = new SolveFrame(); } catch (Exception exc) { System.out.println(exc.getMessage()); exc.printStackTrace(); } }
The code creates a worker, a new instance of SudokuSolveWorker. The worker.execute() statement causes the doInBackground() method of this class to be called. This solves the Sudoku. A property change listener "picks up" the result:
public void propertyChange(PropertyChangeEvent event) { try { SudokuModel solvedModel = (SudokuModel) worker.get(); if (solvedModel.solved) { model = solvedModel; repaint(); } else { JOptionPane.showMessageDialog(null, "Sudoku cannot be solved"); } } catch (Exception exc) { System.out.println(exc.getMessage()); exc.printStackTrace(); } }
As I wrote, this works without freezing up the user interface in the sense that the program seems unstable. However, the user interface does not respond to "commands" (mouse clicks) anymore until the worker thread has finished.
In the first code fragment I create an instance of SolveFrame. This is a simple frame with a "cancel" button. It is drawn on the screen, even though it is called after the worker.execute() statement. I'd like the user to be able to click this "cancel" button, after which the solving of the sudoku puzzle should be stopped. However, since the program does not respond to mouse clicks anymore, the "cancel" button cannot be pressed.
How can I solve this?