Render only a part of a JTable's model










0















I have a large model to display in a JTable and I need to find a way to paginate the data, in the usual way: display 25 entries, 50, 100, 200, or all, etc. However I need to do this while keeping the ability to sort and filter data, and that should take precedence over the row limit. For example if I have one 1000000 entries from which roughly 50000 begin with each letter, and I want to display the first 100 items then filter only elements that begin with G, I should have the first 100 elements that begin with a G. If I change the filter to B, it should show the first 100 elements that start with a B, which were previously invisible. Also, with no filter, sorting should display the first 100 entries starting with A and sorting again should display the first 100 entries starting with Z.



What I have tried:



  1. Limit the value returned by getRowCount to value k in the model. This doesn't work because is sorts/ filter the original k values.

  2. I have tried to write a custom filter that only accept first k entries. This doesn't work because the filter is applied once before sorting and I don't know how to reapply it after sorting.

  3. Hack my way through the rendered so it doesn't render all cell. Didn't find a way to ask the renderer to do nothing.

Thanks for your help.










share|improve this question






















  • Hack my way through the rendered so it doesn't render all cell - the table will only render the cells that are in the viewport. The problem is the storage of all the data in the TableModel.

    – camickr
    Nov 15 '18 at 15:21















0















I have a large model to display in a JTable and I need to find a way to paginate the data, in the usual way: display 25 entries, 50, 100, 200, or all, etc. However I need to do this while keeping the ability to sort and filter data, and that should take precedence over the row limit. For example if I have one 1000000 entries from which roughly 50000 begin with each letter, and I want to display the first 100 items then filter only elements that begin with G, I should have the first 100 elements that begin with a G. If I change the filter to B, it should show the first 100 elements that start with a B, which were previously invisible. Also, with no filter, sorting should display the first 100 entries starting with A and sorting again should display the first 100 entries starting with Z.



What I have tried:



  1. Limit the value returned by getRowCount to value k in the model. This doesn't work because is sorts/ filter the original k values.

  2. I have tried to write a custom filter that only accept first k entries. This doesn't work because the filter is applied once before sorting and I don't know how to reapply it after sorting.

  3. Hack my way through the rendered so it doesn't render all cell. Didn't find a way to ask the renderer to do nothing.

Thanks for your help.










share|improve this question






















  • Hack my way through the rendered so it doesn't render all cell - the table will only render the cells that are in the viewport. The problem is the storage of all the data in the TableModel.

    – camickr
    Nov 15 '18 at 15:21













0












0








0








I have a large model to display in a JTable and I need to find a way to paginate the data, in the usual way: display 25 entries, 50, 100, 200, or all, etc. However I need to do this while keeping the ability to sort and filter data, and that should take precedence over the row limit. For example if I have one 1000000 entries from which roughly 50000 begin with each letter, and I want to display the first 100 items then filter only elements that begin with G, I should have the first 100 elements that begin with a G. If I change the filter to B, it should show the first 100 elements that start with a B, which were previously invisible. Also, with no filter, sorting should display the first 100 entries starting with A and sorting again should display the first 100 entries starting with Z.



What I have tried:



  1. Limit the value returned by getRowCount to value k in the model. This doesn't work because is sorts/ filter the original k values.

  2. I have tried to write a custom filter that only accept first k entries. This doesn't work because the filter is applied once before sorting and I don't know how to reapply it after sorting.

  3. Hack my way through the rendered so it doesn't render all cell. Didn't find a way to ask the renderer to do nothing.

Thanks for your help.










share|improve this question














I have a large model to display in a JTable and I need to find a way to paginate the data, in the usual way: display 25 entries, 50, 100, 200, or all, etc. However I need to do this while keeping the ability to sort and filter data, and that should take precedence over the row limit. For example if I have one 1000000 entries from which roughly 50000 begin with each letter, and I want to display the first 100 items then filter only elements that begin with G, I should have the first 100 elements that begin with a G. If I change the filter to B, it should show the first 100 elements that start with a B, which were previously invisible. Also, with no filter, sorting should display the first 100 entries starting with A and sorting again should display the first 100 entries starting with Z.



