当前位置: 首页 > 知识库问答 >
问题:

SceneBuilder在用自定义控件加载FXML时显示布局失败(“null”)

逄嘉熙
2023-03-14
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
import javafx.beans.DefaultProperty;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.BooleanPropertyBase;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.StringPropertyBase;
import javafx.css.CssMetaData;
import javafx.css.PseudoClass;
import javafx.css.StyleConverter;
import javafx.css.Styleable;
import javafx.css.StyleableBooleanProperty;
import javafx.css.StyleableObjectProperty;
import javafx.css.StyleableProperty;
import javafx.geometry.Orientation;
import javafx.scene.AccessibleAction;
import javafx.scene.AccessibleAttribute;
import javafx.scene.Node;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import javafx.util.Duration;

@DefaultProperty("content")
public class ContentSection extends Control {

    public ContentSection() {
        getStyleClass().setAll(DEFAULT_STYLE_CLASS);

        // initialize pseudo-class state
        pseudoClassStateChanged(PSEUDO_CLASS_EXPANDED, true);
        pseudoClassStateChanged(PSEUDO_CLASS_COLLAPSED, false);
    }

    public ContentSection(final String title, final Node content) {
        this();
        setTitle(title);
        setContent(content);
    }

    private final StringProperty titleProperty = new StringPropertyBase() {
        @Override
        protected void invalidated() {
            notifyAccessibleAttributeChanged(AccessibleAttribute.TEXT);
        }

        @Override
        public Object getBean() {
            return ContentSection.this;
        }

        @Override
        public String getName() {
            return "title";
        };
    };

    public final void setTitle(final String value) {
        titleProperty().set(value);
    }

    public final String getTitle() {
        return titleProperty == null ? null : titleProperty.get();
    }

    public final StringProperty titleProperty() {
        return titleProperty;
    }

    private DoubleProperty iconSizeProperty;

    public final void setIconSize(final double value) {
        iconSizeProperty().set(value);
    }

    public final double getIconSize() {
        return iconSizeProperty == null ? -1 : iconSizeProperty.get();
    }

    public final DoubleProperty iconSizeProperty() {
        if (iconSizeProperty == null) {
            iconSizeProperty = new SimpleDoubleProperty(this, "iconSize", -1);
        }
        return iconSizeProperty;
    }

    private ObjectProperty<FontAwesomeIcon> iconProperty;

    public final void setIcon(final FontAwesomeIcon value) {
        iconProperty().set(value);
    }

    public final FontAwesomeIcon getIcon() {
        return iconProperty == null ? null : iconProperty.get();
    }

    @Override
    public String getUserAgentStylesheet() {
        return ContentSection.class.getClassLoader().getResource("content-section.css").toExternalForm();
    }

    public final ObjectProperty<FontAwesomeIcon> iconProperty() {
        if (iconProperty == null) {
            iconProperty = new SimpleObjectProperty<>(this, "icon");
        }
        return iconProperty;
    }

    private ObjectProperty<Node> contentProperty;

    public final void setContent(final Node value) {
        contentProperty().set(value);
    }

    public final Node getContent() {
        return contentProperty == null ? null : contentProperty.get();
    }

    public final ObjectProperty<Node> contentProperty() {
        if (contentProperty == null) {
            contentProperty = new SimpleObjectProperty<Node>(this, "content");
        }
        return contentProperty;
    }

    private final BooleanProperty expandedProperty = new BooleanPropertyBase(true) {
        @Override
        protected void invalidated() {
            final boolean active = get();
            pseudoClassStateChanged(PSEUDO_CLASS_EXPANDED, active);
            pseudoClassStateChanged(PSEUDO_CLASS_COLLAPSED, !active);
            notifyAccessibleAttributeChanged(AccessibleAttribute.EXPANDED);
        }

        @Override
        public Object getBean() {
            return ContentSection.this;
        }

        @Override
        public String getName() {
            return "expanded";
        }
    };

    public final void setExpanded(final boolean value) {
        expandedProperty().set(value);
    }

    public final boolean isExpanded() {
        return expandedProperty.get();
    }

    public final BooleanProperty expandedProperty() {
        return expandedProperty;
    }

