我实现了一个自定义组件(ToggleSwitch),如本视频所示:https://www.youtube.com/watch?v=maX5ymmQixM 我通过 Maven 创建了一个 .jar 并将该 .jar 添加到 SceneBuilder
该组件可以工作,但根本无法调整大小,并且在 SceneBuilder 中也无法调整大小。
要调整大小需要什么?
我尝试过的
我了解到,SceneBuilder 必须从 Region(而不是像视频中那样从 Parent)进行扩展才能在 SceneBuilder 中的布局选项卡下显示尺寸设置
这是代码
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方法有效:)
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.
关于JavaFX - 如何在 SceneBuilder 中调整自定义组件的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75450330/