JTable不受欢迎的拖放行为

时间:2012-07-27 16:13:21

标签: java swing jtable drag-and-drop

我正在尝试向我的应用程序添加拖放功能,其中拖动事件的发起者是JTable。我目前正在使用内置的拖动支持JTable来调用setDragEnabled(true)

我面临的问题是,为了开始拖动操作,必须首先点击表格的一行,然后释放鼠标;只有第二次鼠标按下(以及所有后续鼠标按下)才会生成拖动事件。即使JTable失去焦点也会发生这种情况 - 即,一旦执行了第一次左键单击操作,拖放功能就完全,直到我换入新的TableModel 。安装新模型后,需要在拖动再次开始工作之前在表上执行左键单击。

阅读setDragEnabled(boolean)的API文档,这意味着这是L& F的责任,因此我可能无法解决这个问题。有没有人有什么建议?我正在使用Alloy L& F但是不愿意改变它。

3 个答案:

答案 0 :(得分:2)

我发现了一个hacky解决方案,即向MouseListener添加JTable并在按下鼠标时挂钩TransferHandle r的exportAsDrag方法:

    final JTable actionTbl = new JTable();
    actionTbl.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent evt) {
            // Need to explicitly start a drag operation when the mouse is pressed.
            // Otherwise drags are only started *after* the user has clicked once
            // on the JTable (this could be down to the L&F not doing the right thing).
            actionTbl.getTransferHandler().exportAsDrag(actionTbl, evt, TransferHandler.COPY);
        }
    });

答案 1 :(得分:1)

setDragEnabled方法

的javadoc引用
  

启用自动拖动处理后,只要用户在项目上按下鼠标按钮(单选模式)或选择(在其他选择中),大多数外观(包括子类BasicLookAndFeel)都会开始拖放操作模式),然后将鼠标移动几个像素。

如果我正确阅读,您在使用单一选择模式时应该会得到所需的行为。

如果您需要将该行为与多个选择结合使用,您可以选择手动处理表上的传入鼠标事件,并在mouse_down上调整选择,然后将鼠标事件委派给JTable。所以在伪代码中:

protected void processEvent(AWTEvent e) {
  if ( isMouseDownEvent( e ) ){
     adjustSelection( e );
  }
  super.processEvent( e );
}

注意:我没有测试过这个。它完全基于我在javadoc中读到的内容,并且可能会有一些不必要的副作用,因为JTable本身仍会处理事件并对其做出反应

答案 2 :(得分:0)

Adamski的解决方案非常有效,但我必须将最后一行中的TransferHandler.COPY更改为TransferHandler.MOVE才能使其正常工作:

final JTable actionTbl = new JTable();
actionTbl.addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent evt) {
        actionTbl.getTransferHandler().exportAsDrag(actionTbl, evt, TransferHandler.MOVE);
    }
});