Re: Reacting to mouse events on a TreeCell. Is it supposed to be this awkward?
FYI.. my first test with Java 8 I get the following exception when I try to do: Bindings.select(this.sceneProperty(), "window", "showing").addListener(... (which may not be necessary on JavaFX 8, but I think I need it for 7u40) 10-08 16:07:22 INFO beans [JavaFX Application Thread]: Property 'window' in ReadOnlyObjectProperty [bean: BrowserTreeCell@63eb8c04[styleClass=cell indexed-cell tree-cell]'null', name: scene, value: null] is null java.lang.NullPointerException at com.sun.javafx.binding.SelectBinding$SelectBindingHelper.getObservableValue(Unknown Source) at com.sun.javafx.binding.SelectBinding$AsObject.computeValue(Unknown Source) at javafx.beans.binding.ObjectBinding.get(Unknown Source) at javafx.beans.binding.ObjectExpression.getValue(Unknown Source) at com.sun.javafx.binding.ExpressionHelper$SingleChange.(Unknown Source) at com.sun.javafx.binding.ExpressionHelper$SingleChange.(Unknown Source) at com.sun.javafx.binding.ExpressionHelper.addListener(Unknown Source) at javafx.beans.binding.ObjectBinding.addListener(Unknown Source) On Tue, Oct 8, 2013 at 4:00 PM, Scott Palmer wrote: > Will do. > > I also just noticed (after using Bindings.select(this.sceneProperty(), > "window", "showing") to try to trigger my "diconnecting") that in 7u40 > TreeCells seem to remain connected to the scene until I force the tree to > repaint. > In my app every time I open a document I rebuild a tree. even when > listening to the above mentioned binding, nothing was triggering as I > loaded new documents until I resized my UI. Then suddenly all those unused > TreeCells were "let go". > > > Scott > > > On Tue, Oct 8, 2013 at 3:48 PM, Jonathan Giles > wrote: > >> I note right at the end you say you're using 7u40. In the JavaFX 2.x >> series of releases it is true that TreeView misbehaved a bit around cell >> reuse. This should no longer be the case in JavaFX 8.0. In any case, the >> best option is to file a bug report and discuss it further in there, >> especially so if you can reproduce the issue in JavaFX 8.0. >> >> One thing that sticks out: you don't say if you're using >> WeakEventHandler or EventHandler instances. If you're using EventHandler >> you could consider using WeakEventHandler. This may help to alleviate >> some of the memory leak. >> >> -- Jonathan >> >> On 9/10/2013 8:37 a.m., Scott Palmer wrote: >> > I'm investigating a memory leak and it seems that the culprit is event >> > listeners attached to TreeCells >> > >> > The GC roots of my leaks are deep in the JavaFX window/event system >> > >> > In a class extending TreeCell, am calling methods on such as: >> > >> > setOnContextMenuRequested(contextMenuRequestHandler); >> > setOnMouseClicked(mouseEventHandler); >> > setOnDragDetected(dragDetectedHandler); >> > >> > All of the event handlers in this case will have a reference to the >> > TreeCell, either via the implicit reference of the anonymous inner >> class, >> > or an explicit member >> > >> > I do this in updateItem when the cell is not empty and has a non-null >> item. >> > If updateItem is called and the cell is empty or has a null item then I >> > clear the event handlers with: >> > >> > setOnContextMenuRequested(null); >> > setOnMouseClicked(null); >> > setOnDragDetected(null); >> > >> > The problem is that TreeView doesn't seem to reuse TreeCells very much. >> It >> > mostly creates new ones. This means that many TreeCells are >> disconnected >> > from the scene graph and "lost" while there is still an event handler >> > connected to it. >> > >> > Am I doing something wrong? >> > This seemed like the correct way to deal with dragging and double >> clicking >> > on tree nodes. >> > >> > The tutorial here: >> > http://docs.oracle.com/javafx/2/ui_controls/tree-view.htm#BABDEADA >> > >> > only goes so far as to add a context menu. (My context menu needs to be >> > constructed dynamically.) So I'm not sure if I'm "allowed" to connect >> > event handlers to TreeCells in this way, but I don't know what the >> > alternative is. >> > >> > I suppose I would have to listen to something to ensure the TreeCell is >> > still part of the scene graph and disconnect the listeners when that >> > changes. It seems a bit awkward. >> > >> > >> > Scott >> > (I'm using 7u40) >> >> >
Re: Reacting to mouse events on a TreeCell. Is it supposed to be this awkward?
Will do. I also just noticed (after using Bindings.select(this.sceneProperty(), "window", "showing") to try to trigger my "diconnecting") that in 7u40 TreeCells seem to remain connected to the scene until I force the tree to repaint. In my app every time I open a document I rebuild a tree. even when listening to the above mentioned binding, nothing was triggering as I loaded new documents until I resized my UI. Then suddenly all those unused TreeCells were "let go". Scott On Tue, Oct 8, 2013 at 3:48 PM, Jonathan Giles wrote: > I note right at the end you say you're using 7u40. In the JavaFX 2.x > series of releases it is true that TreeView misbehaved a bit around cell > reuse. This should no longer be the case in JavaFX 8.0. In any case, the > best option is to file a bug report and discuss it further in there, > especially so if you can reproduce the issue in JavaFX 8.0. > > One thing that sticks out: you don't say if you're using > WeakEventHandler or EventHandler instances. If you're using EventHandler > you could consider using WeakEventHandler. This may help to alleviate > some of the memory leak. > > -- Jonathan > > On 9/10/2013 8:37 a.m., Scott Palmer wrote: > > I'm investigating a memory leak and it seems that the culprit is event > > listeners attached to TreeCells > > > > The GC roots of my leaks are deep in the JavaFX window/event system > > > > In a class extending TreeCell, am calling methods on such as: > > > > setOnContextMenuRequested(contextMenuRequestHandler); > > setOnMouseClicked(mouseEventHandler); > > setOnDragDetected(dragDetectedHandler); > > > > All of the event handlers in this case will have a reference to the > > TreeCell, either via the implicit reference of the anonymous inner class, > > or an explicit member > > > > I do this in updateItem when the cell is not empty and has a non-null > item. > > If updateItem is called and the cell is empty or has a null item then I > > clear the event handlers with: > > > > setOnContextMenuRequested(null); > > setOnMouseClicked(null); > > setOnDragDetected(null); > > > > The problem is that TreeView doesn't seem to reuse TreeCells very much. > It > > mostly creates new ones. This means that many TreeCells are disconnected > > from the scene graph and "lost" while there is still an event handler > > connected to it. > > > > Am I doing something wrong? > > This seemed like the correct way to deal with dragging and double > clicking > > on tree nodes. > > > > The tutorial here: > > http://docs.oracle.com/javafx/2/ui_controls/tree-view.htm#BABDEADA > > > > only goes so far as to add a context menu. (My context menu needs to be > > constructed dynamically.) So I'm not sure if I'm "allowed" to connect > > event handlers to TreeCells in this way, but I don't know what the > > alternative is. > > > > I suppose I would have to listen to something to ensure the TreeCell is > > still part of the scene graph and disconnect the listeners when that > > changes. It seems a bit awkward. > > > > > > Scott > > (I'm using 7u40) > >
Re: Reacting to mouse events on a TreeCell. Is it supposed to be this awkward?
I note right at the end you say you're using 7u40. In the JavaFX 2.x series of releases it is true that TreeView misbehaved a bit around cell reuse. This should no longer be the case in JavaFX 8.0. In any case, the best option is to file a bug report and discuss it further in there, especially so if you can reproduce the issue in JavaFX 8.0. One thing that sticks out: you don't say if you're using WeakEventHandler or EventHandler instances. If you're using EventHandler you could consider using WeakEventHandler. This may help to alleviate some of the memory leak. -- Jonathan On 9/10/2013 8:37 a.m., Scott Palmer wrote: > I'm investigating a memory leak and it seems that the culprit is event > listeners attached to TreeCells > > The GC roots of my leaks are deep in the JavaFX window/event system > > In a class extending TreeCell, am calling methods on such as: > > setOnContextMenuRequested(contextMenuRequestHandler); > setOnMouseClicked(mouseEventHandler); > setOnDragDetected(dragDetectedHandler); > > All of the event handlers in this case will have a reference to the > TreeCell, either via the implicit reference of the anonymous inner class, > or an explicit member > > I do this in updateItem when the cell is not empty and has a non-null item. > If updateItem is called and the cell is empty or has a null item then I > clear the event handlers with: > > setOnContextMenuRequested(null); > setOnMouseClicked(null); > setOnDragDetected(null); > > The problem is that TreeView doesn't seem to reuse TreeCells very much. It > mostly creates new ones. This means that many TreeCells are disconnected > from the scene graph and "lost" while there is still an event handler > connected to it. > > Am I doing something wrong? > This seemed like the correct way to deal with dragging and double clicking > on tree nodes. > > The tutorial here: > http://docs.oracle.com/javafx/2/ui_controls/tree-view.htm#BABDEADA > > only goes so far as to add a context menu. (My context menu needs to be > constructed dynamically.) So I'm not sure if I'm "allowed" to connect > event handlers to TreeCells in this way, but I don't know what the > alternative is. > > I suppose I would have to listen to something to ensure the TreeCell is > still part of the scene graph and disconnect the listeners when that > changes. It seems a bit awkward. > > > Scott > (I'm using 7u40)
Reacting to mouse events on a TreeCell. Is it supposed to be this awkward?
I'm investigating a memory leak and it seems that the culprit is event listeners attached to TreeCells The GC roots of my leaks are deep in the JavaFX window/event system In a class extending TreeCell, am calling methods on such as: setOnContextMenuRequested(contextMenuRequestHandler); setOnMouseClicked(mouseEventHandler); setOnDragDetected(dragDetectedHandler); All of the event handlers in this case will have a reference to the TreeCell, either via the implicit reference of the anonymous inner class, or an explicit member I do this in updateItem when the cell is not empty and has a non-null item. If updateItem is called and the cell is empty or has a null item then I clear the event handlers with: setOnContextMenuRequested(null); setOnMouseClicked(null); setOnDragDetected(null); The problem is that TreeView doesn't seem to reuse TreeCells very much. It mostly creates new ones. This means that many TreeCells are disconnected from the scene graph and "lost" while there is still an event handler connected to it. Am I doing something wrong? This seemed like the correct way to deal with dragging and double clicking on tree nodes. The tutorial here: http://docs.oracle.com/javafx/2/ui_controls/tree-view.htm#BABDEADA only goes so far as to add a context menu. (My context menu needs to be constructed dynamically.) So I'm not sure if I'm "allowed" to connect event handlers to TreeCells in this way, but I don't know what the alternative is. I suppose I would have to listen to something to ensure the TreeCell is still part of the scene graph and disconnect the listeners when that changes. It seems a bit awkward. Scott (I'm using 7u40)