    private final BooleanProperty animatedProperty = new StyleableBooleanProperty(true) {

        @Override
        public Object getBean() {
            return ContentSection.this;
        }

        @Override
        public String getName() {
            return "animated";
        }

        @Override
        public CssMetaData<ContentSection, Boolean> getCssMetaData() {
            return StyleableProperties.ANIMATED;
        }

    };

    public final void setAnimated(final boolean value) {
        animatedProperty().set(value);
    }

    public final boolean isAnimated() {
        return animatedProperty.get();
    }

    public final BooleanProperty animatedProperty() {
        return animatedProperty;
    }

    private final ObjectProperty<Duration> animationDurationProperty = new SimpleObjectProperty<>(this, "animationDuration", Duration.millis(350.0));

    public final void setAnimationDuration(final Duration value) {
        animationDurationProperty().set(value);
    }

    public final Duration getAnimationDuration() {
        return animationDurationProperty().get();
    }

    public final ObjectProperty<Duration> animationDurationProperty() {
        return animationDurationProperty;
    }

    private final BooleanProperty collapsibleProperty = new StyleableBooleanProperty(true) {

        @Override
        public Object getBean() {
            return ContentSection.this;
        }

        @Override
        public String getName() {
            return "collapsible";
        }

        @Override
        public CssMetaData<ContentSection, Boolean> getCssMetaData() {
            return StyleableProperties.COLLAPSIBLE;
        }

    };

    public final void setCollapsible(final boolean value) {
        collapsibleProperty().set(value);
    }

    public final boolean isCollapsible() {
        return collapsibleProperty.get();
    }

    public final BooleanProperty collapsibleProperty() {
        return collapsibleProperty;
    }

    private final ObjectProperty<Number> headerSizeProperty = new StyleableObjectProperty<Number>(44.0) {

        @Override
        public String getName() {
            return "headerSize";
        }

        @Override
        public Object getBean() {
            return ContentSection.this;
        }

        @Override
        public CssMetaData<? extends Styleable, Number> getCssMetaData() {
            return StyleableProperties.HEADER_SIZE;
        }
    };

    public final void setHeaderSize(final Number value) {
        headerSizeProperty().set(value);
    }

    public final Number getHeaderSize() {
        return headerSizeProperty().get();
    }

    public final ObjectProperty<Number> headerSizeProperty() {
        return headerSizeProperty;
    }

    /** {@inheritDoc} */
    @Override
    protected Skin<?> createDefaultSkin() {
        return new ContentSectionSkin(this);
    }

    private static final String DEFAULT_STYLE_CLASS = "content-section";

    private static final PseudoClass PSEUDO_CLASS_EXPANDED = PseudoClass.getPseudoClass("expanded");
    private static final PseudoClass PSEUDO_CLASS_COLLAPSED = PseudoClass.getPseudoClass("collapsed");

    private static class StyleableProperties {

        private static final CssMetaData<ContentSection, Boolean> COLLAPSIBLE =
                new CssMetaData<ContentSection, Boolean>("-fx-collapsible", StyleConverter.getBooleanConverter(), Boolean.TRUE) {

                    @Override
                    public boolean isSettable(final ContentSection n) {
                        return n.collapsibleProperty == null || !n.collapsibleProperty.isBound();
                    }

                    @Override
                    public StyleableProperty<Boolean> getStyleableProperty(final ContentSection n) {
                        return (StyleableProperty<Boolean>) n.collapsibleProperty();
                    }
                };

        private static final CssMetaData<ContentSection, Number> HEADER_SIZE =
                new CssMetaData<ContentSection, Number>("-fx-header-size", StyleConverter.getSizeConverter(), 44.0) {

                    @Override
                    public boolean isSettable(final ContentSection n) {
                        return n.collapsibleProperty == null || !n.collapsibleProperty.isBound();
                    }

                    @Override
                    public StyleableProperty<Number> getStyleableProperty(final ContentSection n) {
                        return (StyleableProperty<Number>) n.headerSizeProperty();
                    }
                };

