javaFX:listview with Radio Button - java

I have a list with items which should carry RadioButton with list items.
the ListView is an observable ArrayList with data I want to add radio Button with each item in list View.

Create a custom ListCell and set the graphic of the ListCell to a RadioButton. You can add more functionality inside updateItem() if required.
Output
Complete Example
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class RadioButtonListView extends Application {
public static final ObservableList names =
FXCollections.observableArrayList();
private ToggleGroup group = new ToggleGroup();
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("List View Sample");
final ListView listView = new ListView();
listView.setPrefSize(200, 250);
listView.setEditable(true);
names.addAll(
"Adam", "Alex", "Alfred", "Albert",
"Brenda", "Connie", "Derek", "Donny",
"Lynne", "Myrtle", "Rose", "Rudolph",
"Tony", "Trudy", "Williams", "Zach"
);
listView.setItems(names);
listView.setCellFactory(param -> new RadioListCell());
StackPane root = new StackPane();
root.getChildren().add(listView);
primaryStage.setScene(new Scene(root, 200, 250));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private class RadioListCell extends ListCell<String> {
#Override
public void updateItem(String obj, boolean empty) {
super.updateItem(obj, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
RadioButton radioButton = new RadioButton(obj);
radioButton.setToggleGroup(group);
// Add Listeners if any
setGraphic(radioButton);
}
}
}
}

Related

JavaFX: Make Chips Editable in JFXChipView

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());

Is there a CheckBoxListCell equivalent for JFoenix so that we can use JFXCheckBox instead of the traditional one?

So I am currently using my JFXListView and trying to set several checkboxes inside of it using CheckBoxListCell. Originally I used this:
listView.setCellFactory(CheckBoxListCell.forListView(new Callback<classForMenuOptions, ObservableValue<Boolean>>() {
#Override
public ObservableValue<Boolean> call(UserMenuOptions item) {
return item.selectedProperty();
}
}));
Is there a way so that I can use JFXCheckBox instead of the traditional CheckBox?
You basically just need to implement your own cellFactory.
import com.jfoenix.controls.JFXCheckBox;
import com.jfoenix.controls.JFXListView;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ListViewExperiments extends Application
{
#Override
public void start(Stage primaryStage) throws Exception
{
primaryStage.setTitle("ListView Experiment 1");
JFXListView<String> listView = new JFXListView<>();
listView.setPrefWidth(200);
listView.setCellFactory(lv -> new ListCell<String>()
{
JFXCheckBox checkBox = new JFXCheckBox();
#Override
public void updateItem(String item, boolean empty)
{
super.updateItem(item, empty);
if (empty) {
//setText(null);
setGraphic(null);
}
else {
checkBox.setText(item);
setGraphic(checkBox);
}
}
});
listView.getItems().add("Item 1");
listView.getItems().add("Item 2");
listView.getItems().add("Item 3");
HBox hbox = new HBox(listView);
Scene scene = new Scene(hbox, 300, 120);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}

Styling JavaFX ComboBox without CSS file

I would like to know if there is any way to style a JavaFX ComboBox programmatically. I have tried to use the method setStyle(String); and styled the button, but it doesn't affect the list
Is there any way to do that?
you can change (for example) the text fill color of the cells of the list in the ComboBox like this:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group(), 200, 200);
ComboBox<String> myComboBox = new ComboBox<String>();
myComboBox.getItems().addAll("A", "B", "C", "D", "E");
myComboBox
.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
#Override
public ListCell<String> call(ListView<String> param) {
final ListCell<String> cell = new ListCell<String>() {
{
super.setPrefWidth(100);
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
setText(item);
if (item.contains("A")) {
setTextFill(Color.RED);
} else if (item.contains("B")) {
setTextFill(Color.GREEN);
} else {
setTextFill(Color.BLACK);
}
} else {
setText(null);
}
}
};
return cell;
}
});
Group root = (Group) scene.getRoot();
root.getChildren().add(myComboBox);
stage.setScene(scene);
stage.show();
}
}
I think better way how to do it is set CSS ID or CSS class in code. For example your comboBox.
yourComboBox.setId("fancybox");
or set class:
yourComboBox.getStyleClass().clear();
yourComboBox.getStyleClass().add("fancyboxes");
and then style them in CSS.
then you can style almost everything on comboBox.
Example:
#fancyBox .cell {
-fx-text-fill: #4059a9;
}
there are many different "extensions" what you can add after #fancyBox and then style it. (Extension I mean that ".cell" after #fancyBox)
this can help you. Just keep searching.
Javafx combobox styling

java - images in javafx

