Tuesday, 15 July 2014

java - MultipleSelectionModel: which list change events to expect from selectedIndices? -



java - MultipleSelectionModel: which list change events to expect from selectedIndices? -

... in particular when modifying underlying items?

below quick illustration selects range , adds item above selection tableview , listview. selectedindices before/after adding:

indices before modification: [2, 3] indices after modification: [3, 4]

expected options:

a single wasreplaced whole range a wasremoved "2" , wasadded "4" ??

actual:

table's selection fires 2 events, each single wasadded list's selection fires waspermutated (that's nuts, or missing?)

output (jdk8u40b12):

change #0 on tableview indices list = [3] alter event data: class javafx.scene.control.multipleselectionmodelbase$3 javafx.scene.control.multipleselectionmodelbase$3@4ececa cursor = 0 kind of change: added affected range: [0, 1] added size: 1 added sublist: [3] alter #1 on tableview indices list = [3, 4] alter event data: class javafx.scene.control.multipleselectionmodelbase$3 javafx.scene.control.multipleselectionmodelbase$3@b0161d cursor = 0 kind of change: added affected range: [1, 2] added size: 1 added sublist: [4] alter #0 on listview indices list = [3, 4] alter event data: class com.sun.javafx.collections.noniterablechange$simplepermutationchange { permutated [4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] } cursor = 0 kind of change: permutated affected range: [0, 2] permutation: [0->4, 1->3]

the producing code:

import javafx.application.application; import javafx.collections.fxcollections; import javafx.collections.listchangelistener; import javafx.collections.observablelist; import javafx.collections.listchangelistener.change; import javafx.scene.control.listview; import javafx.scene.control.selectionmode; import javafx.scene.control.tableview; import javafx.stage.stage; public class selectedindicesonitemsmodified extends application { @override public void start(stage primarystage) throws exception { observablelist<integer> items = fxcollections.observablearraylist(1, 2, 3, 4); tableview<integer> table = new tableview<>(items); table.getselectionmodel().setselectionmode(selectionmode.multiple); table.getselectionmodel().selectrange(2, 4); system.out.println("indices before modification: " + table.getselectionmodel().getselectedindices()); listview<integer> list = new listview<>(items); list.getselectionmodel().setselectionmode(selectionmode.multiple); list.getselectionmodel().selectrange(2, 4); new printinglistchangelistener("tableview indices ", table.getselectionmodel().getselectedindices()); new printinglistchangelistener("listview indices ", list.getselectionmodel().getselectedindices()); items.add(0, 111); } public static void main(string[] args) { launch(args); } public static <t> void prettyprint(change<? extends t> change) { stringbuilder sb = new stringbuilder("\tchange event data:\n"); sb.append("\n " + change.getclass() + "\n " + change); int = 0; change.reset(); while (change.next()) { sb.append("\n\tcursor = ").append(i++).append("\n"); final string kind = change.waspermutated() ? "permutated" : alter .wasreplaced() ? "replaced" : change.wasremoved() ? "removed" : change.wasadded() ? "added" : change.wasupdated() ? "updated" : "none"; sb.append("\t\tkind of change: ").append(kind).append("\n"); sb.append("\t\taffected range: [").append(change.getfrom()) .append(", ").append(change.getto()).append("]\n"); if (kind.equals("added") || kind.equals("replaced")) { sb.append("\t\tadded size: ").append(change.getaddedsize()) .append("\n"); sb.append("\t\tadded sublist: ") .append(change.getaddedsublist()).append("\n"); } if (kind.equals("removed") || kind.equals("replaced")) { sb.append("\t\tremoved size: ").append(change.getremovedsize()) .append("\n"); sb.append("\t\tremoved: ").append(change.getremoved()) .append("\n"); } if (kind.equals("permutated")) { stringbuilder permutationstringbuilder = new stringbuilder("["); (int k = change.getfrom(); k < change.getto(); k++) { permutationstringbuilder.append(k).append("->") .append(change.getpermutation(k)); if (k < change.getto() - 1) { permutationstringbuilder.append(", "); } } permutationstringbuilder.append("]"); string permutation = permutationstringbuilder.tostring(); sb.append("\t\tpermutation: ").append(permutation).append("\n"); } } system.out.println(sb.tostring()); }; public static class printinglistchangelistener implements listchangelistener { string source; int counter; public printinglistchangelistener() { } public printinglistchangelistener(string message, observablelist<?> list) { list.addlistener(this); source = message; } @override public void onchanged(change change) { system.out.println("change #" + counter++ + " on " +source + "\nlist = " + change.getlist()); prettyprint(change); } } }

filed 2 issues, rt-39393 listview, rt-39394 tableview

a tentative partly reply own question

notification count

number of notification (aka: calls changed(change c)) should same number in underlying data, in pseudo-code

itemschanges = 0; itemslistener = c -> itemschanges++; getitems().addlistener(itemslistener); selectedchanges = 0; selectedlistener = c -> selectedchanges++; getselectedindices().addlistener(selectedlistener); getitems().modifysomehow(...); assertequals(itemschanges, selectedchanges);

change types

thinking it, changes in underlying items seem map replaced in selectedindices ("value" below denotes elements in selectedindices):

"real" wasadded: values greater insertion location must increased addedsize

// selectedindices before [2, 4] items.add(0, something); // selectedindices after [3, 5]

-> net effect: 2 values set (== replaced by) new value

"real" wasremoved: values pointing removed items must removed well, values greater remove location must decreased removedsize

// selectedindices before [2, 4, 5, 8] items.removeall(items.get(3), items.get(5)) // selectedindices after [2, 3, 6]

-> net effect: replace [4, 5, 8] @ pos 1 [3, 6]

wasupdated: indices unchanged, though underlying items did alter somehow. depending on context, might thought pass updates through listener or not.

still open: replaced/permutation in items

to expected (at to the lowest degree paper coding :-) notifications correct, isn't quite trivial - , went wrong in multipleselectionmodelbase , subclasses. playing moving nasty details dedicated indiceslist (which is-a transformlist items sourcelist)

java javafx-8 multipleselectionmodel

No comments:

Post a Comment