在树视图中拖动项目时,JavaFX OnMouseDraged未被激发
基本上,我尝试实现这样一种行为,即当从树视图拖动一个项目并在树视图的底部或顶部移动时,树视图将自动向下或向上滚动 到目前为止,我能够简单地扩展TreeView并向其添加onMouseDrawed事件处理程序。像这样在树视图中拖动项目时,JavaFX OnMouseDraged未被激发,java,drag-and-drop,treeview,javafx-8,Java,Drag And Drop,Treeview,Javafx 8,基本上,我尝试实现这样一种行为,即当从树视图拖动一个项目并在树视图的底部或顶部移动时,树视图将自动向下或向上滚动 到目前为止,我能够简单地扩展TreeView并向其添加onMouseDrawed事件处理程序。像这样 public ExtendedTreeView() { super(); setOnMouseDragged((MouseEvent event) -> onMouseMoved(event)); } 事件处理程序如下所示(系统输出基本上仅用于调试目的) M
public ExtendedTreeView()
{
super();
setOnMouseDragged((MouseEvent event) -> onMouseMoved(event));
}
事件处理程序如下所示(系统输出基本上仅用于调试目的)
MouseMoved上的私有void(MouseeEvent事件)
{
System.out.println(“onMouseMoved-----------------------------------------------------------------------------”;
System.out.println(event.getEventType().toString());
//-----仅当正在进行拖动事件时应用
if(event.getEventType().equals(MouseEvent.MOUSE_拖动))
{
//-----首先检查我们是否是滚动边
System.out.println(String.format(“大小:%f:%f”,getWidth(),getHeight());
System.out.println(String.format(“边界:%f:%f:%f:%f”、\u scrollboods.getTop()、\u scrollboods.getRight()、\u scrollboods.getBottom()、\u scrollboods.getLeft());
System.out.println(String.format(“节点:%f:%f”,event.getX(),event.getY());
//-----首选上下方向
ScrollDirection=ScrollDirection.None;
if(event.getY()=\u scrollBounds.getBottom())
方向=滚动方向。底部;
else if(event.getX()>=\u scrollBounds.getRight())
方向=滚动方向。右;
如果(event.getX()正常,那么我就找出了问题所在 我听到了错误的事件,我需要注册的事件是onDragOver事件,而不是OnMouseDraged事件 因此,如果任何人需要autoscrollTreeView,autoscroll treeView的最终解决方案如下所示:
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.DragEvent;
import com.sun.javafx.scene.control.skin.VirtualFlow;
@SuppressWarnings("restriction")
public class AutoscrollTreeView<T> extends TreeView<T>
{
// region Enumerations
private enum ScrollDirection
{
None, Top, Bottom
}
// endregion
// region Static
private static final double _milliSecondToSecondFactor = 1.0d / 1000.0d;
// endregion
// region Fields
/**
* the time interval in milliseconds in which the scroll is performed
*/
private final LongProperty _checkInterval = new SimpleLongProperty(50);
/**
* the actual scroll speed when being in the scroll areas
*/
private final DoubleProperty _scrollSpeed = new SimpleDoubleProperty(1.0);
/**
* the scroll speed increment per second the user remain in the scroll area
*/
private final DoubleProperty _scrollSpeedIncrementPerSecond = new SimpleDoubleProperty(0.0);
/**
* distance from the top, which defines the area which will start a scroll in the -y axis
*/
private final DoubleProperty _dragIdentifierTop = new SimpleDoubleProperty();
/**
* distance from the bottom, which defines the area which will start a scroll in the +y axis
*/
private final DoubleProperty _dragIdentifierBottom = new SimpleDoubleProperty();
/**
* time at which the user entered the any scroll area
*/
private long _initialDragTime = -1;
/**
* last time the interval was checked
*/
private long _lastCheck = -1;
// endregion
// region Constructor
public AutoscrollTreeView()
{
super();
addEventHandlers();
}
public AutoscrollTreeView(TreeItem<T> root)
{
super(root);
addEventHandlers();
}
// endregion
// region Getter/Setter
public final void setCheckInterval(long value)
{
_checkInterval.set(value);
}
public final long getCheckInterval()
{
return _checkInterval.get();
}
public final LongProperty checkIntervalProperty()
{
return _checkInterval;
}
public final void setScrollSpeed(double value)
{
_scrollSpeed.set(value);
}
public final double getScrollSpeed()
{
return _scrollSpeed.get();
}
public final DoubleProperty scrollSpeedProperty()
{
return _scrollSpeed;
}
public final void setScrollSpeedIncrementPerSecond(double value)
{
_scrollSpeedIncrementPerSecond.set(value);
}
public final double getScrollSpeedIncrementPerSecond()
{
return _scrollSpeedIncrementPerSecond.get();
}
public final DoubleProperty scrollSpeedIncrementPerSecondProperty()
{
return _scrollSpeedIncrementPerSecond;
}
public final void setDragIdentiferTop(double value)
{
_dragIdentifierTop.set(value);
}
public final double getDragIdentifierTop()
{
return _dragIdentifierTop.get();
}
public final DoubleProperty dragIdentifierTopProperty()
{
return _dragIdentifierTop;
}
public final void setDragIdentiferBottom(double value)
{
_dragIdentifierBottom.set(value);
}
public final double getDragIdentifierBottom()
{
return _dragIdentifierBottom.get();
}
public final DoubleProperty dragIdentifierBottomProperty()
{
return _dragIdentifierBottom;
}
// endregion
// region Events
private void onDragEvent(DragEvent event)
{
// -----only apply when there is a drag event in progress
if(event.getEventType().equals(DragEvent.DRAG_OVER))
{
if(_lastCheck == -1 || System.currentTimeMillis() - _lastCheck > _checkInterval.get())
{
ScrollDirection direction = ScrollDirection.None;
if(event.getY() <= _dragIdentifierTop.get())
direction = ScrollDirection.Top;
else if(event.getY() >= getHeight() - _dragIdentifierBottom.get())
direction = ScrollDirection.Bottom;
if(direction != ScrollDirection.None)
{
double additionalScrollSpeed = 0;
if(_initialDragTime > 0)
additionalScrollSpeed = _scrollSpeedIncrementPerSecond.get() * (System.currentTimeMillis() - _initialDragTime) * _milliSecondToSecondFactor;
else
_initialDragTime = System.currentTimeMillis();
if(direction == ScrollDirection.Bottom)
scrollY(_scrollSpeed.get() + additionalScrollSpeed);
else
scrollY(-(_scrollSpeed.get() + additionalScrollSpeed));
}
else
{
_initialDragTime = -1;
}
_lastCheck = System.currentTimeMillis();
}
}
else
{
_initialDragTime = -1;
_lastCheck = -1;
}
}
// endregion
// region Private
/**
* adds the necessary event filters
*/
private void addEventHandlers()
{
addEventHandler(DragEvent.DRAG_OVER, event -> onDragEvent(event));
addEventHandler(DragEvent.DRAG_EXITED, event -> onDragEvent(event));
addEventHandler(DragEvent.DRAG_DROPPED, event -> onDragEvent(event));
addEventHandler(DragEvent.DRAG_DONE, event -> onDragEvent(event));
}
private void scrollY(double offset)
{
VirtualFlow<?> flow = ((VirtualFlow<?>) lookup("VirtualFlow"));
flow.adjustPixels(offset);
}
// endregion
}
导入javafx.beans.property.DoubleProperty;
导入javafx.beans.property.LongProperty;
导入javafx.beans.property.SimpleDoubleProperty;
导入javafx.beans.property.SimpleLongProperty;
导入javafx.scene.control.TreeItem;
导入javafx.scene.control.TreeView;
导入javafx.scene.input.DragEvent;
导入com.sun.javafx.scene.control.skin.VirtualFlow;
@禁止警告(“限制”)
公共类AutoscrollTreeView扩展了TreeView
{
//区域枚举
私有枚举滚动方向
{
无,顶部,底部
}
//端区
//区域静态
专用静态最终双精度_毫秒到秒系数=1.0d/1000.0d;
//端区
//区域字段
/**
*执行滚动的时间间隔(毫秒)
*/
私有最终LongProperty _checkInterval=新SimpleLongProperty(50);
/**
*处于滚动区域时的实际滚动速度
*/
私有最终DoubleProperty _scrollSpeed=新的SimpleDoubleProperty(1.0);
/**
*用户保持在滚动区域内的每秒滚动速度增量
*/
private final DoubleProperty _scrollSpeedIncrementPerSecond=新的SimpleDoubleProperty(0.0);
/**
*距顶部的距离,定义将在-y轴上开始滚动的区域
*/
private final DoubleProperty _dragIdentifierTop=新的SimpleDoubleProperty();
/**
*距底部的距离,定义将在+y轴上开始滚动的区域
*/
private final DoubleProperty _dragIdentifierBottom=新的SimpleDoubleProperty();
/**
*用户进入任意滚动区域的时间
*/
私有长_initialDragTime=-1;
/**
*上次检查间隔时间
*/
私有长_lastCheck=-1;
//端区
//区域构造函数
公共AutoscrollTreeView()
{
超级();
addEventHandlers();
}
公共AutoscrollTreeView(TreeItem根目录)
{
超级(根);
addEventHandlers();
}
//端区
//区域Getter/Setter
公共最终作废设置检查间隔(长值)
{
_检查间隔。设置(值);
}
公共最终长getCheckInterval()
{
返回_checkInterval.get();
}
公共最终LongProperty checkIntervalProperty()
{
返回检查间隔;
}
公共最终无效设置CrollSpeed(双倍值)
{
_滚动速度。设置(值);
}
公共最终双getScrollSpeed()
{
return_scrollSpeed.get();
}
公共最终DoubleProperty scrollSpeedProperty()
{
返回速度;
}
公共最终无效设置CrollSpeedIncrementPerSecond(双倍值)
{
_scrollSpeedIncrementPerSecond.set(值);
}
公共最终双getScrollSpeedIncrementPerSecond()函数
{
返回_scrollSpeedIncrementPerSecond.get();
}
公共最终DoubleProperty scrollSpeedIncrementPerSecondProperty()
{
返回_scrollSpeedIncrementPerSecond;
}
公共最终无效setDragIdentiferTop(双值)
{
_dragIdentifierTop.set(值);
}
公共最终双getDragIdentifierTop()
{
return _dragIdentifierTop.get();
}
公共最终双属性dragIdentifierTopProperty()
{
返回_dragIdentifierTop;
}
公共最终无效setDragIdentiferBottom(双值)
{
_dragIdentifierBottom.set(值);
}
公共最终双精度getDragIdentifierBottom()
{
返回_dragIdentifierBottom.get();
}
公共最终DoubleProperty dragIdentifierBottomProperty()
{
返回_dragIdentifierBottom;
}
//端区
//地区活动
私有事件(DrageEvent事件)
{
//-----仅当正在进行拖动事件时应用
if(event.getEventType().equals(DragEvent.DRAG_OVER))
{
如果(_lastCheck==-1 | | System.currentTimeMillis()-_lastCheck>_checkInterval.get())
{
ScrollDirection=ScrollDirection.None;
@FXML
public void onDragDetected(MouseEvent event)
{
Base item = getTreeCell().getItem();
Dragboard dragboard = getTreeCell().startDragAndDrop(TransferMode.MOVE);
//-----get info from the item and put it in the clipboard
dragboard.setContent(content);
//event.consume();
}
@FXML
public void onDragEntered(DragEvent event)
{
boolean acceptDrag = false;
Dragboard dragboard = event.getDragboard();
Base current = getTreeCell().getItem();
//-----get the info from the clipboard and do something with it
//-----essentially the acceptDrag will be set to true here
if((_isDragAccepted = acceptDrag))
{
event.acceptTransferModes(TransferMode.MOVE);
//event.consume();
}
}
@FXML
public void onDragOver(DragEvent event)
{
if(_isDragAccepted)
{
event.acceptTransferModes(TransferMode.MOVE);
//event.consume();
}
}
@FXML
public void onDragExited(DragEvent event)
{
_isDragAccepted = false;
//event.consume();
}
@SuppressWarnings("unchecked")
@FXML
public void onDragDropped(DragEvent event)
{
Dragboard dragboard = event.getDragboard();
TreeItem<Base> currentItem = getTreeCell().getTreeItem();
Base current = getTreeCell().getItem();
//-----get info from clipboard again and do the necessary stuff
//-----essentially an item will be transfered here from one node to another
event.setDropCompleted(true);
//event.consume();
}
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.DragEvent;
import com.sun.javafx.scene.control.skin.VirtualFlow;
@SuppressWarnings("restriction")
public class AutoscrollTreeView<T> extends TreeView<T>
{
// region Enumerations
private enum ScrollDirection
{
None, Top, Bottom
}
// endregion
// region Static
private static final double _milliSecondToSecondFactor = 1.0d / 1000.0d;
// endregion
// region Fields
/**
* the time interval in milliseconds in which the scroll is performed
*/
private final LongProperty _checkInterval = new SimpleLongProperty(50);
/**
* the actual scroll speed when being in the scroll areas
*/
private final DoubleProperty _scrollSpeed = new SimpleDoubleProperty(1.0);
/**
* the scroll speed increment per second the user remain in the scroll area
*/
private final DoubleProperty _scrollSpeedIncrementPerSecond = new SimpleDoubleProperty(0.0);
/**
* distance from the top, which defines the area which will start a scroll in the -y axis
*/
private final DoubleProperty _dragIdentifierTop = new SimpleDoubleProperty();
/**
* distance from the bottom, which defines the area which will start a scroll in the +y axis
*/
private final DoubleProperty _dragIdentifierBottom = new SimpleDoubleProperty();
/**
* time at which the user entered the any scroll area
*/
private long _initialDragTime = -1;
/**
* last time the interval was checked
*/
private long _lastCheck = -1;
// endregion
// region Constructor
public AutoscrollTreeView()
{
super();
addEventHandlers();
}
public AutoscrollTreeView(TreeItem<T> root)
{
super(root);
addEventHandlers();
}
// endregion
// region Getter/Setter
public final void setCheckInterval(long value)
{
_checkInterval.set(value);
}
public final long getCheckInterval()
{
return _checkInterval.get();
}
public final LongProperty checkIntervalProperty()
{
return _checkInterval;
}
public final void setScrollSpeed(double value)
{
_scrollSpeed.set(value);
}
public final double getScrollSpeed()
{
return _scrollSpeed.get();
}
public final DoubleProperty scrollSpeedProperty()
{
return _scrollSpeed;
}
public final void setScrollSpeedIncrementPerSecond(double value)
{
_scrollSpeedIncrementPerSecond.set(value);
}
public final double getScrollSpeedIncrementPerSecond()
{
return _scrollSpeedIncrementPerSecond.get();
}
public final DoubleProperty scrollSpeedIncrementPerSecondProperty()
{
return _scrollSpeedIncrementPerSecond;
}
public final void setDragIdentiferTop(double value)
{
_dragIdentifierTop.set(value);
}
public final double getDragIdentifierTop()
{
return _dragIdentifierTop.get();
}
public final DoubleProperty dragIdentifierTopProperty()
{
return _dragIdentifierTop;
}
public final void setDragIdentiferBottom(double value)
{
_dragIdentifierBottom.set(value);
}
public final double getDragIdentifierBottom()
{
return _dragIdentifierBottom.get();
}
public final DoubleProperty dragIdentifierBottomProperty()
{
return _dragIdentifierBottom;
}
// endregion
// region Events
private void onDragEvent(DragEvent event)
{
// -----only apply when there is a drag event in progress
if(event.getEventType().equals(DragEvent.DRAG_OVER))
{
if(_lastCheck == -1 || System.currentTimeMillis() - _lastCheck > _checkInterval.get())
{
ScrollDirection direction = ScrollDirection.None;
if(event.getY() <= _dragIdentifierTop.get())
direction = ScrollDirection.Top;
else if(event.getY() >= getHeight() - _dragIdentifierBottom.get())
direction = ScrollDirection.Bottom;
if(direction != ScrollDirection.None)
{
double additionalScrollSpeed = 0;
if(_initialDragTime > 0)
additionalScrollSpeed = _scrollSpeedIncrementPerSecond.get() * (System.currentTimeMillis() - _initialDragTime) * _milliSecondToSecondFactor;
else
_initialDragTime = System.currentTimeMillis();
if(direction == ScrollDirection.Bottom)
scrollY(_scrollSpeed.get() + additionalScrollSpeed);
else
scrollY(-(_scrollSpeed.get() + additionalScrollSpeed));
}
else
{
_initialDragTime = -1;
}
_lastCheck = System.currentTimeMillis();
}
}
else
{
_initialDragTime = -1;
_lastCheck = -1;
}
}
// endregion
// region Private
/**
* adds the necessary event filters
*/
private void addEventHandlers()
{
addEventHandler(DragEvent.DRAG_OVER, event -> onDragEvent(event));
addEventHandler(DragEvent.DRAG_EXITED, event -> onDragEvent(event));
addEventHandler(DragEvent.DRAG_DROPPED, event -> onDragEvent(event));
addEventHandler(DragEvent.DRAG_DONE, event -> onDragEvent(event));
}
private void scrollY(double offset)
{
VirtualFlow<?> flow = ((VirtualFlow<?>) lookup("VirtualFlow"));
flow.adjustPixels(offset);
}
// endregion
}