1

Given a JScrollPane containing a thousand components using some LayoutManager. Each component can be either in a loaded or unloaded state. There are not enough resources for all to be loaded.

I'd like to have only the visible components load()ed in memory, and the invisible components unload()ed. When the user scrolls, a listener needs to keep updating the components' states: unload() the previously visible, and load() the newly visible.

  1. At any given moment, how do I know which components are visible?
  2. Can I know this without iterating the whole thousand? (as if an efficient viewPort.getVisibleComponents())

I was going to have a prepared sorted list of all component Ys, then in runtime binary search the ViewPort's Y to reach an index which may guide me to the visible ones. This failed as component Ys all returned 0 during list preparation time. This needs to be efficient.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Ten_of_a_Kind
  • 61
  • 1
  • 8
  • 1
    1) *"Each component can be either in a loaded or unloaded state. There are not enough resources for all to be loaded."* Are you certain? How are you certain? OOME? *"This needs to be efficient."* How long does it take to search a list of thousands of objects? (I'm guessing 'not long') 2) Why the need to even 'find objects'? If each has an `Action`, that action will know what to do and should have/be given access to any components (e.g. a progress-bar) that it needs on being created. – Andrew Thompson Nov 21 '12 at 02:03
  • 2
    `JTable` scales well in the thousands regime; load the currently selected row in a `ListSelectionListener`, shown [here](http://stackoverflow.com/a/12306104/230513). – trashgod Nov 21 '12 at 02:06
  • 2
    See also this [*Easy, simple to use LRU cache in Java*](http://stackoverflow.com/q/224868/230513). – trashgod Nov 21 '12 at 02:31
  • 1
    What if you override paintComponent() method for each of the thousand components? hen it's called it's visible. – StanislavL Nov 21 '12 at 05:57
  • @Andrew: Regarding (1) this code will run off a ViewPort changeListener, so yes, any delay is very much felt. (2) The component's Action, namely `load()`, is costly and should only be called for visible components. Calling every component's `load()` defeats the purpose (and will kill resources along the way). – Ten_of_a_Kind Nov 22 '12 at 22:59
  • @trashgod: Regarding (1. Table) I haven't thought of this ... I don't see the connection to any selection-listener, I'm looking for visibility, but maybe its possible on a JTable. Regarding (2 LRU) LRU cache, I think my problem regards more to "who is visible now" and less to the loading ... but if I'm missing your point then can you give me a hint? – Ten_of_a_Kind Nov 22 '12 at 23:00
  • @StanislavL: This is a direction! While it'll only tell me when to `load()`, and not when to `unload()`, it is something to think about... – Ten_of_a_Kind Nov 22 '12 at 23:03

1 Answers1

1

For concreteness, I will assume 1000's of records, each represented by an instance of class Record. Each such Record should contain a unique, meaningful key of type Key.

  • Obtain the List<Key>, possibly in a background task.

  • Construct a one-column TableModel of the key values.

  • Use this model to construct a JTable, table.

  • Add the table to a JScrollPane on the left side of a suitable layout.

  • On the right, add a panel that can Display the details of a single, selected Record.

  • Let Display contain a ListSelectionListener, seen here, that updates the details for whichever Record is currently selected in the table.

  • Add each selected Record to a cache, retrieving the Record from storage, possibly in a background task, only if not already present in the cache.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045