        private static final CssMetaData<ContentSection, Boolean> ANIMATED =
                new CssMetaData<ContentSection, Boolean>("-fx-animated", StyleConverter.getBooleanConverter(), Boolean.TRUE) {

                    @Override
                    public boolean isSettable(final ContentSection n) {
                        return n.animatedProperty == null || !n.animatedProperty.isBound();
                    }

                    @Override
                    public StyleableProperty<Boolean> getStyleableProperty(final ContentSection n) {
                        return (StyleableProperty<Boolean>) n.animatedProperty();
                    }
                };

        private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
        static {
            final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<CssMetaData<? extends Styleable, ?>>(Control.getClassCssMetaData());
            styleables.add(COLLAPSIBLE);
            styleables.add(ANIMATED);
            styleables.add(HEADER_SIZE);
            STYLEABLES = Collections.unmodifiableList(styleables);
        }
    }

    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
        return StyleableProperties.STYLEABLES;
    }

    @Override
    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
        return getClassCssMetaData();
    }

    @Override
    public Orientation getContentBias() {
        final Node c = getContent();
        return c == null ? super.getContentBias() : c.getContentBias();
    }

    @Override
    public Object queryAccessibleAttribute(final AccessibleAttribute attribute, final Object... parameters) {
        switch (attribute) {
            case TEXT: {
                final String accText = getAccessibleText();
                if (accText != null && !accText.isEmpty()) {
                    return accText;
                }
                return getTitle();
            }
            case EXPANDED:
                return isExpanded();
            default:
                return super.queryAccessibleAttribute(attribute, parameters);
        }
    }

    @Override
    public void executeAccessibleAction(final AccessibleAction action, final Object... parameters) {
        switch (action) {
            case EXPAND:
                setExpanded(true);
                break;
            case COLLAPSE:
                setExpanded(false);
                break;
            default:
                super.executeAccessibleAction(action);
        }
    }

}
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;

import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView;
import javafx.animation.Animation.Status;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.ListChangeListener;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.util.Duration;

@SuppressWarnings("restriction")
public class ContentSectionSkin extends BehaviorSkinBase<ContentSection, ContentSectionBehavior> {

    private final BorderPane container;
    private final HBox header;
    private final BorderPane contentContainer;

    private Timeline timeline;
    private double transitionStartValue;

    private DoubleProperty transition;

    private FontAwesomeIconView expandCollapseIcon;

    private Button expandCollapseButton;

    private HBox sectionToolBar;

    public ContentSectionSkin(final ContentSection contentSection) {
        super(contentSection, new ContentSectionBehavior(contentSection));
        transitionStartValue = 0;

        container = createContainer();
        getChildren().setAll(container);

        header = createHeader();
        container.setTop(header);

        contentContainer = createContentContainer();
        container.setCenter(contentContainer);

        registerChangeListener(contentSection.contentProperty(), "CONTENT");
        registerChangeListener(contentSection.expandedProperty(), "EXPANDED");
        registerChangeListener(contentSection.collapsibleProperty(), "COLLAPSIBLE");

        sectionToolBar.getChildren().addListener((ListChangeListener<Node>) c -> updateHeader());

        if (contentSection.isExpanded()) {
            setTransition(1.0f);
            setExpanded(contentSection.isExpanded());
        } else {
            setTransition(0.0f);
            if (getSkinnable().getContent() != null) {
                getSkinnable().getContent().setVisible(false);
            }
        }
    }

    @Override
    protected double computeMaxWidth(final double height, final double topInset, final double rightInset, final double bottomInset, final double leftInset) {
        return Double.MAX_VALUE;
    }

    @Override
    protected double computeMinHeight(final double width, final double topInset, final double rightInset, final double bottomInset, final double leftInset) {
        final double headerHeight = snapSize(header.prefHeight(width));
        final double contentHeight = contentContainer.minHeight(width) * getTransition();
        final double minHeight = headerHeight + snapSize(contentHeight) + topInset + bottomInset;
        return minHeight;
    }

    @Override
    protected double computeMinWidth(final double height, final double topInset, final double rightInset, final double bottomInset, final double leftInset) {
        final double headerWidth = snapSize(header.prefWidth(height));
        final double contentWidth = snapSize(contentContainer.minWidth(height));
        final double minWidth = Math.max(headerWidth, contentWidth) + leftInset + rightInset;
        return minWidth;
    }

