I created a CustomCB a combo box which is of type a userObject. In my case I have used <APerson>
as userObject. Entire project and the TESTER are here. First one is CustomCB, the components and the JAR file generated out of this code is added to the Library. This can be loaded in SCENE BUILDER. Thereafter it is available for scene design.
Then of course, you have a tester CustomCB2, which also can use a FXML instead of the way I have done.
I actually want the items starting with the text I type in the ComboBox to appear in the list. But I don't know how to do it. Because the FIRST NAME or LAST NAME of the PERSON class can start with 'Pe'. If I find a solution, I will post it here.
This is the Custom Component.
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;
}
}
This is the FXML for the Custom Component.
<?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>
This is the controller for this FXML but do not mention it in FXML file. It throws error.
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());
}
}
Download controlsfx-8.40.12.jar from WEB and include this in the BUILD PATH as library.
Now create a jar file for this project. "CustomCB.jar".
This JAR file has to be included as custom control in Scene Builder. I use version 10.0.
Now that it is part of Scene builder you can use this component in designing, unless you can do it the way I have done in my TEST CODE. You need to include "CustomCB.jar" as part of the library for building.
This is the code for the tester.
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));
}
}
It needs lot of improvements. If anyone can improvise, please add it here.