有没有办法检测多个节点上的同一事件?

问题描述 投票:0回答:1

我正在研究一种元素周期表,有一个事件最终,当您将鼠标悬停时,会在所述元素上放大一点并显示更多信息,问题是它并没有真正做到这一点工作很好。可以说是跟踪,因为如果鼠标移动得有点快,或者很快离开位于边缘的面板,它就不会检测到鼠标的退出。 这是鼠标进入或退出时应执行的动画代码:

public void onScale(int i){
    double currentScaleX = Panes[i].getScaleX();
    double currentScaleY = Panes[i].getScaleY();//stores the current scale
    
    if (currentScaleX == 1.0 && currentScaleY == 1.0) {//verify that said scale is the original (equal to 1)
      

        TranslateTransition translate = new TranslateTransition(Duration.millis(50), Symbol[i]);
        translate.setToY(-4);
        translate.playFromStart();//move the symbol up a little

        TranslateTransition tratn = new TranslateTransition(Duration.millis(50), AtomicNumber[i]);
        tratn.setToY(-2);
        tratn.playFromStart();

        TranslateTransition tratm = new TranslateTransition(Duration.millis(50), AtomicMass[i]);
        tratm.setToY(-2);
        tratm.playFromStart();

        TranslateTransition trnm = new TranslateTransition(Duration.millis(50), Name[i]);
        trnm.setToY(3);
        trnm.playFromStart();
        
        AtomicMass[i].setVisible(true);
        OxidationNumber[i].setVisible(true);//makes the atomic mass and oxidation number visible
        
        ScaleTransition scale = new ScaleTransition(Duration.millis(100), Panes[i]);
        scale.setToX(1.5);
        scale.setToY(1.5);
        scale.playFromStart();
        //The panel is brought to the foreground, (note that this will not affect its position in the childlist unlike the .tofront method)
        Panes[i].setViewOrder(-1.0);
        Panes[i].getParent().setViewOrder(-1.0);
        
        
        
    }
}

public void offScale(int i){
    double currentScaleX = Panes[i].getScaleX();
    double currentScaleY = Panes[i].getScaleY();
    
    if (currentScaleX > 1.0 && currentScaleY > 1.0) {
        
        TranslateTransition translate = new TranslateTransition(Duration.millis(50), Symbol[i]);
        translate.setToY(0);
        translate.playFromStart();

        TranslateTransition tratn = new TranslateTransition(Duration.millis(50), AtomicNumber[i]);
        tratn.setToY(0);
        tratn.playFromStart();

        TranslateTransition tratm = new TranslateTransition(Duration.millis(50), AtomicMass[i]);
        tratm.setToY(0);
        tratm.playFromStart();
        
        TranslateTransition trnm = new TranslateTransition(Duration.millis(50), Name[i]);
        trnm.setToY(0);
        trnm.playFromStart();

        AtomicMass[i].setVisible(false);
        OxidationNumber[i].setVisible(false);
        
        ScaleTransition scale = new ScaleTransition(Duration.millis(100), Panes[i]);
        scale.setToX(1.0);
        scale.setToY(1.0);
        scale.playFromStart();
        Panes[i].setViewOrder(0.0);
        Panes[i].getParent().setViewOrder(0.0);
    }
    
}

那么,你有什么建议吗?我正在使用窗格向量。 PS:我现在用来完成类似工作的方法是创建另一个方法,稍后在初始化整个表的另一个方法中调用该方法。 调用动画的方法:

    @FXML
private void MouseEntered(MouseEvent event) {
    Pane pane = (Pane) event.getSource();//creates a local variable based on the pane
    onScale(Integer.parseInt(pane.getId()));
    for(int i=1; i<=118; i++){
        offScale(i);
    }
}

@FXML
private void MouseExited(MouseEvent event) {
    Pane pane = (Pane) event.getSource();
    offScale(Integer.parseInt(pane.getId()));
    
}

在初始化方法的一部分中有一个循环,它分配如下事件:

    Panes[i].setOnMouseEntered(this::MouseEntered);
    Panes[i].setOnMouseExited(this::MouseExited);
java javafx fxml
1个回答
0
投票

MOUSE_ENTERED
MOUSE_EXITED
事件应该始终被传递,无论您移动鼠标的速度如何或鼠标是否离开整个窗口。您没有提供一个最小的、完整的示例,所以我不能绝对确定问题是什么。然而,我相信问题是你正在为每个“方向”创建两个单独的动画。这意味着“按比例”动画可以与“非比例”动画并行运行,从而导致结果不一致。您应该使用单个动画并操纵其
rate
属性。如果您希望多个动画并行运行,我还建议您使用
ParallelTransition
,而不是单独播放每个动画。

例如:

import javafx.animation.Animation;
import javafx.animation.FadeTransition;
import javafx.animation.ParallelTransition;
import javafx.animation.ScaleTransition;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

    private static final int ROWS = 5;
    private static final int COLUMNS = 5;

    @Override
    public void start(Stage primaryStage) throws Exception {
        var root = new GridPane();
        root.setPadding(new Insets(30));
        root.setHgap(5);
        root.setVgap(5);
        root.setAlignment(Pos.CENTER);

        for (int row = 0; row < ROWS; row++) {
            for (int col = 0; col < COLUMNS; col++) {
                int index = row * COLUMNS + col;
                var cell = createCell(index);
                root.add(cell, col, row);
            }
        }

        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

    private Node createCell(int index) {
        var square = new Rectangle(75, 75, Color.WHITE);
        square.setStroke(Color.BLACK);
        square.setStrokeWidth(1);

        var indexLabel = new Label(Integer.toString(index));

        var moreInfoLabel = new Label("More info!");
        moreInfoLabel.setOpacity(0);

        var cell = new StackPane(square, indexLabel, moreInfoLabel);
        installAnimations(indexLabel, moreInfoLabel, cell);
        return cell;
    }

    private void installAnimations(Label indexLabel, Label moreInfoLabel, Node cell) {
        var animation = new ParallelTransition(
                createToCornerAnimation(indexLabel),
                createFadeInAndOutAnimation(moreInfoLabel),
                createScaleAnimation(cell));

        animation.setOnFinished(e -> cell.setViewOrder(cell.isHover() ? -2 : 0));
        cell.setOnMouseEntered(e -> {
            e.consume();
            cell.setViewOrder(-1);
            animation.setRate(1); // forward
            animation.play();
        });
        cell.setOnMouseExited(e -> {
            e.consume();
            cell.setViewOrder(-1);
            animation.setRate(-1); // reverse
            animation.play();
        });
    }

    private Animation createToCornerAnimation(Node node) {
        var animation = new TranslateTransition(Duration.millis(250), node);
        animation.setFromX(0);
        animation.setFromY(0);
        animation.toXProperty().bind(node.layoutXProperty().negate().add(5));
        animation.toYProperty().bind(node.layoutYProperty().negate().add(5));
        return animation;
    }

    private Animation createFadeInAndOutAnimation(Node node) {
        var animation = new FadeTransition(Duration.millis(250), node);
        animation.setFromValue(0);
        animation.setToValue(1);
        return animation;
    }

    private Animation createScaleAnimation(Node node) {
        var animation = new ScaleTransition(Duration.millis(250), node);
        animation.setFromX(1.0);
        animation.setFromY(1.0);
        animation.setToX(1.5);
        animation.setToY(1.5);
        return animation;
    }
}

输出:

© www.soinside.com 2019 - 2024. All rights reserved.