JTable单元格处于编辑状态时,按一次enter键焦点水平移动(右移)

在JTable中如何用enter键代替tab键的功能,这是一个坑;

在单元格处于编辑状态时按一次enter键,焦点水平移动;必须得按2次enter键才能水平移动;

其实这个问题的关键在于:光标在单元格中时,按enter键时table的keylistener监听不到键入事件,因此在table上对enter注册的action事件不能被触发;

为了能在单元格在编辑时也能触发enter事件,就必须对处于编辑的单元格添加keyListener,这样问题就能解决了;

关键代码:

1,对table注册按enter键时触发的事件:

       
        InputMap enter = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);        
        enter.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER ,0),"ENTER");       
        table.getActionMap().put("ENTER", myAction);

2,在单元格被选中时,按enter键水平移动

       Action myAction = new AbstractAction() {
		@Override
		public void actionPerformed(ActionEvent e) {			
			int rowCount = table.getRowCount();			
			int colCount = table.getColumnCount();			
			if(rowCount <=0)return;
			//取被选中状态的row/col
			int row = table.getSelectedRow();			
			int col = table.getSelectedColumn();						
			if(row < 0 || col < 0)return;			
			if(col < colCount-1) {				
				col+=1;
			}else {
				if(row < rowCount-1) {
					col = 0;					
					row+=1;
				}else {					
					row=col=0;
				}				
			}
//			table.setRowSelectionInterval(row, row);		
//			table.setColumnSelectionInterval(col, col);
			table.changeSelection(row, col, false, false);			
		}
    	   
       };

3,在单元格被编辑时,按enter键水平移动

        table.addFocusListener(new FocusListener() {

			@Override
			public void focusGained(FocusEvent e) {
				// TODO Auto-generated method stub
				
			}

			/**焦点在单元格时enter键水平移动*/
			@Override
			public void focusLost(FocusEvent e) {
				//在编辑单元格时,按enter键执行;如果不在被编辑单元格添键盘监听,
				//那么处于编辑状态时,必须按2此enter键才会水平移动;
				//因为第一次按enter时,焦点不在table中,不会触发enter事件
				if(table.isEditing()) {
					
					table.getEditorComponent().addKeyListener(new KeyListener() {

						@Override
						public void keyTyped(KeyEvent e) {
							// TODO Auto-generated method stub
							
						}

						@Override
						public void keyPressed(KeyEvent e) {
							if(e.getKeyCode() == KeyEvent.VK_ENTER) {
								int rowCount = table.getRowCount();
								
								int colCount = table.getColumnCount();
								
								if(rowCount <=0)return;
								//注意取编辑时的row/col
								int row = table.getEditingRow();
								
								int col = table.getEditingColumn();
											
								if(row < 0 || col < 0)return;
								
								if(col < colCount-1) {				
									col+=1;
								}else {
									if(row < rowCount-1) {
										col = 0;					
										row+=1;
									}else {					
										row=col=0;
									}	
									//***注意这个换行时,有一个坑;在换行时会调用2次该方法,
									//如果有对单元格的编辑后的校验,那就坑爹了,
									//因此为了避免这个坑,可以在这里停止table的编辑
									//如果没有编辑后事件校验,单纯的想用enter代替tab功能,那就不用stopEditing;
									if(table.isEditing())
										table.getCellEditor().stopCellEditing();
									
								}
//								table.setRowSelectionInterval(row, row);		
//								table.setColumnSelectionInterval(col, col);
								table.changeSelection(row, col, false, false);			

								
								
							}
							
						}

						@Override
						public void keyReleased(KeyEvent e) {
							// TODO Auto-generated method stub
							
						}
						
					});
					
					
				}
				
				
			}
        	
        	
        });

代码完整实现:

扫描二维码关注公众号,回复: 2462250 查看本文章
package javaGUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultCellEditor;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.table.DefaultTableModel;

import javaGUI.Tab1.MyAction;
import javaGUI.Tab1.MyText;

public class TableCSDN extends JFrame implements ActionListener{

	
	private  JTable table;  
	private  DefaultTableModel model;  
	private  JScrollPane jsp1;  
	private  JButton jb1,jb2,jb3,jb4;  
	private  JPanel jp1;  
	
	public static void main(String[] args) {
		new TableCSDN();
	}
	
