单元格编辑器中组件内的焦点遍历
我正在尝试轻松编辑使用自定义组件来显示信息的表格。 每个 Cell 有 3 个数据文本。
我想要的是:
- 如果单元格获得焦点,则开始编辑第一个值。
- 编辑第一个值时,用户按 [TAB],然后去编辑第二个值(不要转到下一个单元格)
- 如果我在第三个值中按 [TAB],然后去编辑下一个单元格(输入 1sr 值) )
我在论坛中查找,但没有找到这个案例,这个问题...仍在阅读以学习 Swing
提前感谢您的回答,这是我的代码:
public class PruebaTabla extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new PruebaTabla().setVisible(true);
}});
}
public PruebaTabla(){
JTable tabla = new JTable();
tabla.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tabla.setCellSelectionEnabled(true);
tabla.setDefaultRenderer(ModelClass.class, new ModelClassCellRederer());
tabla.setDefaultEditor(ModelClass.class, new ModelClasstroCellEditor());
tabla.setRowHeight(30);
CustomModel model = new CustomModel();
model.setModel(new ModelClass[][]{
{new ModelClass(), new ModelClass(), new ModelClass()},
{new ModelClass(), new ModelClass(), new ModelClass()},
{new ModelClass(), new ModelClass(), new ModelClass()}});
tabla.setModel(model);
getContentPane().add(new JScrollPane(tabla));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(480,150);
setLocationRelativeTo(null);
}
private class ModelClass {
private String value1;
private String value2;
private String value3;
public ModelClass(){
setValue1("" + Math.round(Math.random() * 100));
setValue2("" + Math.round(Math.random() * 100));
setValue3("" + Math.round(Math.random() * 100));
}
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
public String getValue3() {
return value3;
}
public void setValue3(String value3) {
this.value3 = value3;
}
}
private class CustomModel extends AbstractTableModel{
ModelClass[][] model;
String[] columnNames = new String[] {"Column1", "Column2", "Column3"};
@Override
public Class<?> getColumnClass(int columnIndex) {
return ModelClass.class;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
public int getColumnCount() {
return 3;
}
public int getRowCount() {
return 3;
}
public Object getValueAt(int rowIndex, int columnIndex) {
return model[rowIndex][columnIndex];
}
public ModelClass[][] getModel() {
return model;
}
public void setModel(ModelClass[][] model) {
this.model = model;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
}
private class ModelClassCellRederer implements TableCellRenderer {
JPanel panel = new JPanel();
private JLabel label1= new JLabel();
private JLabel label2 = new JLabel();
private JLabel label3 = new JLabel();
ModelClassCellRederer(){
panel.add(label1);
panel.add(label2);
panel.add(label3);
}
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
if (isSelected) {
panel.setBackground(table.getSelectionBackground());
panel.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
} else {
panel.setBackground(table.getBackground());
panel.setBorder(null);
}
ModelClass v = (ModelClass) value;
label1.setText(v.getValue1());
label2.setText(v.getValue2());
label3.setText(v.getValue3());
return panel;
}
}
private class ModelClasstroCellEditor extends DefaultCellEditor {
JPanel panel = new JPanel();
private JTextField label1= new JTextField();
private JTextField label2 = new JTextField();
private JTextField label3 = new JTextField();
ModelClass actual;
public ModelClasstroCellEditor() {
super(new JCheckBox());
panel.add(label1);
panel.add(label2);
panel.add(label3);
setClickCountToStart(1);
}
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
actual = (ModelClass) value;
label1.setText(actual.getValue1());
label2.setText(actual.getValue2());
label3.setText(actual.getValue3());
return panel;
}
@Override
public Object getCellEditorValue() {
if (actual != null){
actual.setValue1(label1.getText());
actual.setValue2(label2.getText());
actual.setValue3(label3.getText());
}
return actual;
}
@Override
public boolean isCellEditable(EventObject anEvent) {
if (anEvent instanceof KeyEvent) {
final KeyEvent keyEvent = (KeyEvent) anEvent;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (!Character.isIdentifierIgnorable(keyEvent.getKeyChar())) {
label1.setText("" + keyEvent.getKeyChar());
}
label1.setCaretPosition(label1.getText().length());
label1.requestFocusInWindow();
}
});
}
return super.isCellEditable(anEvent);
}
}
}
i´m trying to make easy edit to a table thas uses a custom component for displaying info.
Each Cell hast 3 data texts.
What i want is:
- if a cell gets focus, start editing the 1st value.
- while editing the 1st value user press [TAB], then go editing the 2nd value (don´t go to the next cell)
- if i press [TAB] in the 3rd value, then, go editing the next cell (entering the 1sr value)
I wass looking in forums an i didn´t find this case, this problem... still reading to learn Swing
Thanks in advance for your answers, this is my code:
public class PruebaTabla extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new PruebaTabla().setVisible(true);
}});
}
public PruebaTabla(){
JTable tabla = new JTable();
tabla.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tabla.setCellSelectionEnabled(true);
tabla.setDefaultRenderer(ModelClass.class, new ModelClassCellRederer());
tabla.setDefaultEditor(ModelClass.class, new ModelClasstroCellEditor());
tabla.setRowHeight(30);
CustomModel model = new CustomModel();
model.setModel(new ModelClass[][]{
{new ModelClass(), new ModelClass(), new ModelClass()},
{new ModelClass(), new ModelClass(), new ModelClass()},
{new ModelClass(), new ModelClass(), new ModelClass()}});
tabla.setModel(model);
getContentPane().add(new JScrollPane(tabla));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(480,150);
setLocationRelativeTo(null);
}
private class ModelClass {
private String value1;
private String value2;
private String value3;
public ModelClass(){
setValue1("" + Math.round(Math.random() * 100));
setValue2("" + Math.round(Math.random() * 100));
setValue3("" + Math.round(Math.random() * 100));
}
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
public String getValue3() {
return value3;
}
public void setValue3(String value3) {
this.value3 = value3;
}
}
private class CustomModel extends AbstractTableModel{
ModelClass[][] model;
String[] columnNames = new String[] {"Column1", "Column2", "Column3"};
@Override
public Class<?> getColumnClass(int columnIndex) {
return ModelClass.class;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
public int getColumnCount() {
return 3;
}
public int getRowCount() {
return 3;
}
public Object getValueAt(int rowIndex, int columnIndex) {
return model[rowIndex][columnIndex];
}
public ModelClass[][] getModel() {
return model;
}
public void setModel(ModelClass[][] model) {
this.model = model;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
}
private class ModelClassCellRederer implements TableCellRenderer {
JPanel panel = new JPanel();
private JLabel label1= new JLabel();
private JLabel label2 = new JLabel();
private JLabel label3 = new JLabel();
ModelClassCellRederer(){
panel.add(label1);
panel.add(label2);
panel.add(label3);
}
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
if (isSelected) {
panel.setBackground(table.getSelectionBackground());
panel.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
} else {
panel.setBackground(table.getBackground());
panel.setBorder(null);
}
ModelClass v = (ModelClass) value;
label1.setText(v.getValue1());
label2.setText(v.getValue2());
label3.setText(v.getValue3());
return panel;
}
}
private class ModelClasstroCellEditor extends DefaultCellEditor {
JPanel panel = new JPanel();
private JTextField label1= new JTextField();
private JTextField label2 = new JTextField();
private JTextField label3 = new JTextField();
ModelClass actual;
public ModelClasstroCellEditor() {
super(new JCheckBox());
panel.add(label1);
panel.add(label2);
panel.add(label3);
setClickCountToStart(1);
}
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
actual = (ModelClass) value;
label1.setText(actual.getValue1());
label2.setText(actual.getValue2());
label3.setText(actual.getValue3());
return panel;
}
@Override
public Object getCellEditorValue() {
if (actual != null){
actual.setValue1(label1.getText());
actual.setValue2(label2.getText());
actual.setValue3(label3.getText());
}
return actual;
}
@Override
public boolean isCellEditable(EventObject anEvent) {
if (anEvent instanceof KeyEvent) {
final KeyEvent keyEvent = (KeyEvent) anEvent;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (!Character.isIdentifierIgnorable(keyEvent.getKeyChar())) {
label1.setText("" + keyEvent.getKeyChar());
}
label1.setCaretPosition(label1.getText().length());
label1.requestFocusInWindow();
}
});
}
return super.isCellEditable(anEvent);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
目前,您的 JTable 使用
UIManager.get("Table.ancestorInputMap")
中的 InputMap 处理键盘输入。目前,该选项卡已映射到字符串“selectNextColumnCell”,该字符串映射到 JTable 的 ActionMap 中的一个操作,可将您移动到下一个单元格。您可以执行以下操作:
创建一个 Action,其 actionPerformed 方法执行您所追求的遍历策略。
在 ActionMap 中,将“someStringThatDescribesYourAction”作为键,将 1 中的 Action 作为值。
在InputMap中,将
KeyStroke.getKeyStroke("TAB")
作为键,将2中的字符串作为值。这将替换当前的操作,从而将您移动到下一个单元格。Currently, your JTable handles keyboard input using an InputMap from
UIManager.get("Table.ancestorInputMap")
. This currently has tab mapped to the String "selectNextColumnCell", which maps to an Action in JTable's ActionMap that moves you to the next cell.You can do the following:
Create an Action whose actionPerformed method does the traversal policy that you're after.
In the ActionMap, put "someStringThatDescribesYourAction" as the key, and your Action from 1 as the value.
In the InputMap, put
KeyStroke.getKeyStroke("TAB")
as the key, and the String from 2 as the value. This will replace the current Action which moves you to the next cell regardless.