ListView with ImageViews for cells very bugged?
Kevin Rushforth
kevin.rushforth at oracle.com
Wed Jul 12 14:57:10 UTC 2023
The updateItem docs [1] already say this. I had missed that the test
program didn't do this, so thanks to Ajit for pointing it out.
And yes, https://bugs.openjdk.org/browse/JDK-8090254 should be closed as
not an issue with a reference to the doc bug that clarified this.
-- Kevin
[1]
https://download.java.net/java/early_access/javafx21/docs/api/javafx.controls/javafx/scene/control/Cell.html#updateItem(T,boolean)
On 7/12/2023 7:50 AM, Andy Goryachev wrote:
>
> Ajit is right - perhaps javadoc for updateItem() should explicitly
> mention this?
>
> Also, perhaps https://bugs.openjdk.org/browse/JDK-8090254 should be
> closed - we recently updated javadoc to read
>
>
> Warning: Nodes should not be inserted directly into the items list
>
> (this is a different issue altogether)
>
> -andy
>
> *From: *Ajit Ghaisas <ajit.ghaisas at oracle.com>
> *Date: *Wednesday, July 12, 2023 at 02:26
> *To: *John Hendrikx <john.hendrikx at gmail.com>
> *Cc: *openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>, Andy
> Goryachev <andy.goryachev at oracle.com>
> *Subject: *Re: ListView with ImageViews for cells very bugged?
>
> Hi John,
>
> This looks like a user code issue and not a JavaFX bug.
>
> Most of the vertical scrollbar issues that you have mentioned get
> fixed by adding a call to "super.updateItem(image, empty);" as a first
> call in the cell factory method "protected void updateItem(Image
> image, boolean empty)”
>
> I am seeing an exception when I scroll fully down and then scroll up
> by clicking empty area on the vertical scrollbar. This looks like a
> separate issue though.
>
> Regards,
>
> Ajit
>
>
>
> On 12-Jul-2023, at 5:18 AM, Andy Goryachev
> <andy.goryachev at oracle.com> wrote:
>
> Thank you for the code sample, John!
>
> Had to replace loading from https:// to a local file://, but I do
> see some of the issues you've mentioned (on macOS):
>
> 2), 5), and 6).
>
> There is also a new issue:
>
> 7) when the top of the cell is outside of the view area, the image
> is not shown at all (but the cell is sized correctly).
>
> All this is indeed weird. Looks like the time is right to create a
> bug, unless it's this one:
>
> JDK-8090254 <https://bugs.openjdk.org/browse/JDK-8090254>
>
>
>
> [ListView] page up/down navigation doesn't work, when items are
> large (again!) <https://bugs.openjdk.org/browse/JDK-8090254>
>
> -andy
>
> *From:*openjfx-dev <openjfx-dev-retn at openjdk.org> on behalf of
> John Hendrikx <john.hendrikx at gmail.com>
> *Date:*Tuesday, July 11, 2023 at 16:34
> *To:*openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
> *Subject:*Re: ListView with ImageViews for cells very bugged?
>
> I said I'd do it tomorrow, but here is a full example anyway with
> pre-loaded images, and without external dependencies:
>
> package org.int4.sdui.ui;
>
> import javafx.application.Application;
> import javafx.scene.Scene;
> import javafx.scene.control.Button;
> import javafx.scene.control.ListCell;
> import javafx.scene.control.ListView;
> import javafx.scene.control.TextArea;
> import javafx.scene.image.Image;
> import javafx.scene.image.ImageView;
> import javafx.scene.layout.HBox;
> import javafx.scene.layout.Priority;
> import javafx.scene.layout.VBox;
> import javafx.stage.Stage;
>
> public class Main2 {
>
> public static void main(String[] args) {
> Application.launch(UI.class, args);
> }
>
> public static class UI extends Application {
>
> @Override
> public void start(Stage primaryStage) throws
> InterruptedException {
> Image image1 = new Image("https://picsum.photos/512/512"
> <https://picsum.photos/512/512>);
> Image image2 = new Image("https://picsum.photos/512/512"
> <https://picsum.photos/512/512>);
>
> TextArea prompt = new TextArea("a flower on Mars");
> Button button = new Button("Submit");
> ListView<Image> listView = new ListView<>();
>
> while(image1.isBackgroundLoading() ||
> image2.isBackgroundLoading()) {
> Thread.sleep(100);
> }
>
> listView.getItems().addAll(image1, image2);
> listView.setCellFactory(lv -> {
> final ImageView imageView = new ImageView();
>
> return new ListCell<>() {
> protected void updateItem(Image image, boolean empty) {
> if(empty) {
> setGraphic(null);
> }
> else {
> imageView.setImage(image);
> setGraphic(imageView);
> }
> }
> };
> });
>
> HBox hbox = new HBox() {{
> getChildren().addAll(
> new VBox() {{
> getChildren().addAll(prompt, button);
> }},
> listView
> );
> }};
>
> HBox.setHgrow(listView, Priority.ALWAYS);
>
> Scene scene = new Scene(hbox);
>
> primaryStage.setScene(scene);
> primaryStage.show();
> }
> }
> }
>
>
>
>
>
> --John
>
> On 12/07/2023 01:17, Andy Goryachev wrote:
>
> I'll need to replicate this scenario to be able to say
> anything definitive.
>
> Just by looking at the cell factory code though, I suspect
> there might be some async processing around
>
> new ImageView(new Image(new
> > ByteArrayInputStream(imageHandle.getImageData()))));
>
> which might cause the issue.
>
> Could you try pre-loading images?
>
> -andy
>
> *From:*openjfx-dev<openjfx-dev-retn at openjdk.org>
> <mailto:openjfx-dev-retn at openjdk.org>on behalf of Kevin
> Rushforth<kevin.rushforth at oracle.com>
> <mailto:kevin.rushforth at oracle.com>
> *Date:*Tuesday, July 11, 2023 at 15:58
> *To:*openjfx-dev at openjdk.org<openjfx-dev at openjdk.org>
> <mailto:openjfx-dev at openjdk.org>
> *Subject:*Re: ListView with ImageViews for cells very bugged?
>
> What you have should work, but will create redundant images and
> ImageView ojbects. The recommendation is to create the nodes
> (ImageView
> in this case) in the constructor of the cell factory and call
> setGraphic
> with either null or that factory's node.
>
> Having said that, I doubt that this is related to the visual
> problems
> you are seeing. Maybe Ajit or Andy have some ideas.
>
> -- Kevin
>
>
> On 7/11/2023 3:50 PM, John Hendrikx wrote:
> > I tend to avoid ListView, because for some reason it seems
> to just
> > never do what I want unless used for its mundane rows of
> text use
> > case. I so far always just implemented my own skin for
> ListView that
> > deals with displays that have many images that need to scroll
> > smoothly, but...
> >
> > Recently, I've again attempted to use ListView, this time
> for showing
> > (so far) fixed size ImageViews with images exactly 512x512
> pixels in
> > size:
> >
> > The cell factory looks like this, which I think is a correct
> > implementation:
> >
> > listView.setCellFactory(lv -> {
> > return new ListCell<>() {
> > protected void updateItem(ImageHandle imageHandle,
> boolean
> > empty) {
> > if(empty) {
> > setGraphic(null);
> > }
> > else {
> > try {
> > setGraphic(new ImageView(new Image(new
> > ByteArrayInputStream(imageHandle.getImageData()))));
> > }
> > catch(IOException e) {
> > e.printStackTrace();
> > }
> > }
> > }
> > };
> > });
> >
> > Now, this is with JavaFX 21-ea-24 (but also happens on 19).
> I spotted
> > the following IMHO bugs:
> >
> > 1) When the ImageView is so large that a single row is only
> partially
> > visible, the scrollbar is incorrect (it shows a full bar,
> even if half
> > of a row is displayed).
> >
> > 2) The vertical scrollbar doesn't respond to a click in the
> non-thumb
> > area at all (you'd expect to make it scroll a page up or
> down that way)
> >
> > 3) When jerkily resizing the window, I can sometimes have a
> vertical +
> > horizontal scrollbar when there's a full row visible +
> anywhere from 0
> > to 10 extra empty pixels (probably the potential height of a
> > horizontal scrollbar) with the vertical scroll bar still
> visible. The
> > algorithm to hide the scrollbar apparently is not
> deterministic and
> > depends on mouse movement speed.
> >
> > 4) When a row is less than half visible, scrolling the
> window down to
> > another ImageView will jump the view and hide the first cell
> that
> > should still be visible for the bottom 0-49% of its height.
> >
> > 5) It's possible to get the vertical scroll bar in such a
> state that
> > it doesn't respond to the mouse any more at all, even by
> dragging the
> > thumb. Some keyboard action and mouse scrolling sometimes
> restores it
> > to relatively normal functioning.
> >
> > 6) Mouse wheel scrolling acts weird. With one large cell
> visible and
> > two rows available, scrolling only **down** on the mouse
> wheel will
> > scroll down, then jump back up, and scroll down again... it's
> > impossible to scroll all the way down to get to a point
> where it stops
> > scrolling as it keeps jumping back.
> >
> > This is with ImageView's. I suppose they're known to have
> problems...
> > but then I switched to a Region, which contain an ImageView with
> > proper min/pref/max implementations. This improved the
> situation
> > somewhat. The scrollbar was much more reliable, but I still saw
> > almost all of the above issues, but somewhat more reliable than
> > before. Still rows would disappear when (for the most part)
> > invisible, those and the jumps of the view are just totally
> unacceptable.
> >
> > I'm not quite sure what to make of this, it seems the
> control is not
> > meant for arbitrary graphics.
> >
> > --John
> >
> >
> >
> > package org.int4.sdui.ui;
> >
> > import hs.mediasystem.util.image.ImageHandle;
> > import hs.mediasystem.util.javafx.control.Containers;
> >
> > import java.io.ByteArrayInputStream;
> > import java.io.IOException;
> > import java.util.Base64;
> > import java.util.List;
> >
> > import javafx.application.Application;
> > import javafx.scene.Scene;
> > import javafx.scene.control.Button;
> > import javafx.scene.control.ListCell;
> > import javafx.scene.control.ListView;
> > import javafx.scene.control.TextArea;
> > import javafx.scene.image.Image;
> > import javafx.scene.image.ImageView;
> > import javafx.scene.layout.HBox;
> > import javafx.scene.layout.Priority;
> > import javafx.stage.Stage;
> >
> > import kong.unirest.core.Unirest;
> >
> > public class Main {
> >
> > public static void main(String[] args) {
> > Application.launch(UI.class, args);
> > }
> >
> > public static class UI extends Application {
> >
> > @Override
> > public void start(Stage primaryStage) {
> > TextArea prompt = new TextArea("a flower on Mars");
> > Button button = new Button("Submit");
> > ListView<ImageHandle> listView = new ListView<>();
> >
> > listView.setCellFactory(lv -> {
> > return new ListCell<>() {
> > protected void updateItem(ImageHandle imageHandle,
> boolean
> > empty) {
> > if(empty) {
> > setGraphic(null);
> > }
> > else {
> > try {
> > setGraphic(new ImageView(new Image(new
> > ByteArrayInputStream(imageHandle.getImageData()))));
> > }
> > catch(IOException e) {
> > e.printStackTrace();
> > }
> > }
> > }
> > };
> > });
> >
> > button.setOnAction(e -> {
> > Txt2ImgResponse response =
> textToImage(prompt.getText());
> >
> > for(String image : response.images) {
> > listView.getItems().add(new
> > InMemoryImageHandle(Base64.getDecoder().decode(image)));
> > }
> > });
> >
> > HBox hbox = Containers.hbox(Containers.vbox(prompt,
> button),
> > listView);
> >
> > HBox.setHgrow(listView, Priority.ALWAYS);
> >
> > Scene scene = new Scene(hbox);
> >
> > primaryStage.setScene(scene);
> > primaryStage.show();
> > }
> >
> > private Txt2ImgResponse textToImage(String prompt) {
> > return
> Unirest.post("http://127.0.0.1:7860/sdapi/v1/txt2img")
> > .body(new Txt2Img(prompt, 5))
> > .contentType("application/json")
> > .asObject(Txt2ImgResponse.class)
> > .getBody();
> > }
> > }
> >
> > static class InMemoryImageHandle implements ImageHandle {
> > private final byte[] data;
> >
> > public InMemoryImageHandle(byte[] data) {
> > this.data = data;
> > }
> >
> > @Override
> > public byte[] getImageData() {
> > return data;
> > }
> >
> > @Override
> > public String getKey() {
> > return null;
> > }
> >
> > @Override
> > public boolean isFastSource() {
> > return true;
> > }
> > }
> >
> > record Txt2Img(String prompt, int steps) {}
> > record Txt2ImgResponse(List<String> images) {}
> > }
> >
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20230712/5e78b7c1/attachment-0001.htm>
More information about the openjfx-dev
mailing list