JTable 失去焦点时取消编辑状态

转载地址: http://www.cnblogs.com/aquar/p/3263761.html

当JTable的单元格处于编辑状态时,如果用户触发以下事件,表格就会退出编辑状态,进而调用TableModel的

public void setValueAt(Object aValue, int row, int column)

1. 回车确认

2. 使用方向键或tab移动到别的单元格

3. 鼠标点击别的单元格

但是,如果用户点击了表格之外的控件,表格中单元格还是处于编辑状态,此时如果点击的是“保存”按钮,由于单元格并没有接受用户的输入,导致当前编辑的单元格的值为null,用户输入的数据没有保存。

同时,由于表格中的所有单元格是共用一个CellEditor,当用户新建一行时,通常会让光标移动到新建的行的某一个单元格,此时原来正在编辑的单元格就会替换到新增加的行中,而之前单元格的输入的内容没有保存。

因此,在触发其他操作之前,最好能够取消表格正在编辑的状态。

方法1.

JTable table = new JTable(...); 
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

当其他控件获取焦点后,表格会停止编辑,但是点击最小化时没有效果。

方法2.

if (table.isEditing()) 
    table.getCellEditor().stopCellEditing();

在需要取消表格编辑状态的按钮等控件的事件响应中根据具体情况来取消表格的编辑状态。

原文说点击表格的表头,使用第一种方法,表格不会退出编辑状态,但是经测试也是会退出编辑状态的。

表格Model简单继承DefaultTableModel

package  com.aquar.table;
 
import  com.aquar.data.Movie;
 
import  javax.swing.table.DefaultTableModel;
import  java.util.ArrayList;
import  java.util.Date;
import  java.util.List;
import  java.util.Vector;
 
/**
  * Created with IntelliJ IDEA.
  * User: Edison
  * Date: 13-8-16
  * Time: 下午10:46
  * A table model for movies.
  */
public  class  TableModelMovie extends  DefaultTableModel {
     private  static  final  int  COL_NAME = 0 ;
     private  static  final  int  COL_PREMIERE = COL_NAME + 1 ;
     private  static  final  int  COL_DIRCTOR = COL_PREMIERE + 1 ;
 
     public  TableModelMovie() {
         init();
         mockData();
     }
 
     private  void  init() {
         columnIdentifiers.add( "Name" );
         columnIdentifiers.add( "Premiere" );
         columnIdentifiers.add( "Director" );
     }
 
     /**
      * make some movies.
      */
     private  void  mockData() {
         List<Movie> list = new  ArrayList<>();
         list.add( new  Movie( "The Shawshank Redemption" , new  Date(), "Frank Darabont" ));
         list.add( new  Movie( "The Godfather" , new  Date(), " Francis Ford Coppola" ));
         list.add( new  Movie( "Pulp Fiction" , new  Date(), "Quentin Tarantino" ));
         list.add( new  Movie( "The Dark Knight" , new  Date(), "Frank Darabont" ));
         fillTableData(list);
     }
 
     private  void  fillTableData(List<Movie> movies) {
         dataVector.clear();
         for  (Movie movie : movies) {
             Vector rowVector = new  Vector();
             rowVector.add(movie);
             dataVector.add(rowVector);
         }
         fireTableDataChanged();
     }
 
     @Override
     public  Object getValueAt( int  row, int  column) {
         Object ret = "" ;
         if  (row > dataVector.size()) {
             return  ret;
         }
         // Get one row data.
         Vector rowData = (Vector) dataVector.elementAt(row);
         Movie movie = (Movie) rowData.elementAt( 0 );
         switch  (column) {
         case  COL_NAME:
             ret = movie.getName();
             break ;
         case  COL_PREMIERE:
             ret = movie.getPremiere().toString();
             break ;
         case  COL_DIRCTOR:
             ret = movie.getDirector();
             break ;
         default :
             break ;
         }
         return  ret;
     }
 
     @Override
     public  void  setValueAt(Object aValue, int  row, int  column) {
         if  (row > dataVector.size()) {
             return  ;
         }
         // Get one row data.
         Vector rowData = (Vector) dataVector.elementAt(row);
         Movie movie = (Movie) rowData.elementAt( 0 );
         switch  (column) {
         case  COL_NAME:
             movie.setName(aValue.toString());
             break ;
         case  COL_DIRCTOR:
             movie.setDirector(aValue.toString());
             break ;
         default :
             break ;
         }
     }
 
     @Override
     public  boolean  isCellEditable( int  row, int  column) {
         return  column == COL_NAME || column == COL_DIRCTOR;
     }
}

数据对象

package  com.aquar.data;
 
import  java.util.Date;
import  java.util.List;
 
/**
  * Created with IntelliJ IDEA.
  * User: Edison
  * Date: 13-8-16
  * Time: 下午10:30
  * To change this template use File | Settings | File Templates.
  */
public  class  Movie {
     private  String name;
     private  Date premiere;
     private  String publisher;
     private  String director;
     private  List<String> starrings;
 
     public  Movie(String movName, Date movPremiere, String movDirector) {
         this .name = movName;
         this .premiere = movPremiere;
         this .director = movDirector;
     }
 
     public  String getName() {
         return  name;
     }
 
     public  Date getPremiere() {
         return  premiere;
     }
 
     public  String getPublisher() {
         return  publisher;
     }
 
     public  String getDirector() {
         return  director;
     }
 
     public  List<String> getStarrings() {
         return  starrings;
     }
 
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  void  setPremiere(Date premiere) {
         this .premiere = premiere;
     }
 
     public  void  setPublisher(String publisher) {
         this .publisher = publisher;
     }
 
     public  void  setDirector(String director) {
         this .director = director;
     }
 
     public  void  setStarrings(List<String> starrings) {
         this .starrings = starrings;
     }
}

程序入口和UI

package  com.aquar.main;
 
import  com.aquar.table.TableModelMovie;
 
import  javax.swing.*;
import  java.awt.*;
import  java.awt.event.ActionEvent;
import  java.awt.event.ActionListener;
 
/**
  * Created with IntelliJ IDEA.
  * User: Edison
  * Date: 13-7-14
  * Time: 下午11:55
  * To change this template use File | Settings | File Templates.
  */
public  class  MainFrame {
     private  final  int  width = 800 ;
     private  final  int  height = 600 ;
     private  JFrame mFrame;
     private  JTable movTable;
 
     public  MainFrame() {
         mFrame = new  JFrame();
         mFrame.setLayout( new  BorderLayout( 0 , 0 ));
         mFrame.setSize( new  Dimension(width, height));
         mFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 
         initUI();
 
         mFrame.setVisible( true );
     }
 
     private  void  initUI() {
         TableModelMovie modelMovie = new  TableModelMovie();
         movTable = new  JTable(modelMovie);
         movTable.setRowHeight( 20 );
         movTable.putClientProperty( "terminateEditOnFocusLost" , Boolean.TRUE);
         JScrollPane scrollPane = new  JScrollPane(movTable);
         mFrame.add(scrollPane, BorderLayout.CENTER);
 
         JPanel footPanel = new  JPanel();
         JButton newBtn = new  JButton( "New" );
         newBtn.addActionListener( new  ActionListener() {
             @Override
             public  void  actionPerformed(ActionEvent e) {
//                if (movTable.isEditing()) {
//                    movTable.getCellEditor().stopCellEditing();
//                }
             }
         });
 
         footPanel.add(newBtn);
         mFrame.add(footPanel, BorderLayout.SOUTH);
     }
 
     public  void  show() {
 
     }
 
     public  static  void  main(String[] args) {
         new  MainFrame();
 
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值