What I have tried:



  1. Limit the value returned by getRowCount to value k in the model. This doesn't work because is sorts/ filter the original k values.

  2. I have tried to write a custom filter that only accept first k entries. This doesn't work because the filter is applied once before sorting and I don't know how to reapply it after sorting.

  3. Hack my way through the rendered so it doesn't render all cell. Didn't find a way to ask the renderer to do nothing.

Thanks for your help.







java swing jtable






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 '18 at 13:12









rhobincurhobincu

6571419




6571419












  • Hack my way through the rendered so it doesn't render all cell - the table will only render the cells that are in the viewport. The problem is the storage of all the data in the TableModel.

    – camickr
    Nov 15 '18 at 15:21

















  • Hack my way through the rendered so it doesn't render all cell - the table will only render the cells that are in the viewport. The problem is the storage of all the data in the TableModel.

    – camickr
    Nov 15 '18 at 15:21
















Hack my way through the rendered so it doesn't render all cell - the table will only render the cells that are in the viewport. The problem is the storage of all the data in the TableModel.

– camickr
Nov 15 '18 at 15:21





Hack my way through the rendered so it doesn't render all cell - the table will only render the cells that are in the viewport. The problem is the storage of all the data in the TableModel.

– camickr
Nov 15 '18 at 15:21












1 Answer
1






active

oldest

votes


















1














Don't mess with the render and table itself - the problem lies elsewhere.



What you need is a table model capable of pagination. You can do pagination in two ways:




  • Site-based pagination (Google style): show N entries per page, and show a specific page only (change the current page using buttons: [<] [1] [2] [3] ... [>])


  • Infinity scrolling: virtual table model, loading visible data on demand. Clearly the better solution, if you ask me.

Implementing infinity scrolling:



  • table model acts as an adapter to a repository, where the actual data is fetched (supporting filtering, pagination (getting the row count and request pages with offset and page size) and sorting).

  • table model caches requested pages of data.

  • when a specific row is requested (over the table model interface), the table model attempts to serve the row from the cache. If the row is not cached, the table model triggers asynchronous page loading and returns an empty (sentinel) row (the cell renderer can then show a loading indicator for such rows).

  • asynchronous page loading loads requested pages from the repository (and makes sure the same page is loaded only once when requesting it multiple times concurrently) and returns them to the table model.

  • the table model, once it receives the asynchronously requested page, fires a table model change event for the rows of the received page, so the table gets properly repainted.

Advantages:



  • to the user, it looks like all the data is available

  • only data which is requested from the model are loaded

  • data gets loaded quickly and asynchronously, making the view very responsive

  • sorting and filtering is done in the backend/repository, so there's no need to process and discard huge amounts of data in the client

  • works well with databases and REST interfaces which support filtering, sorting and pagination.

  • that's really the way JTables are intended to be used (model as adapter, flyweight rendering pattern in the UI).





share|improve this answer


















  • 1





    Thank you for the advice! I was hoping to reuse code instead of refactoring the model, but you're right, your way is probably better.

    – rhobincu
    Nov 15 '18 at 16:37











  • I have begun to write an implementation. A couple of comments: 1: I suppose that when a new filter or sort criterion is set, the cache needs to be flushed. 2: when the table is displayed, it requests all data, not only the viewport rows, as @camickr said. Am I missing something?

    – rhobincu
    Nov 15 '18 at 21:59











  • 1: yes, changing the filter or sorting has to flush the cache, and invalidate all pending async fetch requests. You can use a version counter on the table model, and memorize the version when async loading pages. Increase the version when changing the filter or sorting, and discard loaded pages for previous versions. 2: I just tested it, logging which rows are requested, and only those of the current viewport where requested, not all (not even when quickly scrolling).

    – Peter Walser
    Nov 16 '18 at 11:26










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53320288%2frender-only-a-part-of-a-jtables-model%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Don't mess with the render and table itself - the problem lies elsewhere.



