简体   繁体   中英

Building Custom Component for SceneBuilder (JavaFX)

I followed this blog Adding a Custom JavaFX Component to Scene Builder 2.0 , and built my own Custom component.

FXML file:

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

<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<fx:root id="AnchorPane" maxHeight="-Infinity" prefHeight="25.0" prefWidth="400.0" styleClass="mainFxmlClass" type="AnchorPane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <stylesheets>
        <URL value="@style.css" />
    </stylesheets>
   <children>
      <HBox fx:id="border" prefHeight="25.0" prefWidth="400.0" styleClass="textbox-container" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
         <children>
            <Label fx:id="label" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="25.0" prefWidth="200.0" styleClass="textbox-label" text="Label" HBox.hgrow="ALWAYS" />
            <HBox minWidth="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS">
               <children>
                  <TextField fx:id="textbox" prefWidth="176.0" styleClass="textbox" HBox.hgrow="ALWAYS" />
                  <Button fx:id="clear" focusTraversable="false" mnemonicParsing="false" styleClass="button-controller" text="X" />
               </children>
            </HBox>
         </children>
      </HBox>
   </children>
</fx:root>

Controller Class:

public class CellTextFieldClear extends AnchorPane {

    @FXML
    private HBox border;
    @FXML
    private Label label;
    @FXML
    private TextField textbox;
    @FXML
    private Button clear;

    public CellTextFieldClear(){
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/celltextfieldclear/CellTextFieldClear.fxml"));
        loader.setRoot(this);
        loader.setController(this);
        try{
            loader.load();
        }catch(IOException exception){
            throw new RuntimeException(exception);
        }
    }

    public void setOnActionHandlerForClear(EventHandler<ActionEvent> event){
        clear.setOnAction(event);
    }

    public void setEditable(boolean value){
        textbox.setEditable(value);
    }

    public String getTextFromTextBox(){
        return textbox.getText();
    }

    public void setTextBoxText(String text){
        textbox.setText(text);
    }

    public void setLableText(String text){
        label.setText(text);
    }

    public String getTextFromLabel(){
        return label.getText();
    }
}

StyleSheet:

.textbox {
    -fx-background-radius: 0;
    -fx-background-insets: 0;
    -fx-background-color:  white;
}

.textbox-label {
    -fx-background-color:  #b0c4de;
    -fx-padding: 0 0 0 5;
}

.textbox-container {
    -fx-border-color: #191970;
    -fx-border-width: 0.5;
}

.button-controller {
    -fx-background-radius: 0; 
    -fx-background-insets: 0; 
    -fx-background-color: white;
}

.button-controller:hover {
    -fx-background-color:
        #ecebe9,
        rgba(0,0,0,0.05),
        linear-gradient(#dcca8a, #c7a740),
        linear-gradient(#f9f2d6 0%, #f4e5bc 20%, #e6c75d 80%, #e2c045 100%),
        linear-gradient(#f6ebbe, #e6c34d);
    -fx-background-insets: 0 0 -1 0; 
    -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.1) , 2, 0.0 , 0 , 1);
}

.button-controller:pressed {
    -fx-background-color:
        #ecebe9,
        rgba(0,0,0,0.05),
        linear-gradient(#dac980, #c6a530),
        linear-gradient(#f8f0d4 0%, #f3e4ba 20%, #e0c050 80%, #e3c440 100%),
        linear-gradient(#f5fbae, #e7c94f);
    -fx-background-insets: 0 0 -1 0; 
    -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.1) , 2, 0.0 , 0 , 1);
}

Output: 产量

Now my question is I cannot change the value of label from Scene Builder. Can we create a custom field which will appear on Scene Builder and which will help to change the Label Text?

In order to have editable fields on Scene Builder, you should use properties. Otherwise, a ReadOnlyStringWrapper is used.

For instance these:

private final BooleanProperty editable = new SimpleBooleanProperty();

public boolean isEditable() {
    return editable.get();
}

public void setEditable(boolean value) {
    editable.set(value);
}

public final BooleanProperty editableProperty() {
    return editable;
}

private final StringProperty textFromTextBox = new SimpleStringProperty();

public String getTextFromTextBox() {
    return textFromTextBox.get();
}

public void setTextFromTextBox(String value) {
    textFromTextBox.set(value);
}

public final StringProperty textFromTextBoxProperty() {
    return textFromTextBox;
}

private final StringProperty labelText = new SimpleStringProperty();

public String getLabelText() {
    return labelText.get();
}

public void setLabelText(String value) {
    labelText.set(value);
}

public final StringProperty labelTextProperty() {
    return labelText;
}

And then bind the controls to those properties:

public CellTextFieldClear(){
    ...

    textbox.editableProperty().bind(editableProperty());
    textbox.textProperty().bind(textFromTextBoxProperty());
    label.textProperty().bind(labelTextProperty());
}

自定义控件

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM