2

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

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

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

4

3 回答 3

2

我发现了一个 hacky 解决方案,即在按下鼠标时将 a 添加到r 的方法MouseListener中:JTableTransferHandleexportAsDrag

    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);
        }
    });
于 2012-07-27T19:10:57.367 回答
1

引用该setDragEnabled方法的javadoc

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

如果我没看错的话,当你使用单选模式时,你应该会得到想要的行为。

如果您需要将该行为与多项选择相结合,您可以选择手动处理桌子上传入的鼠标事件,并在 mouse_down 上调整选择,然后将鼠标事件委托给JTable. 所以在伪代码中:

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

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

于 2012-07-27T16:29:38.423 回答
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);
    }
});
于 2016-02-03T15:53:51.773 回答