我正在尝试向我的应用程序添加拖放功能,其中拖动事件的发起者是JTable
。我目前正在使用内置的拖动支持JTable
来调用setDragEnabled(true)
。
我面临的问题是,为了开始拖动操作,必须首先点击表格的一行,然后释放鼠标;只有第二次鼠标按下(以及所有后续鼠标按下)才会生成拖动事件。即使JTable
失去焦点也会发生这种情况 - 即,一旦执行了第一次左键单击操作,拖放功能就完全,直到我换入新的TableModel
。安装新模型后,需要在拖动再次开始工作之前在表上执行左键单击。
阅读setDragEnabled(boolean)
的API文档,这意味着这是L& F的责任,因此我可能无法解决这个问题。有没有人有什么建议?我正在使用Alloy L& F但是不愿意改变它。
答案 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
方法
启用自动拖动处理后,只要用户在项目上按下鼠标按钮(单选模式)或选择(在其他选择中),大多数外观(包括子类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);
}
});