I want to ask if it is possible to make a chip in JFXChipView
editable once it has been set.
You can create your own JFXChip
and implement a behavior to enable editing. First, you need to have an editable label. I looked up online and I found this post: JavaFX custom control - editable label. Then, you can extend JFXChip
to use that EditableLabel
:
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXChip;
import com.jfoenix.controls.JFXChipView;
import com.jfoenix.svg.SVGGlyph;
import javafx.beans.binding.Bindings;
import javafx.beans.property.Property;
import javafx.scene.layout.HBox;
public class EditableChip<T> extends JFXChip<Property<T>> {
protected final HBox root;
public EditableChip(JFXChipView<Property<T>> view, Property<T> item) {
super(view, item);
JFXButton closeButton = new JFXButton(null, new SVGGlyph());
closeButton.getStyleClass().add("close-button");
closeButton.setOnAction(event -> {
view.getChips().remove(item);
event.consume();
});
// Create the label with an initial value from the item
String initialValue = view.getConverter().toString(item);
EditableLabel label = new EditableLabel(initialValue);
label.setMaxWidth(100);
// Bind the item to the text in the label
item.bind(Bindings.createObjectBinding(() -> view.getConverter().fromString(label.getText()).getValue(), label.textProperty()));
root = new HBox(label, closeButton);
getChildren().setAll(root);
}
}
Note: I am using Property<T>
instead of using the desired class T
because JFXChipView
stores the item the first time you add it. And in that case, you're going to get the values as you entered them the first time when calling JFXChipView#getChips()
.
Sample application:
import com.jfoenix.controls.JFXChipView;
import javafx.application.Application;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class EditableChipViewApp extends Application {
@Override
public void start(Stage primaryStage) {
JFXChipView<Property<String>> chipView = new JFXChipView<>();
chipView.setChipFactory(EditableChip::new);
chipView.setConverter(new StringConverter<Property<String>>() {
@Override
public String toString(Property<String> object) {
return object == null ? null : object.getValue();
}
@Override
public Property<String> fromString(String string) {
return new SimpleStringProperty(string);
}
});
VBox container = new VBox(chipView);
Scene scene = new Scene(container, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Result:
This is how you get the actual values of the chips:
List<String> chipsValues = chipView.getChips().stream().map(Property::getValue).collect(Collectors.toList());