The Source for Java Technology Collaboration
User: Password:



Alexander Potochkin

Alexander Potochkin's Blog

Debug Swing repainting

Posted by alexfromsun on November 06, 2007 at 11:22 AM | Comments (9)

As everybody knows if you need to repaint a Swing component you should call Component.repaint() method, another well-known tip for the fast painting is:

If only part of your component needs to be updated, make paint requests using a version of repaint that specifies the painting region.

It is very simple piece of advice - not to paint more than you need, but sometimes this situation is not easy to catch. Usually it is obvious when you paint less than you need, but repainting something which hasn't been changed is a kind of "invisible" operation.

If the whole frame is repainted when any of its children is repainted you would hardly notice it on modern computer and that is the reason why I decided to return to my old love, Swing debugging and add one debugging tool to JXLayer project

A visual indication for repainting events must work for every component, no matter which color it is painted, so I created an elegant layer's UI delegate which catches repainting and shows fade-out effect using inverted colors for a repainted area.

With this painter you can study your GUI and eliminate unnecessary painting, moreover it is very interesting just to see how Swing paints the core components - what part of a JTree is repainted when you open a node? What is repainted when you open a popup ?
Now it easy to get answers for this kind of questions.

For example, it is easy to see what part of JTextField is repainted when you type in it and what happens when JTree's selection is changed.I was also very pleased to check that we don't paint more than we need when selection of JTable is changed (second tab in the demo)

I hope you'll find it useful for painting optimization for your custom components and LookAndFeels.
As usual it works for all LookAndFeels, the only thing you need is to wrap a container with your components with JXLayer and set DebugPainter from JXLayer's demo package.

A flash presentation is available, press the green button below to start:

Have a nice day
alexp


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Wow!
    It's charming to see DebugPainter at work and it seems to be very useful too.
    I'll try it soon in my application.

    Thanks,
    Davide

    Posted by: davide71 on November 06, 2007 at 12:23 PM

  • Hi Alex,
    After trying DebugPainter in my application, using many custom components from mine and third party libraries, I can surely say that
    it's not only a useful debugging tool but also a wonderful teaching tool revealing in an intuitive manner how and when swing paints components.
    I'm learning a lot from your blog. Well Done!
    FYI, the new binary distribution has been likely compiled with JDK 1.7.
    However sources still work fine with JDK 1.5.

    Thanks,
    Davide

    Posted by: davide71 on November 06, 2007 at 03:48 PM

  • Hello Davide

    Thank you for your comment!

    it's not only a useful debugging tool but also a wonderful teaching tool revealing in an intuitive manner how and when swing paints components
    I enjoy this phrase :-)

    the new binary distribution has been likely compiled with JDK 1.7.
    Ops, recompiled with JDK 1.5 and committed to CVS;
    the official JDK for SwingHelper projects is 1.5, thanks for noticing it

    Have a look to another demos from SwingHelper
    they may be useful for your projects as well

    Thanks
    alexp


    Posted by: alexfromsun on November 07, 2007 at 12:42 AM

  • Great tool! Nice idea.

    Posted by: vity01 on November 07, 2007 at 09:35 AM

  • Hi Alex,
    I looked at JXLayer demos. They are really interesting and your blogs even more (I'm eager to learn best practices).
    I mean, when I read that multiple glasspane tricks can interfere each other suddenly I realized I have a problem.
    My project adopts an improved implementation of TreeOverlay and AutoScroll from Santhosh's blog, but the approach is the same.
    To better understand what I'm talking about please look at
    http://www.jroller.com/page/santhosh/20050522#partially_visible_jtree_nodes
    and
    http://www.jroller.com/santhosh/entry/enhanced_scrolling_in_swing
    Individually these features work fine, but both replace glasspane, so when the user presses
    the middle mouse button on a partially visible node of a scrollable tree a conflict rises.

    Do you think JXLayer can be used to successfully implement TreeOverlay and/or AutoScroll so that they can coexist with no conflict?

    Thanks
    Davide

    Posted by: davide71 on November 11, 2007 at 10:15 AM

  • Hello Davide

    TreeOverlay is an iteresting approach, but I would look for a piece of code
    which allows data tips to go outside of the frame
    (it can't be implemented with a GlassPane)
    This project sounds interesting - https://datatips.dev.java.net/

    As for AutoScroll, it can definitely be done with JXLayer
    wrap your scrollPane with JXLayer and to the same stuff as Santosh does
    with the exception that the scroll icon will be painted with layer's painter

    Thanks
    alexp

    Posted by: alexfromsun on November 12, 2007 at 10:15 AM

  • this is a cool idea. I don't know if giving the developer feedback as when it repaints an unexpected area would be useful, but maybe.

    Posted by: ah_um on November 14, 2007 at 02:31 PM

  • Hello Alex,
    thanks for the datatips project link.
    Unfortunately it has four open bugs and it has been likely abandoned from his author two years ago.
    However his approach is very interesting. I'll study his code.
    The following link seems to be very interesting too.
    http://www.jroller.com/swinguistuff/entry/jtree_show_clipped_cells

    As for AutoScroll, thanks again for your hint.
    Wrapping each JScrollPane in a project with a JXLayer using a ScrollIconPainter works fine.
    But what I really appreciate in Santhosh's approach is you can get the enhanced
    scrolling to all JScrollPanes of an application with just a single line of code.
    Theoretically, you can install this feature even if you have no application's sources. It seems magic! :-)
    Simply wrap application's main method like the following:

    public static void main(String[] args) {
    // initializes and installs enhanced scrolling
    ScrollGestureRecognizer.getInstance();

    // runs the original main method
    OriginalMainClass.main(args);
    }

    Well, that's not my case... I own my application sources. :-)
    However, I would like to achieve this goal with JXLayer too, so that all my projects soon can have autoscroll ability without modifying existing code.
    But while dinamically setting/restoring at runtime a glasspane it's trivial (and you teach me unsafe too), wrapping/unwrapping doesn't.
    I mean, I would like to wrap/unwrap a scrollpane with JXLayer transparently at runtime when the user starts/stops scrolling.
    With the following approach

    Container parent = scrollPane.getParent();
    parent.remove(scrollPane);
    parent.add(new JXLayer(scrollPane));

    the result depends on the container's layout, thus
    you have no grant the new component will be in the same place of the old one.
    Is there a layout-indipendent solution to replace a component inside a container without loosing his original location?
    I tried and googled around with no success.
    Am I missing something?

    Thanks in advance
    Davide

    Posted by: davide71 on November 17, 2007 at 06:44 AM

  • Hello Davide
    Installing glassPane is very easy, that's right
    it is a global resource which usually doesn't affect the other components in the frame
    JXLayer is an extra layer for a particular component,
    so it is supposed to be added in development time, not in runtime
    it's like - if you need to decorate your component wrap it with JXLayer and whatever you need
    but if you don't want to change your code, a GlassPane which combines datalips and mouseScrolling might be a solution for you

    is there a layout-indipendent solution to replace a component inside a container without loosing his original location?


    I am afraid there is no general solution even how to remove one component
    and then return it back to its original place

    Thanks
    alexp

    Posted by: alexfromsun on November 19, 2007 at 05:32 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds