Découpe Circulaire JavaFX


Je développe une application de bureau JavaFX et je voudrais superposer une fenêtre circulaire sur un autre panneau.

Voici une image très simple représentant ce que je veux, la zone blanche serait transparente et montrant le panneau sous-jacent. La zone noire serait de couleur unie et empêcherait les événements de la souris de se déclencher sur le panneau sous-jacent.

Exemple

J'ai examiné l'utilisation d'un Canevas avec un écouteur d'événements attaché qui ignore tous les événements dans le circles radius mais je me demande s'il existe une méthode plus efficace / moins hacky pour le faire?

Merci d'avance.

Author: Fooble, 2018-04-30

1 answers

Définir le cas échéant Shape sur l'clip la propriété de l'avant Node.

Javadoc de la propriété clip:

Spécifie un nœud à utiliser pour définir la forme d'écrêtage de ce Nœud. Ce nœud d'écrêtage n'est pas un enfant de ce nœud dans le sens du graphique de scène. Il est plutôt utilisé pour définir le clip pour ce nœud.

Par exemple, vous pouvez utiliser un nœud ImageView comme masque pour représenter le Clip. Ou vous pouvez utiliser l'un des nœuds de forme géométrique comme le rectangle ou le cercle. Ou vous pouvez utiliser un nœud de texte pour représenter le clip.

Voir la documentation de classe pour Node pour les restrictions de structure de graphique de scène sur la définition du clip. Si ces restrictions sont violées par une modification de la variable clip, la modification est ignorée et la valeur précédente de la variable clip est restaurée.

Notez qu'il s'agit d'une caractéristique conditionnelle. Voir ConditionalFeature.SHAPE_CLIP pour plus d'informations.

Il y a un connu limitation du clip de mixage avec une transformation 3D. L'écrêtage est essentiellement une opération d'image 2D. Le résultat d'un Clip défini sur un nœud de groupe avec des enfants transformés en 3D entraînera le rendu de ses enfants dans l'ordre sans mise en mémoire tampon Z appliquée entre ces enfants.

Quoi qu'il en soit, vous pouvez utiliser un Rectangle qui est de la même taille que le Node. Ensuite, créez un Circle centré sur le Rectangle avec le rayon souhaité. À partir de ces deux formes, créez une nouvelle forme en utilisant Shape.subtract(rectangle, circle);. Cela va créer un "trou" au milieu du Rectangle qui montrera tout Node sous-jacent.

Exemple de code:

private void setClipViewport(Region region) {
    int width = region.getWidth();
    int height = region.getHeight();

    Rectangle rect = new Rectangle(0, 0, width, height);
    Circle circ = new Circle(width / 2, height / 2, Math.min(width, height) / 2);

    Shape clip = Shape.subtract(rect, circ);

    region.setClip(clip);
}

Mon exemple ne redimensionne pas le clip si nécessaire, cependant. Donc, si votre interface utilisateur peut redimensionner, vous devrez ajouter ce comportement.

 2
Author: Slaw, 2018-04-30 05:45:46