I am still pretty new to java and i am still learning. I have never used images before so it is possible if I can have help add a image. I am not that sure what needs to be done in order to add one. Thank you
enter image description here
here is the code:
import javafx.application.Application;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
class User {
private StringProperty order = new SimpleStringProperty();
public String getOrder() {
return order.get();
}
public void setOrder(String order) {
this.order.set(order);
}
public StringProperty orderProperty() {
return order;
}
}
public class pizza extends Application {
private User user = new User();
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Pizza System");
Button btn = new Button();
btn.setText("place order");
BorderPane pane = new BorderPane();
pane.setBottom(btn);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
btn.setText("Order has been placed. Please wait at least 30 minutes.");
}
});
RadioButton tomatoButton = new RadioButton("Tomato");
RadioButton pepperButton = new RadioButton("Pepper");
RadioButton mushroomButton = new RadioButton("Mushrooms");
ChoiceBox<String> pizzaType = new ChoiceBox<String>();
pizzaType.getItems().addAll("", "Small", "Medium", "Large");
pizzaType.getSelectionModel().selectFirst();
HBox topHBox = new HBox(15.0, tomatoButton, pepperButton, mushroomButton, pizzaType);
// create custom Binding that binds selection of radio buttons and choice box
StringBinding orderBinding = createOrderBinding(tomatoButton.selectedProperty(), pepperButton.selectedProperty(), mushroomButton.selectedProperty(), pizzaType.getSelectionModel().selectedItemProperty());
// bind orderBinding to orderProperty of User
user.orderProperty().bind(orderBinding);
TextArea orderArea = new TextArea();
// bind orderProperty of User to textProperty of TextArea
orderArea.textProperty().bindBidirectional(user.orderProperty());
BorderPane root = new BorderPane();
root.setTop(topHBox);
root.setCenter(orderArea);
root.setBottom(btn);
Scene scene = new Scene(root, 400, 300);
stage.setScene(scene);
stage.show();
}
public StringBinding createOrderBinding(BooleanProperty tomato, BooleanProperty pepper, BooleanProperty mushroom, ReadOnlyObjectProperty<String> selectedPizzaType) {
StringBinding binding = new StringBinding() {
{
// bind 4 provided properties.
super.bind(tomato, pepper, mushroom, selectedPizzaType);
}
#Override
protected String computeValue() {
StringBuilder sb = new StringBuilder("Pizza content:\n");
if (tomato.get())
sb.append("\tTomato\n");
if (pepper.get())
sb.append("\tPepper\n");
if (mushroom.get())
sb.append("\tMushroom\n");
sb.append("Pizza type:\n").append("\t" + selectedPizzaType.get());
return sb.toString();
}
};
return binding;
}
public static void main(String[] args) {
Application.launch(args);
}
}
JavaFX uses an Image to load the image file and it has a node called ImageView to place that image on the screen graph.
Considering that the image is present at the same location as your class file, you can use this:
// Load Image
Image image = new Image(getClass().getResource("image.jpg").toExternalForm());
// Set the Image on the ImageView
ImageView imageView = new ImageView(image);
// specify a size
imageView.setFitWidth(200);
imageView.setFitHeight(200);
// Place ImageView in a container
root.setRight(imageView);

Replace a selected Label with a TextField

I have created ListView of Labels using :
ListView<Label> list = new ListView<Label>();
Image folder = new Image(getClass().getResourceAsStream("folder.png"));
ObservableList<Label> data = FXCollections.observableArrayList();
for (int i = 0; i < 6; i++) {
Label lbl = new Label();
lbl.setText("label" + i);
lbl.setGraphic(new ImageView(folder));
lbl.setContentDisplay(ContentDisplay.LEFT);
lbl.setGraphicTextGap(10.2);
data.add(lbl);
}
list.setItems(data);
I want the user to be able to double click on any of the Labels within the ListView, the selected Label should be replaced with a TextField so that the user can enter a new label name dynamically.
After the user presses Enter the TextField should turn back into a Label.
Don't use Label as the type of data for the ListView. Use String. Then you can just use the standard TextFieldListCell which has exactly the functionality you describe. Since you want a graphic in the standard cell display, just subclass TextFieldListCell and override the appropriate methods to include the graphic when the text field is not displayed:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import javafx.util.converter.DefaultStringConverter;
public class EditableListViewTest extends Application {
#Override
public void start(Stage primaryStage) {
ListView<String> list = new ListView<>();
Image testImg = new Rectangle(12, 12, Color.CORNFLOWERBLUE).snapshot(null, null);
for (int i = 0; i < 6; i++) {
list.getItems().add("label "+i);
}
StringConverter<String> identityStringConverter = new DefaultStringConverter();
list.setCellFactory(lv -> new TextFieldListCell<String>(identityStringConverter) {
private ImageView imageView = new ImageView(testImg);
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (! empty && ! isEditing()) {
setStaticGraphic();
}
}
#Override
public void cancelEdit() {
super.cancelEdit();
setStaticGraphic();
}
#Override
public void commitEdit(String newValue) {
super.commitEdit(newValue);
setStaticGraphic();
}
private void setStaticGraphic() {
setGraphic(imageView);
setContentDisplay(ContentDisplay.LEFT);
setGraphicTextGap(10.2);
}
});
list.setEditable(true);
primaryStage.setScene(new Scene(new BorderPane(list), 250, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Categories