What you need is a table model capable of pagination. You can do pagination in two ways:




  • Site-based pagination (Google style): show N entries per page, and show a specific page only (change the current page using buttons: [<] [1] [2] [3] ... [>])


  • Infinity scrolling: virtual table model, loading visible data on demand. Clearly the better solution, if you ask me.

Implementing infinity scrolling:



  • table model acts as an adapter to a repository, where the actual data is fetched (supporting filtering, pagination (getting the row count and request pages with offset and page size) and sorting).

  • table model caches requested pages of data.

  • when a specific row is requested (over the table model interface), the table model attempts to serve the row from the cache. If the row is not cached, the table model triggers asynchronous page loading and returns an empty (sentinel) row (the cell renderer can then show a loading indicator for such rows).

  • asynchronous page loading loads requested pages from the repository (and makes sure the same page is loaded only once when requesting it multiple times concurrently) and returns them to the table model.

  • the table model, once it receives the asynchronously requested page, fires a table model change event for the rows of the received page, so the table gets properly repainted.

Advantages:



  • to the user, it looks like all the data is available

  • only data which is requested from the model are loaded

  • data gets loaded quickly and asynchronously, making the view very responsive

  • sorting and filtering is done in the backend/repository, so there's no need to process and discard huge amounts of data in the client

  • works well with databases and REST interfaces which support filtering, sorting and pagination.

  • that's really the way JTables are intended to be used (model as adapter, flyweight rendering pattern in the UI).





share|improve this answer


















  • 1





    Thank you for the advice! I was hoping to reuse code instead of refactoring the model, but you're right, your way is probably better.

    – rhobincu
    Nov 15 '18 at 16:37











  • I have begun to write an implementation. A couple of comments: 1: I suppose that when a new filter or sort criterion is set, the cache needs to be flushed. 2: when the table is displayed, it requests all data, not only the viewport rows, as @camickr said. Am I missing something?

    – rhobincu
    Nov 15 '18 at 21:59











  • 1: yes, changing the filter or sorting has to flush the cache, and invalidate all pending async fetch requests. You can use a version counter on the table model, and memorize the version when async loading pages. Increase the version when changing the filter or sorting, and discard loaded pages for previous versions. 2: I just tested it, logging which rows are requested, and only those of the current viewport where requested, not all (not even when quickly scrolling).

    – Peter Walser
    Nov 16 '18 at 11:26















1














Don't mess with the render and table itself - the problem lies elsewhere.



What you need is a table model capable of pagination. You can do pagination in two ways:




  • Site-based pagination (Google style): show N entries per page, and show a specific page only (change the current page using buttons: [<] [1] [2] [3] ... [>])


  • Infinity scrolling: virtual table model, loading visible data on demand. Clearly the better solution, if you ask me.

Implementing infinity scrolling:



  • table model acts as an adapter to a repository, where the actual data is fetched (supporting filtering, pagination (getting the row count and request pages with offset and page size) and sorting).

  • table model caches requested pages of data.

  • when a specific row is requested (over the table model interface), the table model attempts to serve the row from the cache. If the row is not cached, the table model triggers asynchronous page loading and returns an empty (sentinel) row (the cell renderer can then show a loading indicator for such rows).

  • asynchronous page loading loads requested pages from the repository (and makes sure the same page is loaded only once when requesting it multiple times concurrently) and returns them to the table model.

  • the table model, once it receives the asynchronously requested page, fires a table model change event for the rows of the received page, so the table gets properly repainted.

Advantages:



  • to the user, it looks like all the data is available

  • only data which is requested from the model are loaded

  • data gets loaded quickly and asynchronously, making the view very responsive

  • sorting and filtering is done in the backend/repository, so there's no need to process and discard huge amounts of data in the client

  • works well with databases and REST interfaces which support filtering, sorting and pagination.

  • that's really the way JTables are intended to be used (model as adapter, flyweight rendering pattern in the UI).





share|improve this answer


















  • 1





    Thank you for the advice! I was hoping to reuse code instead of refactoring the model, but you're right, your way is probably better.

    – rhobincu
    Nov 15 '18 at 16:37











  • I have begun to write an implementation. A couple of comments: 1: I suppose that when a new filter or sort criterion is set, the cache needs to be flushed. 2: when the table is displayed, it requests all data, not only the viewport rows, as @camickr said. Am I missing something?

    – rhobincu
    Nov 15 '18 at 21:59











  • 1: yes, changing the filter or sorting has to flush the cache, and invalidate all pending async fetch requests. You can use a version counter on the table model, and memorize the version when async loading pages. Increase the version when changing the filter or sorting, and discard loaded pages for previous versions. 2: I just tested it, logging which rows are requested, and only those of the current viewport where requested, not all (not even when quickly scrolling).

    – Peter Walser
    Nov 16 '18 at 11:26













1












1








1







Don't mess with the render and table itself - the problem lies elsewhere.



What you need is a table model capable of pagination. You can do pagination in two ways:




  • Site-based pagination (Google style): show N entries per page, and show a specific page only (change the current page using buttons: [<] [1] [2] [3] ... [>])


  • Infinity scrolling: virtual table model, loading visible data on demand. Clearly the better solution, if you ask me.

Implementing infinity scrolling:



  • table model acts as an adapter to a repository, where the actual data is fetched (supporting filtering, pagination (getting the row count and request pages with offset and page size) and sorting).

  • table model caches requested pages of data.

  • when a specific row is requested (over the table model interface), the table model attempts to serve the row from the cache. If the row is not cached, the table model triggers asynchronous page loading and returns an empty (sentinel) row (the cell renderer can then show a loading indicator for such rows).

  • asynchronous page loading loads requested pages from the repository (and makes sure the same page is loaded only once when requesting it multiple times concurrently) and returns them to the table model.

  • the table model, once it receives the asynchronously requested page, fires a table model change event for the rows of the received page, so the table gets properly repainted.

Advantages:



  • to the user, it looks like all the data is available

  • only data which is requested from the model are loaded

  • data gets loaded quickly and asynchronously, making the view very responsive

  • sorting and filtering is done in the backend/repository, so there's no need to process and discard huge amounts of data in the client

  • works well with databases and REST interfaces which support filtering, sorting and pagination.

  • that's really the way JTables are intended to be used (model as adapter, flyweight rendering pattern in the UI).





share|improve this answer













Don't mess with the render and table itself - the problem lies elsewhere.



What you need is a table model capable of pagination. You can do pagination in two ways:




  • Site-based pagination (Google style): show N entries per page, and show a specific page only (change the current page using buttons: [<] [1] [2] [3] ... [>])


  • Infinity scrolling: virtual table model, loading visible data on demand. Clearly the better solution, if you ask me.

Implementing infinity scrolling:



  • table model acts as an adapter to a repository, where the actual data is fetched (supporting filtering, pagination (getting the row count and request pages with offset and page size) and sorting).

  • table model caches requested pages of data.

  • when a specific row is requested (over the table model interface), the table model attempts to serve the row from the cache. If the row is not cached, the table model triggers asynchronous page loading and returns an empty (sentinel) row (the cell renderer can then show a loading indicator for such rows).

  • asynchronous page loading loads requested pages from the repository (and makes sure the same page is loaded only once when requesting it multiple times concurrently) and returns them to the table model.

  • the table model, once it receives the asynchronously requested page, fires a table model change event for the rows of the received page, so the table gets properly repainted.

Advantages:



  • to the user, it looks like all the data is available

  • only data which is requested from the model are loaded

  • data gets loaded quickly and asynchronously, making the view very responsive

  • sorting and filtering is done in the backend/repository, so there's no need to process and discard huge amounts of data in the client

  • works well with databases and REST interfaces which support filtering, sorting and pagination.

  • that's really the way JTables are intended to be used (model as adapter, flyweight rendering pattern in the UI).






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 15 '18 at 14:25









