participate


Swing - Turning a component into a BufferedImage
This question is answered. Correct Answer available

<<   Back to Forum  |   Give us Feedback
3 Duke Stars rewarded for this thread
This topic has 7 replies on 1 page.
Maxideon
Posts:1,469
Registered: 10/16/08
Re: Turning a component into a BufferedImage      
Oct 30, 2009 9:13 PM (reply 5 of 7)  (In reply to #3 )
Correct
 
doLayout() only lays out the component it's called on, which in this case is a JScrollPane. So the viewport and the scrollbars get size, but not the table, which is a subcomponent of the viewport.

validate() calls validateTree() which does propagate the doLayout. But if you look at the source code for validate() it only does this if the component has a peer (that is, it's displayable). And validateTree() is a protected method, so it can't be called directly.

So in theory, you need to replicate the propagation of doLayout yourself. Perhaps like so,

private static void propagateDoLayout(Component c) {
    synchronized (c.getTreeLock()) {
        c.doLayout();
 
        if (c instanceof Container) {
            for (Component subComp : ((Container) c).getComponents()) {
                propagateDoLayout(subComp);
            }
        }
    }
}


Then in your SSCCE, you simply insert the following statement after you set the size,

public static BufferedImage takeScreenShot(JComponent srs) {
    ...
    srs.setSize(dim);
    propagateDoLayout(srs);
    ...
}


This works ... to a certain extent. The table part is painted correctly, but the column header is suspiciously missing. After digging around a little bit, I found out that the column header isn't added to the JScrollPane until the JTable gets a peer. Here's the source for addNotify() of the JTable class

public void addNotify() {
    super.addNotify();
    configureEnclosingScrollPane();
}


and the configureEnclosingScrollPane() method is what adds the column header. And of course ... it to is a protected method.

So a complete solution would be to override the method and give it public access. You then call it manually, just before you set the size and propagate the doLayout on the JScrollPane.

This of course means that there probably isn't a JComponent to Image method that will always work as intended without putting the JComponent in a packed frame (do to this very case). But you should be able to properly paint most JComponents by setting the size and doing the layout propagation thingy.
 
camickr
Posts:33,025
Registered: 27/02/98
Re: Turning a component into a BufferedImage   
Oct 30, 2009 9:37 PM (reply 6 of 7)  (In reply to #5 )
 
 
doLayout() only lays out the component it's called on,

Good to know.

Here's the source for addNotify() of the JTable class

Wow, I've overriden the addNotify() method before and it always seemed to work. The API description for addNotify() in the JComponent class simply says: "Notifies this component that it now has a parent component"

So, I thought all you needed to do was add a Component to a Container and the addNotify() code would execute immediately. I now see that the addNotify() code won't execute until the Container has a peer.

I'll have to go back over my code to see if the delay in execution will cause problems. Thanks for the heads up!

I'll have to update my ScreenImage link with this usefull information.
 
camickr
Posts:33,025
Registered: 27/02/98
Re: Turning a component into a BufferedImage   
Oct 31, 2009 8:31 AM (reply 7 of 7)  (In reply to #5 )
 
 
Just realized that if you really don't want to use a frame and pack() it, then you should be able to do the following:

JTable table = new JTable(...)
JScrollPane scrollPane = new JScrollPane( table );
scrollPane.setColumnHeaderView( table.getTableHeader() );
scrollPane.setSize(...);
propagateDoLayout( scrollPane );
 
This topic has 7 replies on 1 page.
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 28
  • Guests : 129

About Sun forums
  • Oracle Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Oracle Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums