Here's a message I am plagued by, which occurs when I attempt to programmatically "select" cells (whether empty or not) in a grid via keypress combo shift-rightarrow or shift-leftarrow:
Exception in thread "AWT-EventQueue-0" javax.swing.text.StateInvariantError:
Bad caret position
(Note that there is NO problem if I "select" via shift-uparrow or shift-downarrow.)
It happens when I attempt to change the font of the "selected" cells:
static Font fontSelected = new Font("Serif", Font.BOLD , POINTSIZE);
static Font fontNormal = new Font("Serif", Font.PLAIN, POINTSIZE);
(If I make the Font.type the SAME (both BOLD, both PLAIN, both ITALIC), no problem.)
The error occurs near code where I push a "selected" JTextField onto a stack (named stack), which is defined like so:
class GenericStack<E>:
public LinkedList <E> stack = new LinkedList<>();
Here's the class declaration where the stack and fonts are used:
public class Grid extends GenericStack<JTextField> implements ActionListener, KeyListener, KeyCodes, Serializable
Here's what's pushed onto stack:
public static JTextField[][] cells = new JTextField[N][N];
Here's how cells are created:
guiFrame.add(textPanel);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
cells[i][j] = addCell(textPanel, i, j);
private JTextField addCell (Container parent, int row, int col) {
JTextField cell;
cell = new JTextField();
cell.setFont(fontNormal); // 'default' font set
cell.setText("x"); // for debugging
String r, c; // 11x11 grid
if(row < N-1) r = "" + row; else r = "A"; // rows r: 0,1,2,...A
if(col < N-1) c = "" + col; else c = "A"; // cols c: 0,1,2,...A
cell.setActionCommand(r + c); // cell rc: 00..0A;10..1A;...A0..AA;
cell.addKeyListener(this);
cell.setHorizontalAlignment(JTextField.CENTER);
parent.add(cell);
return cell;
}
Here's main:
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Grid();
}
});
}
Here's where the font is changed (for any "selected" cell):
if(currentCell.selected){
Grid.cells[currentCell.row][currentCell.col].setBackground(Color.RED);
Grid.cells[currentCell.row][currentCell.col].setFont(fontSelected);
stack.push(Grid.cells[currentCell.row][currentCell.col]);
}
The error occurs in this block of code--if I comment out the setFont line, no problem; if I instead change the font declarations to involve the same font, no problem.
Especially puzzling me is that the stack trace doesn't specify which line of code caused the error.
I'm not sure why your exception is occurring, but it can be solved by queuing the font change on the Swing event thread:
Myself, I try to avoid KeyListeners with Swing applications but instead prefer key bindings. For example: