【问题标题】:Pane Shape Modification窗格形状修改
【发布时间】:2017-11-16 22:47:12
【问题描述】:

好吧,长话短说,我正在尝试创建一种聊天/消息系统,需要一点帮助。我正在尝试在我的容器上创建一个箭头,如下图所示。图像是从 ControlsFX 和它们的 PopOver 窗口中取出的。我不能使用他们的弹出窗口小部件,因为它的行为与我使用它的目的有点不符。

我继续创建了我自己的小聊天窗口弹出窗口,它将自己定位在我定义的父对象上,但我真的希望它有一个指向该对象的箭头。箭头也总是面朝下,应该在弹出窗口的左下角。

还应该注意,弹出窗口不是一个窗口,它是一个简单的 VBox,其中填充了文本行。如果需要,我当然可以将其包装在窗格中。谁能想出正确的方法来创建这个箭头?我的 VBox 背景也作为渐变,因此箭头不能像通过 getChildren().add 与“相同颜色”一样放在底部,因为这样渐变就会关闭。它必须(以某种方式)成为容器的一部分。

================================================ ============================== 编辑:

好的,所以我今天大部分时间都在学习 SVG 路径,这并不太复杂,但有点乏味。我最终选择的路径是:

"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"

现在唯一的问题是箭头尾部的高度随着窗格的大小而增长。例如,如果我在框中有很多文本,则窗格的高度会增加(当然)并且箭头也会变长。这种行为并不是一个彻底的交易破坏者,但它并不是我真正想要的。我希望路径中的大写 Ls 确保箭头的点无论如何都保持不变,但它不起作用。对此有什么想法吗?

【问题讨论】:

  • 你试过StackPane 有类似这样的背景图片吗?
  • 我没有测试过这个,但它可能值得一看:github.com/Elltz/ChatBubble/tree/master/ChatBubbleLib/Src/…
  • 你发现菲利普了吗?我的目标是类似的结果
  • @JawnyThompson 如果您正在谈论获取面板本身,那么是的。我最终使用的 SVG 路径就在“编辑”部分的下方。至于尾巴随着盒子的高度而增长,答案是NO。不太确定如何解决这个问题,因为此弹出窗口实际上是针对游戏的,并且文本框可以是任意高度(由显示的文本量决定)。由于倾斜,这个高度略微移动了箭头,但不管我想什么。
  • @JawnyThompson 我自己写了那个 SVG 路径,它把箭头放在弹出窗口的左下角。

标签: java javafx javafx-8 javafx-2 javafx-css


【解决方案1】:

有多种方法可以达到您想要的效果。 一种方法是在区域上使用 CSS -fx-shape 属性规范。请参阅JavaFX CSS reference 了解有关此设置以及如何使用它的信息。

下面的示例使用内联样式,但对于更易于维护和实质性的应用程序,请使用外部 CSS 样式表。

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);
    }
}

我意识到在这个应用程序中演示的气泡形状并不是您想要的形状,但我从您的描述中不明白您想要的形状是什么。 iconmonstr.com 已经创建了许多气泡形状,您可以使用它的界面来搜索气泡并选择您想要的形状,或者如果您有工具(例如 Inkscape),您可以为您的自定义形状定义自己的 svg 路径) 和技能。要从现有的 svg 文件中提取 svg 路径,请打开 svg 文件,希望它以紧凑的路径字符串格式编码,如果是,只需将 svg 中的路径部分复制并粘贴到您的 JavaFX css 文件中。


执行此操作的另一种方法是以编程方式构造一个 path,您可以通过将两者放在 StackPane 中来与内容分层。

【讨论】:

  • 我很抱歉我实际上忘了把那个形状混淆了。基本上只是一个带圆角的矩形。左下角的“指针”。我认为使用 -fx-shape 最简单,但我对 svg 路径真的不是很熟悉(老实说,从来不需要学习它)。
  • 您的回答让我朝着正确的方向前进。我从 iconmonstr 下载了几个文件,并在测试项目中使用了你的 sn-p 代码来获得正确的形状。不过,如果您可以查看我原始帖子的结尾,我确实仍有问题。
  • 我不是 svg 路径专家,但 StackOverflow 上会有其他人是。我建议您针对确切的 svg 路径规范提出一个单独的具体问题,并将其标记为svg。
猜你喜欢
  • 2010-11-16
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多