I have written some Java Swing code that collects some input, does some calculations, and then displays the result.
Expected result:
- For every user input:
- User goes to File -> New -> Enters some data.
- Mouse cursor turns into spinner as calculations are computed.
- Result is displayed.
- Mouse cursor returns to default.
Actual result:
- For first user input:
- User goes to File -> New -> Enters some data.
- Mouse cursor remains unchanged as calculations are computed.
- Result is displayed.
- For each subsequent usage, the result is the expected result described above.
I am pretty new to Swing, and I have been trying to get to the bottom of this without much luck. I have narrowed down the error to a specific line of the code. If I comment out the line
JOptionPane.showConfirmDialog(null, null, "Enter new maze parameters", JOptionPane.OK_CANCEL_OPTION);
in the code, then the spinner appears the first time through as expected. If I leave the line in, then I have the problem as described.
Please note that I have heavily trimmed this sample down to eliminate a lot of the U/I flow that is in the actual program, but this sample does break as described. I was not able to simplify my sample code further.
The simplified code
package ca.pringle.maze.ui;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import ca.pringle.maze.logic.Edge;
import ca.pringle.maze.logic.MazeConfig;
import ca.pringle.maze.logic.MazeMaker;
import ca.pringle.maze.logic.PathFinder;
import ca.pringle.maze.util.Pair;
public final class MazeDrawer extends JFrame {
private final MazePanel mazePanel;
public MazeDrawer() {
mazePanel = new MazePanel();
}
public void init() {
final JScrollPane scrollPane = new JScrollPane(mazePanel);
final JMenuBar menuBar = createMenuBar((actionEvent) -> generateNewMaze());
setJMenuBar(menuBar);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(scrollPane, BorderLayout.CENTER);
setSize(100, 100);
setVisible(true);
repaint();
}
void generateNewMaze() {
// if I comment out this line below, then the spinner appears on the first run as expected.
// if I leave this line in, then the spinner does not appear on the first run, only on subsequent runs
JOptionPane.showConfirmDialog(null, null, "Enter new maze parameters", JOptionPane.OK_CANCEL_OPTION);
final MazeConfig mazeConfig = new MazeConfig(1000, 1000, 1);
final MazeMaker mazeMaker = new MazeMaker(mazeConfig);
final PanelDimensions panelDimensions = new PanelDimensions(mazeConfig.getRows(), mazeConfig.getColumns(), 15, 15);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
// the two lines below can take a long time depending on the inputs. I tried removing
// them and replacing with a sleep to simulate and simplify the problem, but no luck,
// so I left them in, even if I did not include the code.
final Set<Edge> edges = mazeMaker.generateUndirectedMazeEdges();
final Pair<Integer, Integer> startAndEndNodes = new PathFinder().findLongestPath(edges, mazeConfig);
mazePanel.update(edges, startAndEndNodes, panelDimensions);
mazePanel.setPreferredSize(new Dimension(panelDimensions.panelWidth, panelDimensions.panelHeight));
mazePanel.repaint();
setSize(Math.min(1200, panelDimensions.panelWidth + 11), Math.min(700, panelDimensions.panelHeight + 53));
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
private JMenuBar createMenuBar(final ActionListener menuListener) {
final JMenuBar bar = new JMenuBar();
final JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
final JMenuItem newMenuItem = new JMenuItem("New", KeyEvent.VK_N);
newMenuItem.addActionListener(menuListener);
fileMenu.add(newMenuItem);
bar.add(fileMenu);
return bar;
}
}
Any help is appreciated. Please assume I am a complete Swing noob, so a more specific answer/explanation is more likely to help than a high level one that assumes I know something about Swing. I will read any suggested documentation of course.
If there are any problems or clarifications needed, please let me know, I am happy to update the post as many times as required.