Javafx tableview row contextmenu bindings - javafx

Per this link, I have added context menu to my tableview using the following pattern -
row.contextMenuProperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu)null));
I have a requirement where the multiple rows can be selected (SelectionMode.MULTIPLE) and I need to display the context menu when a row property matches a specific value. I have tried this but no luck -
// Show menu only if row is not null and value property == "foo"
row.contextMenuProperty().bind(
Bindings.when(Bindings.and(Bindings.isNotNull(row.itemProperty()), Bindings.equal("foo", row.getItem().value))
.then(rowMenu)
.otherwise((ContextMenu)null));
UPDATE
I got this working via a listener -
row.emptyProperty().addListener((obs, wasEmpty, isEmpty) -> {
if (isEmpty) {
row.setContextMenu(null);
} else {
if (row.getItem().name.get().equals("foo")) {
row.setContextMenu(contextMenu);
}
}
});
Question - Is there a way to achieve this using the Bindings API?

Your binding does this:
Bindings.equal("foo", row.getItem().value)
But your listener does this:
row.getItem().name.get().equals("foo")
So perhaps, using this in the binding would work:
Bindings.equal("foo", row.getItem().name.get())

Related

Javafx validate CheckBoxTableCell when check a checkbox

I follow this example to use CheckBoxTableCell in TableView:
JavaFX: CheckBoxTableCell get ActionEvent when user check a checkBox
I have table in my project like this:
I tried this code to validate (in the same row) if primary checkbox or secondary checkbox is selected, the other one unselect. But code doesnt work:
primaryTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(i -> {
Diet diet = diets.get(i);
if (diet.isPrimary()) {
diet.setSecondary(false);
}
return diet.primaryProperty();
}));
secondaryTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(i -> {
Diet diet = diets.get(i);
if (diet.isSecondary()) {
diet.setPrimary(false);
}
return diet.secondaryProperty();
}));
How can i code in order to uncheck one checkbox if other one in same row is checked (preferably using bindings)? thanks and sorry for my english

How can I use .lookUp() before the stage is shown (or use it once the stage is shown)

I want to use .lookup() so that I can create an event for when the content of a TextArea is clicked, but I get null when I use textArea.lookup(".content"). After searching why this is, I found out that it returns null if called before stage.show(). My next reaction was to somehow check for an event that is cast once the stage is shown, but that event is only accessible if you have access to the stage itself, which I do not in this case. What else can I do?
Don't register the handler at the content node. Let TextArea deal with the creation of the content node on its own, register a event handler at the TextArea directly and use the pickResult of the event to determine, if the click happened inside the node with style class content.
textArea.setOnMouseClicked(evt -> {
Node n = evt.getPickResult().getIntersectedNode();
while (n != textArea) {
if (n.getStyleClass().contains("content")) {
// do something with content node
System.out.println("content: " + n);
break;
}
n = n.getParent();
}
});
Generate a layout pass on the node:
node.applyCss();
node.layout();
as defined in the answer to:
Get the height of a node in JavaFX (generate a layout pass)
After that, your lookup functions on the node should work as expected.

allowsSelectionDuringEditing property for NSTableView

