默认
发表评论 7
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
[已解决]Jtable里怎么实现撤销和恢复
阅读(27186) | 评论(7 收藏2 淘帖
   
   如题,Jtable里怎么实现撤销和恢复,也就是Ctrl+Z、Ctrl+Y。
  不知道eclipse里是用什么方法实现的,我现在的思路是继承 AbstractTableModel 在里面记录数据的增删改操作。
但具体还不知道如何写下去。
  请各位大神帮帮忙指点迷津,谢谢~!

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

标签:Java Swing
上一篇:swing中绑定热键的时候怎么判断热键占用的问题下一篇:swing调用摄像头并拍照保存
推荐方案
评论 7
是的,只能使用你帖子里说的类似方法自已去实现,JTable本身没有任何这方面的支持的。
快捷键的设定去查下JTable有ActionMap的东西,默认已经设置了很多快捷键,确保不出现冲突哦
引用:JackJiang 发表于 2016-05-07 21:48
是的,只能使用你帖子里说的类似方法自已去实现,JTable本身没有任何这方面的支持的。

能否给个demo我参考参考,感激不尽
签名: 是否记得我骄傲地说:这世界我曾经来过
我没有这种代码,实现起来也并不难啊
今天有时间研究了一下,写了个简单的方法来实现,并来分享一下。
先写一个类继承AbstractUndoableEdit,在里面重写undo和redo方法。
public class ZundoableEdit extends AbstractUndoableEdit {
               
        private MyTableModel model;    //MyTableModel继承自AbstractTableModel
        private int colIndex;      //model的列号
        private int rowIndex;      //model的行号
        private Object newValue;   //记录新值
        private Object oldValue;   //记录旧值
        
        public ZundoableEdit(MyTableModel model,Object oldValue,Object newValue,int rowIndex,int colIndex){
                this.model=model;
                this.oldValue=oldValue;
                this.newValue=newValue;
                this.rowIndex=rowIndex;
                this.colIndex=colIndex;
        }   
        @Override
        public void undo() throws CannotUndoException {
                super.undo();
                model.setValueAt(oldValue, rowIndex, colIndex);   //撤销操作,重新赋予旧值
                model.fireTableCellUpdated(rowIndex, colIndex);
        }      
        @Override
        public void redo() throws CannotRedoException {
                super.redo();
                model.setValueAt(newValue, rowIndex, colIndex);     //重做操作,赋予新值
                model.fireTableCellUpdated(rowIndex, colIndex);
        }
}


接下来,用swing的undo包中的UndoManager对象来管理ZundoableEdit 的实例对象:
UndoManager undoManager=new UndoManager();
然后在主程序中监听model的变化:model.addTableModelListener(tableChangeListener);
/**model元素改变事件监听*/
private TableModelListener tableChangeListener=new TableModelListener() {
        
        @Override
        public void tableChanged(TableModelEvent e) {
            if(selectedRow!=-1 || selectedCol!=-1){
                //获得改变后的值
                Object newValue=model.getValueAt(selectedRow, selectedCol);
                //如果前后两次的值不一样,则新建ZundoableEdit的匿名对象,添加到undomanager中管理
                if(!tempValue.equals(newValue)){
                    undoManager.addEdit(new ZundoableEdit(model, tempValue,
                            newValue, selectedRow, selectedCol));
                    reSetSorter(newValue.toString().trim(), selectedCol);
                }
            }
        }
};


并且监听table的鼠标点击事件:table.addMouseMotionListener(tableCellListener);获得所修改的单元格的列号和行号。
/**table鼠标监听事件*/
private MouseAdapter tableCellListener = new MouseAdapter() {
               
       public void mousePressed(MouseEvent e) {
             int colIndex=table.columnAtPoint(e.getPoint());
             int rowIndex = table.rowAtPoint(e.getPoint());
           //转换为model的行号和列号
             selectedRow = table.convertRowIndexToModel(rowIndex);
             selectedCol = table.convertColumnIndexToModel(colIndex);
            //用一个全局变量来保存"旧值"(修改前的)
             tempValue = model.getValueAt(selectedRow, selectedCol);
       };
}


最后在undo和redo按钮中调用即可:
case MENU_UNDO:
        if(undoManager.canUndo()){
                undoManager.undo();
        }
break;
case MENU_REDO:
         if(undoManager.canRedo()){
                undoManager.redo();
         }
break;
签名: 是否记得我骄傲地说:这世界我曾经来过
引用:zjj7188 发表于 2016-05-27 11:58
今天有时间研究了一下,写了个简单的方法来实现,并来分享一下。
先写一个类继承AbstractUndoableEdit,在 ...

需要注意的是:
如果在自己的tablemodel类中重写了setValueAt()方法,并添加了fireTableCellUpdated()方法,
那就不要在主程序中添加fireTableDataChanged()方法,这回导致重复触发tablemodel的TableModelListener监听器,导致会有两次undo和两次redo。
或者,在自己的tablemodel类中复写一个setValueAt()方法,不要添加fireTableCellUpdated()方法。
签名: 是否记得我骄傲地说:这世界我曾经来过
引用:zjj7188 发表于 2016-05-27 12:10
需要注意的是:
如果在自己的tablemodel类中重写了setValueAt()方法,并添加了fireTableCellUpdated()方 ...

赞一个!
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部