将子项添加到JavaFX Control / Parent类

时间:2015-12-02 10:29:44

标签: java javafx

添加了以前在我所有子类中都可见的子节点,如此处的示例所示。

由于我最近做了一些更改(在非常旧的Java SWING代码的大量移植中),例如,TextFieldTextArea中的子项仍然可见,但Button中没有(ish)控件,即使添加内容在列表中。

显然,我并不了解有关增加子女的政策。有什么想法吗?

public class QButton extends Button  {
    ...
    public QButton(String str) {
        ...
        ObservableList<Node> children = getChildren();
        System.out.println("Children: " + children);

        Rectangle rect = new Rectangle(0., 0., 200., 200.);
        rect.setStroke(Color.RED);
        rect.setFill(Color.TRANSPARENT);
        rect.setStrokeWidth(2);
        getChildren().add(rect);
        rect.setVisible(true);

        children = getChildren();
        System.out.println("Children: " + children);
    }
    ...

1 个答案:

答案 0 :(得分:3)

在JavaFX中,UI控件使用MVC(模型/视图/控制器)模式。 Control本身(例如Button)是Model,渲染被委托给在JavaFX中称为Skin的View。 Control的节点图由View(Skin)维护,因此无法简单地修改Control的子节点。有关架构的详细概述,请参阅https://wiki.openjdk.java.net/display/OpenJFX/UI+Controls+Architecture

另一种方法可能是将ButtonRectangle放入Group,以便Rectangle覆盖Button,然后使用{ {1}}在应用程序的场景图中。

否则,如果您真的想要继承Group并在其中添加Button,则需要为Rectangle创建自定义外观。以下示例显示了如何完成此操作 - 一个缺点是Buttons(Button)的基础外观类不是公共的,因此您需要扩展非公共类(您通常不应该这样做,但是除了复制来自ButtonSkin的一大堆代码之外,我目前还没有看到其他选择。在Java 9中,皮肤类将在com.sun.javafx包中公开(请参阅 javafx.scene.control.skin的{​​{3}}。

以下代码显示了如何完成:

ButtonSkin

基本上,package com.example; import javafx.scene.control.Button; import javafx.scene.control.Skin; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; // DO NOT DO THIS - com.sun is not public! // (However, it seems that there is currently no alternative besides duplicating the code) // With Java 9, change to javafx.scene.control.skin.ButtonSkin class QButtonSkin extends com.sun.javafx.scene.control.skin.ButtonSkin { private Rectangle rect = null; public QButtonSkin(Button button) { super(button); } @Override protected void updateChildren() { super.updateChildren(); if (rect == null) { rect = new Rectangle(0., 0., 200., 200.); rect.setStroke(Color.RED); rect.setFill(Color.TRANSPARENT); rect.setStrokeWidth(2); } getChildren().add(rect); } } public class QButton extends Button { public QButton(String str) { super(str); } @Override protected Skin<?> createDefaultSkin() { Skin<?> result = new QButtonSkin(this); return result; } } 会创建一个新的默认外观(您也可以在CSS中执行此操作)。新的Skin覆盖QButton以将矩形添加到控件的子节点。这里我们需要考虑调用序列 - 超类的构造函数调用updateChildren()本身,因此我们无法在Skin的构造函数中创建updateChildren()

根据您的使用情况,您可能需要添加一些其他代码,例如管理Rectangle的边界和几何。