【问题标题】:How can I "highlight" or put a border around a JavaFX 8 Canvas?如何“突出显示”或在 JavaFX 8 画布周围设置边框?
【发布时间】:2015-05-05 13:35:24
【问题描述】:

我正在尝试为 Image Viewer 桌面产品组合一个简单的 POC。我的查看器需要支持注释,因此我决定尝试使用我正在查看的图像的主画布,然后使用较小的画布对象来放置注释。

注释需要能够被拖动、删除、重新排序等。

但是,要显示选择了哪个画布,我需要突出显示它,或者在其上放置阴影,或者在其周围加上边框。

我看不到可以在其中应用的 CSS 样式。我已经将它包装在一个 HBox 中以模拟效果,但我想知道是否有其他方式?

谢谢!

【问题讨论】:

    标签: canvas javafx-8


    【解决方案1】:

    CanvasNode 的直接子类,因此它只支持为Node 定义的CSS 属性。这些不包括应用边框的标准方法,例如-fx-background-color-fx-border-color

    但是,Node 支持 -fx-effect 属性,因此您可以使用它。这是一个使用内联样式的“简单粗暴”的示例(在实际应用中,我建议使用外部样式表;也许,根据您的要求,子类化 Canvas 以提供“选择”行为):

    import javafx.application.Application;
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.scene.Scene;
    import javafx.scene.canvas.Canvas;
    import javafx.scene.canvas.GraphicsContext;
    import javafx.scene.layout.HBox;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    
    public class CanvasCSSEffect extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            Canvas canvas1 = new Canvas(400, 400);
            Canvas canvas2 = new Canvas(400, 400);
    
            GraphicsContext gc1 = canvas1.getGraphicsContext2D();
            gc1.setFill(Color.CORNSILK);
            gc1.fillRect(0, 0, 400, 400);
    
            GraphicsContext gc2 = canvas2.getGraphicsContext2D();
            gc2.setFill(Color.ANTIQUEWHITE);
            gc2.fillRect(0, 0, 400, 400);
    
            ObjectProperty<Canvas> selectedCanvas = new SimpleObjectProperty<>();
            selectedCanvas.addListener((obs, oldCanvas, newCanvas) -> {
                if (oldCanvas != null) {
                    oldCanvas.setStyle("");
                }
                if (newCanvas != null) {
                    newCanvas.setStyle("-fx-effect: innershadow(gaussian, #039ed3, 10, 1.0, 0, 0);");
                }
            });
    
            canvas1.setOnMouseClicked(e -> selectedCanvas.set(canvas1));
            canvas2.setOnMouseClicked(e -> selectedCanvas.set(canvas2));
    
            HBox root = new HBox(10, canvas1, canvas2);
            primaryStage.setScene(new Scene(root));
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    【讨论】:

    • 当我尝试您的示例时,它按预期在画布周围放置了一个框。当我将它应用到我的画布上时,它上面只有文本并且是透明的,它改变了文本颜色。有没有办法让它在只有文本的画布上执行与您的示例相同的操作?
    • 嗯,这不是很有趣吗...我需要再尝试一下。我猜这个效果是应用于第一个不透明的像素,或者一些这样的算法。除非您可以使用基色填充画布,否则您可能不得不使用 Pane 包裹。
    • 我已经能够模仿在它周围使用 HBox 来满足我的需要。选择让我感到悲伤。如果我添加一个新类来处理 selectionHandler,(只是扩展窗格)我不能在场景构建器中使用它。但它有功能。
    • 当我回到电脑前时,我会更新一个对 FXML 友好的类来管理选择。你需要多选吗(如果不需要,支持 ToggleGroup 是一个很好的方法......)
    • 我在这里发布了关于该主题的另一个问题:stackoverflow.com/questions/30063792/…,我只需要选择突出显示的节点并取消选择当前选择的任何节点。这一切都有效,但与 SceneBuilder 的集成只是痛苦的。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    相关资源
    最近更新 更多