    @Override
    protected double computePrefHeight(final double width, final double topInset, final double rightInset, final double bottomInset, final double leftInset) {
        final double headerHeight = snapSize(header.prefHeight(width));
        final double contentHeight = contentContainer.prefHeight(width) * getTransition();
        final double prefHeight = headerHeight + snapSize(contentHeight) + topInset + bottomInset;
        return prefHeight;
    }

    @Override
    protected double computePrefWidth(final double height, final double topInset, final double rightInset, final double bottomInset, final double leftInset) {
        final double headerWidth = snapSize(header.prefWidth(height));
        final double contentWidth = snapSize(contentContainer.prefWidth(height));
        final double prefWidth = Math.max(headerWidth, contentWidth) + leftInset + rightInset;
        return prefWidth;
    }

    private BorderPane createContainer() {
        final BorderPane container = new BorderPane();
        container.setMinSize(0.0, 0.0);
        return container;
    }

    private BorderPane createContentContainer() {
        final BorderPane contentContainer = new BorderPane();
        contentContainer.getStyleClass().setAll("content");
        contentContainer.setMinSize(0.0, 0.0);

        if (getSkinnable().getContent() != null) {
            contentContainer.setCenter(getSkinnable().getContent());
        }

        return contentContainer;
    }

    private Button createExpandCollapseButton() {
        final Button expandCollapseButton = new Button();
        expandCollapseButton.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

        expandCollapseButton.setOnAction(event -> {
            getSkinnable().setExpanded(!getSkinnable().isExpanded());
        });

        final StackPane expandCollapseIconContainer = new StackPane();
        expandCollapseIconContainer.getStyleClass().setAll("icon-container");
        expandCollapseIconContainer.setId("last");
        expandCollapseIconContainer.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
        expandCollapseIconContainer.setPrefSize(21, 21);
        expandCollapseIconContainer.setMinSize(21, 21);
        expandCollapseButton.setGraphic(expandCollapseIconContainer);

        expandCollapseIcon = new FontAwesomeIconView(FontAwesomeIcon.CHEVRON_DOWN);
        expandCollapseIcon.setStyleClass("icon");
        expandCollapseIconContainer.getChildren().add(expandCollapseIcon);
        return expandCollapseButton;
    }

    private HBox createHeader() {
        final HBox header = new HBox();
        header.getStyleClass().setAll("header");
        header.setPrefHeight(getSkinnable().getHeaderSize().doubleValue());
        header.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

        header.getChildren().add(createIconContainer());
        header.getChildren().add(createTitleLabel());
        header.getChildren().add(createPlaceholder());
        header.getChildren().add(createSectionToolBar());

        return header;
    }

    private FontAwesomeIconView createIcon() {
        final FontAwesomeIconView iconView = new FontAwesomeIconView();
        iconView.setStyleClass("icon");
        iconView.setIcon(getSkinnable().getIcon());
        iconView.glyphSizeProperty().bind(getSkinnable().iconSizeProperty());
        return iconView;
    }

    private StackPane createIconContainer() {
        final StackPane iconContainer = new StackPane();
        iconContainer.getStyleClass().setAll("icon-container");
        iconContainer.setPrefSize(50, 50);
        iconContainer.getChildren().add(createIcon());
        return iconContainer;
    }

    private Pane createPlaceholder() {
        final Pane placeholder = new Pane();
        HBox.setHgrow(placeholder, Priority.ALWAYS);
        return placeholder;
    }

    private HBox createSectionToolBar() {
        sectionToolBar = new HBox();
        sectionToolBar.getStyleClass().setAll("section-tool-bar");
        expandCollapseButton = createExpandCollapseButton();
        if (getSkinnable().isCollapsible()) {
            sectionToolBar.getChildren().add(sectionToolBar.getChildren().size(), expandCollapseButton);
        }
        return sectionToolBar;
    }

    private Label createTitleLabel() {
        final Label titleLabel = new Label();
        titleLabel.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
        titleLabel.textProperty().bind(getSkinnable().titleProperty());
        return titleLabel;
    }

