Bugs in TreeTableViewSkin. resizeColumnToFitContent() - labels always ellipsized
Hi, we recently came across some limitations (you might call them bugs) in the tree table implementation. We were unhappy with the default behavior of the tree table implementation. Some columns were always ellipsized and the user would need to manually resize the column to fit the contests. After analysis it turned out that there are various bugs inTreeTableViewSkin. resizeColumnToFitContent(). We subclassed inTreeTableViewSkin and fixed that method (fortunately it's protected ;)). I'l explain the bugs below. Is anyone aware of an existing bug report for this issue? If we have a tree table where the first column contains long text (>80px) and is auto-resizable, then TreeTableViewSkin#resizeColumnToFitContent calculates the preferred width incorrectly and the label is ellipsized (because during layout phase, the calculations are performed in other way). We've found two reasons for that: 1. This method creates mocked cell and row. However for row: * TreeTableRow implementation is used and any custom factories are ignored * Cell is not added to row children. As a result if we have some padding in a cell, based on a row class (e.g..row-class > .cell { -fx-padding: 20px }), then this padding won't be considered while resizeColumnToFitContent 2. When width is calculated for a cell, there is a special method TreeTableCellSkin#leftLabelPadding, which makes offset for a label based on indentation and disclosure node size. However, at the time of calling resizeColumnToFitContent, disclosure size is considered 0 (it's stored in TableRowSkinBase#maxDisclosureWidthMap, which is filled only when row is layouting). One more note - during preferred width calculation, only expanded nodes are considered. This could be expected behaviour, however in some cases it makes sense to have it configurable and make the column suit even collapsed rows I'm keen to hear feedback from the community. We can also share our "fixed" skin which is a subclass of inTreeTableViewSkin. Kind regards, Daniel
RE: Planning for JavaFX.next
Hi, Thanks for collecting feedback! * TableView / TreeTableView: freezing columns (standard in many business apps) * TableView: in "data grid" scenarios it would be nice if the table would provide an API similar to the one in Swing ("void setValueAt(Object aValue, int rowIndex, int columnIndex)") * Focus traversal API -> I think this must be done one day ;) Kind regards, Daniel > -Original Message- > From: openjfx-dev [mailto:openjfx-dev-boun...@openjdk.java.net] On Behalf > Of Jonathan Giles > Sent: Thursday, December 08, 2016 12:45 AM > To: openjfx-dev@openjdk.java.net > Subject: Planning for JavaFX.next > > Hi folks, > > Development on JDK 9 is slowly starting to ramp down, and we are starting to > turn our attention to the goals for JavaFX in JDK 10 and beyond. We are > starting to compile our list of what we think is important, but we really > want to > hear from the community about what their highest priorities are to them. As > always, it's important to keep in mind what JavaFX is (e.g. it isn't aiming > to be a > high-performance game engine), but even still there are bound to be a > number of places where people might want to weigh in, for example: > > * New layout containers (e.g. Flexbox) > * Public APIs for UI control behaviors > * Marlin renderer enabled by default > * Support for CSS animations > * CSS performance improvements > * TableView improvements (cell spanning, row / column freezing, etc) > * TableView performance > * Focus traversal API > * WebGL support in WebView > * Improved image I/O support > * A JavaFX equivalent of the AWT Desktop APIs > * Multi-res image API > * NIO-backed writable images > > If there are other areas of interest that aren't listed here, please start > discussing them and we can work together to determine priorities. > If all you want to do is add a +1 for one of more of the items above, even > that > will be very useful. > > Thanks, > -- Jonathan
RE: JDK-8163078 ArrayIndexOutOfBounds is thrown in Parent.updateCachedBounds
Hi Stefan, >From code review it seems that this is not the case. I'll ask my team mate to >check this programmatically just to make sure... Note that JDK-8163078 contains a code example which reproduces the exception but adds and removes listeners on the JavaFX thread. Kind regards, Daniel > -Original Message- > From: Stefan Fuchs [mailto:snfu...@gmx.de] > Sent: Wednesday, November 09, 2016 7:59 PM > To: Daniel Glöckner; openjfx-dev@openjdk.java.net > Subject: Re: JDK-8163078 ArrayIndexOutOfBounds is thrown in > Parent.updateCachedBounds > > Hi Daniel, > > are you registering or removing the listeners on a thread other than the > JavaFX Application Thread? > I think the Observables are not thread save. > > > -- regards > Stefan > > > Hi guys, > > > > We're facing an exception triggered from Parent.updateCachedBounds. I've > pasted the stack trace below. > > > > This looks very similar to https://bugs.openjdk.java.net/browse/JDK- > 8163078. > > > > We have a few listeners to layoutBounds property, similar to the reporter of > that issue. This seems to trigger the issue. > > > > For us it's hard to reproduce this issue in our application. If the bug > > shows > up the result is quite disastrous though. The application freezes in this > case. > > > > Has anyone observed this bug or is aware of a workaround? P4 suggests that > it's a low priority issue with minor loss of functionality... really? > > > > Kind regards, > > Daniel > > > > ERROR [28.10.16 13:01:45.415] DefaultLogger uncaughtException() > > java.lang.ArrayIndexOutOfBoundsException: -1 > > at java.util.ArrayList.elementData(Unknown Source) > > at java.util.ArrayList.get(Unknown Source) > > at > com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrappe > r.java:89) > > at > com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.ja > va:306) > > at javafx.scene.Parent.updateCachedBounds(Parent.java:1591) > > at javafx.scene.Parent.recomputeBounds(Parent.java:1535) > > at javafx.scene.Parent.impl_computeGeomBounds(Parent.java:1388) > > at > javafx.scene.layout.Region.impl_computeGeomBounds(Region.java:3078) > > at javafx.scene.Node.updateGeomBounds(Node.java:3579) > > at javafx.scene.Node.getGeomBounds(Node.java:3532) > > at javafx.scene.Node.getLocalBounds(Node.java:3480) > > at javafx.scene.Node.updateTxBounds(Node.java:3643) > > at javafx.scene.Node.getTransformedBounds(Node.java:3426) > > at javafx.scene.Node.updateBounds(Node.java:559) > > at javafx.scene.Parent.updateBounds(Parent.java:1719) > > at javafx.scene.Parent.updateBounds(Parent.java:1717) > > at javafx.scene.Parent.updateBounds(Parent.java:1717) > > at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2404) > > at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:355) > > at java.security.AccessController.doPrivileged(Native Method) > > at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354) > > at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381) > > at > com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510) > > at > com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490) > > at > com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(Quantum > Toolkit.java:319) > > at > com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.jav > a:95) > > at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) > > at > com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:19 > 1) > > at java.lang.Thread.run(Unknown Source) > >
JDK-8163078 ArrayIndexOutOfBounds is thrown in Parent.updateCachedBounds
Hi guys, We're facing an exception triggered from Parent.updateCachedBounds. I've pasted the stack trace below. This looks very similar to https://bugs.openjdk.java.net/browse/JDK-8163078. We have a few listeners to layoutBounds property, similar to the reporter of that issue. This seems to trigger the issue. For us it's hard to reproduce this issue in our application. If the bug shows up the result is quite disastrous though. The application freezes in this case. Has anyone observed this bug or is aware of a workaround? P4 suggests that it's a low priority issue with minor loss of functionality... really? Kind regards, Daniel ERROR [28.10.16 13:01:45.415] DefaultLogger uncaughtException() java.lang.ArrayIndexOutOfBoundsException: -1 at java.util.ArrayList.elementData(Unknown Source) at java.util.ArrayList.get(Unknown Source) at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89) at com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306) at javafx.scene.Parent.updateCachedBounds(Parent.java:1591) at javafx.scene.Parent.recomputeBounds(Parent.java:1535) at javafx.scene.Parent.impl_computeGeomBounds(Parent.java:1388) at javafx.scene.layout.Region.impl_computeGeomBounds(Region.java:3078) at javafx.scene.Node.updateGeomBounds(Node.java:3579) at javafx.scene.Node.getGeomBounds(Node.java:3532) at javafx.scene.Node.getLocalBounds(Node.java:3480) at javafx.scene.Node.updateTxBounds(Node.java:3643) at javafx.scene.Node.getTransformedBounds(Node.java:3426) at javafx.scene.Node.updateBounds(Node.java:559) at javafx.scene.Parent.updateBounds(Parent.java:1719) at javafx.scene.Parent.updateBounds(Parent.java:1717) at javafx.scene.Parent.updateBounds(Parent.java:1717) at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2404) at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:355) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354) at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490) at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) at java.lang.Thread.run(Unknown Source)
RE: Running JavaFX headless without native dependencies
Hi, We're successfully running our full-blown JavaFX application on our build server to run automated performance tests. Monocle is used as a renderer. Here are the relevant JVM arguments: -Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw -Dprism.useFontConfig=false -Dprism.fontdir=" + jdk_path + "/jre/lib/fonts" The font dir stuff was required on our build server. I'm sure you need to tweak this to make it work :) Kind regards, Daniel > -Original Message- > From: openjfx-dev [mailto:openjfx-dev-boun...@openjdk.java.net] On Behalf > Of Tobi > Sent: Tuesday, October 04, 2016 10:39 PM > To: openjfx-dev@openjdk.java.net Mailing > Subject: Running JavaFX headless without native dependencies > > Hi, > > is it possible to run JavaFX in a headless mode without native dependencies? > Maybe I could use software rendering or monocle to do it? > > So I would like to cut off the real render part of JavaFX (e.g. OpenGL or > DirectX). > > > Thank you for your help. > > Best, > Tobi
RE: Playing a sound at regular intervals
Hi, Thanks for the explanation. For now we'll use AudioInputStream / Clip from javax.sound.sampled which seems wo work nicely for WAV clips. That API also offers continuous playback but without strange delays ;) Kind regards, Daniel > -Original Message- > From: David DeHaven [mailto:david.deha...@oracle.com] > Sent: Tuesday, August 23, 2016 4:16 PM > To: Daniel Glöckner > Cc: openjfx-dev@openjdk.java.net > Subject: Re: Playing a sound at regular intervals > > > > We're trying to play a notification sound at a regular interval (every > > 500ms) > in a loop. > > > > It should sound like "bing.bing.bing." and not like > > "bing..bing..bing...bing" if > you know what I mean ;) > > > > From the JavaDoc we were guessing that an efficient way to do this would be > to set cycle count to indefinite on the audio clip / on the media player and > call > play() once. > > > > Observations: > > - Cycle count doesn't work for mp3 files. No problem, just use WAV. > > - The playback does not happen at regular intervals. -> not usable in this > scenario > > > > Our solution so far has been to have a scheduled executor which calls > audioclip.play() every 500 ms. This creates a new thread every time (see stack > trace below) and we don't like this approach. > > For the moment this is a better solution, until we can get a few internal > things > fixed in AudioClip. > > In the current implementation there will always be at least one new thread > created. > > > There are bugs filed on this already, specifically: > https://bugs.openjdk.java.net/browse/JDK-8090414 > https://bugs.openjdk.java.net/browse/JDK-8087423 > > And possibly related: > https://bugs.openjdk.java.net/browse/JDK-8088375 > > -DrD-
Playing a sound at regular intervals
Hi, We're trying to play a notification sound at a regular interval (every 500ms) in a loop. It should sound like "bing.bing.bing." and not like "bing..bing..bing...bing" if you know what I mean ;) >From the JavaDoc we were guessing that an efficient way to do this would be to >set cycle count to indefinite on the audio clip / on the media player and call >play() once. Observations: - Cycle count doesn't work for mp3 files. No problem, just use WAV. - The playback does not happen at regular intervals. -> not usable in this scenario Our solution so far has been to have a scheduled executor which calls audioclip.play() every 500 ms. This creates a new thread every time (see stack trace below) and we don't like this approach. Are there any experts for NativeMediaPlayer on this mailing list? Kind regards, Daniel Daemon Thread [Thread-21] (Suspended) owns: NativeMediaAudioClipPlayer (id=1523) NativeMediaPlayer$EventQueueThread(Thread).init(ThreadGroup, Runnable, String, long, AccessControlContext) line: 365 NativeMediaPlayer$EventQueueThread(Thread).init(ThreadGroup, Runnable, String, long) line: 349 NativeMediaPlayer$EventQueueThread(Thread).() line: 445 NativeMediaPlayer$EventQueueThread.(NativeMediaPlayer) line: 386 GSTMediaPlayer(NativeMediaPlayer).(NativeMedia) line: 109 GSTMediaPlayer.(GSTMedia) line: 46 GSTMediaPlayer.(Locator) line: 62 GSTPlatform.createMediaPlayer(Locator) line: 121 PlatformManager.createMediaPlayer(Locator) line: 201 NativeMediaManager.getPlayer(Locator) line: 222 MediaManager.getPlayer(Locator) line: 104 NativeMediaAudioClipPlayer.play() line: 319 NativeMediaAudioClipPlayer.clipScheduler() line: 112 NativeMediaAudioClipPlayer.access$000() line: 47 NativeMediaAudioClipPlayer$Enthreaderator.lambda$static$4() line: 85 2056540299.run() line: not available Thread.run() line: 745
End-to-end performance tests for distributed JavaFX application
Hi, We're looking at developing a performance benchmark suite for our distributed JavaFX application. We want end-to-end metrics which include rendering / event processing in the UI. Example 1) @T_0 server sends update to client, @T_1 client receives the update, @T_2 the update is rendered. Measure T_2 - T_0. Example 2) @T_0 user clicks on a button which triggers a remote action, @T_1 UI has performed the remote call, @T_2 the server has reacted to the call. Measure T_2 - T_0. We want to automate the performance tests so we would need some kind of test driver which would start the UI and "click buttons". Maybe TestFX (https://github.com/TestFX/TestFX), Automaton (https://github.com/renatoathaydes/Automaton) or JemmyFX (https://jemmy.java.net/JemmyFXGuide/jemmy-guide.html) would be a good candidate for this job (example 2). Also, we would need to detect when an update is rendered (example 1). Does anyone on this list have experience with such performance measurements? Any hints appreciated ;) Kind regards, Daniel
RE: Structuring CSS Stylesheets
Hi, > -Original Message- > From: Kevin Rushforth [mailto:kevin.rushfo...@oracle.com] > Sent: Monday, August 15, 2016 6:02 PM > To: David Grieve > Cc: Daniel Glöckner; openjfx-dev@openjdk.java.net > Subject: Re: Structuring CSS Stylesheets > > One slight correction on how to contribute below. > > > David Grieve wrote: > > > > > > On 8/15/16 10:52 AM, Daniel Glöckner wrote: > >>>> We found the culprits by patching the JRE, adding some statistics > >>>> to SimpleSelector and CompoundSelector. I was wondering whether > >>>> there are easier ways but anyway, it works ;) > >>> This sounds like some code that would be good to share with the > >>> community. :) > >> [DG] Sure thing. It's not too complicated and doesn't use external > >> libs. Any hint where I could post it / paste it? > > See https://wiki.openjdk.java.net/display/OpenJFX/Community for how to > > contribute > > That page is just a placeholder, and finding what you need in the sub-pages a > bit tricky. See the following page for how to contribute: > > http://openjdk.java.net/contribute/ > > -- Kevin > > > >> need them, for example our UI component factory would add table.css > >> to a TableView's list of stylesheets (tv. > >> getStylesheets().add("/path/to/table.css"). > >> The global theme.css would be minimal and only define colors and fonts. > >>>> What do you think about this approach? Will this work nicely with > >>>> caching of > >>> CSS styles in JavaFX? > >>> I think if you are going to go this route, you might want to use > >>> Region#getUserAgentStylesheets() which adds the styles as user-agent > >>> styles. > >>> But I don't think it will buy you much in terms of CSS performance. > >> [DG] We also want to control / override the CSS of standard JavaFX > >> controls like TreeTableView. Ideally we don't need to sub class them > >> so we would need to use parent. getStylesheets().add(), right? > > I doubt that getUserAgentStylesheets() or getStylesheets() is going to > > have much impact. My guess is that having the stylesheets added to the > > scene is going to be your best bet. I say this because the code that > > does the style matching has to combine styles together from > > Region#getUserAgentStylesheets() and Parent#getStylesheets(), whereas > > the styles from scene stylesheets are already combined. You have to > > think of these different sources of styles as sets of styles. When you > > have Region or Parent stylesheets, you have to create a union of those > > styles with the default user-agent stylesheets (e.g., caspian.css). > > With just scene stylesheets, you have just one set (this isn't 100% > > accurate, but close enough for this discussion). OK. So if we're talking about performance it might be a good idea to add the CSS to the scene and make sure that all CSS selectors are efficient. > > > >>> If you the biggest bang for your buck relative to JavaFX CSS > >>> performance, avoid style lookup and relative font sizes. > >> [DG] Could you explain what you mean by "avoid style lookups"? > > You know about styles like '-fx-base' used in caspian.css. You change > > the color for -fx-base and the basic colors of the UI change. This > > magic happens at runtime. So if I have a label in a cell in a table, > > and it has a style "-fx-border-color: -fx-base", JavaFX will - at > > runtime - try to resolve -fx-base into an actual color. It starts at > > the leaf and looks tries to resolve -fx-base. If it can't resolve it, > > it looks for a style in the parent node, and so on up the parent-chain > > all the way to the root node. The worst case scenario, then, is that > > there are no styles that resolve the value until you get to .root. > > > > This is what I mean by 'style lookups'. > > > > Its great stuff (the brainchild of Jasper Potts) because I can change > > the look of my UI just by setting '-fx-base'. But if I were developing > > a UI and I didn't care to let the users of my UI make such changes, > > I'd go through and remove all the lookups in caspian.css (not trivial > > because there are many many lookups - not just -fx-base). Or use a > > pre-processor such as SASS or LESS. > > > > The same sort of lookup happens when you have an em (or other relative > > size) because you need a font or a font-size to complete the > > calculation. In most cases, the lookup for a font or font-size goes > > all the way to .root, where it fails and falls back on > > Font.getDefault(). But its a trade off since em sizes let your UI more > > easily scale to different displays. > > Thanks a lot for the in-depth explanation. We're using a lot of style lookups in our CSS, mostly to define colors similar to -fx-base in your example. We will look at using a preprocessor as you suggested. This was anyway on our TODO list to be able to support user specific font sizes.
Focus Traversal of Nodes / Cells in TreeTableView
Hi, We're trying to implement an editable data grid using a TreeTableView. The tree table contains nodes: List> columns = ...; theTreeTable.getColumns().setAll(columns); Some of the nodes are custom controls (basically advanced text fields) which are editable: someColumn.setCellValueFactory(cellDate -> { SomeModel lineModel = cellDate.getValue().getValue(); Node someEditor = GuiComponentUtils.createEditorComponent(); someEditor.setModel(lineModel); return new SimpleObjectProperty<>( someEditor); }); The task at hand is to make these controls focus traversable (column by column and row by row). We have to consider the case that the table is not fully visible, i.e. wrapped in a ScrollPane. This does not work out of the box since the components might not exist if they are not visible. Any ideas how this could be implemented? Is this case considered at all in JavaFX's implementation of focus traversal? Maybe it will be in Java 9? Kind regards, Daniel
RE: Structuring CSS Stylesheets
Hi, Thanks a lot for your comments, David. > -Original Message- > From: openjfx-dev [mailto:openjfx-dev-boun...@openjdk.java.net] On Behalf > Of David Grieve > Sent: Monday, August 15, 2016 4:35 PM > To: openjfx-dev@openjdk.java.net > Subject: Re: Structuring CSS Stylesheets > > > > On 8/15/16 9:46 AM, Daniel Glöckner wrote: > > Hi, > > > > We recently came across a number of performance issues which were caused > by our poor CSS. > > > > Our stylesheet contained too many selectors, specifically too many generic > selectors targeting "common" JavaFX controls (.text, .label etc.). > Make the selectors as specific as possible. Avoid the universal selector '*' > if you > can. > > > > We found the culprits by patching the JRE, adding some statistics to > > SimpleSelector and CompoundSelector. I was wondering whether there are > > easier ways but anyway, it works ;) > This sounds like some code that would be good to share with the community. :) [DG] Sure thing. It's not too complicated and doesn't use external libs. Any hint where I could post it / paste it? > > > > We've meanwhile improved our CSS performance (by making a bunch of > selectors more specific) but want to re-structure the stylesheets to be more > future-proof (with even better performance ;)). > > > > Could you quickly comment on the following idea? > > > > Our CSS is already divided into several stylesheets (e.g. table.css, some- > dialog.css etc.). > > These stylesheets are all imported via @import into a global theme.css. > theme.css is then added to the scene. > > > > We're thinking about adding the individual stylesheets only to nodes which > need them, for example our UI component factory would add table.css to a > TableView's list of stylesheets (tv. > getStylesheets().add("/path/to/table.css"). > The global theme.css would be minimal and only define colors and fonts. > > > > What do you think about this approach? Will this work nicely with caching of > CSS styles in JavaFX? > I think if you are going to go this route, you might want to use > Region#getUserAgentStylesheets() which adds the styles as user-agent styles. > But I don't think it will buy you much in terms of CSS performance. [DG] We also want to control / override the CSS of standard JavaFX controls like TreeTableView. Ideally we don't need to sub class them so we would need to use parent. getStylesheets().add(), right? > > If you the biggest bang for your buck relative to JavaFX CSS performance, > avoid > style lookup and relative font sizes. [DG] Could you explain what you mean by "avoid style lookups"?
Structuring CSS Stylesheets
Hi, We recently came across a number of performance issues which were caused by our poor CSS. Our stylesheet contained too many selectors, specifically too many generic selectors targeting "common" JavaFX controls (.text, .label etc.). We found the culprits by patching the JRE, adding some statistics to SimpleSelector and CompoundSelector. I was wondering whether there are easier ways but anyway, it works ;) We've meanwhile improved our CSS performance (by making a bunch of selectors more specific) but want to re-structure the stylesheets to be more future-proof (with even better performance ;)). Could you quickly comment on the following idea? Our CSS is already divided into several stylesheets (e.g. table.css, some-dialog.css etc.). These stylesheets are all imported via @import into a global theme.css. theme.css is then added to the scene. We're thinking about adding the individual stylesheets only to nodes which need them, for example our UI component factory would add table.css to a TableView's list of stylesheets (tv. getStylesheets().add("/path/to/table.css"). The global theme.css would be minimal and only define colors and fonts. What do you think about this approach? Will this work nicely with caching of CSS styles in JavaFX? Kind regards, Daniel