首页 文章

将自定义组件添加到SceneBuilder 2.0

提问于
浏览
9

我需要在窗格上有一个选择侦听器和select方法,以便能够在单击节点时监视并显示突出显示 .

我做了以下事情:

public class PaneWithSelectionListener extends Pane {

    private ObjectProperty<Annotation> selectedAnnotation = new SimpleObjectProperty<>();

    public PaneWithSelectionListener() { 
        super();
        selectedAnnotation.addListener((obs, oldAnno, newAnno) -> {
            if (oldAnno != null) {
                oldAnno.setStyle("");
            }
            if (newAnno != null) {
                newAnno.setStyle("-fx-border-color: blue;-fx-border-insets: 5;-fx-border-width: 1;-fx-border-style: dashed;");
            }
        });

        setOnMouseClicked(e->selectAnnotation(null));
    }

    public void selectAnnotation(Annotation ann){
        selectedAnnotation.set(ann);
    }
}

这很有效 - 但是我不能再使用SceneBuilder了,因为我的FXML引用了这个 PaneWithSelectionListener 而不是 Pane . 我不确定如何将自定义窗格导入SceneBuilder . 我看过其他问题,它们都是FXML和控制器的组合 - 这只是一个 Pane .

有没有人知道这样做的方法,或者可能在初始化时将 Pane 换成 PaneWithSelectionListener

谢谢

2 回答

  • 14

    如果问题只是在SceneBuilder中使您的自定义类可用,则可以通过以下步骤执行此操作:

    • 将自定义类(以及任何支持类,如 Annotation )捆绑为jar文件

    • 在SceneBuilder中,激活左窗格顶部"Library"旁边的下拉按钮:
      enter image description here

    • 选择"Import JAR/FXML File..."

    • 选择从步骤1创建的Jar文件

    • 确保选中您在SceneBuilder( PaneWithSelectionListener )中需要访问的类

    • 按"Import Component"

    • PaneWithSelectionListener 现在将出现在左窗格中"Custom"下的SceneBuilder中:
      enter image description here

    您会注意到SceneBuilder中的下拉列表有一个“自定义库文件夹”选项,您可以从中打开存储jar文件的文件夹 . 对于快速选项,您只需将jar文件复制到此文件夹(并在短暂延迟后),所包含的类将显示在“自定义”列表中 .

  • 0

    我创建了一个CustomCB组合框,其类型为userObject . 在我的情况下,我使用 <APerson> 作为userObject . 整个项目和TESTER都在这里 . 第一个是CustomCB,将从此代码生成的组件和JAR文件添加到库中 . 这可以在SCENE BUILDER中加载 . 此后,它可用于场景设计 .

    当然,你有一个测试仪CustomCB2,它也可以使用FXML而不是我的方式 .

    我实际上希望以我在ComboBox中键入的文本开头的项目出现在列表中 . 但我不知道该怎么做 . 因为PERSON类的FIRST NAME或LAST NAME可以以'Pe'开头 . 如果我找到解决方案,我会在这里发布 .

    这是自定义组件 .

    package customCB;
        /*
         * To change this license header, choose License Headers in Project Properties.
         * To change this template file, choose Tools | Templates
         * and open the template in the editor.
         */
        import javafx.beans.property.IntegerProperty;
        import javafx.beans.property.SimpleIntegerProperty;
        import javafx.beans.property.SimpleStringProperty;
        import javafx.beans.property.StringProperty;
    
        /**
         *
         * @author Hornigold Arthur
         */
    
        public class APerson {
    
        private final StringProperty firstName;
        private final StringProperty lastName;
        private final IntegerProperty familyID;
        private final IntegerProperty personID;
    
        public APerson() {
            this(null, null, 0,0);
        }
    
        /**
         * Constructor with some initial data.
         * 
         * @param familyID
         * @param familyName
         */
    
        public  APerson (String firstName, String lastName, int familyID, int personID) {
            this.firstName = new SimpleStringProperty(firstName);
            this.lastName = new SimpleStringProperty(lastName);
            this.familyID = new SimpleIntegerProperty(familyID);
            this.personID = new SimpleIntegerProperty(personID);
        }
    
        public int getFamilyID() {
            return familyID.get();
        }
    
        public void setFamilyID(int FamilyID) {
            this.familyID.set(FamilyID);
        }
    
        public IntegerProperty familyIDProperty() {
            return familyID;
        }
    
        public int getPersonID() {
            return personID.get();
        }
    
        public void setPersonID(int PersonID) {
            this.personID.set(PersonID);
        }
    
        public IntegerProperty personIDProperty() {
            return personID;
        }
    
        public String getFirstName() {
            return firstName.get();
        }
    
        public void setFirstName(String FirstName) {
            this.firstName.set(FirstName);
        }
    
        public StringProperty firstNameProperty() {
            return firstName;
        }
    
        public String getLastName() {
            return lastName.get();
        }
    
        public void setLastName(String LastName) {
            this.lastName.set(LastName);
        }
    
        public StringProperty lastNameProperty() {
            return lastName;
        }
    
    
        public String toString() {
            String name = getFirstName() + " " + getLastName()+ " [" + getFamilyID() +"]";
            return name;
        }
    }
    

    这是自定义组件的FXML .

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.ComboBox?>
    <?import javafx.scene.layout.VBox?>
    
    <fx:root stylesheets="@application.css" type="javafx.scene.layout.VBox" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
        <ComboBox fx:id="myCustomCombo" editable="true" onAction="#cbOnAction" prefWidth="300.0" style="-fx-background-color: white;" />
    </fx:root>
    

    这是FXML的控制器,但在FXML文件中没有提到它 . 它抛出错误 .

    package customCB;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.ResourceBundle;
    
    import org.controlsfx.control.textfield.TextFields;
    
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.ListView;
    import javafx.scene.layout.VBox;
    
    public class CustomComboController extends VBox{
    
        @FXML
        private ResourceBundle resources;
    
        @FXML
        private URL location;
    
        @FXML
        private ComboBox<APerson> myCustomCombo;
    
        @FXML
        void cbOnAction(ActionEvent event) {
    
        }
    
        @FXML
        void initialize() {
            assert myCustomCombo != null : "fx:id=\"myCustomCombo\" was not injected: check your FXML file 'CustomLvFXML.fxml'.";
        }
    
        public CustomComboController() {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("customCombo.fxml"));
            fxmlLoader.setRoot(this);
            fxmlLoader.setController(this);
    
            try {
                fxmlLoader.load();
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            }
        }
    
        public void setCBValues(javafx.collections.ObservableList<APerson> values) {
            myCustomCombo.setItems(values);
            myCustomCombo.setEditable(true);
            TextFields.bindAutoCompletion(myCustomCombo.getEditor(), myCustomCombo.getItems());
        }
    
    }
    

    从WEB下载controlsfx-8.40.12.jar并将其作为库包含在BUILD PATH中 .

    现在为此项目创建一个jar文件 . “CustomCB.jar” .

    此JAR文件必须作为自定义控件包含在Scene Builder中 . 我使用的是10.0版 .

    现在它是Scene构建器的一部分,您可以在设计中使用此组件,除非您可以按照我在TEST CODE中的方式执行此操作 . 您需要包含“CustomCB.jar”作为构建库的一部分 .

    这是测试人员的代码 .

    package customCB2;
    
    
        import javafx.application.Application;
        import javafx.stage.Stage;
        import javafx.scene.Scene;
        import javafx.scene.layout.VBox;
    
    
        public class Main extends Application {
    
            static private javafx.collections.ObservableList<APerson> fathers = javafx.collections.FXCollections.observableArrayList();
            static private javafx.collections.ObservableList<APerson> mothers = javafx.collections.FXCollections.observableArrayList();
    
    
    
        @Override
        public void start(Stage stage) throws Exception {
    
            CustomComboController customControl2 = new CustomComboController();
            CustomComboController customControl3 = new CustomComboController();
    
            loadFathers();
            loadMothers();
    
            customControl2.setCBValues(fathers);
            customControl3.setCBValues(mothers);
    
            VBox root = new VBox();
            root.getChildren().addAll(customControl2, customControl3);
    
            stage.setScene(new Scene(root));
            stage.setTitle("Custom Control Combo box");
            stage.setWidth(300);
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
        private void loadFathers() {
            fathers.clear();
            fathers.add(new APerson("Hornigold","Arthur",1,63));
            fathers.add(new APerson("Andrews","Sundareson",2,60));
            fathers.add(new APerson("Christopher","Easweradoss",3,57));
            fathers.add(new APerson("Arthur","Kennedy",4,55));
        }
    
        private void loadMothers() {
            mothers.clear();
            mothers.add(new APerson("Victoria","Arthur",1,95));
            mothers.add(new APerson("Eliza", "Daniel",1,60));
            mothers.add(new APerson("Nesammal", "Rivington",2,57));
            mothers.add(new APerson("Ratnammal","Andews",1,55));
        }
    
    
    }
    

    它需要很多改进 . 如果有人可以即兴创作,请在此处添加 .

相关问题