    private void disableCache() {
        getSkinnable().getContent().setCache(false);
    }

    private void doAnimationTransition() {
        if (getSkinnable().getContent() == null) {
            return;
        }

        Duration duration;
        if (timeline != null && (timeline.getStatus() != Status.STOPPED)) {
            duration = timeline.getCurrentTime();
            timeline.stop();
        } else {
            duration = getSkinnable().getAnimationDuration();
        }

        timeline = new Timeline();
        timeline.setCycleCount(1);

        KeyFrame k1, k2;

        if (getSkinnable().isExpanded()) {
            k1 = new KeyFrame(Duration.ZERO, event -> {
                // start expand
                getSkinnable().getContent().setVisible(true);
            }, new KeyValue(transitionProperty(), transitionStartValue));

            k2 = new KeyFrame(duration, event -> {
                // end expand
            }, new KeyValue(transitionProperty(), 1, Interpolator.LINEAR)

            );
        } else {
            k1 = new KeyFrame(Duration.ZERO, event -> {
                // Start collapse
            }, new KeyValue(transitionProperty(), transitionStartValue));

            k2 = new KeyFrame(duration, event -> {
                // end collapse
                getSkinnable().getContent().setVisible(false);
            }, new KeyValue(transitionProperty(), 0, Interpolator.LINEAR));
        }

        timeline.getKeyFrames().setAll(k1, k2);
        timeline.play();
    }

    private void enableCache() {
        getSkinnable().getContent().setCache(true);
    }

    public BorderPane getContentContainer() {
        return contentContainer;
    }

    private double getTransition() {
        return transition == null ? 0.0 : transition.get();
    }

    @Override
    protected void handleControlPropertyChanged(final String property) {
        super.handleControlPropertyChanged(property);
        if ("CONTENT".equals(property)) {
            final Node content = getSkinnable().getContent();
            if (content == null) {
                contentContainer.setCenter(null);
            } else {
                contentContainer.setCenter(content);
            }
        } else if ("EXPANDED".equals(property)) {
            setExpanded(getSkinnable().isExpanded());
        } else if ("COLLAPSIBLE".equals(property)) {
            updateHeader();
        }
    }

    private void setExpanded(final boolean expanded) {
        if (!getSkinnable().isCollapsible()) {
            setTransition(1.0f);
            return;
        }

        // we need to perform the transition between expanded / hidden
        if (getSkinnable().isAnimated()) {
            transitionStartValue = getTransition();
            doAnimationTransition();
        } else {
            if (expanded) {
                setTransition(1.0f);
            } else {
                setTransition(0.0f);
            }
            if (getSkinnable().getContent() != null) {
                getSkinnable().getContent().setVisible(expanded);
            }
            getSkinnable().requestLayout();
        }
    }

    private void setTransition(final double value) {
        transitionProperty().set(value);
    }

    private DoubleProperty transitionProperty() {
        if (transition == null) {
            transition = new SimpleDoubleProperty(this, "transition", 0.0) {
                @Override
                protected void invalidated() {
                    container.requestLayout();
                    updateExpandCollapseIconRotation();
                }
            };
        }
        return transition;
    }

    private void updateExpandCollapseIconRotation() {
        expandCollapseIcon.setRotate(180 * getTransition());
    }

    private void updateHeader() {
        if (getSkinnable().isCollapsible() && !sectionToolBar.getChildren().contains(expandCollapseButton)) {
            sectionToolBar.getChildren().add(sectionToolBar.getChildren().size(), expandCollapseButton);
        } else if (sectionToolBar.getChildren().contains(expandCollapseButton)) {
            sectionToolBar.getChildren().remove(expandCollapseButton);
        }
    }

}
import static javafx.scene.input.KeyCode.SPACE;

import java.util.ArrayList;
import java.util.List;

import com.sun.javafx.scene.control.behavior.BehaviorBase;
import com.sun.javafx.scene.control.behavior.KeyBinding;

import javafx.scene.input.MouseEvent;

@SuppressWarnings("restriction")
public class ContentSectionBehavior extends BehaviorBase<ContentSection> {

    private final ContentSection contentSection;

