adding item to TreeView when node gets expanded - javafx

Is there anyway I can add items to a TreeView control just when a node gets expanded?
I'd like to add child items to a tree item when the users expands the parent item.

Use expandedProperty, like in the example below:
treeItem.expandedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
BooleanProperty bb = (BooleanProperty) observable;
TreeItem t = (TreeItem) bb.getBean();
_treeItemEventHandler.onTreeItemExpanded(t);
// add items to t
}
});

Related

set caretPosition to the right in a textField (javaFX)

I am developing an javaFX application where the user has several textfields to fill and edit. I want that if you enter a new textfield by jumping from another by pressing TAB the content of the textfield is not selected and also the cursor is on the right. The textfields have an event listener that detects when they receive the focus and I have been testing various methods of the API to position the cursor and deselect content when entering the textfield, for the moment, all without success.
Where is my error?
id_ip2B_tf.focusedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
// 1 - don't work
id_ip2B_tf.deselect();
id_ip2B_tf.positionCaret(id_ip2B_tf.getLength());
// 2 - don't work
id_ip2B_tf.end();
}
}
Can you try wrapping the logic of setting the caret in Platform.runLater. Something like..
id_ip2B_tf.focusedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
Platform.runLater(()->{
id_ip2B_tf.deselect();
id_ip2B_tf.positionCaret(id_ip2B_tf.getLength());
});
}
}
});

Javafx TableView data refresh

I have combobox, tableview as TableView<Person> and 3 columns.
I want to populate the updated data in TableView as per item I select in combobox.
My Issue: every time I select the item in combobox, the data in table view is added. I want the details to be displayed for the selected item only.
Code:
public class MyTableController {
private TableView<Person> personTableView;
private ObservableList<Person> personTableViewData= FXCollections.observableArrayList();
initialize() {
comboBox.valueProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue ov, String oldValue, String newValue) {
List<Person> filteredPersonList =
personList.stream().filter(person -> person.getFirstName().contains(newValue)).collect(Collectors.toList());
personTableViewData.addAll(filteredPersonList);
personTableView.setItems(personTableViewData);
}
}
Use ObservableList.setAll instead of ObservableList.addAll or alternatively create a new ObservableList. Otherwise you're adding new items to the same list on every change instead of replacing the items:
initialize() {
personTableView.setItems(personTableViewData);
comboBox.valueProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue ov, String oldValue, String newValue) {
List<Person> filteredPersonList =
personList.stream().filter(person -> person.getFirstName().contains(newValue)).collect(Collectors.toList());
personTableViewData.setAll(filteredPersonList);
}
}

Idiomatic way to implement context dependent MenuBar?

I have a #FXML Menu editMenu defined, and I want to populate it depending on which of my TreeViews is currently in focus, and on whether or not there are any TreeItems selected.
What would be the idiomatic way of doing this? I haven't been able to find a nice onFocus method for the TreeViews.
Thanks!
All Nodes have a focusedProperty() with which you can register a listener. Additionally, the Scene has a focusOwner property you can observe.
So you can do something like
scene.focusOwnerProperty().addListener(new ChangeListener<Node>() {
#Override
public void changed(ObservableValue<? extends Node> obs, Node oldFocusOwner, Node newFocusOwner) {
// update menu based on newFocusOwner
}
});
If you're using FXML, it can be difficult to get hold of the Scene in the controller. You may need to do something like:
ChangeListener<Node> menuUpdater = new ChangeListener<Node>() {
#Override
public void changed(ObservableValue<? extends Node> obs, Node oldFocusOwner, Node newFocusOwner) {
// update menu based on newFocusOwner
}
};
someNode.sceneProperty().addListener(new ChangeListener<Scene>() {
#Override
public void changed(ObservableValue<? extends Scene> obs, Scene oldScene, Scene newScene) {
if (oldScene != null) {
oldScene.focusOwnerProperty().removeListener(menuUpdater);
}
if (newScene != null) {
newScene.focusOwnerProperty().addListener(menuUpdater);
}
}
});
where someNode is any node in the scene graph.

Checkbox selected bind with TableView

How to bind with TableView selection model with checkbox isSelected in table view.In manually (using mouse multiple select) select the item in tableview
ObservableList<T> observableList = tableView.getSelectionModel().getSelectedItems();
System.out.println(observableList);
how to bind checkbox with tableview
box.selectedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
if (t1) {
Object object = getTableView().getItems().get(getTableRow().getIndex());
objects.add(object);
getTableView().getItems().set(getTableRow().getIndex(), object);
tableView.getSelectionModel().getSelectedItem(); //tableView.getSelectionModel().setSelectedIndex(getTableRow().getIndex());
} else {
Object object = getTableView().getItems().get(getTableRow().getIndex());
objects.remove(object);
}
System.out.println(objects);
}
});
if Checkbox is selected in row that row item bind with getSelectionModel().getSelectedItems() or how set manually setSelectedItems in tableView
Add to this line in box.selectedProperty().addListener()
tableView.getSelectionModel().select(getTableRow().getIndex());
box.selectedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
if (t1) {
tableView.getSelectionModel().select(getTableRow().getIndex());
} else {
tableView.getSelectionModel().clearSelection(getTableRow().getIndex());
}
}
});

