禁用JTable

时间:2016-06-28 15:05:39

标签: java swing drag-and-drop jtable

问题

我想点击JTable中未选中的单元格然后拖动它,i。即该表应处于拖动模式。问题是JTable有一种机制,当你点击一个未选择的单元格并拖动时,你实际上并没有处于拖动模式,而是处于选择模式。选择模式应该只能通过点击进行,并且可以通过shift +点击进行扩展,而不是通过拖动进行扩展。

从我发现的罪魁祸首是在BasicTableUI中,但不幸的是,那些与之相关的东西都是私密的。

问题

如何通过拖动来阻止选择,并在单击未选中的单元格并拖动时立即进入拖动模式?

我搜索过,但我发现的解决方案都不令人满意。或者它们适用于较旧的Java版本。

代码

这里有一些复制代码:

  • 单击未选中的单元格并拖动鼠标。将选择单元格。
  • 单击选定的单元格并拖动。该表处于拖动模式。

代码:

import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.DropMode;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class Main {
  public static void main(String args[]) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);

    Object rowData[][] = { 
        { "a", "a", "a" }, 
        { "a", "a", "a" }, 
        { "a", "a", "a" }, 
        { "a", "a", "a" }, 
        { "a", "a", "a" }, 
        };

    Object columnNames[] = { "Column 1", "Column 2", "Column 3" };
    final JTable table = new JTable( rowData, columnNames);

    table.setDragEnabled( true);
    table.setDropMode( DropMode.INSERT_ROWS);

    table.addMouseMotionListener( new MouseMotionAdapter() {

      @Override
      public void mouseDragged(MouseEvent e) {

        boolean selectionIsAdjusting = table.getSelectionModel().getValueIsAdjusting();

        if( selectionIsAdjusting) {
          System.out.println("selecting");
        } else {
          System.out.println("dragging");
        }

      }
    });

    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);

    JScrollPane scrollPane = new JScrollPane( table);
    frame.add( scrollPane, BorderLayout.CENTER);
    frame.setSize( 300, 150);
    frame.setVisible( true);

  }
}

截图:

enter image description here

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您可以在 +0 -102,048,224 +4,865,284 中直接调用TransferHandler#exportAsDrag(...)方法:

MouseMotionListener#mouseDragged(...)

答案 1 :(得分:-1)

  

选择模式应该只能通过点击进行,并且可以通过shift +点击进行扩展,而不是通过拖动进行扩展

您可以通过使用一些额外的逻辑覆盖JTable的processMouseEvent方法来改变行为。当发生按钮按下事件 - 并且shift没有停止时 - 在调用父方法之前将JTable的选择更改为当前单击的行。

JTable table = new JTable( rowData, columnNames){
    @Override
        public void processMouseEvent(MouseEvent e){
            Component c = (Component)e.getSource();
            if (e.getModifiersEx() == MouseEvent.BUTTON1_DOWN_MASK  && ( e.getModifiers() & MouseEvent.SHIFT_DOWN_MASK) == 0 ){
                int row = rowAtPoint(e.getPoint());
                int col = columnAtPoint(e.getPoint());
                if ( !isCellSelected(row, col) ){
                     clearSelection();
                     changeSelection(row, col, false, false);
                }

            }
            MouseEvent e1 = new MouseEvent(c, e.getID(), e.getWhen(), 
                    e.getModifiers() | InputEvent.CTRL_MASK, 
                    e.getX(), e.getY(), 
                    e.getClickCount(), 
                    e.isPopupTrigger() , 
                    e.getButton());

            super.processMouseEvent(e1);
        }
};