	public TableCSDN() {
		
		  
        String[] name = new String[]{"列1","列2","列3","列4","列5"};  
        String[][] data = new String[5][5];  
        int value = 1;  
        for (int i=0; i<data.length; i++){  
            for(int j=0; j<data[i].length; j++){  
                data[i][j] = String.valueOf(value++);  
            }  
        }         
        model = new DefaultTableModel(data, name);          
        table = new JTable(model);           
        jsp1 = new JScrollPane(table); 
        jp1 = new JPanel(); 
        jb1 = new JButton("添加列");  
        jb2 = new JButton("添加行");  
        jb3 = new JButton("删除列");  
        jb4 = new JButton("删除行");          
        this.add(jp1, BorderLayout.SOUTH);  
        jp1.add(jb2);  
        jp1.add(jb3);  
        jp1.add(jb4);  
        this.add(jsp1);  
                
        /***start焦点在table时,按enter键水平移动
         * 
         * 只有焦点在table上时,才会执行这个action;
         * 
         * */
       Action myAction = new AbstractAction() {

		@Override
		public void actionPerformed(ActionEvent e) {
			
			int rowCount = table.getRowCount();
			
			int colCount = table.getColumnCount();
			
			if(rowCount <=0)return;
			//取被选中状态的row/col
			int row = table.getSelectedRow();
			
			int col = table.getSelectedColumn();
						
			if(row < 0 || col < 0)return;
			
			if(col < colCount-1) {				
				col+=1;
			}else {
				if(row < rowCount-1) {
					col = 0;					
					row+=1;
				}else {					
					row=col=0;
				}				
			}
//			table.setRowSelectionInterval(row, row);		
//			table.setColumnSelectionInterval(col, col);
			table.changeSelection(row, col, false, false);			
		}
    	   
       };
        /**end 焦点在table时,按enter键水平移动;*/
       
       
        InputMap enter = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);        
        enter.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER ,0),"ENTER");       
        table.getActionMap().put("ENTER", myAction);
        
        table.addFocusListener(new FocusListener() {

			@Override
			public void focusGained(FocusEvent e) {
				// TODO Auto-generated method stub
				
			}

			/**焦点在单元格时enter键水平移动*/
			@Override
			public void focusLost(FocusEvent e) {
				//在编辑单元格时,按enter键执行;如果不在被编辑单元格添键盘监听,
				//那么处于编辑状态时,必须按2此enter键才会水平移动;
				//因为第一次按enter时,焦点不在table中,不会触发enter事件
				if(table.isEditing()) {
					
					table.getEditorComponent().addKeyListener(new KeyListener() {

						@Override
						public void keyTyped(KeyEvent e) {
							// TODO Auto-generated method stub
							
						}

						@Override
						public void keyPressed(KeyEvent e) {
							if(e.getKeyCode() == KeyEvent.VK_ENTER) {
								int rowCount = table.getRowCount();
								
								int colCount = table.getColumnCount();
								
								if(rowCount <=0)return;
								//注意取编辑时的row/col
								int row = table.getEditingRow();
								
								int col = table.getEditingColumn();
											
								if(row < 0 || col < 0)return;
								
								if(col < colCount-1) {				
									col+=1;
								}else {
									if(row < rowCount-1) {
										col = 0;					
										row+=1;
									}else {					
										row=col=0;
									}	
//***注意这个换行时,有一个坑;在换行时会调用2次该方法,
//如果有对单元格的编辑后的校验,那就坑爹了,
//因此为了避免这个坑,可以在这里停止table的编辑
//如果没有编辑后事件校验,单纯的想用enter代替tab功能,那就不用stopEditing;
									if(table.isEditing())
										table.getCellEditor().stopCellEditing();
									
								}
//								table.setRowSelectionInterval(row, row);		
//								table.setColumnSelectionInterval(col, col);
								table.changeSelection(row, col, false, false);			

								
								
							}
							
						}

						@Override
						public void keyReleased(KeyEvent e) {
							// TODO Auto-generated method stub
							
						}
						
					});
					
					
				}
				
				
			}
        	
        	
        });
        
        
        
        
        jb2.addActionListener(this);  
        jb3.addActionListener(this);  
        jb4.addActionListener(this);  
        this.setSize(400, 400);  
        this.setVisible(true);  
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
    
	}
	
	
	
	
	@Override
	public void actionPerformed(ActionEvent e) {
		  
        if (e.getSource().equals(jb1)){  
            model.addColumn("新增列");  
        }  
        //新增一行  
        if (e.getSource().equals(jb2)){  
        	model.addRow(new Vector());  
          
        }  
        /** 
         * 删除列 做法: 先通过getColumnCount获取表格模型列数,通过 setColumnCount设置 
         * setColumnCount如果新大小   小于   当前大小,则将丢弃索引 columnCount 处及其之后的所有列 
         */  
        if (e.getSource().equals(jb3)){  
            int col = model.getColumnCount()-1;  
            model.setColumnCount(col);  
        }  
        if (e.getSource().equals(jb4)){  
            int row = model.getRowCount()-1;  
            if(row < 0){  
                return ;  
            }  
            model.removeRow(row);  
        }  
    
	}

	
	
	
	
	
	
	
	
	
}

猜你喜欢

转载自blog.csdn.net/m0_37550986/article/details/81090426