I try to create my own component for JavaFX. In this component, there are 2 methods in which true or false is transmitted and, depending on this, the contents of the component change, but when you import the Jar file into Scene Builder, the Custom block has only one property and it is not editable.
enter image description here
How can I allow editing this property and add my own to it?

Github

Controller

 public class ShowPassword extends Control { private final String DEF_STYLE_CLASS = "show-password"; public ShowPassword() { init(); } private void init() { getStyleClass().setAll(DEF_STYLE_CLASS); } @Override protected Skin<?> createDefaultSkin() { return new ShowPasswordSkin(this); } private BooleanProperty showing; private BooleanProperty showVisisble; public final void setShowing(boolean value){ ShowingProperty().set(value); } public final void setShowVisisble(boolean value){ ShowVisisbleProperty().set(value); } public final BooleanProperty ShowVisisbleProperty(){ if (showVisisble==null){ showVisisble = new BooleanPropertyBase() { @Override protected void invalidated() { final Boolean v = get(); pseudoClassStateChanged(PSEUDO_CLASS_SHOW_VISIBLE,v); } @Override public Object getBean() { return ShowPassword.this; } @Override public String getName() { return "show-visible"; } }; } return showVisisble; } public final BooleanProperty ShowingProperty(){ if (showing==null){ showing = new BooleanPropertyBase() { @Override protected void invalidated() { final Boolean v = get(); pseudoClassStateChanged(PSEUDO_CLASS_SHOWING,v); } @Override public Object getBean() { return ShowPassword.this; } @Override public String getName() { return "showing"; } }; } return showing; } public final boolean isShowing(){ return showing == null?false:showing.get(); } public final boolean isShowVisible(){ return showVisisble == null?false:showVisisble.get(); } @Override public String getUserAgentStylesheet() { return ShowPassword.class.getResource("showpassword.css").toExternalForm(); } private static final PseudoClass PSEUDO_CLASS_SHOWING = PseudoClass.getPseudoClass("showing"); private static final PseudoClass PSEUDO_CLASS_SHOW_VISIBLE = PseudoClass.getPseudoClass("show-visible"); } 

Skin

 public class ShowPasswordSkin extends SkinBase<ShowPassword> { private Image lockImg = new Image(getClass().getResourceAsStream("/icon/lock.png")); private Image unlockImg = new Image(getClass().getResourceAsStream("/icon/unlock.png")); private GridPane container; private StackPane stackField; private ImageView leftImg; private ImageView rightImg; private TextField textField; private PasswordField passwordField; public ShowPasswordSkin(ShowPassword control) { super(control); container = new GridPane(); stackField = new StackPane(); leftImg = new ImageView(); rightImg = new ImageView(); textField = new TextField(); rightImg.setPickOnBounds(true); passwordField = new PasswordField(); container.setGridLinesVisible(true); RowConstraints row1 = new RowConstraints(); RowConstraints row2 = new RowConstraints(); RowConstraints row3 = new RowConstraints(); ColumnConstraints col1 = new ColumnConstraints(38,38,38); ColumnConstraints col2 = new ColumnConstraints(); ColumnConstraints col3 = new ColumnConstraints(38,38,38); container.getRowConstraints().addAll(row1,row2,row3); if (control.isShowVisible()){ col2.setMinWidth(100); col2.setMaxWidth(9999); col2.setHgrow(Priority.ALWAYS); container.getColumnConstraints().addAll(col1,col2); container.add(leftImg,0,0); container.add(stackField,1,0); }else { col2.setMinWidth(100); col2.setMaxWidth(9999); col2.setHgrow(Priority.ALWAYS); container.getColumnConstraints().addAll(col1,col2,col3); container.add(leftImg,0,0); container.add(stackField,1,0); container.add(rightImg,2,0); } leftImg.setImage(leftImage(control.isShowVisible())); stackField.getChildren().addAll(textField,passwordField); getChildren().add(container); rightImg.setOnMouseReleased(e -> mousePresed(control)); rightImg.setImage(showStateChanget(false)); control.ShowingProperty().addListener(((observable, oldValue, newValue) -> { System.out.println(newValue); if (newValue.booleanValue() != oldValue.booleanValue()){ rightImg.setImage(showStateChanget(newValue)); } })); } private Image leftImage(boolean value) { InputStream imageStram; if (value){ imageStram = getClass().getResourceAsStream("/icon/login.png"); }else { imageStram = getClass().getResourceAsStream("/icon/key.png"); } return new Image(imageStram); } private Image showStateChanget(boolean value) { fieldActive(textField,value); fieldActive(passwordField,!value); return value?unlockImg:lockImg; } private void fieldActive(TextField field,boolean value){ field.setDisable(!value); field.setVisible(value); field.setOpacity(value?1:0); } private void mousePresed(ShowPassword showPassword){ showPassword.setShowing(!showPassword.isShowing()); } @Override protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) { ShowPassword showPassword = getSkinnable(); showPassword.setLayoutY(contentY); showPassword.setLayoutX(contentX); container.setLayoutX(contentX); container.setLayoutY(contentY); container.resize(showPassword.getWidth(),showPassword.getHeight()); } @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { return (leftImg.getFitWidth()+(getSkinnable().isShowVisible()?rightImg.getFitWidth():0))-(leftInset+rightInset); } @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { return (leftImg.getFitHeight()+(getSkinnable().isShowVisible()?rightImg.getFitHeight():0))-(topInset+bottomInset); } @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { return 9999; } @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { return 9999; } } 

    1 answer 1

    The property "Show visible" is not editable, because property \ getter \ setter names are not consistent:

     private BooleanProperty showVisisble; public final boolean isShowVisible(){...} public final void setShowVisisble(boolean value){...} 

    The showing property was not added automatically due to the features of the SceneBuilder parser. If replaced by:

     private BooleanProperty showingA; public final boolean isShowingA(){...} public final void setShowingA(boolean value){...} 

    then everything will fall into place.

    enter image description here