我是JavaFX动画的新手。我正在尝试将代码作为另一个大项目的试验; 基本上我想用鼠标拖动移动圆圈, 当圆圈在矩形上方时,突出显示矩形。 如果将圆圈拖放到矩形上,请将其颜色更改为圆形的颜色。
到目前为止,我已经设法用鼠标移动圆圈,但我不确定为什么矩形的OnDragEntered方法什么都不做。
这是FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="com.sc.colordx.controller.D15Controller">
<children>
<Rectangle fx:id="r1" arcHeight="5.0" arcWidth="5.0" fill="WHITE" height="152.0" layoutX="33.0" layoutY="14.0" onDragDropped="#fillBox" onDragEntered="#highlightBox" pickOnBounds="true" stroke="BLACK" strokeType="INSIDE" width="52.5" />
<Rectangle fx:id="r2" arcHeight="5.0" arcWidth="5.0" fill="WHITE" height="152.0" layoutX="91.0" layoutY="14.0" onDragDropped="#fillBox" onDragEntered="#highlightBox" stroke="BLACK" strokeType="INSIDE" width="52.5" />
<Circle fx:id="c1" fill="DODGERBLUE" layoutX="348.0" layoutY="262.0" onDragDetected="#startDrag" onMouseDragged="#moveCircle" onMouseReleased="#removeBind" radius="54.5" stroke="BLACK" strokeType="INSIDE" />
<Circle id="c1" fx:id="c2" fill="#ff3d00" layoutX="217.0" layoutY="262.0" onDragDetected="#startDrag" onMouseDragged="#moveCircle" onMouseReleased="#removeBind" radius="54.5" stroke="BLACK" strokeType="INSIDE" />
</children>
</AnchorPane>
这是控制器:
package com.sc.colordx.controller;
import java.awt.Point;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.animation.TranslateTransition;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.input.DragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;
public class D15Controller implements Initializable {
@FXML
private Circle c1;
@FXML
private Rectangle r1;
// Animation Data
private static final Duration TRANSLATE_DURATION = Duration.seconds(0.25);
private TranslateTransition transition;
@FXML
private Circle c2;
@FXML
private Rectangle r2;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb)
{
// TODO
transition = createTranslateTransition(c1);
}
private TranslateTransition createTranslateTransition(final Circle circle) {
final TranslateTransition transition = new TranslateTransition(TRANSLATE_DURATION, circle);
return transition;
}
@FXML
private void removeBind(MouseEvent event)
{
if(event.getSource() instanceof Circle)
{
Circle circle = (Circle)event.getSource();
circle.setOpacity(1);
}
}
private void fillBox(DragEvent event)
{
System.out.println("Drag detected");
if(event.getGestureTarget() instanceof Rectangle)
{
Rectangle target=(Rectangle)event.getGestureTarget();
Circle source=(Circle)event.getGestureSource();
target.setFill(source.getFill());
}
}
@FXML
private void moveCircle(MouseEvent event)
{
Circle circle=null;
event.setDragDetect(true);
if(event.getSource() instanceof Circle)
{
circle=(Circle)event.getSource();
circle.setOpacity(0.25);
if (!event.isControlDown())
{
circle.setCenterX(event.getX());
circle.setCenterY(event.getY());
}
else
{
transition.setToX(circle.getCenterX());
transition.setToY(circle.getCenterY());
transition.playFromStart();
}
}
}
@FXML
private void startDrag(MouseEvent event)
{
if(event.getSource() instanceof Circle)
{
Circle source=(Circle)event.getSource();
source.startFullDrag();
}
}
@FXML
private void highlightBox(DragEvent event)
{
System.out.println("Highlight box");
if(event.getGestureSource() instanceof Circle)
{
Circle source=(Circle)event.getGestureSource();
Rectangle target=(Rectangle)event.getGestureTarget();
target.setFill(source.getFill());
}
}
}
这是正确的做法吗?或者我错误地混合了拖动和放大器放下动画? 对于那些想要使用它的人来说,它是实施色盲测试的开始。
答案 0 :(得分:9)
我很久以前就发现了这个问题。但是没有时间在这里更新答案。虽然我必须说缺乏单一的回应令人惊讶。
moveCircle()方法中必须存在以下行:
1. circle.setMouseTransparent(true);
确保圆形下的节点可以在拖动鼠标时检测拖动。
2. event.consume();
确保消耗此事件,并且可以跟踪拖动检测事件。 highlightbox方法应包含:
event.acceptTransferModes(TransferMode.ANY);
我已经使用自定义事件处理程序完成了任务,而不是上面提到的那些因此我没有粘贴整个代码。