Java 插入符号位置错误消息
下面是一条令我困扰的消息,当我试图通过按键组合键在Java 插入符号位置错误消息,java,swing,fonts,jtextfield,getcaretpos,Java,Swing,Fonts,Jtextfield,Getcaretpos,下面是一条令我困扰的消息,当我试图通过按键组合键在网格中以编程方式“选择”单元格(无论是否为空)时会出现此消息shift rightarrow或shift leftarrow: Exception in thread "AWT-EventQueue-0" javax.swing.text.StateInvariantError: Bad caret position (请注意,如果我通过shift-uparrow或shift-dowarrow进行“选择”,则没有问题) 当我尝试更改“选定”单
网格中以编程方式“选择”单元格(无论是否为空)时会出现此消息shift rightarrow
或shift leftarrow
:
Exception in thread "AWT-EventQueue-0" javax.swing.text.StateInvariantError:
Bad caret position
(请注意,如果我通过shift-uparrow
或shift-dowarrow
进行“选择”,则没有问题)
当我尝试更改“选定”单元格的字体时,会发生这种情况:
(如果我将Font.type设置为相同的(粗体、普通、斜体),没有问题)
错误发生在代码附近,我将一个“选定的”JTextField
推到堆栈(名为stack
)上,该堆栈的定义如下:
class GenericStack<E>:
public LinkedList <E> stack = new LinkedList<>();
以下是创建单元格的方法:
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;
}
此处是更改字体的位置(对于任何“选定”单元格):
错误发生在这段代码中——如果我注释掉setFont
行,没有问题;如果我将字体声明更改为使用相同的字体,则没有问题
尤其让我困惑的是,堆栈跟踪没有指定导致错误的代码行。我删除了所有不影响获取消息的代码,包括光标移动代码,因此在运行此操作时,将显示一个网格,要获取错误,请按住shift键并按向右箭头键。(这是我应该做的吗?)(附言——我甚至拿出了所有通用链表(堆栈)的东西,结果证明,这些东西与问题无关。)
封装sscce;
导入java.awt.Container;
导入java.awt.Dimension;
导入java.awt.Font;
导入java.awt.GridLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
类单元
{
int row,col;
布尔选择;
单元格(整数行,整数列){
this.row=行;
this.col=col;
}
}
公共类SSCCE实现ActionListener、KeyListener
{
公共静态最终整数左=37,上=38,右=39,下=40;
公共静态最终整数N=11;
JFrame-guiFrame;
JPanel文本面板;
公共静态JTextField[][]单元格=新JTextField[N][N];
公共静态单元currentCell=新单元(0,0);
静态字体fontSelected=新字体(“衬线”,Font.BOLD,12);
静态字体fontNormal=新字体(“衬线”,Font.PLAIN,12);
公共SSCCE(){
textPanel=newjpanel();
setLayout(新的GridLayout(N,N));
guiFrame=newjframe();
setMinimumSize(新尺寸(400400));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setLocationRelativeTo(null);
添加(textPanel);
对于(int i=0;i
我不确定发生异常的原因,但可以通过在Swing事件线程上排队更改字体来解决:
@Override
public void keyPressed(KeyEvent evt) {
final JComponent comp = (JComponent) evt.getSource();
int keyCode = evt.getKeyCode();
boolean shiftIsDown = evt.isShiftDown();
currentCell.selected = ((shiftIsDown & (keyCode == RIGHT | keyCode == UP
| keyCode == LEFT | keyCode == DOWN)));
if (currentCell.selected) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
comp.setFont(fontSelected);
}
});
}
}
就我自己而言,我尽量避免使用Swing应用程序的键侦听器,而是更喜欢键绑定。例如:
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class SSCCE2 extends JPanel {
private static final int ROW_COUNT = 11;
private static final int colCount = 3;
private static final Font NORMAL_FONT = new Font("Serif", Font.PLAIN, 18);
private static final Font SELECTED_FONT = NORMAL_FONT.deriveFont(Font.BOLD);
private JTextField[][] fields = new JTextField[ROW_COUNT][ROW_COUNT];
public SSCCE2() {
FontAction fontAction = new FontAction();
int condition = WHEN_FOCUSED;
setLayout(new GridLayout(ROW_COUNT, ROW_COUNT));
for (int i = 0; i < fields.length; i++) {
for (int j = 0; j < fields[i].length; j++) {
JTextField cell = new JTextField(colCount);
InputMap inputMap = cell.getInputMap(condition);
ActionMap actionMap = cell.getActionMap();
int[] arrowKeyCodes = {KeyEvent.VK_UP, KeyEvent.VK_DOWN,
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT};
for (int keyCode : arrowKeyCodes) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode,
KeyEvent.SHIFT_DOWN_MASK);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), fontAction);
}
cell.setFont(NORMAL_FONT);
cell.setHorizontalAlignment(JTextField.CENTER);
add(cell);
fields[i][j] = cell;
}
}
}
private class FontAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent evt) {
for (JTextField[] row : fields) {
for (JTextField textField : row) {
if (textField.hasFocus()) {
textField.setFont(SELECTED_FONT);
} else {
textField.setFont(NORMAL_FONT);
}
}
}
}
}
private static void createAndShowGui() {
SSCCE2 mainPanel = new SSCCE2();
JFrame frame = new JFrame("SSCCE2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
导入java.awt.Font;
导入java.awt.GridLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.KeyEvent;
导入javax.swing.*;
@抑制警告(“串行”)
公共类SSCCE2扩展了JPanel{
私有静态最终整数行计数=11;
私有静态final int colCount=3;
专用静态最终字体普通字体=新字体(“衬线”,字体.PLAIN,18);
选定的专用静态最终字体\u Font=普通\u Font.deriveFont(Font.BOLD);
私有JTextField[][]字段=新JTextField[行计数][行计数];
公共SSCCE2(){
FontAction FontAction=新FontAction();
int条件=聚焦时;
setLayout(新网格布局(行计数,行计数));
for(int i=0;i 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;
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Grid();
}
});
}
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]);
}
package sscce;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
class Cell
{
int row, col;
boolean selected;
Cell(int row, int col){
this.row = row;
this.col = col;
}
}
public class SSCCE implements ActionListener, KeyListener
{
public static final int LEFT = 37, UP = 38, RIGHT = 39, DOWN = 40;
public static final int N = 11;
JFrame guiFrame;
JPanel textPanel;
public static JTextField[][] cells = new JTextField[N][N];
public static Cell currentCell = new Cell(0,0);
static Font fontSelected = new Font("Serif", Font.BOLD , 12);
static Font fontNormal = new Font("Serif", Font.PLAIN, 12);
public SSCCE(){
textPanel = new JPanel();
textPanel.setLayout(new GridLayout(N, N));
guiFrame = new JFrame();
guiFrame.setMinimumSize(new Dimension(400, 400));
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setLocationRelativeTo(null);
guiFrame.add(textPanel);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
cells[i][j] = addCell(textPanel, i, j);
guiFrame.setVisible(true);
}
private JTextField addCell (Container parent, int row, int col) {
JTextField cell;
cell = new JTextField();
cell.setFont(fontNormal);
cell.addKeyListener((KeyListener) this);
cell.setHorizontalAlignment(JTextField.CENTER);
parent.add(cell);
return cell;
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SSCCE();
}
});
}
@Override
public void keyPressed(KeyEvent evt) {
int keyCode = evt.getKeyCode();
boolean shiftIsDown = evt.isShiftDown();
currentCell.selected = ((shiftIsDown & (keyCode == RIGHT | keyCode == UP | keyCode == LEFT | keyCode == DOWN)));
if(currentCell.selected ){
SSCCE.cells[currentCell.row][currentCell.col].setFont(fontSelected);
}
}
@Override
public void keyTyped(KeyEvent e){ }
@Override
public void keyReleased(KeyEvent e){ }
@Override
public void actionPerformed(ActionEvent e){}
}
@Override
public void keyPressed(KeyEvent evt) {
final JComponent comp = (JComponent) evt.getSource();
int keyCode = evt.getKeyCode();
boolean shiftIsDown = evt.isShiftDown();
currentCell.selected = ((shiftIsDown & (keyCode == RIGHT | keyCode == UP
| keyCode == LEFT | keyCode == DOWN)));
if (currentCell.selected) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
comp.setFont(fontSelected);
}
});
}
}
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class SSCCE2 extends JPanel {
private static final int ROW_COUNT = 11;
private static final int colCount = 3;
private static final Font NORMAL_FONT = new Font("Serif", Font.PLAIN, 18);
private static final Font SELECTED_FONT = NORMAL_FONT.deriveFont(Font.BOLD);
private JTextField[][] fields = new JTextField[ROW_COUNT][ROW_COUNT];
public SSCCE2() {
FontAction fontAction = new FontAction();
int condition = WHEN_FOCUSED;
setLayout(new GridLayout(ROW_COUNT, ROW_COUNT));
for (int i = 0; i < fields.length; i++) {
for (int j = 0; j < fields[i].length; j++) {
JTextField cell = new JTextField(colCount);
InputMap inputMap = cell.getInputMap(condition);
ActionMap actionMap = cell.getActionMap();
int[] arrowKeyCodes = {KeyEvent.VK_UP, KeyEvent.VK_DOWN,
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT};
for (int keyCode : arrowKeyCodes) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode,
KeyEvent.SHIFT_DOWN_MASK);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), fontAction);
}
cell.setFont(NORMAL_FONT);
cell.setHorizontalAlignment(JTextField.CENTER);
add(cell);
fields[i][j] = cell;
}
}
}
private class FontAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent evt) {
for (JTextField[] row : fields) {
for (JTextField textField : row) {
if (textField.hasFocus()) {
textField.setFont(SELECTED_FONT);
} else {
textField.setFont(NORMAL_FONT);
}
}
}
}
}
private static void createAndShowGui() {
SSCCE2 mainPanel = new SSCCE2();
JFrame frame = new JFrame("SSCCE2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}