JTable中实现拖拽式多选、删除功能

从IBM notes邮箱中得到的灵感,在收件箱的最左侧可以使用鼠标拖拽选择多封邮件,或者是拖拽取消多封邮件的选择,以及Ctrl-A全选所有邮件的功能,觉得很是方便,省去了在界面中添加全选按钮导致界面难看、不易布局的问题

public class MyDialog extends JDialog implements ListSelectionListener{ private boolean mousePressed ; private boolean anchorSelected ; private boolean ctrlA ; public MyDialog(){ myTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); myTable.addKeyListener(new KeyAdapter(){ @Override public void keyPressed(KeyEvent e) { if(e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK && e.getKeyCode() == KeyEvent.VK_A){ ctrlA = true; logger.debug("Ctrl-A pressed"); } } }); myTable.addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { int rowIndex = myTable.rowAtPoint(e.getPoint()); if (rowIndex == -1) { return ; } logger.debug("MouseClicked:" + rowIndex); if (e.getButton()==MouseEvent.BUTTON3) { myTable.getSelectionModel().clearSelection(); return; } mousePressed = false; tableModel.updateObject(tableModel.getRow(rowIndex).setSelected(!anchorSelected)); } @Override public void mouseReleased(MouseEvent e) { int rowIndex = myTable.rowAtPoint(e.getPoint()); if (rowIndex == -1) { return ; } mousePressed = false; logger.debug("MouseReleased:" + rowIndex); } public void mousePressed(MouseEvent e) { int rowIndex = myTable.rowAtPoint(e.getPoint()); if (rowIndex == -1) { return ; } mousePressed = true; logger.debug("MousePressed:" + rowIndex); } }); myTable.getSelectionModel().addListSelectionListener(this); } public void valueChanged(ListSelectionEvent e) { ListSelectionModel lsm = (ListSelectionModel)e.getSource(); int anchorSelectionIndex = lsm.getAnchorSelectionIndex(); int leadSelectionIndex = lsm.getLeadSelectionIndex() ; if(anchorSelectionIndex == leadSelectionIndex && mousePressed){ return; } logger.debug("ListSelection: getFirstIndex " + e.getFirstIndex() + "|getLastIndex " + e.getLastIndex()); logger.debug("ListSelection: getAnchorSelectionIndex " + anchorSelectionIndex); logger.debug("ListSelection: getLeadSelectionIndex " + leadSelectionIndex); //取出拖选的第一行,并保存其选择状态 anchorSelected = tableModel.getRow(anchorSelectionIndex).isSelected(); if(ctrlA){ //如果是全选,则将所有行全部设为选中状态 logger.debug("ListSelection: Ctrl-A"); for(int row = 0 ; row < boxTable.getRowCount() ; row ++){ tableModel.updateObject(tableModel.getRow(row).setSelected(true)); } ctrlA = false; return; } //如果不是全选,则修改所有选择行的状态,该状态与拖选的第一行的初始状态相反 for(int row :boxTable.getSelectedRows()){ if(anchorSelectionIndex == leadSelectionIndex){ tableModel.updateObject(tableModel.getRow(row).setSelected(!anchorSelected)); }else{ tableModel.updateObject(tableModel.getRow(row).setSelected(anchorSelected)); } } } }

下面是改进版本,主要是使用逐个更新替换全部更新,并且在右键中取消并重新加入ListSelectionListener

public class MyDialog extends JDialog implements ListSelectionListener{ private boolean mousePressed ; private boolean anchorSelected ; private boolean ctrlA ; public MyDialog(){ myTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); myTable.addKeyListener(new KeyAdapter(){ @Override public void keyPressed(KeyEvent e) { if(e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK && e.getKeyCode() == KeyEvent.VK_A){ ctrlA = true; logger.debug("Ctrl-A pressed"); } } }); myTable.addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { int rowIndex = myTable.rowAtPoint(e.getPoint()); if (rowIndex == -1) { return ; } logger.debug("MouseClicked:" + rowIndex); if (e.getButton()==MouseEvent.BUTTON3) { myTable.getSelectionModel().removeListSelectionListener(MyDialog.this); myTable.getSelectionModel().clearSelection(); myTable.getSelectionModel().addListSelectionListener(MyDialog.this); return; } mousePressed = false; tableModel.updateObject(tableModel.getRow(rowIndex).setSelected(!anchorSelected)); } @Override public void mouseReleased(MouseEvent e) { int rowIndex = myTable.rowAtPoint(e.getPoint()); if (rowIndex == -1) { return ; } mousePressed = false; logger.debug("MouseReleased:" + rowIndex); } public void mousePressed(MouseEvent e) { int rowIndex = myTable.rowAtPoint(e.getPoint()); if (rowIndex == -1) { return ; } mousePressed = true; logger.debug("MousePressed:" + rowIndex); } }); myTable.getSelectionModel().addListSelectionListener(this); } public void valueChanged(ListSelectionEvent e) { ListSelectionModel lsm = (ListSelectionModel)e.getSource(); int anchorSelectionIndex = lsm.getAnchorSelectionIndex(); int leadSelectionIndex = lsm.getLeadSelectionIndex() ; if(anchorSelectionIndex == leadSelectionIndex && mousePressed){ return; } logger.debug("ListSelection: getFirstIndex " + e.getFirstIndex() + "|getLastIndex " + e.getLastIndex()); logger.debug("ListSelection: getAnchorSelectionIndex " + anchorSelectionIndex); logger.debug("ListSelection: getLeadSelectionIndex " + leadSelectionIndex); //取出拖选的第一行,并保存其选择状态 anchorSelected = tableModel.getRow(anchorSelectionIndex).isSelected(); if(ctrlA){ //如果是全选,则将所有行全部设为选中状态 logger.debug("ListSelection: Ctrl-A"); for(int row = 0 ; row < boxTable.getRowCount() ; row ++){ tableModel.updateObject(tableModel.getRow(row).setSelected(true)); } ctrlA = false; return; } //如果不是全选,则修改所有选择行的状态,该状态与拖选的第一行的初始状态相反 if (anchorSelectionIndex == leadSelectionIndex) { tableModel.updateObject(tableModel.getRow(leadSelectionIndex).setSelected(!anchorSelected)); } else { tableModel.updateObject(tableModel.getRow(leadSelectionIndex).setSelected(anchorSelected)); } } }

你可能感兴趣的:(JTable中实现拖拽式多选、删除功能)