Pane Shape Modification

[亡魂溺海] 提交于 2019-12-08 03:30:47

问题


Ok so to make a long story short I'm trying to create a sort of chat/message system and need a small bit of assistance. I'm trying to create an arrow on my container as the one shown in the image below. The image is taken off of ControlsFX and from their PopOver window. I CANNOT use their popover widget because it behaves a little wonky with what I'm using it for.

I went ahead and created my own little chat window popup that positions itself over the parent object that I define but I would really like it to have an arrow pointing to the object. The arrow will also ALWAYS face down and should be in the lower left-hand corner of the popup.

It should also be noted that the popup is NOT a window its a simple VBox that populates with lines of text. I could of course wrap that in a Pane if its needed. Can anyone come up with the proper way to create this arrow? I have my VBox background as a gradient as well so the arrow can't just be like plopped on the bottom through getChildren().add with the "same color" because then the gradient would be off. It has to be (somehow) a part of the container.

=========================================================================== EDIT:

Alright so I spent the greater part of today learning SVG Pathing which isn't too awful complicated but it's slightly tedious. The path I ended up going with is:

"M30 0 h100 a6,6 0 0,1 6,6 v50 a6,6 0 0,1 -6,6 h-88 L38 68 L34 62 h-4 a6,6 0 
 0,1 -6,-6 v-50 a6,6 0 0,1 6,-6 z"

Now the only problem with this is the arrow tail height grows with the size of the pane. For instance if I have a LOT of text in the box the pane grows in height (of course) and the arrow gets longer too. This behavior isn't a total deal breaker but it's not really what I had intended. I expected the capital Ls in the pathing to make sure that the points of the arrow stay put no matter what but it didn't work. Any thoughts on this?


回答1:


There are a number of ways to achieve the effect which you wish. One way is to use a CSS -fx-shape attribute specification on a region. See the JavaFX CSS reference for info on this setting and how to use it.

The sample below uses inline styles, but for a more maintainable and substantial application use an external CSS stylesheet.

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Bubble extends Application {
    private static final String SQUARE_BUBBLE =
            "M24 1h-24v16.981h4v5.019l7-5.019h13z";
    // source for svg path string: https://iconmonstr.com/speech-bubble-7/
    private static final String ROUND_BUBBLE =
            "M12 1c-6.628 0-12 4.573-12 10.213 0 2.39.932 4.591 2.427 6.164l-2.427 5.623 7.563-2.26c9.495 2.598 16.437-3.251 16.437-9.527 0-5.64-5.372-10.213-12-10.213z";

    @Override
    public void start(Stage stage) {
        Label label = new Label("hello, world");
        label.setStyle("-fx-font-size: 16px;");

        StackPane bubble = new StackPane(label);
        bubble.setPadding(new Insets(20));
        bubble.setStyle(
            "-fx-background-color: lightblue; " +
            "-fx-border-color: navy; -fx-border-width: 2px; " + 
            "-fx-shape: \"" + ROUND_BUBBLE + "\";"
        );
        bubble.setEffect(new DropShadow(10, 5, 5, Color.MIDNIGHTBLUE));

        StackPane layout = new StackPane(bubble);
        layout.setPadding(new Insets(20));

        stage.setScene(new Scene(layout));
        stage.show();
    }

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

I realize that the bubble shape demoed in this application isn't exactly the shape which you want but I don't understand from your description what the shape you want is. There are numerous bubble shapes already created at iconmonstr.com, you can just use its interface to search for speech bubbles and select the shape you want, or you can define your own svg path for your custom shape if you have the tools (e.g. Inkscape) and skill for that. To extract the svg path from an existing svg file, open up the svg file, hope that it is encoded in a compact path string format, and if it is, just copy and paste the path part from the svg into your JavaFX css file.


Another way to do this would be to programmatically construct a path which you would layer with the content by placing both in a StackPane.



来源:https://stackoverflow.com/questions/47340418/pane-shape-modification

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!