1

I am working on a JPanel extension that is only for rendering its contents to a BufferedImage, which I then use as a texture for rendering in OpenGL. For this, I create my special JPanel extension with a layout manager etc., like I would if I was building a normal Swing GUI.

In order to render it to an image, I make sure to call doLayout first and then I use the printAll(java.awt.Graphics) method to print it and the added components:

    Graphics2D g = image.createGraphics();
    printAll(g);

Swing itself (EDT, RepaintManager etc) is never involved, I just create the components (outside any window or frame) and directly use printAll.

This is working perfectly well for most "atomic" components (such as buttons, labels, lists), but I hit on a problem with the JScrollPane. Whatever I try, the JScrollPane will never paint its viewports (the main viewport and the scroll bars) to the given Graphics but only its border, and even manually calling printAll on the viewports yields no result.

I attached two screenshots which show a "before and after" of a simple GUI consisting of a JList and a JButton. On the first image, I use the raw JList, in the second image, I wrapped it into a JScrollPane using new JScrollPane(list).

Using a JList directly Using a JList wrapped in a JScrollPane

I failed to find any magic inside the JScrollPane code related to painting its viewports. Maybe something needs to be initialized that Swing would do, but I forgot. Is there any way I can get those viewports to show up?

pdinklag
  • 1,241
  • 1
  • 12
  • 28
  • Using `validate()` (which needs, in my case, a call to `addNotify()` first) instead of `doLayout()` fixes the problem, thanks! – pdinklag Mar 04 '12 at 08:57
  • Any chance you could make that comment an answer so I can accept it? I'm not sure how to proceed here on StackOverflow if the actual answer is kinda "hidden" in another question's answer and has been hinted using a comment... – pdinklag Apr 10 '12 at 06:35
  • Umm.. apparently not. I just tried that, only to see a new comment with addendum **Trivial answer converted to comment** ;) I'll try again, something a little more subtle. – Andrew Thompson Apr 10 '12 at 06:39

2 Answers2

1

See Why does the JTable header not appear in the image? for some general tips about rendering components to images. Try calling combinations of validate(), addNotify() & doLayout() as mentioned in the code of that thread.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
1

not sure from your question

1) if there is about JScrollPane or JViewport, becasue JViewport is only (from JScrollPane) about visible Rectangle on the screen,

2) every JComponent returns Graphics2D

3) please why do you call doLayout() / addNotify(), in the case that all events for Swing GUI are done on EDT, or are there some events based on Swing Timer

4) better would be edit your question with SSCCE that generated un_wanted output to the GUI

5) for JViewport you have to create and override your own RepaintManager

6) maybe stupid question, please ensure us that there isn't any animations of JComponent, meaning moving accross JScrollPane and freezed on EDT by Thread.sleep(int)

EDIT (could be most important)

7) for OpenGL you have to implements Components based on Java AWT

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I am not sure which of those things do not get clear in my question. I am only just rendering components using their `printAll` methods, there is no EDT (unless the instantiation of a JComponent creates one), there are no events which could be dispatched and I do not use any timers. The _SSCCE_ is just there, do a `printAll` on a component that has not been added to any kind of an actual window (e.g. JFrame) and thus is not managed by Swing's 100s of managers, and you should get a very similar result. – pdinklag Apr 10 '12 at 06:31
  • 1
    @pdinklag there are common areas 1) JComponents, 2) LayoutManager, 3) Graphics2D, 4) working with Graphics2D, 5) printing modified or broken Graphics2D, baterry not included :-) – mKorbel Apr 10 '12 at 06:40