Peter WalserPeter Walser

10.6k23756




10.6k23756







  • 1





    Thank you for the advice! I was hoping to reuse code instead of refactoring the model, but you're right, your way is probably better.

    – rhobincu
    Nov 15 '18 at 16:37











  • I have begun to write an implementation. A couple of comments: 1: I suppose that when a new filter or sort criterion is set, the cache needs to be flushed. 2: when the table is displayed, it requests all data, not only the viewport rows, as @camickr said. Am I missing something?

    – rhobincu
    Nov 15 '18 at 21:59











  • 1: yes, changing the filter or sorting has to flush the cache, and invalidate all pending async fetch requests. You can use a version counter on the table model, and memorize the version when async loading pages. Increase the version when changing the filter or sorting, and discard loaded pages for previous versions. 2: I just tested it, logging which rows are requested, and only those of the current viewport where requested, not all (not even when quickly scrolling).

    – Peter Walser
    Nov 16 '18 at 11:26












  • 1





    Thank you for the advice! I was hoping to reuse code instead of refactoring the model, but you're right, your way is probably better.

    – rhobincu
    Nov 15 '18 at 16:37











  • I have begun to write an implementation. A couple of comments: 1: I suppose that when a new filter or sort criterion is set, the cache needs to be flushed. 2: when the table is displayed, it requests all data, not only the viewport rows, as @camickr said. Am I missing something?

    – rhobincu
    Nov 15 '18 at 21:59











  • 1: yes, changing the filter or sorting has to flush the cache, and invalidate all pending async fetch requests. You can use a version counter on the table model, and memorize the version when async loading pages. Increase the version when changing the filter or sorting, and discard loaded pages for previous versions. 2: I just tested it, logging which rows are requested, and only those of the current viewport where requested, not all (not even when quickly scrolling).

    – Peter Walser
    Nov 16 '18 at 11:26







1




1





Thank you for the advice! I was hoping to reuse code instead of refactoring the model, but you're right, your way is probably better.

– rhobincu
Nov 15 '18 at 16:37





Thank you for the advice! I was hoping to reuse code instead of refactoring the model, but you're right, your way is probably better.

– rhobincu
Nov 15 '18 at 16:37













I have begun to write an implementation. A couple of comments: 1: I suppose that when a new filter or sort criterion is set, the cache needs to be flushed. 2: when the table is displayed, it requests all data, not only the viewport rows, as @camickr said. Am I missing something?

– rhobincu
Nov 15 '18 at 21:59





I have begun to write an implementation. A couple of comments: 1: I suppose that when a new filter or sort criterion is set, the cache needs to be flushed. 2: when the table is displayed, it requests all data, not only the viewport rows, as @camickr said. Am I missing something?

– rhobincu
Nov 15 '18 at 21:59













1: yes, changing the filter or sorting has to flush the cache, and invalidate all pending async fetch requests. You can use a version counter on the table model, and memorize the version when async loading pages. Increase the version when changing the filter or sorting, and discard loaded pages for previous versions. 2: I just tested it, logging which rows are requested, and only those of the current viewport where requested, not all (not even when quickly scrolling).

– Peter Walser
Nov 16 '18 at 11:26





1: yes, changing the filter or sorting has to flush the cache, and invalidate all pending async fetch requests. You can use a version counter on the table model, and memorize the version when async loading pages. Increase the version when changing the filter or sorting, and discard loaded pages for previous versions. 2: I just tested it, logging which rows are requested, and only those of the current viewport where requested, not all (not even when quickly scrolling).

– Peter Walser
Nov 16 '18 at 11:26



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53320288%2frender-only-a-part-of-a-jtables-model%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3

Museum of Modern and Contemporary Art of Trento and Rovereto