Application I'm trying to develop is heavily built around being able to have editable TableViews. I'm beginning to conclude that most if not all of my problems stem from the fact that I do not see allowsSelectionDuringEditing available for NSTableView as it is for UITableView.
First, would like to get insight into why.
Second, how do I go about implementing one in my NSTableView class?
Finally, I have a NSSegmentedControl in one of my columns. So I need to implement allowSelectiongWhenFocused property somewhere, because while I have focus on the button and allowing user to use <- and -> with spacebar to select switch(es), I don't want mouse / keyboard from changing the selected row.
As an aside, while I now know how to write custom UI classes and hook them into Interface Builder, I'm struggling on when/whether to customize NSTableView, NSTableRowView, NSTableCellView or NSSegmentedControl. I've tried to understand how refuseFirstResponder works as well. Trial and error is not getting me anywhere - I fix something and break something somwehre else. If someone can suggest any other reading besides Apple documentation (sometimes I suspect if it is in English) would really appreciate it.
Here's what I would do:
Subclass NSTableRowView and override hitTest(_:). If the row is not selected then the row view returns itself instead of a control. The first click in a row selects the row and doesn't change the value of a control.
override func hitTest(_ point: NSPoint) -> NSView? {
let view = super.hitTest(point)
if view == nil || self.isSelected {
return view
}
else {
return self
}
}
Implement NSTableViewDelegate's tableView(_:rowViewForRow:) to use the custom row view:
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
return MyTableRowView()
}
Implement NSTableViewDelegate's selectionShouldChange(in:) so a row can't be deselected if the values aren't valid or other conditions aren't met.
func selectionShouldChange(in tableView: NSTableView) -> Bool {
let row = tableView.selectedRow
if (row >= 0) {
return self.validateRow(row)
}
else {
return true
}
}

tornadofx EventBus expand table row using tableview object

Background:
Suppose I have multiple fragments of a single table in a view, each with a rowExpander.
Expected Behaviour:
If in one table fragment I expand a row, other fragments same indexed row should get expanded. Same for collapse
My Progress:
Sample Fragment:
tableview(dataset) {
column("First Name", Person::firstNameProperty)
column("Last Name", Person::lastNameProperty)
rowExpander(true) {
selectedData.item?.apply {
fire(ExpandDataEvent(dataset.indexOf(this)))
}
column("Mobile Nos.", Person::mobileNumProperty)
column("Email Ids", Person::emailIdProperty)
}
bindSelected(selectedData)
subscribe<ExpandDataEvent> { event ->
selectionModel.select(event.index)
}
}
Event Class:
class ExpandDataEvent(val index: Int) : FXEvent()
What I understand from "subscribe" is that it gets called when an event is fired (currently I am firing the event whenever the user expands the row by either double-click/clicking the plus sign); and since the subscribe is placed inside tableview, it gets called for all the table fragments present (which is what I want). But in the subscribe method I am doing a selectionModel.select(event.index) which only selects the corresponding index row. I want to expand the row (preferably by using the selectionModel)
Question 2:
Is it possible to remove the plus sign column? For rowExpand, if I have set expandOnDoubleClick to true, I dont want the plus sign column in my tableview.
The rowExpander builder returns the actual ExpanderColumn which is basically a normal TableColumn. Save a reference to the expander so that you can operate on it later:
val expander = rowExpander(true) { ... }
Directly below, you can now hide the expander column:
expander.isVisible = false
Now it's easy to toggle the expanded state of a specific row from the event subscriber as well:
subscribe<ExpandDataEvent> { event ->
expander.toggleExpanded(event.index)
selectionModel.select(event.index)
}
You might want to double check that you don't toggle the expander for the tableview that fired the event, so consider including the event source in your event and discriminate on that in the subscriber.
I will investigate if we can add a visible boolean parameter to the rowExpander builder function so you don't need to call isVisible manually :)

show different item on selectionchange on a grid

i have a grid and a form, i need to show different items on the form each time we select a row on that grid
i ve been looking on how to do this, and found
Ext.getCmp('myform').hide() // or .show()
and
listeners: { selectionchange: function () {...}
now i dont know which row is selected so i can specify which item to show
thanks
You get the selected rows as second parameter in the selectionchange event handler:
listeners: {
selectionchange: function (view, selections, options) {
console.log(view, selections, options);
}
}
So the first selected row is the first element in the selections array:
record = selections[0]
This is described in the Ext JS 4 API documentation for the selectionchange event.
Try to following code in your grid.
listeners:{
itemclick:function(view, record, item, index, e ) {
var v = record.get('firstName');
....
....
}
}
firstName will be your dataindex of colums in your grid.
You can get value of any field like this.

Resources