
A responsive desktop tool keeps clicks, painting and keyboard input moving while slower work runs separately. This guide builds a small table of numbers and their squares. The deliberately delayed calculation makes the interface behavior easy to observe: start a job, resize the window, cancel it and try again.
Run the desktop example
You need a desktop environment and a JDK; the downloadable sources were compiled and checked with Java 25. Start with a consistent Java setup. Extract the ZIP into an empty folder, open a terminal there and run:
Download the source, checks and README (ZIP)
javac SquareTable.java SwingCheck.java
java SquareTableThe window contains a row-count field, Start and Cancel buttons, a sortable table and a status line. With the default 20 rows, completion takes roughly two seconds because each row deliberately waits 100 milliseconds. This delay represents slow work; squaring a number itself needs no background thread.
Enter 3 and expect rows (1, 1), (2, 4) and (3, 9). Click a column header to sort. The column model declares integer values so that 10 sorts after 2. Try 0, 101 and a word: the status should request a whole number from 1 to 100, and no new job should start.
Give the components clear responsibilities
SquareTable is a panel, which makes its behavior testable without creating a top-level window. BorderLayout places controls above the scrollable table and the status below it. A small FlowLayout arranges the controls. These layout managers respond to resizing; fixed pixel coordinates would make different fonts and display scales harder to accommodate.
The DefaultTableModel owns the rows; JTable displays them. The example makes cells read-only and lets the view sort without changing the calculation order. The label uses setLabelFor to associate it with the input field. Keep useful labels visible and use the keyboard to check that every control is reachable. See the JTable contract when adding editing, custom renderers or selection behavior.
Keep slow work away from the event thread
The event dispatch thread (EDT) handles interface events. The program creates the window through SwingUtilities.invokeLater. Button listeners already run on that thread, so they can validate the field and change the model safely. The listener captures the row count before starting the worker; the worker never reads the text field.
protected Void doInBackground() throws Exception {
for (int i = 1; i <= rows; i++) {
if (isCancelled()) break;
Thread.sleep(100);
publish(new int[]{i, i * i});
}
return null;
}publish sends results to process, where the model receives rows on the EDT. A single callback may receive several rows, so process the whole list. done updates the final status and enables the controls. The SwingWorker documentation defines those thread boundaries and the one-use worker lifecycle. Create a fresh worker for each run.
Make cancellation and failures visible
Starting disables Start and the row-count field, preventing overlapping jobs. Cancel calls cancel(true); the loop checks cancellation and its interruptible sleep can end early. The display retains any rows already shown and labels them as partial. Cancellation is cooperative: replace the simulated work with a real operation only after deciding how that operation stops and releases resources.
done calls get to distinguish completion, cancellation and execution failure. Waiting for an unfinished worker from a button listener would freeze the interface. The download handles each outcome and restores controls. When adding file or network work, show a useful error to the user and put diagnostic detail in an appropriate log.
On narrow screens, scroll this table horizontally. Keyboard users can focus it and use the arrow keys.
| Action | Expected result |
|---|---|
| Drag or resize while running | Window continues repainting. |
| Cancel a 100-row run | Partial rows remain; controls become available again. |
| Run again after cancellation | Old rows clear and a fresh worker completes. |
| Enter an invalid count | Clear validation message; existing results remain. |
Run java -Djava.awt.headless=true SwingCheck for automated validation, completion and cancellation checks. This exercises the panel and EDT without opening a window. Also perform the visible checks above on the target desktop; font scaling, focus order and display integration depend on that environment.