简体   繁体   English

禁用JTable中的拖动选择

[英]Disable drag selection in JTable

Problem 问题

I'd like to click on an unselected cell in a JTable and drag it, ie the table should be in drag mode. 我想点击JTable中一个未选中的单元格并拖动它,即表格应该处于拖动模式。 The problem is that the JTable has a mechanism that when you click on an unselected cell and drag, you actually aren't in drag mode, but in selection mode. 问题是JTable有一种机制,当你点击一个未选择的单元格并拖动时,你实际上不是处于拖动模式,而是处于选择模式。 Selection mode should only be possible via click and should be extendable via shift + click, not via dragging. 选择模式应该只能通过点击进行,并且可以通过shift +点击进行扩展,而不是通过拖动进行扩展。

From what I've found the culprit is in BasicTableUI, but unfortunately everything there that's relevant is private. 从我发现的罪魁祸首是在BasicTableUI,但不幸的是那里的相关内容是私有的。

Question

How can you prevent selection via dragging and be instantly in drag mode when you click on an unselected cell and drag it? 当您单击未选择的单元格并拖动它时,如何通过拖动阻止选择并立即处于拖动模式?

I searched, but none of the solutions I found were satisfactory. 我搜索过,但我找到的解决方案都没有令人满意。 Or they were for older Java versions. 或者它们适用于较旧的Java版本。

Code

Here's some code for the reproduction: 这是复制的一些代码:

  • Click on an unselected cell and drag the mouse. 单击未选中的单元格并拖动鼠标。 The cells will be selected. 将选择单元格。
  • Click on a selectged cell and drag. 单击选定的单元格并拖动。 The table is in drag mode. 该表处于拖动模式。

The code: 编码:

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);

  }
}

Screenshot: 截图:

在此输入图像描述

Thank you very much for the help! 非常感谢你的帮助!

You might be able to directly call TransferHandler#exportAsDrag(...) method in MouseMotionListener#mouseDragged(...) : 您可以在MouseMotionListener#mouseDragged(...)直接调用TransferHandler #exportAsDrag(...)方法:

import java.awt.*;
import java.awt.event.*;
import java.util.Optional;
import javax.swing.*;
import javax.swing.table.*;

public class Main2 {
  public JComponent makeUI() {
    Object columnNames[] = {"Column 1", "Column 2", "Column 3"};
    Object data[][] = {
      { "a", "a", "a" },
      { "a", "a", "a" },
      { "a", "a", "a" },
      { "a", "a", "a" },
      { "a", "a", "a" },
    };
    JTable table = new JTable(new DefaultTableModel(data, columnNames));
    table.setDragEnabled(true);
    table.setDropMode(DropMode.INSERT_ROWS);
    table.addMouseMotionListener(new MouseAdapter() {
      @Override public void mouseDragged(MouseEvent e) {
        JComponent c = (JComponent) e.getComponent();
        Optional.ofNullable(c.getTransferHandler())
                .ifPresent(th -> th.exportAsDrag(c, e, TransferHandler.COPY));
      }
    });
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);

    JPanel p = new JPanel(new BorderLayout());
    p.add(new JScrollPane(table));
    p.add(new JTextField(), BorderLayout.SOUTH);
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new Main2().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

Selection mode should only be possible via click and should be extendable via shift + click, not via dragging 选择模式应该只能通过点击进行,并且可以通过shift +点击进行扩展,而不是通过拖动进行扩展

You may be able to alter the behavior by overriding JTable's processMouseEvent method with some additional logic. 您可以通过使用一些额外的逻辑覆盖JTable的processMouseEvent方法来改变行为。 When a button down event occurs - and shift is not down - alter the selection of the JTable to the current clicked row before calling the parent method. 当发生按钮按下事件 - 并且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);
        }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM