Re: ScrollPane.prefViewportWidth == computed size?
A similar, or at least related, issue I created a while back: https://javafx-jira.kenai.com/browse/RT-17988 On 04/06/2013, at 5:28 AM, Werner Lehmann wrote: > Hi Richard, > > thanks for the quick reply. FYI, I am currently using a hardcoded value with > some extra space, hopefully sufficient for all platforms. > > On 03.06.2013 20:57, Richard Bair wrote: >> I think calling it a bug would be fair, and this approach should work. > > I'll create a ticket later. > >> Hmmm. I guess fitToWidth doesn't work for you because you want the >> content to dictate the size of the scroll pane, and not the other way >> around? Maybe a combination of this and a subclass to work around the >> issue you are seeing? > > Exactly. fitToWidth removes the horizontal scrollbar but abbreviates the > label text ("..."). The suggested subclass approach does not work because > prefWidth() is final in Control. Is there any event I could listen for to > update the prefWidth? I tried "onSceneChange" but that seems to be too early > as prefWidth(-1) returns 0.0 then. > >> Or maybe the ScrollPane, when fitToWidth is true, automatically >> adjusts its pref width to match that of its content? That would seem >> to be the "right" thing to do in this case, but I don't know that it >> does (or that it makes sense in all cases?). > > ScrollPane.fitToWidth resizes its content (if resizable) to its viewport > width. Does nothing if content is not resizable, and does not seem to change > ScrollPane.prefWidth. I'd say "fit-to-width" could mean both: "fit content to > viewport width" and "fit viewport width to content". The former is already > implemented, of course. No horizontal scrollbar in either case. > >> So it seems to me that there are at least 2 different ways we could >> go about supporting this specific use case, one seems like a >> straightforward thing (let -1 have meaning for prefViewportWidth) and >> one is the result of a perhaps questionable interpretation >> (fitToWidth=true changes the way we compute the prefWidth of the >> ScrollPane). Both seem reasonable ways to have tried to use the >> control and both yield unexpected results it sounds like. > > The binding was not really obvious to me but eventually I arrived here and it > would be nice to have this working. Additional API would make this easier to > find but it might be hard to come up with something which makes sense in the > API and does not change or conflict with existing API. > > Werner
Re: ScrollPane.prefViewportWidth == computed size?
Hi Richard, thanks for the quick reply. FYI, I am currently using a hardcoded value with some extra space, hopefully sufficient for all platforms. On 03.06.2013 20:57, Richard Bair wrote: I think calling it a bug would be fair, and this approach should work. I'll create a ticket later. Hmmm. I guess fitToWidth doesn't work for you because you want the content to dictate the size of the scroll pane, and not the other way around? Maybe a combination of this and a subclass to work around the issue you are seeing? Exactly. fitToWidth removes the horizontal scrollbar but abbreviates the label text ("..."). The suggested subclass approach does not work because prefWidth() is final in Control. Is there any event I could listen for to update the prefWidth? I tried "onSceneChange" but that seems to be too early as prefWidth(-1) returns 0.0 then. Or maybe the ScrollPane, when fitToWidth is true, automatically adjusts its pref width to match that of its content? That would seem to be the "right" thing to do in this case, but I don't know that it does (or that it makes sense in all cases?). ScrollPane.fitToWidth resizes its content (if resizable) to its viewport width. Does nothing if content is not resizable, and does not seem to change ScrollPane.prefWidth. I'd say "fit-to-width" could mean both: "fit content to viewport width" and "fit viewport width to content". The former is already implemented, of course. No horizontal scrollbar in either case. So it seems to me that there are at least 2 different ways we could go about supporting this specific use case, one seems like a straightforward thing (let -1 have meaning for prefViewportWidth) and one is the result of a perhaps questionable interpretation (fitToWidth=true changes the way we compute the prefWidth of the ScrollPane). Both seem reasonable ways to have tried to use the control and both yield unexpected results it sounds like. The binding was not really obvious to me but eventually I arrived here and it would be nice to have this working. Additional API would make this easier to find but it might be hard to come up with something which makes sense in the API and does not change or conflict with existing API. Werner
Re: ScrollPane.prefViewportWidth == computed size?
> Problem: this works only if the content prefWidth is set explicitly. If it is > -1, prefViewportWidth is also -1 (because it is bound) and that computes a > value too small to fit the (computed) prefWidth of the content, leading to a > horizontal scrollbar. Is this a bug I think calling it a bug would be fair, and this approach should work. > or am I supposed to do this differently? Hmmm. I guess fitToWidth doesn't work for you because you want the content to dictate the size of the scroll pane, and not the other way around? Maybe a combination of this and a subclass to work around the issue you are seeing? public class MyScrollPane extends ScrollPane { public MyScrollPane() { setFitToWidth(true); } @Override protected double prefWidth(double height) { Insets insets = getInsets(); return insets.getLeft() + content.prefWidth(height) + insets.getRight()); } } Ok I didn't try compiling that ("content" for sure will break) but this should set the pref width of the scroll pane based on the pref width of the content, and then add in the padding (for whatever kind of border you may have supplied). This might still be wrong because it doesn't take into account the scroll bar width when the vertical scrollbar is shown. Bummer. Or maybe the ScrollPane, when fitToWidth is true, automatically adjusts its pref width to match that of its content? That would seem to be the "right" thing to do in this case, but I don't know that it does (or that it makes sense in all cases?). So it seems to me that there are at least 2 different ways we could go about supporting this specific use case, one seems like a straightforward thing (let -1 have meaning for prefViewportWidth) and one is the result of a perhaps questionable interpretation (fitToWidth=true changes the way we compute the prefWidth of the ScrollPane). Both seem reasonable ways to have tried to use the control and both yield unexpected results it sounds like. Richard
ScrollPane.prefViewportWidth == computed size?
Hi, I am trying to show a ScrollPane resized so that the full width of its content is visible: no horizontal scrolling, no clipping, no content resizing. Only vertical scrolling if necessary. Seems as if prefViewportWidth should do the trick. Since I don't want to hardcode some width I am binding it to the prefWidth of the scrollpane content. Problem: this works only if the content prefWidth is set explicitly. If it is -1, prefViewportWidth is also -1 (because it is bound) and that computes a value too small to fit the (computed) prefWidth of the content, leading to a horizontal scrollbar. Is this a bug, or am I supposed to do this differently? Here is a test case. It only works if vb.prefWidth is set explicitly at the end. Which of course is not a dynamic value... public class PrefViewportTest extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) throws Exception { // Scene -> HBox -> ScrollPane -> VBox -> Label Label l = new Label("some boring not too short text"); VBox vb = new VBox(); vb.getChildren().add(l); ScrollPane sp = new ScrollPane(); sp.setContent(vb); sp.prefViewportWidthProperty().bind(vb.prefWidthProperty()); HBox hb = new HBox(); hb.getChildren().add(sp); primaryStage.setScene(new Scene(hb, 300, 200)); primaryStage.show(); System.out.println("before: " + vb.getPrefWidth()); // prints -1.0 vb.setPrefWidth(vb.prefWidth(-1)); System.out.println("after: " + vb.getPrefWidth()); // prints 164.0 } } Rgds Werner