java - 在 JTable 中禁用拖动选择

标签 java swing drag-and-drop jtable

问题

我想单击 JTable 中未选定的单元格并将其拖动,即。 e.表格应处于拖动模式。问题是 JTable 有一种机制,当您单击未选定的单元格并拖动时,您实际上不是处于拖动模式,而是处于选择模式。选择模式只能通过单击实现,并且应该可以通过 Shift + 单击而不是通过拖动来扩展。

据我所知,罪魁祸首是在 BasicTableUI 中,但不幸的是,那里的所有相关内容都是私有(private)的。

问题

如何防止通过拖动进行选择,并在单击未选定的单元格并拖动它时立即进入拖动模式?

我进行了搜索,但没有找到令人满意的解决方案。或者它们适用于较旧的 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

非常感谢您的帮助!

最佳答案

您或许可以直接调用TransferHandler#exportAsDrag(...) MouseMotionListener#mouseDragged(...) 中的方法:

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

关于java - 在 JTable 中禁用拖动选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38079861/

相关文章:

java - 鼠标移动-十字准线光标

reactjs - 如何解决 'react-dnd-html5-backend' 不包含默认导出?

java - 从 LambdaMetafactory 创建 BiConsumer

java - 如何让一个按钮打开一个新窗口并关闭旧窗口

java - 如何编写一个简单的相机应用程序?

javascript - HTML5 循环中定义的多个放置目标

java - 如何设置优先鼠标监听器

java - 想要在值为 NULL 或 VOID 时显示错误消息(如果 EditText 为空但应用程序不断崩溃)

java - 从按下的 JMenuItem 获取文本?

java - 在不阻塞 UI 的情况下将大量项目添加到 ListModel