How to check whether JComponent inside JScrollPane is visible to a user?
Asked Answered
E

1

7

Imagine you have a JScrollPane and many JLabels or any other JComponents added to it.

How would you check if a certain component is visible/partially visible/not visible to user? (scrolling)

I have tried to Google but could not find an easy solution. Is there some existing method I am missing or we have to deal with coordinates and rectangular comparison?

UPD: the following is not working in my case. It seem to relate to JLabel.setVisible(true/false) but not being inside JScrollPane

JLabel.isVisible();
Ervinervine answered 29/11, 2012 at 14:19 Comment(0)
J
14

Have a look at JComponent java doc:

Rectangle r = child.getVisibleRect();
if (r.getSize().equals(child.getSize())) {
   // fully visible
} else if (r.isEmpty()) {
   // not visible
} else {
  // partly visible
}

Edit

changed the condition for not-visible to use Rectangle api - thanks to @mKorbel for reminding me :-)

Jointed answered 29/11, 2012 at 14:32 Comment(9)
@Jointed why not to use if (r.intersects(child)) {Toxicant
@Toxicant an option if you were interested only in whether any part of the child or nothing is visible. And would require a second rectange. Or maybe I misunderstand what you are suggesting?Jointed
I've done that but if you move the scroll bar and some new buttons appear they still print that they are not visible. The r rectangle never changes in respect to the scrollbar nor the components scrollbar. Any solution? Or i am doing something wrong?Rafaelita
i have found a solution. I replaced your first line of code with this: Rectangle r = scrollPane.getViewport().getViewRect(). Where scrollPane obviously is the variable pointing to the Scroll Pane.Rafaelita
you also need to check if the component is already added to the scroll pane (or it's respective parent) because getVisibleRect().isEmpty() will rectangle with the component width and height and 0,0 coordinates.Tal
@Tal you also need to check if the component is already added to the scroll pane hmm .. when the user can scroll it it feels safe to assume that it's added to the scrollpane, or what do I misunderstand?Jointed
I have a use case where I load the text via DB reads and I want to load only for visible components. I do that in separate threads and sometimes it gets invoked after the component is created and has some initial size. It happens on random basis since I'm invoking the thread start through the paint method. Maybe not the best, but possible to have non-empty visible rect for brand new component (check isEmpty() implementation)Tal
@Tal thanks for the clarification :) BTW: invoking the thread start through the paint method sounds like a recipe for desaster - paint methods are for painting, nothing else.Jointed
@Jointed Of course it depends on your logic - the paint attempt is basically my "visible on screen" event, so I just fire an event which start thread only once. Not beautiful but quite sufficient. It's made for proof of concept so I might think for better way in near futureTal

© 2022 - 2024 — McMap. All rights reserved.