2

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.

enter image description here

=========================================================================== 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?

Philip Vaughn
  • 606
  • 6
  • 20
  • Did you try a `StackPane` with a background image similar to this? – SedJ601 Nov 16 '17 at 22:54
  • I haven't tested this, but it may be worth looking at: https://github.com/Elltz/ChatBubble/tree/master/ChatBubbleLib/Src/rumorsapp – SedJ601 Nov 16 '17 at 22:56
  • Did you figure it out Philip? I'm aiming for a similar outcome – DarkMental Jan 10 '18 at 15:03
  • @JawnyThompson if you're talking about getting the panel itself then yes. The SVG Path I ended up going with is just under the "EDIT" section. As far as the tail growing with the height of the box NO is the answer. Not quite sure how to solve this one as this popup is actually for a game and the text box can be any height (determined by how much text is displayed). This height slightly moves the arrow because of the slant but whatever I suppose. – Philip Vaughn Jan 10 '18 at 17:26
  • 1
    @JawnyThompson I wrote that SVG Path myself and it places the arrow in the lower left corner of the popup. – Philip Vaughn Jan 10 '18 at 17:27
  • @PhilipVaughn Alright thanks a lot! – DarkMental Jan 13 '18 at 02:48

1 Answers1

3

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.

hello, world

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.

jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • I'm sorry for the confusion on the shape I actually forgot to put that. Basically just a rectangle with rounded corners. The "pointer" on the bottom left. I figured that it'd be easiest to use -fx-shape but I'm really not very familiar with svg pathing (never really needed to learn it to be honest). – Philip Vaughn Nov 17 '17 at 00:01
  • Your answer sent me in the right direction. I downloaded several files from iconmonstr and also used your snippet of code in a test project to get the shape correct. I did still have an issue though if you could check the end of my original post. – Philip Vaughn Nov 17 '17 at 06:03
  • I'm not an expert of svg paths, but there will be others on StackOverflow who are. I suggest you ask a separate specific question regarding the exact svg path specification, and tag it [svg](https://stackoverflow.com/questions/tagged/svg). – jewelsea Nov 17 '17 at 07:46