javafx - How to implement correct doubleclick-to-edit in TableView -


problem

the tableview seems go edit mode click on selected cell.
unwanted , inconsistent behavior, because selection changes if click outside of current selection.
doesn't change when click inside current selection.

if anything, real double click should required go edit mode, @ least when work on desktop.

reproduction:

create tableview selection mode:


// cell selection mode instead of row selection
table.getselectionmodel().setcellselectionenabled(true);
// allow selection of multiple cells
table.getselectionmodel().setselectionmode(selectionmode.multiple);

now select multiple cells (via shift keypress). click on single cell of selected cells.

the current behavior:

  • the table goes edit mode

question

the requested behavior:

  • only selection should change, i. e. single cell should selected; edit mode should happen on double-click

how can achieve this?

code

here's full example. took code oracle samples website, added above lines , pre-selected cells. when click on single cell after program start, table goes directly edit mode:


    public class tableviewsample extends application {
private tableview<person> table = new tableview<person>();
private final observablelist<person> data =
fxcollections.observablearraylist(
new person("jacob", "smith", "jacob.smith@example.com"),
new person("isabella", "johnson", "isabella.johnson@example.com"),
new person("ethan", "williams", "ethan.williams@example.com"),
new person("emma", "jones", "emma.jones@example.com"),
new person("michael", "brown", "michael.brown@example.com"));
final hbox hb = new hbox();
public static void main(string[] args) { launch(args); }
@override
public void start(stage stage) {
scene scene = new scene(new group());
stage.settitle("table view sample");
stage.setwidth(450);
stage.setheight(550);
final label label = new label("address book");
label.setfont(new font("arial", 20));
table.seteditable(true);
tablecolumn firstnamecol = new tablecolumn("first name");
firstnamecol.setminwidth(100);
firstnamecol.setcellvaluefactory( new propertyvaluefactory<person, string>("firstname"));
firstnamecol.setcellfactory(textfieldtablecell.fortablecolumn());
firstnamecol.setoneditcommit(
new eventhandler<celleditevent<person, string>>() {
@override
public void handle(celleditevent<person, string> t) {
((person) t.gettableview().getitems().get(t.gettableposition().getrow())
).setfirstname(t.getnewvalue());
}
});
tablecolumn lastnamecol = new tablecolumn("last name");
lastnamecol.setminwidth(100);
lastnamecol.setcellvaluefactory(
new propertyvaluefactory<person, string>("lastname"));
lastnamecol.setcellfactory(textfieldtablecell.fortablecolumn());
lastnamecol.setoneditcommit(
new eventhandler<celleditevent<person, string>>() {
@override
public void handle(celleditevent<person, string> t) {
((person) t.gettableview().getitems().get(
t.gettableposition().getrow())).setlastname(t.getnewvalue());
}
});
tablecolumn emailcol = new tablecolumn("email");
emailcol.setminwidth(200);
emailcol.setcellvaluefactory(
new propertyvaluefactory<person, string>("email"));
emailcol.setcellfactory(textfieldtablecell.fortablecolumn());
emailcol.setoneditcommit(
new eventhandler<celleditevent<person, string>>() {
@override
public void handle(celleditevent<person, string> t) {
((person) t.gettableview().getitems().get(
t.gettableposition().getrow())).setemail(t.getnewvalue());
}
});
table.setitems(data);
table.getcolumns().addall(firstnamecol, lastnamecol, emailcol);
final textfield addfirstname = new textfield();
addfirstname.setprompttext("first name");
addfirstname.setmaxwidth(firstnamecol.getprefwidth());
final textfield addlastname = new textfield();
addlastname.setmaxwidth(lastnamecol.getprefwidth());
addlastname.setprompttext("last name");
final textfield addemail = new textfield();
addemail.setmaxwidth(emailcol.getprefwidth());
addemail.setprompttext("email");
final button addbutton = new button("add");
addbutton.setonaction(new eventhandler<actionevent>() {
@override
public void handle(actionevent e) {
data.add(new person(addfirstname.gettext(),
addlastname.gettext(),addemail.gettext()));
addfirstname.clear();
addlastname.clear();
addemail.clear();
}
});
hb.getchildren().addall(addfirstname, addlastname, addemail, addbutton);
hb.setspacing(3);
final vbox vbox = new vbox();
vbox.setspacing(5);
vbox.setpadding(new insets(10, 0, 0, 10));
vbox.getchildren().addall(label, table, hb);
((group) scene.getroot()).getchildren().addall(vbox);
stage.setscene(scene);
stage.show();
// cell selection mode instead of row selection table.getselectionmodel().setcellselectionenabled(true);
// allow selection of multiple cells
table.getselectionmodel().setselectionmode(selectionmode.multiple);
// select demo purposes
table.getselectionmodel().selectall();
}
public static class person {
private final simplestringproperty firstname;
private final simplestringproperty lastname;
private final simplestringproperty email;
private person(string fname, string lname, string email) {
this.firstname = new simplestringproperty(fname);
this.lastname = new simplestringproperty(lname);
this.email = new simplestringproperty(email);
}
public string getfirstname() {
return firstname.get();
}
public void setfirstname(string fname) {
firstname.set(fname);
}
public string getlastname() {
return lastname.get();
}
public void setlastname(string fname) {
lastname.set(fname);
}
public string getemail() {
return email.get();
}
public void setemail(string fname) {
email.set(fname);
}
}
}

you can try clear selection on mouse pressed event:

table.addeventfilter( mouseevent.mouse_pressed, new eventhandler<mouseevent>() {
@override
public void handle( mouseevent event ) {
if( event.iscontroldown()) {
return;
}
if ( table.geteditingcell() == null) {
table.getselectionmodel().clearselection();
}
}
});