4

I'm attempting to implement a MultipleSelectionModel for ControlsFX' GridView. Researching the internet, Jonathan Giles mentioned that it was a bad idea to add listeners to every GridCell. This left me wondering how to notify the selection model of events such selection, deselection etc. Before reading that, I was thinking that the Node used in the GridCell will consume a mouse/touch/key event and use the GridCells' updateSelected method accordingly. My question here is if this updating propagates to any listeners/models at all, or do I have to bind it (somewhere) manually, which I don't know how to do at the moment.

Also, selection models use a read-only observable list, which poses another issue as to how to bind the GridView's data (i.e. items list) to the selection model's list, which I assume is what the model uses for its processes.

I could probably bypass using a selection model altogether, and go with intercepting input events at the Cell/Node level, and do stuff like highlighting on the Cell's updateItem method, while using a backing ObservableList or 2, to track everything, and refresh accordingly, but this isn't the best way, much less a good one. A selection model for GridView, should be the only way to go, which is why I'm here.

Adam Law
  • 542
  • 1
  • 7
  • 21

1 Answers1

3

You don't necessarily have to use a MultiSelectionModel or whatever JavaFX brings along. It's sufficient to use a Set or a List to store the nodes you select.

Here's an example about How to select multiple components of Canvas using ctrl key in javafx? with an answer from me. I guess it covers your needs. If not, please be specific about what you need.

Community
  • 1
  • 1
Roland
  • 18,114
  • 12
  • 62
  • 93
  • that's a really nice answer, Roland, and what I was also thinking to do. It's just that the thread I linked to above gave me pause, seeing that it's coming from one of the authors of ControlsFX, who's also a heavy contributor to OpenJDK and other major projects. I'm implementing GridView in a control where potential users are sort of crazy about hoarding massive troves of images in one location. I'd like the most performant way, and I do not mind if it's also the most difficult. I WILL credit your answer when the time comes, if nothing else comes up. – Adam Law Apr 19 '15 at 23:33
  • Well, I used more than a 1000 nodes and still didn't get a performance problem. Depends on your requirements. Alternatively you can put a single listener on the underlying pane and find the proper node once you click on the pane. But if your users are hording lots of images, I guess you could rather run into a memory problem. – Roland Apr 19 '15 at 23:37
  • That's good to know. Thanks :) 1000 is but a scratch on the surface for the users I've mentioned (and they just seem to hate dividing stuff up into sub-folders), but I know this can be mitigated by only generating what can be actually seen. I really want to use GridView because its layout automatically adjusts to the parent's dimension, which saves me time from implementing something of my own, unless I set things up in a rigid (column) scheme, like the 1 in your solution. It'd be great to hear from the ControlsFX team, since they said they'd accept submissions for GridView with a sel. model. – Adam Law Apr 19 '15 at 23:45
  • I just wanted to say that, while waiting on more answers for my OP, I've implemented your solution and it works really well. I've added some stuff like drag and drop, and started on automating layout adjustment etc.Thanks again for going out of your way to help :) – Adam Law Apr 20 '15 at 05:06
  • Seems no one else will be chiming in. I've worked on your proposed solution enough to say that it will perform well enough for the requirements. Thanks again for all your help. – Adam Law Apr 22 '15 at 09:48
  • @AdamLaw please post some details about the working solution, especially how you detect which cell was clicked. – aditsu quit because SE is EVIL Apr 24 '16 at 06:59
  • Roland's answer holds all the the important details. As for knowing which was clicked, you can let the individual Node handle it. In the case of the example in Roland's answer, it's the ImageViews, so just use any of the mouse events e.g ImageView.setOnMouseReleased to do the handling. – Adam Law Apr 24 '16 at 22:20
  • @AdamLaw I just realized now that Roland is adding a listener to each node, which is exactly what you (and I) didn't want to do. I think I found a better way (event filter on GridView, then `event.getPickResult().getIntersectedNode()`); I'm still working on it. Please ping me if you want to respond to my comment (or else it won't notify me). – aditsu quit because SE is EVIL Apr 27 '16 at 05:39
  • @aditsu Thanks for the info. What was unacceptable was adding a listener per GridCell, as Cells of JavaFX Views are somewhat bloated, so adding to them is really a bad idea. However, for the Roland's approach, it doesn't suffer from the same issue. I think if we analyze the event traversal in the solution you're working on, it won't be that different from directly letting the node handle the event itself. But, yes, I believe both ways would have use cases where they'd shine best. – Adam Law May 04 '16 at 14:53