2017-06-27 4 views
1

Nous avons besoin d'un «nœud principal» qui, lorsque la souris se trouve à l'intérieur de celui-ci, un autre nœud («nœud contextuel de survol») apparaît dans la scène. Lorsque la souris sort du "Node principal", le "Nœud popup hover" disparaît. De plus, le "Node principal" a un "Node interne" dans lequel lorsque vous cliquez dessus, un autre Node ("Click popup Node") apparaît dans la Scene et si vous cliquez à nouveau, le "Click popup Node" disparaît. Le problème que nous avons est que, lorsque la souris plane à l'intérieur du "nœud interne", le "hover popup Node" disparaît que nous ne voulons pas. Nous voulons seulement que le "Nœud popup hover" disparaisse lorsque la souris passe à l'extérieur du "Node principal". c'est-à-dire lorsque la souris se trouve à l'intérieur du "nœud interne", nous voulons toujours que le "nœud de survol spatial" soit visible.Événements de souris à volets multiples

Voir exemple de code:

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class MultiPaneMouseTest extends Application { 

    private Rectangle hoverPopupNode; 
    private Rectangle clickPopupNode; 

    @Override 
    public void init() throws Exception { 
     super.init(); 
    } 

    @Override 
    public void start(Stage primaryStage) { 

     BorderPane borderPane = new BorderPane(); 

     Rectangle mainNode = new Rectangle(200, 100); 
     mainNode.setArcWidth(6); 
     mainNode.setArcHeight(6); 
     mainNode.setFill(Color.web("0x00ff00")); 
     mainNode.setOnMouseEntered(e -> { 
      System.out.println("mouse entered " + e); 
      hoverPopupNode.setVisible(true); 
     }); 
     mainNode.setOnMouseExited(e -> { 
      System.out.println("mouse exited " + e); 
      hoverPopupNode.setVisible(false); 
     }); 

     Rectangle innerNode = new Rectangle(50, 25); 
     innerNode.setArcWidth(6); 
     innerNode.setArcHeight(6); 
     innerNode.setFill(Color.web("0xffffff")); 
     innerNode.setOnMouseClicked(e -> { 
      System.out.println("mouse clicked " + e); 
      clickPopupNode.setVisible(!clickPopupNode.isVisible()); 
     }); 

     hoverPopupNode = new Rectangle(100, 100); 
     hoverPopupNode.setArcWidth(6); 
     hoverPopupNode.setArcHeight(6); 
     hoverPopupNode.setFill(Color.web("0x0000ff")); 
     hoverPopupNode.setVisible(false); 
     borderPane.setRight(hoverPopupNode); 

     clickPopupNode = new Rectangle(100, 100); 
     clickPopupNode.setArcWidth(6); 
     clickPopupNode.setArcHeight(6); 
     clickPopupNode.setFill(Color.web("0xff0000")); 
     clickPopupNode.setVisible(false); 
     borderPane.setLeft(clickPopupNode); 


     StackPane stackPane = new StackPane(); 
     stackPane.getChildren().add(mainNode); 
     stackPane.getChildren().add(innerNode); 
     borderPane.setCenter(stackPane); 

     Scene scene = new Scene(borderPane); 

     primaryStage.setTitle("Sample Test"); 
     primaryStage.setScene(scene); 
     primaryStage.setX(500.0); 
     primaryStage.setY(500.0); 
     primaryStage.setWidth(500.0); 
     primaryStage.setHeight(500.0); 
     primaryStage.show(); 
    } 

    @Override 
    public void stop() throws Exception { 
     super.stop(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

Si je comprends bien, une solution, peut-être pas le meilleur, est d'attacher au noeud intérieur un événement 'onmouseentered': dans celui-ci vous définissez, sinon défini, la propriété' visible' du hoverpopupnode. –

+0

@MarcoLuzzara, cela fonctionnerait assez bien dans cet échantillon mais pas dans notre application actuelle. Dans notre application, le nœud interne n'a pas d'accès direct au nœud contextuel du vol stationnaire assoacié du nœud principal. –

Répondre

1

Faites le mainNode un Pane (ou sous-classe appropriée) et ajouter le innerNode à lui comme un nœud enfant. S'il existe une relation parent-enfant entre mainNode et childNode, la souris sera toujours considérée comme planant au-dessus de mainNode lorsqu'elle est au-dessus de innerNode. Vous pouvez définir l'arrière-plan d'un Pane (ou de n'importe quelle région) pour obtenir les mêmes effets de remplissage et de rayon d'angle que sur le Rectangle.

import javafx.application.Application; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.layout.Background; 
import javafx.scene.layout.BackgroundFill; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.CornerRadii; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class MultiPaneMouseTest extends Application { 

    private Rectangle hoverPopupNode; 
    private Rectangle clickPopupNode; 

    @Override 
    public void init() throws Exception { 
     super.init(); 
    } 

    @Override 
    public void start(Stage primaryStage) { 

     BorderPane borderPane = new BorderPane(); 

     StackPane mainNode = new StackPane(); 
     mainNode.setMinSize(200, 100); 
     mainNode.setMaxSize(200, 100); 

     mainNode.setBackground(new Background(new BackgroundFill(Color.web("0x00ff00"), new CornerRadii(6), Insets.EMPTY))); 

     // note you can replace these listeners with 
     // hoverPopupNode.visibleProperty().bind(mainNode.hoverProperty()); 
     // (but obviously after the hoverPopupNode has been instantiated) 

     mainNode.setOnMouseEntered(e -> { 
      System.out.println("mouse entered " + e); 
      hoverPopupNode.setVisible(true); 
     }); 
     mainNode.setOnMouseExited(e -> { 
      System.out.println("mouse exited " + e); 
      hoverPopupNode.setVisible(false); 
     }); 

     Rectangle innerNode = new Rectangle(50, 25); 
     innerNode.setArcWidth(6); 
     innerNode.setArcHeight(6); 
     innerNode.setFill(Color.web("0xffffff")); 
     innerNode.setOnMouseClicked(e -> { 
      System.out.println("mouse clicked " + e); 
      clickPopupNode.setVisible(!clickPopupNode.isVisible()); 
     }); 

     mainNode.getChildren().add(innerNode); 

     hoverPopupNode = new Rectangle(100, 100); 
     hoverPopupNode.setArcWidth(6); 
     hoverPopupNode.setArcHeight(6); 
     hoverPopupNode.setFill(Color.web("0x0000ff")); 
     hoverPopupNode.setVisible(false); 
     borderPane.setRight(hoverPopupNode); 

     clickPopupNode = new Rectangle(100, 100); 
     clickPopupNode.setArcWidth(6); 
     clickPopupNode.setArcHeight(6); 
     clickPopupNode.setFill(Color.web("0xff0000")); 
     clickPopupNode.setVisible(false); 
     borderPane.setLeft(clickPopupNode); 


     StackPane stackPane = new StackPane(); 
     stackPane.getChildren().add(mainNode); 

     borderPane.setCenter(stackPane); 

     Scene scene = new Scene(borderPane); 

     primaryStage.setTitle("Sample Test"); 
     primaryStage.setScene(scene); 
     primaryStage.setX(500.0); 
     primaryStage.setY(500.0); 
     primaryStage.setWidth(500.0); 
     primaryStage.setHeight(500.0); 
     primaryStage.show(); 
    } 

    @Override 
    public void stop() throws Exception { 
     super.stop(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
}