JAVAFX event triggered when selecting a check box

My JavaFx FXML application has an issue.
When I select a checkbox on a form, I want to execute a method based on the checkbox that was clicked. Is there any way that I can pass the name of the checkbox through to the method so I can perform some conditional work on it?
I have two checkboxes and only one can be selected. When I click on one, the other should be de-selected and vice versa. Obviously the code below will not work so I am looking to pass the name of the object that was clicked.
Any help would be appreciated,
many thanks.
#FXML private void updateRcs(){
if (chkRcsuri.isSelected()){
chkRcsuri2.setSelected(false);
}
if (chkRcsuri2.isSelected()){
chkRcsuri.setSelected(false);
}
}
You can use change tracking or use Event handling mechanism of JavaFX.
With checkboxes like this,
final CheckBox chk1 = new CheckBox("chk 1");
final CheckBox chk2 = new CheckBox("chk 2");
Change tracking
chk1.selectedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
chk2.setSelected(!newValue);
}
});
chk2.selectedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
chk1.setSelected(!newValue);
}
});
Using event handling
EventHandler eh = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if (event.getSource() instanceof CheckBox) {
CheckBox chk = (CheckBox) event.getSource();
System.out.println("Action performed on checkbox " + chk.getText());
if ("chk 1".equals(chk.getText())) {
chk2.setSelected(!chk1.isSelected());
} else if ("chk 2".equals(chk.getText())) {
chk1.setSelected(!chk2.isSelected());
}
}
}
};
chk1.setOnAction(eh);
chk2.setOnAction(eh);
Wouldn't radio buttons give you a mutually exclusive selection? Just make sure you set the groupname to be the same - selecting one would then automatically de-select the other and you can just put additional logic in the Action event.
Better than trying to re-write same functionality around checkboxes.
So I was trying to do a similar thing, except I had multiple checkboxes and then one that would be nonsensical to have selectable in conjuction with the others. I made two seperate listeners and set one general purpose one to the main boxes, and a specialized one to the exception.
#FXML private CheckBox redCB = new CheckBox();
#FXML private CheckBox blueCB = new CheckBox();
#FXML private CheckBox greenCB = new CheckBox();
#FXML private CheckBox whiteCB = new CheckBox();
#FXML private CheckBox blackCB = new CheckBox();
#FXML private CheckBox colorlessCB = new CheckBox();
//assigning listeners
redCB.selectedProperty().addListener(colorCheckChange);
blueCB.selectedProperty().addListener(colorCheckChange);
greenCB.selectedProperty().addListener(colorCheckChange);
whiteCB.selectedProperty().addListener(colorCheckChange);
blackCB.selectedProperty().addListener(colorCheckChange);
colorlessCB.selectedProperty().addListener(colorlessCheckChange);
//note: this is the only different one^^^
//making listeners
ChangeListener colorCheckChange = new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> ov,
Boolean old_val, Boolean new_val) {
if (new_val)
colorlessCB.setSelected(false);
}};
ChangeListener colorlessCheckChange = new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> ov,
Boolean old_val, Boolean new_val) {
if (new_val)
{
redCB.setSelected(false);
blueCB.setSelected(false);
greenCB.setSelected(false);
blackCB.setSelected(false);
whiteCB.setSelected(false);
}
}
};
The first one basically just makes sure that colorlessCB isn't selected while trying to select the other colors, and vice verca. This way you also avoid the problem of de-selecting one, and the other one automatically reselecting itself.
This is my solution. But be sure about the a variable to be appropriate for you
//First in FXML file
<CheckBox fx:id="chkbxAuto" mnemonicParsing="false" onAction="#autoConfig" text="Auto" />
// in controler
public class FXMLController implements Initializable {
private static int a = 0;
//references to lables
....
#FXML
private Label lblStateValue;
#FXML
private Group grpSetting; // a group of elements which I want to be disabled and enabled
...
#FXML
private void autoConfig(ActionEvent event) {
System.out.println("Configing automatically");
a++;
if(a%2==1){
lblStateValue.setText("Auto configuration enabled"); // it change a lable to show the state
grpSetting.setDisable(true); // it disable a group of elements
}
else{
lblStateValue.setText("Auto configuration disabled");
grpSetting.setDisable(false);
}
a%=10;
}
...
I know this question is pretty old, but I found when looking for the same problem. I found a solution which
a) seems clearer (at least to me comparing to the listener definition) for reading source code and
b) Defining a changeListener on a checkBox gave me some problems.
Anyway my solution was to define an onAction function for the checkbox.
yourCheckboxName.setOnAction(this::aFunctionName);
...
void aFunctionName() {
if(yourCheckboxName.isSelected()) {
doThis()
} else {
doThat()
}
}
Attention This needs Java8 or higher.
None of the above options take advantage of the most commpact lambda expresions that can be used to add this very repetitive listeners.
Let suppose you have two checkboxes:
chk1.selectedProperty().addListener((observable, oldValue, newValue) -> chk2.setSelected(!newValue));
chk2.selectedProperty().addListener((observable, oldValue, newValue) -> chk1.setSelected(!newValue));

Resources