1

Is it possible to cache all row renderers so that each row is rendered just once after table updates? I am not expecting much data.

1 Answers1

3

JTable renderers serve the view; an RTL renderer should have no perceptible overhead unless your model's getValueAt() implementation imposes it. Instead, let your TableModel acquire its data, caching only if necessary. This example extends AbstractTableModel and acquires its entire data on construction. If acquisition will impose a delay, use an instance of SwingWorker, as shown in the API or in this example.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • +1 inspite of torpeding my efforts to wring out some code :-) – kleopatra Aug 28 '12 at 16:16
  • Guilty as charged! I was hoping that @Ahmet might add an RTL renderer to my [example](http://stackoverflow.com/a/9134371/230513) as a test. – trashgod Aug 28 '12 at 16:29
  • 1
    thanks, gonna need some time to digest this info and how it relates to my situation though. I guess the problem is related to this: http://stackoverflow.com/questions/4333577/string-width-via-fontmetrics-calculation-is-very-slow-if-there-are-arabic-or-per – Ahmet Noyan Kızıltan Aug 28 '12 at 18:04
  • This may be (at least partially) platform dependent. If the delay is perceptible, let the model cache each row's completed `TextLayout` where the renderer can access it quickly. – trashgod Aug 28 '12 at 23:27
  • 1
    Yes, the delay is indeed perceptiple. Your suggestion looks promising, but I have two questions; 1) How do I acquire the automatically calculated TextLayout? Do you mean I should calculate it myself? 2) How do I make the renderer use the previously calculated TextLayout? – Ahmet Noyan Kızıltan Nov 08 '12 at 20:17
  • You might looks the examples [here](http://stackoverflow.com/a/5998117/230513), showing how to construct the `TextLayout`, and [here](http://stackoverflow.com/a/4287269/230513), showing how to buffer an image of the rendered text. You'll have to profile to see which would be better. – trashgod Nov 09 '12 at 00:45
  • As in your second example, I used BufferedImage by overriding paintingComponent (instead of setText method) and it is now ultra fast. Do you know how I could multi-line the output? I am using a JTextArea instead of a JLabel in my renderer, which auto-adjusts row sizes according to text lengths. But since now I am using an image instead everything is on one line. – Ahmet Noyan Kızıltan Nov 13 '12 at 21:36
  • Excellent. You can `paint()` any component in a `BufferedImage`, as shown [here](http://stackoverflow.com/a/7028497/230513). – trashgod Nov 13 '12 at 22:48
  • I guess you meant painting JTextArea and caching the BufferedImage to be later returned by getTableCellRendererComponent. So I removed my paintComponent override and tried that. The result: Creating TextLayout dynamically and painting it was lot faster than using setText on JTextArea and caching it. Besides that, caching significiantly increased ram usage. So I guess I will stick with the first technique. But on the other hand, I need to split my string into several lines. The following may solve my problem: http://www.java2s.com/Code/Java/2D-Graphics-GUI/WrapstringaccordingtoFontMetrics.htm – Ahmet Noyan Kızıltan Nov 15 '12 at 15:21