JavaFX - 如何在 SceneBuilder 中调整自定义组件的大小?

标签 javafx scenebuilder custom-component resizable

我实现了一个自定义组件(ToggleSwitch),如本视频所示:https://www.youtube.com/watch?v=maX5ymmQixM 我通过 Maven 创建了一个 .jar 并将该 .jar 添加到 SceneBuilder

该组件可以工作,但根本无法调整大小,并且在 SceneBuilder 中也无法调整大小。 enter image description here

enter image description here

要调整大小需要什么

我尝试过的

我了解到,SceneBuilder 必须从 Region(而不是像视频中那样从 Parent)进行扩展才能在 SceneBuilder 中的布局选项卡下显示尺寸设置 enter image description here

这是代码


import javafx.animation.FillTransition;
import javafx.animation.ParallelTransition;
import javafx.animation.TranslateTransition;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Parent;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;

public class ToggleSwitch extends Region {

    private   double PREFERRED_WIDTH = 100;
    private   double PREFERRED_HEIGHT = 50;

    private final BooleanProperty switchedOn = new SimpleBooleanProperty(false);
    private final TranslateTransition translateAnimation = new TranslateTransition(Duration.seconds(0.25));
    private final FillTransition fillAnimation = new FillTransition(Duration.seconds(0.25));
    private final ParallelTransition animation = new ParallelTransition(translateAnimation,fillAnimation);

    private double width;
    private double height;
    private Rectangle background;
    private Circle trigger;


    public ToggleSwitch(){

        width = PREFERRED_WIDTH;
        height = PREFERRED_HEIGHT;
        background = new Rectangle(width,height);
        background.setFill(Color.WHITE);
        background.setStroke(Color.LIGHTGRAY);
        background.setArcWidth(50);
        background.setArcHeight(50);


        trigger = new Circle(height/2);
        trigger.setCenterX(height/2);
        trigger.setCenterY(height/2);
        trigger.setFill(Color.WHITE);
        trigger.setStroke(Color.LIGHTGRAY);

        translateAnimation.setNode(trigger);
        fillAnimation.setShape(background);

        getChildren().addAll(background,trigger);

        switchedOn.addListener((observableValue, oldState, newState) -> {
            boolean isOn = newState;
            translateAnimation.setToX(isOn ? 100-50 : 0);
            fillAnimation.setFromValue(isOn ? Color.WHITE : Color.LIGHTGREEN);
            fillAnimation.setToValue(isOn ? Color.LIGHTGREEN : Color.WHITE);
            animation.play();
        });

        setOnMouseClicked(event -> {
            switchedOn.set(!switchedOn.get());
        });

        widthProperty().addListener(o->resize());
        heightProperty().addListener(o->resize());

    }
    

    private void resize () {
        width = getWidth() - getInsets().getLeft() - getInsets().getRight();
        height = getHeight();
    }

    public BooleanProperty switchedOnProperty() {
        return switchedOn;
    }
    
}

如何将其实现为可调整大小以便我可以使用 SceneBuilder ?

最佳答案

@James_D 谢谢,效果非常好。

重写layoutChildren方法有效:)

enter image description here

enter image description here

public class ToggleSwitch extends Region {

private   double PREFERRED_WIDTH = 100;
private   double PREFERRED_HEIGHT = 50;

private final BooleanProperty switchedOn = new SimpleBooleanProperty(false);
private final TranslateTransition translateAnimation = new TranslateTransition(Duration.seconds(0.25));
private final FillTransition fillAnimation = new FillTransition(Duration.seconds(0.25));
private final ParallelTransition animation = new ParallelTransition(translateAnimation,fillAnimation);

private double width;
private double height;
private Rectangle background;
private Circle trigger;


public ToggleSwitch(){

    width = PREFERRED_WIDTH;
    height = PREFERRED_HEIGHT;
    background = new Rectangle(width,height);
    background.setFill(Color.WHITE);
    background.setStroke(Color.LIGHTGRAY);
    background.setArcWidth(50);
    background.setArcHeight(50);


    trigger = new Circle(height/2);
    trigger.setCenterX(height/2);
    trigger.setCenterY(height/2);
    trigger.setFill(Color.WHITE);
    trigger.setStroke(Color.LIGHTGRAY);

    translateAnimation.setNode(trigger);
    fillAnimation.setShape(background);

    getChildren().addAll(background,trigger);

    switchedOn.addListener((observableValue, oldState, newState) -> {
        boolean isOn = newState;
        translateAnimation.setToX(isOn ? getWidth()-trigger.getRadius()*2 : 0);
        fillAnimation.setFromValue(isOn ? Color.WHITE : Color.LIGHTGREEN);
        fillAnimation.setToValue(isOn ? Color.LIGHTGREEN : Color.WHITE);
        animation.play();
    });

    setOnMouseClicked(event -> {
        switchedOn.set(!switchedOn.get());
    });

}


@Override
protected void layoutChildren(){
    double width = getWidth();
    double height= getHeight();
    background.setWidth(width);
    background.setHeight(height);
    background.setArcWidth(height);
    background.setArcHeight(height);

    trigger.setRadius(height/2);
    trigger.setCenterX(height/2);
    trigger.setCenterY(height/2);
}

public BooleanProperty switchedOnProperty() {
    return switchedOn;
}

}

To implement a more custom layout, a Region subclass must override computePrefWidth, computePrefHeight, and layoutChildren. Note that layoutChildren is called automatically by the scene graph while executing a top-down layout pass and it should not be invoked directly by the region subclass.

Region API

关于JavaFX - 如何在 SceneBuilder 中调整自定义组件的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75450330/

相关文章:

java - 如何更高效地更新TriangleMesh的点?

Java FXML - 显示文本输入字段的字符串长度

jquery - mCustomScrollbar - 滚动条只出现在 F12 按下时(开发工具/Firebug)而不是隐藏元素/div

java - 创造比数独游戏更伟大的游戏板

java - 从场景中提取内容

JavaFX:在按键事件上获取 TableView 中的目标行索引

JavaFX 获取我的应用程序的 PrimaryStage(主菜单)

JavaFX - 强制从 TextField 输入大写

delphi - 为什么包内缺少 x.dfm?

安卓 : how to create custom component