JDK-6726866 : Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u10
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-07-17
  • Updated: 2011-01-19
  • Resolved: 2008-12-03
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u12 b02Fixed 7Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
As discussed in this thread:
  http://forums.java.net/jive/thread.jspa?threadID=43881&tstart=0

The following test case shows rendering artifacts in non-opaque toplevels
when JInternalFrames are used:
public class NonOpaqueWindowTest2 extends JFrame
{
  public NonOpaqueWindowTest2()
  {
    super();    
    setWindowNonOpaque(this);
    
    JDesktopPane desktop = new JDesktopPane();
    JInternalFrame iFrame = new JInternalFrame("Test", true, true, true, true);
    iFrame.add(new JLabel("internal Frame"));
    iFrame.setBounds(10, 10, 300, 200);
    iFrame.setVisible(true);
    desktop.add(iFrame);    
    getContentPane().add(desktop);
    
    setTitle(getClass().getSimpleName());
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(400, 400);
    setLocationRelativeTo(null);
    setVisible(true);
  }
  
  private void setWindowNonOpaque(Window w)
  {
    try 
    {
      Class<?> c = Class.forName("com.sun.awt.AWTUtilities");
      Method m = c.getMethod("setWindowOpaque", Window.class, boolean.class);
      m.invoke(null, w, false);
    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }    
  }
 
  public static void main(String[] args) throws Exception
  {
    EventQueue.invokeLater(new Runnable(){
      public void run()
      {
        JFrame.setDefaultLookAndFeelDecorated(true);
        new NonOpaqueWindowTest2();
      }      
    });
  }  
}

Comments
EVALUATION When FASTER_DRAG_MODE is on, DefaultDesktopManager.dragFrameFaster() is responsible for painting dragged internal frame. However it fails to paint when the top level frame is non-opaque (the new 6u10 feature, see com.sun.awt.AWTUtilities) because AWT invokes frame.paint() to repaint its content and all kind of painting optimizations that are not reflected in paint() method, skipped by AWT. dragFrameFaster() uses RepaintManager.copyArea() to speed the painting up, it is certainly bypasses by usual paint() routine, so this optimizations is to be switched off for non-opaque windows. Another point is OUTLINE_DRAG_MODE, for this property DefaultDesktopManager.dragFrame() paints decorations on the JComponent.safelyGetGraphics(desktopPane); this is also can't be caught by AWT. Supporting this mode for non-opaque window requires non trivial refactoring, because the whole DefaultDesktopManager painting is to be affected. This is too risky for update release. I decided to always use DEFAULT_DRAG_MODE for non-opaque windows, because it seems to be only reliable solution in this situation
20-11-2008

EVALUATION We use painting optimization when internalFrame is being dragged, in this case we use currentManager.copyArea() method which doesn't work for the non-opaque topLevels Note that problems with resizing of internal frames are covered by another CR #6738762
19-08-2008

EVALUATION This is reproducible with and w/o the d3d pipeline enabled it it is likely related to the way repainting of non-opaque swing toplevels is handled.
17-07-2008