    public ContentSectionBehavior(final ContentSection contentSection) {
        super(contentSection, CONTENT_SECTION_BINDINGS);
        this.contentSection = contentSection;
    }

    /***************************************************************************
     *                                                                         *
     * Key event handling                                                      *
     *                                                                         *
     **************************************************************************/

    private static final String PRESS_ACTION = "Press";

    protected static final List<KeyBinding> CONTENT_SECTION_BINDINGS = new ArrayList<KeyBinding>();
    static {
        CONTENT_SECTION_BINDINGS.add(new KeyBinding(SPACE, PRESS_ACTION));
    }

    @Override
    protected void callAction(final String name) {
        switch (name) {
            case PRESS_ACTION:
                if (contentSection.isCollapsible() && contentSection.isFocused()) {
                    contentSection.setExpanded(!contentSection.isExpanded());
                    contentSection.requestFocus();
                }
                break;
            default:
                super.callAction(name);
        }
    }

    /***************************************************************************
     *                                                                         *
     * Mouse event handling                                                    *
     *                                                                         *
     **************************************************************************/

    @Override
    public void mousePressed(final MouseEvent e) {
        super.mousePressed(e);
        final ContentSection contentSection = getControl();
        contentSection.requestFocus();
    }

    /**************************************************************************
     *                         State and Functions                            *
     *************************************************************************/

    public void expand() {
        contentSection.setExpanded(true);
    }

    public void collapse() {
        contentSection.setExpanded(false);
    }

    public void toggle() {
        contentSection.setExpanded(!contentSection.isExpanded());
    }

}
<?xml version="1.0" encoding="UTF-8"?>

<?import org.test.ContentSection?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.StackPane?>

<ScrollPane fx:id="root" fitToWidth="true" fitToHeight="true" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
    <content>
        <VBox styleClass="content">
            <children>
                <ContentSection fx:id="contentSection" collapsible="false" VBox.vgrow="ALWAYS">
                    <content>
                        <StackPane>
                            <children>
                                <Label text="Test" />
                            </children>
                        </StackPane>
                    </content>
                </ContentSection>
            </children>
        </VBox>
    </content>
</ScrollPane>

有人知道下一步该怎么做吗?我看不出有什么办法去寻找问题...

向帕特里克问好

暂时还没有答案

 类似资料:
  • 因此,在我尝试编写JavaFX教程和FXML示例时。但是,每当我在.fxml文件中向GridPane中添加一些内容时,程序就会崩溃。它打开一个普通的GridPane,如果没有其他东西放在其中。 } 究竟是什么原因导致它坠毁?

  • > 我是使用fx:root,还是不使用它?我选择用它。所以在控件的controller+root类中,我将自己设置为root和controller,就像需要的那样。但它仍然说“root尚未设置。在加载之前使用setRoot()方法。” 在包含自定义控件的父FXML中,我应该导入什么? 正确的类路径是什么,以便我可以在SceneBuilder2.0中显示我的自定义控件?我根本不太明白“/.../..

  • 我有一个自定义组件,它在包含行的FXML文件上进行布局 我在SceneBuilder1.0上创建了这个文件,但是我尝试在SceneBuilder2.0上打开这个文件,我遇到了异常 还必须说明:在应用程序中,通过代码设置root,这个fxml加载很好。 链接JIRA:https://javafx-jira.kenai.com/browse/dtl-5968

  • 我在打开我的时遇到问题。当我运行项目时,一切都运行得很好,但是我不能在下进行修改。每次我想要添加到中时,我都需要删除包含,做我想做的,并手动将代码粘贴到中,而不是粘贴到中(不能在Tab下包含?)。

  • 我正在进行的项目使用的是JavaFx框架,因此我们使用的是fxml文件和场景构建器。我已经为我们的应用程序制作了一个自定义控件,根据我在web上找到的示例,它工作得非常好。但是,我们将有多个带有公共基本功能的自定义控件。因此,我想将基本功能继承到一个自定义控件中。 我正在尝试做的是创建一个扩展自定义根控件类的自定义控件。CustomControl.fxml文件如下所示: 它是皮包骨头,当我打开Cu