I have two tableviews (one for employees and one for projects) and want to check on which a doubleclick happened. After that the data of the selected Item in the selected TableView should be loaded into TextFields.
My Employees just have an ID, a surename and a forename.
In Projects there is an ID and a projectname
#FXML
public void mouseClicked(MouseEvent event) {
if (event.getClickCount() == 2) //Checking double click
{
if(event.getTarget() == mitarbeiterview) {
Mitarbeiter abk = mitarbeiterview.getSelectionModel().getSelectedItem();
eintragVorname.setText(abk.getVorname());
eintragNachname.setText(abk.getNachname());
}else if(event.getTarget() == projektview) {
Projekt abk = projektview.getSelectionModel().getSelectedItem();
eintragBezeichnung.setText(abk.getName());
}
}
}
Related
I have customized a Hyperlink cell here. I want the tableview to select the content when I click this link, but after I add Hyperlink, the tableview's selected seems to be invalid.
tb_uGoodUrl.setCellFactory(new Callback<TableColumn<GoodModel, String>, TableCell<GoodModel, String>>() {
#Override
public TableCell<GoodModel, String> call(TableColumn<GoodModel, String> param) {
TableCell<GoodModel, String> cell = new TableCell<GoodModel, String>() {
private final Hyperlink hyperlink = new Hyperlink();
{
hyperlink.setOnMouseClicked(event -> {
if(event.getClickCount() == 2){
String url = getItem();
hostServices.showDocument(url);
}
});
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
}else {
hyperlink.setText(getItem());
setGraphic(hyperlink);
}
}
};
return cell;
}
});
Click on the link, the cell is not selected
If the cell is not selected, a null exception will be reported when the following code is used.
TablePosition pos = tableView.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
// Item here is the table view type:
GoodModel item = tableView.getItems().get(row);
TableColumn col = pos.getTableColumn();
// this gives the value in the selected cell:
String data = (String) col.getCellObservableValue(item).getValue();
The effect you want to achieve is as follows
Rendering
You can manually select the cell, using the table's selection model, when the Hyperlink is clicked on.
// Assuming this code is inside a TableCell implementation
hyperlink.setOnAction(event -> {
event.consume();
getTableView().getSelectionModel().select(getIndex(), getTableColumn());
// show your document
});
I used the onAction property which will be fired when the Hyperlink has been clicked once. This is typical behavior for a hyperlink, but if you want to only perform the action on a double-click then you can keep using your onMouseClicked handler.
Note the above does not take into account multiple-selection mode.
I have a TableView in my JavaFX application.
I would like to style differently row when it is double-clicked on it, and differently when it is single-clicked.
Here is what I achieve:
final PseudoClass doubleClickPseudoClass = PseudoClass.getPseudoClass("new");
setRowFactory(tableView -> {
final TableRow<Bean> row = new TableRow<Bean>();
row.setOnMouseClicked(event -> {
if (event.getClickCount() == 2 && (! row.isEmpty())) {
row.pseudoClassStateChanged(doubleClickPseudoClass, true);
});
return row;
});
However, when the user doubles click on every new row, I want all previously double-clicked rows to be styled without applying "new" class:
row.pseudoClassStateChanged(doubleClickPseudoClass, false);
How can I do that?
Now I have cumulative styled all rows as they are double-clicked.
You shouldn't use TableRows to store the state themselves since new items may be assigned to a TableRow instance. Instead use a property to store the item double-clicked item and use a listener for styling the rows:
final ObjectProperty<Bean> doubleClickedObject = new SimpleObjectProperty<>();
setRowFactory(tableView -> new TableRow<Bean>() {
private void updateStyle() {
pseudoClassStateChanged(doubleClickPseudoClass, !isEmpty() && doubleClickedObject.get() == getItem());
}
private final InvalidationListener listener;
{
listener = o -> updateStyle();
doubleClickedObject.addListener(new WeakInvalidationListener(listener));
setOnMouseClicked(event -> {
if (!isEmpty() && event.getClickCount() == 2) {
doubleClickedObject.set(getItem());
}
});
}
#Override
protected void updateItem(Bean item, boolean empty) {
super.updateItem(item, empty);
updateStyle();
}
});
I have 3 fields:
#FXML
private TextField name;
#FXML
private TextField lastName;
#FXML
private TextField phoneNumber;
I created for them EventHandler:
EventHandler<InputEvent> fieldChangeListener = new EventHandler<InputEvent>() {
public void handle(InputEvent event) {
String input = ((TextField) event.getSource()).getText();
System.out.println("Changed: "+event.getSource());
event.consume();
}
};
And assigned to them:
name.addEventHandler(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, fieldChangeListener);
lastName.addEventHandler(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, fieldChangeListener);
phoneNumber.addEventHandler(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, fieldChangeListener);
How can I determine which one of my 3 fields triggered event?
I want to call different functions depending on which one of those was changed, like:-
if(name){
function changedName();
}
else if(lastName){
function changedLastName();
}
else if(phoneNumber){
function changedPhoneNumber();
}
Instead of setting one event handler on all of them, create 3 different handlers
EventHandler<InputEvent> nameChangedHandler = (event) -> changedName();
EventHandler<InputEvent> lastNameChangedHandler = (event) -> changedLastName();
EventHandler<InputEvent> phoneNumberChangedHandler = (event) -> changedPhoneNumber();
and then then add them to their respective TextFields. If you are using a single event handler because there is common code at the start and end, then simply refactor those into separate functions and call them in all the event handlers.
If you still need an explicit check then use
Object source = event.getSource();
if(source == name) {
changedName();
} else if(source == lastName) {
changedLastName();
} else if(source == phoneNumber) {
changedPhoneNumber();
}
TextField input = ((TextField) event.getSource());
input.getId();
I need to click on the button that is already in a column to automatically select the row to be able to get and set the selected item. Otherwise, generate nullpointer. I was thinking of adding a listener that when I click the button select the row directly, but I do not know.
ScreenShot :
This is the code:
botonVisitar.setOnAction((ActionEvent event) -> {
TextInputDialog dialog1 = new TextInputDialog();
Stage stage1 = (Stage) dialog1.getDialogPane().getScene().getWindow();
stage1.getIcons().add(new Image(this.getClass().getResource("icono.jpg").toString()));
dialog1.setTitle("Visita:");
dialog1.setContentText("Ingresar Tipo de visita: (por ejemplo: llamada, mail, mensaje, etc)");
Optional<String> result1 = dialog1.showAndWait();
if (result1.isPresent()) {
TablaVisita.getSelectionModel().getSelectedItem().setTipoVisita(result1.get());
TablaVisita.getSelectionModel().getSelectedItem().setFechaVisita(LocalDate.now());
//If it is not selected i get nullPointer.
}
I assume you're doing this in a custom TableCell used with a cellFactory, which means you can use the TableRow to get the table item:
new TableCell<MyItem, Void>() {
private final Button botonVisitar = new Button("Visitar");
{
botonVisitar.setOnAction((ActionEvent event) -> {
...
if (result1.isPresent()) {
MyItem item = (MyItem) getTableRow().getItem();
item.setTipoVisita(result1.get());
item.setFechaVisita(LocalDate.now());
}
});
}
#Override
public void updateItem(Void item, boolean empty) {
super.updateItem(item, empty);
setGraphic(empty ? null : botonVisitar);
}
}
i am trying to put elements on a listview and treeview with javafx, but both controls wont refresh theyre content. i am using an obvservable list to control the items and every time i delete one item, the listview or treeview removes it from the datasource. but the view is not updating. i am still seeing all the items. the only difference is, the removed item can not be selected any more. for example link 2 shows the collaped item list. image 1 shows the items before they are collaped. the items are collapsed but the old entry is still visible. does anybody know a solution for this problem. thank you all for helping me
link 1: treeview is not collapsed
link 2: treeview is collapsed but not updating old view
this is the custom cell factory i use to display a listview:
public ListCell<T> call(final ListView<T> param) {
ListCell<T> cell = new ListCell<T>(){
#Override
protected void updateItem(final T persistentObject, final boolean empty) {
super.updateItem(persistentObject, empty);
if(persistentObject instanceof POProcessStep){
POProcessStep poProcessStep = (POProcessStep) persistentObject;
if (persistentObject != null) {
super.setText(poProcessStep.getId() + " - " + poProcessStep.getTitle());
}
}else if(persistentObject instanceof POProcess){
POProcess poProcess = (POProcess) persistentObject;
if (persistentObject != null) {
super.setText(poProcess.getId() + " - " + poProcess.getTitle());
}
}else if(persistentObject instanceof POCategory){
POCategory poCategory = (POCategory) persistentObject;
if(persistentObject != null){
super.setText(poCategory.getId() + " - " + poCategory.getTitle());
}
}else if(persistentObject instanceof String){
if(persistentObject != null){
super.setText(String.valueOf(persistentObject));
}
}
super.setGraphic(null);
}
};
return cell;
}
Your cell factory's updateItem(...) needs to handle the case where the cell is empty. This will be exactly the scenario when an item is removed (or becomes empty because a node in the TreeView was collapsed) and the cell that previously showed an item is reused as an empty cell:
public ListCell<T> call(final ListView<T> param) {
ListCell<T> cell = new ListCell<T>(){
#Override
protected void updateItem(final T persistentObject, final boolean empty) {
super.updateItem(persistentObject, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
// ... rest of your code.
}
}
}
return cell ;
}