Lookup model details when constructing JavaFX context menuitem - javafx

Follow-up to this question.
I need to construct one of the MenuItems with some content from the row model.
row.getItem() is null as the row isnt initialized in the rowfactory callback.
Is there a way to defer the creation of the context menu when the row model has been populated?
For example, if the row as a String property name = "foo", the MenuItem should display "Add foo".

In the context of my answer to Determine a JavaFX table row details when reusing tableview context menu you would do
table.setRowFactory(t -> {
TableRow<Item> row = new TableRow<>();
ContextMenu contextMenu = new ContextMenu();
MenuItem item1 = new MenuItem();
// ...
row.itemProperty().addListener((obs, oldItem, newItem) -> {
item1.setText(/* value depending on newItem... */);
});
// ...
}

Related

JavaFX MenuItem, handling the event

I'm developing an small application and I have a problem when creating the menu bar.
This is my start method:
public void start(#SuppressWarnings("exports") Stage prymaryStage) throws Exception {
// Stats menu
Menu statsMenu = new Menu("Stats");
// PairName menu
Menu pairNameMenu = new Menu("Choose pair");
// Stats Menu items
MenuItem gStats = new MenuItem("General stats");
// Pair list
ArrayList<String> pairNameList = DatabaseMethods.returnPairNameList();
// PairName items (probably i will have to change)
for (String item : pairNameList) {
pairNameMenu.getItems().add(new MenuItem(item));
}
statsMenu.getItems().addAll(gStats, pairNameMenu);
// Main menu bar
MenuBar menuBar = new MenuBar();
menuBar.getMenus().addAll(statsMenu);
// BorderPane settings
BorderPane borderPane = new BorderPane();
borderPane.setTop(menuBar);
Scene scene = new Scene(borderPane, 1200, 800);
prymaryStage.setTitle("English minimal pair training");
prymaryStage.setScene(scene);
prymaryStage.show();
}
The problem I have is in this part of the code:
ArrayList<String> pairNameList = DatabaseMethods.returnPairNameList();
// PairName items (probably i will have to change)
for (String item : pairNameList) {
pairNameMenu.getItems().add(new MenuItem(item));
}
I was trying to create the items of a submenu from an ArrayList. This data is fetch from a database and the data is returned in form of an ArrayList. I didn't find any other way to do the menu items than pairNameMenu.getItems().add(new MenuItem(item)); inside the for loop.
Now I want to handle the click in the items but I don't know how to do it. I've tried with .setOnAction but Eclipse says the .add(new MenuItem(item)) can't be use in that case and recomends .addAll and the same happens, Eclipse says that's an error and recomends .add
I tried to add this code after new MenuItem(item)
.addEventHandler(new EventHandler<ActionEvent>() {
public void handle(ActionEvent even) {
}
})
But it didn't work either.
I'm pretty new to Java and JavaFX, this is my first project so sorry if this is a very basic question.
Thank you for your time
You have to loop through pairNameMenu items after you have created and added all the items to pairNameMenu:
pairNameMenu.getItems().foreach((item) ->{
item.addEventHandler.....
....
....
});
or do something like below when creating the MenuItems:
for (String item : pairNameList) {
MenuItem tempMenuItem = new MenuItem(item);
tempMenuItem..addEventHandler.....
....
....
pairNameMenu.getItems().add(tempMenuItem);
}

How to get the column title and first column row value for a cell in javafx

I have JavaFX tableview that I have created dynamically. When one double-clicks on a cell on the tableview, I need to get the name of the column the cell is in and the value of the first cell in the row this cell is in. I have tried searching over google and found no particular solution to this problem. Kindly show me some sample code.
Ok, so first, let's assume your TableView is attached to a model:
public TableView<MyModel> myTable;
where MyModel is something like:
public class MyModel {
private Integer id;
private String name;
// ... etc.
}
so, MyModel is a common POJO. You can have columns of your TableView like:
TableColumn<MyModel, Integer> id = new TableColumn<>("ID");
id.setCellValueFactory(new PropertyValueFactory<>("id"));
TableColumn<MyModel, String> name = new TableColumn<>("Name");
name.setCellValueFactory(new PropertyValueFactory<>("name"));
and then, to add the columns to your table:
myTable.getColumns().addAll(id, name);
Now, let's listen to the click event using a rowFactory:
myTable.setRowFactory(tv -> {
TableRow<MyModel> row = new TableRow<>();
row.setOnMouseClicked(event -> {
// check for non-empty rows, double-click with the primary button of the mouse
if (!row.isEmpty() && event.getClickCount() == 2 && event.getButton() == MouseButton.PRIMARY) {
MyModel element = row.getItem();
// now you can do whatever you want with the myModel variable.
System.out.println(element);
}
});
return row ;
});
That should do the work.

Accessing the Value of a CheckBox in TableView

I'm having trouble getting the boolean value of whether a checkbox in a tableView for JavaFX is selected or not.
(Link to Image)
https://i.imgur.com/pIWDcfI.png
For some reason the when I getCellObservableValue() to get the CheckBox at index 1, I get null as the result.
//From SceneBuilder/JavaFX file
<TableColumn fx:id="labelColumn" prefWidth="112.57145690917969" text="Use
as Label" />
//Setting Up Table, which displays everything correctly
TableColumn<Integer,CheckBox> labelColumn = (TableColumn<Integer,
CheckBox>) elements.get("labelColumn");
labelColumn.setCellFactory(data -> new CheckBoxTableCell<>());
monitorTable.setEditable(true);
//Trying to Access, which gives null pointer exception
CheckBox cb = (CheckBox) labelColumn.getCellObservableValue(1);
System.out.println(cb.isSelected());
That method returns null if there's no cellValueFactory set. Besides, you should really have a model to hold this stateā€”a TableView is just a view. Unlike the TableViewSelectionModel, which represents which items are selected solely in the context of the TableView itself, a column containing CheckBoxes represents the "boolean state" of a property of the model. For example:
public class ToDoTask {
private final StringProperty name = new SimpleStringProperty(this, "name");
private final BooleanProperty complete = new SimpleBooleanProperty(this, "complete");
// constructors, getters, setters, and property-getters omitted for brevity
}
A TableView for displaying that class could be configured like the following:
TableView<ToDoTask> table = new TableView<>();
table.setItems(...);
TableColumn<ToDoTask, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(features -> features.getValue().nameProperty());
table.getColumns().add(nameCol);
TableColumn<ToDoTask, Boolean> completeCol = new TableColumn<>("Complete");
completeCol.setCellValueFactory(features -> features.getValue().completeProperty());
completeCol.setCellFactory(CheckBoxTableCell.forTableColumn(completeCol));
table.getColumns().add(completeCol);
You would then query if a task is complete by accessing the model:
table.getItems().get(...).isComplete();
Another option to setting the cellValueFactory is to register a Callback with the CheckBoxTableCells themselves. See CheckBoxTableCell#forTableColumn(Callback).
Also, note that getCellObservableValue() returns an ObservableValue. A CheckBox is not an ObservableValue. If you weren't receiving null you'd be getting a ClassCastException.

How can I add GridPane(contains 3 Buttons) to the Cell of a JAvaFX TableView

I have a TableView named as "customers" with TableColumns related to customer details.
In the same TableView, I want to add one more TableColum as "Action" in which User should have possibilities to Add,View and delete Product details for particular Customer.
Tried multiple things by googling it but till now didn't get any solution for it.
Just add a TableColumn with a custom cellFactory. BTW: You probably want to use a single column/row for the Buttons, in which case you can simply use HBox or VBox, but you could of course replace the layout in the following code:
TableColumn<Product, Void> buttonColumn = new TableColumn<>("Action");
buttonColumn.setCellFactory(col -> new TableCell<Product, Void>() {
private final VBox container;
{
Button add = new Button("Add");
Button view = new Button("View");
Button delete = new Button("Delete");
delete.setOnAction(evt -> {
// delete this row item from TableView items
getTableView().getItems().remove(getIndex());
});
view.setOnAction(evt -> {
// call some method with the row item as parameter
viewProduct(getTableRow().getItem());
});
add.setOnAction(...);
container = new VBox(5, add, view, delete);
}
#Override
public void updateItem(Void item, boolean empty) {
super.updateItem(item, empty);
setGraphic(empty ? null : container);
}
});
tableView.getColumns().add(buttonColumn);

javafx set onkeypressed for an editable comboboxtablecell

I have an editable tableview with editable column with this cell factory
tblColumn.setCellFactory(t -> {
ComboBoxTableCell myComboBoxTableCell = new ComboBoxTableCell();
myComboBoxTableCell.setOnKeyPressed(e -> {
System.out.println("key pressed");
KeyCode code = e.getCode();
System.out.println("code "+code);
});
myComboBoxTableCell.setComboBoxEditable(true);
return myComboBoxTableCell;
});
what i'm trying to do is to get letter typed in the editable comboBoxTableCell, but when i type, the onKeyPressed method is not fired. am i doing something wrong?
PLease help.

Resources